Error Handling

Understand the error format and how to handle API errors gracefully.

Error Response Format

All API errors return a consistent JSON body:

{
  "error": {
    "code": "USER_NOT_FOUND",
    "message": "No user found with id usr_abc123",
    "status": 404,
    "requestId": "req_xyz456"
  }
}
FieldTypeDescription
codestringMachine-readable error code
messagestringHuman-readable description
statusintegerHTTP status code
requestIdstringUse this when contacting support

HTTP Status Codes

CodeMeaning
200 OKRequest succeeded
201 CreatedResource created
204 No ContentDeleted successfully
400 Bad RequestValidation error
401 UnauthorizedMissing or invalid token
403 ForbiddenInsufficient permissions
404 Not FoundResource does not exist
409 ConflictDuplicate resource
429 Too Many RequestsRate limit exceeded
500 Internal Server ErrorServer-side failure

Validation Errors

400 responses include field-level details in errors:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request body is invalid",
    "status": 400,
    "errors": [
      { "field": "email", "message": "Must be a valid email address" },
      { "field": "name",  "message": "Required" }
    ]
  }
}

Retrying Requests

Use exponential backoff for retries:

async function fetchWithRetry(url: string, options: RequestInit, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const res = await fetch(url, options);
    if (res.ok) return res;
    if (res.status < 500 && res.status !== 429) throw new Error(`HTTP ${res.status}`);
    await new Promise(r => setTimeout(r, 2 ** i * 500)); // 500ms, 1s, 2s
  }
  throw new Error('Max retries exceeded');
}