Error Handling
The API returns standard HTTP codes accompanied by structured error messages.
Error Format
All errors follow this format:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description"
}
}
HTTP Codes
| Code | Meaning | When |
|---|---|---|
200 | OK | Successful request |
401 | Unauthorized | Missing or invalid authentication |
402 | Payment Required | Insufficient credits |
403 | Forbidden | Insufficient scope |
404 | Not Found | Resource not found |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server error |
Common Error Codes
Authentication
{
"error": {
"code": "MISSING_API_KEY",
"message": "Authorization header missing"
}
}
{
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid or revoked API key"
}
}
Permissions
{
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "Scope 'appointments:create' required"
}
}
Resources
{
"error": {
"code": "APPOINTMENT_NOT_FOUND",
"message": "Appointment with id 12345 not found"
}
}
Rate Limiting
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 3600 seconds"
}
}
Headers: Retry-After: 3600
Credits
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Your organization has 0 credits remaining"
}
}
Error Handling in Code
With cURL
response=$(curl -s -w "\n%{http_code}" ...)
http_code=$(echo "$response" | tail -n1)
body=$(echo "$response" | head -n-1)
if [ $http_code -ne 200 ]; then
echo "Error: $body"
fi
With SDKs
SDKs automatically handle errors with typed exceptions:
try {
const appointment = await client.appointments.create({...});
} catch (error) {
if (error.code === 'INSUFFICIENT_CREDITS') {
// Redirect to recharge page
} else if (error.code === 'RATE_LIMIT_EXCEEDED') {
// Retry with backoff
}
}
Retry Logic
For temporary errors (429, 500, 503), implement retry with exponential backoff:
async function retryRequest(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.status === 429 || error.status >= 500) {
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error; // Non-retriable error
}
}
}
throw new Error('Max retries exceeded');
}