Errors
API error codes and handling.
Error Handling
The Coline API returns structured errors that help you diagnose and handle issues programmatically.
Error Response Format
All errors follow a consistent format:
{
"error": {
"code": "not_found",
"message": "File not found"
}
}HTTP Status Codes
400 Bad Request
The request was malformed or contains invalid parameters.
{
"error": {
"code": "invalid_request",
"message": "Missing required field: name"
}
}Common causes:
- Missing required parameters
- Invalid JSON in request body
- Invalid parameter types
- Validation failures
401 Unauthorized
Authentication failed. The request lacks valid credentials.
{
"error": {
"code": "unauthorized",
"message": "Invalid or expired token"
}
}Common causes:
- Missing
Authorizationheader - Invalid API key or OAuth token
- Expired token
- Revoked API key
Action: Check your credentials and regenerate if needed.
403 Forbidden
The user is authenticated but not authorized to perform this action.
{
"error": {
"code": "forbidden",
"message": "Insufficient permissions to access this resource"
}
}Common causes:
- API key lacks required scopes
- User doesn't have access to the workspace
- Resource has restricted permissions
- OAuth app wasn't granted required scopes
Action: Check permissions and request additional scopes if using OAuth.
404 Not Found
The requested resource doesn't exist.
{
"error": {
"code": "not_found",
"message": "File not found"
}
}Common causes:
- Resource was deleted
- Wrong ID or slug
- Resource belongs to a different workspace
Action: Verify the resource ID or handle gracefully for deleted resources.
409 Conflict
The request conflicts with the current state of the resource.
{
"error": {
"code": "conflict",
"message": "A file with this name already exists"
}
}Common causes:
- Duplicate names in the same folder
- Concurrent modification conflicts
- Resource already exists
Action: Use unique names or check existence before creating.
422 Unprocessable Entity
The request was understood but contains semantic errors.
{
"error": {
"code": "validation_failed",
"message": "Invalid date format"
}
}Common causes:
- Invalid data formats
- Business rule violations
- Schema validation failures
429 Too Many Requests
Rate limit exceeded.
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded. Try again in 60 seconds."
}
}Action: Implement exponential backoff and respect the Retry-After header.
500 Internal Server Error
Server-side error occurred.
{
"error": {
"code": "internal_error",
"message": "An unexpected error occurred"
}
}Action: Retry with exponential backoff. Contact support if persistent.
502/503/504 Gateway/Service Errors
Temporary server or gateway issues.
Action: Retry with exponential backoff.
Error Codes Reference
| Code | HTTP Status | Description |
|---|---|---|
invalid_request | 400 | Malformed request |
validation_failed | 400/422 | Validation error |
unauthorized | 401 | Authentication failed |
forbidden | 403 | Permission denied |
not_found | 404 | Resource not found |
conflict | 409 | State conflict |
rate_limited | 429 | Rate limit exceeded |
internal_error | 500 | Server error |
Handling Errors in Code
With the SDK
import { ColineApiError, isColineApiError } from '@colineapp/sdk'
try {
const file = await ws.getFile('file_123')
} catch (error) {
if (isColineApiError(error)) {
switch (error.status) {
case 401:
console.error('Auth failed - refresh credentials')
break
case 403:
console.error('Permission denied - check scopes')
break
case 404:
console.error('File not found - may have been deleted')
break
case 429:
const delay = 60 // Use Retry-After header
await sleep(delay * 1000)
break
default:
if (error.isRetryable) {
// Retry with backoff
}
}
}
}With Raw HTTP
const response = await fetch('https://api.coline.app/v1/...', {...})
if (!response.ok) {
const error = await response.json()
console.error(`Error ${response.status}:`, error.error.message)
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After')
await sleep(parseInt(retryAfter) * 1000)
}
}Retry Strategies
Exponential Backoff
async function withRetry(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn()
} catch (error) {
if (!isColineApiError(error) || !error.isRetryable) {
throw error
}
const delay = Math.pow(2, i) * 1000
await sleep(delay)
}
}
throw new Error('Max retries exceeded')
}Circuit Breaker Pattern
For production applications, consider implementing a circuit breaker to prevent cascading failures during API outages.
Logging Errors
Log errors with context for debugging:
catch (error) {
if (isColineApiError(error)) {
logger.error({
status: error.status,
code: error.code,
message: error.message,
endpoint: 'getFile',
fileId: 'file_123'
})
}
}User-Friendly Messages
Don't expose raw API errors to users. Map them to friendly messages:
const errorMessages = {
not_found: 'This item no longer exists.',
forbidden: 'You don\'t have permission to do that.',
rate_limited: 'Please wait a moment before trying again.',
internal_error: 'Something went wrong. Please try again.'
}
showToast(errorMessages[error.code] || 'An error occurred')Next Steps
- Rate Limits — Handling rate limiting
- Endpoints — API endpoint reference