Error Handling
Robust error handling is essential for building reliable integrations. This guide covers error formats, common error codes, and strategies for graceful degradation.
Request completed successfully
Invalid request or authentication
Temporary server issues
Error Response Format
All API errors follow a consistent JSON structure with detailed information for debugging.
{
"error": {
"code": "validation_error",
"message": "The request body contains invalid fields",
"details": [
{
"field": "email",
"code": "invalid_format",
"message": "Email address is not valid"
},
{
"field": "phone",
"code": "missing_required",
"message": "Phone number is required"
}
],
"request_id": "req_abc123xyz",
"documentation_url": "https://docs.synaptis.io/errors/validation_error"
}
}HTTP Status Codes
| Status | Meaning | Action |
|---|---|---|
| 200 OK | Request succeeded | Process response data |
| 201 Created | Resource created | Process created resource |
| 400 Bad Request | Invalid request format | Fix request and retry |
| 401 Unauthorized | Invalid or missing API key | Check authentication |
| 403 Forbidden | Insufficient permissions | Check API key scopes |
| 404 Not Found | Resource doesn't exist | Check resource ID |
| 422 Unprocessable | Validation failed | Fix validation errors |
| 429 Too Many Requests | Rate limit exceeded | Wait and retry |
| 500 Internal Error | Server error | Retry with backoff |
| 502 Bad Gateway | Upstream error | Retry with backoff |
| 503 Service Unavailable | Service temporarily down | Retry with backoff |
Error Codes
Specific error codes provide detailed information about what went wrong.
Authentication Errors
invalid_api_keyThe API key provided is invalid or has been revokedexpired_tokenThe access token has expired. Refresh using your refresh tokeninsufficient_scopeThe API key lacks required permissions for this endpointValidation Errors
validation_errorOne or more fields failed validationinvalid_formatField value doesn't match expected formatmissing_requiredA required field is missing from the requestLead Processing Errors
duplicate_leadA lead with this data already exists in the systemlead_rejectedLead failed quality checks and was rejectedno_matching_buyersNo buyers matched the lead's criteriacapacity_exceededAll matching buyers have reached their capacity limitsRetry Strategies
Implement intelligent retry logic to handle transient failures gracefully.
Only retry on 5xx errors and 429. Don't retry 4xx errors (except 429) as they indicate client issues.
class APIClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.maxRetries = 3;
this.baseDelay = 1000;
}
async request(endpoint, options = {}) {
let lastError;
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
try {
const response = await fetch(`https://api.synaptis.io/v1${endpoint}`, {
...options,
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
...options.headers
}
});
// Don't retry client errors (except rate limiting)
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
const error = await response.json();
throw new APIError(error, response.status);
}
// Retry on rate limit
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
await this.sleep(retryAfter * 1000);
continue;
}
// Retry on server errors
if (response.status >= 500) {
throw new Error(`Server error: ${response.status}`);
}
return await response.json();
} catch (error) {
lastError = error;
if (error instanceof APIError) throw error;
if (attempt < this.maxRetries) {
// Exponential backoff with jitter
const delay = this.baseDelay * Math.pow(2, attempt);
const jitter = delay * 0.2 * Math.random();
await this.sleep(delay + jitter);
}
}
}
throw lastError;
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}Fallback Patterns
Design your integration to degrade gracefully when the API is unavailable.
Store failed requests in a queue and process them when the API recovers.
Return cached results when fresh data cannot be retrieved.
Stop making requests after repeated failures to prevent cascade issues.
Display helpful messages instead of exposing technical error details.