Skip to main content

Error handling

How to handle errors from the Synjar API.

Error response format

All errors return a consistent JSON structure:

{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {}
}
}

HTTP status codes

StatusMeaningRetry
400Bad request - Invalid inputNo
401Unauthorized - Invalid authNo
403Forbidden - Insufficient permissionsNo
404Not found - Resource doesn't existNo
409Conflict - Resource state conflictMaybe
413Payload too large - File too bigNo
429Rate limited - Too many requestsYes
500Internal error - Server issueYes
503Service unavailable - MaintenanceYes

Error codes reference

Authentication errors

CodeHTTPDescription
UNAUTHORIZED401Missing or invalid token
TOKEN_EXPIRED401Token has expired
INVALID_CREDENTIALS401Wrong email/password
FORBIDDEN403Insufficient permissions

Validation errors

CodeHTTPDescription
VALIDATION_ERROR400Invalid input data
MISSING_FIELD400Required field missing
INVALID_FORMAT400Field format invalid

Resource errors

CodeHTTPDescription
NOT_FOUND404Resource not found
ALREADY_EXISTS409Resource already exists
CONFLICT409Resource state conflict

Document errors

CodeHTTPDescription
FILE_TOO_LARGE413Exceeds size limit
UNSUPPORTED_FORMAT400File type not supported
PROCESSING_FAILED500Document processing error

Rate limit errors

CodeHTTPDescription
RATE_LIMITED429Too many requests

Handling errors

JavaScript example

async function apiRequest(url, options) {
const response = await fetch(url, options);

if (!response.ok) {
const error = await response.json();

switch (response.status) {
case 401:
// Handle auth error - redirect to login
throw new AuthError(error.error.message);

case 429:
// Rate limited - retry after delay
const retryAfter = response.headers.get('Retry-After') || 60;
await sleep(retryAfter * 1000);
return apiRequest(url, options);

case 500:
case 503:
// Server error - retry with backoff
throw new ServerError(error.error.message);

default:
throw new ApiError(error.error.code, error.error.message);
}
}

return response.json();
}

Python example

import requests
import time

def api_request(url, **kwargs):
response = requests.request(url=url, **kwargs)

if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after)
return api_request(url, **kwargs)

if response.status_code >= 500:
raise ServerError(response.json()['error']['message'])

if not response.ok:
error = response.json()['error']
raise ApiError(error['code'], error['message'])

return response.json()

Rate limit handling

When you receive a 429 response:

  1. Check Retry-After header for wait time
  2. Wait the specified seconds
  3. Retry the request
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
return retry(request);
}

Exponential backoff

For 5xx errors, use exponential backoff:

async function withRetry(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (i === maxRetries - 1) throw error;
if (error.status < 500) throw error;

const delay = Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, delay));
}
}
}

See also