Coline Docs
API Reference

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 Authorization header
  • 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

CodeHTTP StatusDescription
invalid_request400Malformed request
validation_failed400/422Validation error
unauthorized401Authentication failed
forbidden403Permission denied
not_found404Resource not found
conflict409State conflict
rate_limited429Rate limit exceeded
internal_error500Server 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

On this page