Error Codes
Understand API error responses and how to handle them.
Error Response Format
All error responses follow a consistent JSON format with a success flag, error message, and error code.
{
"success": false,
"error": "Human-readable error message",
"code": "ERROR_CODE"
}HTTP Status Codes
The API uses standard HTTP status codes to indicate success or failure.
Success Codes
| Code | Description |
|---|---|
200 | OK - Request succeeded |
201 | Created - Resource created successfully |
202 | Accepted - Request queued for async processing |
Client Error Codes
| Code | Description |
|---|---|
400 | Bad Request - Invalid parameters or malformed JSON |
401 | Unauthorized - Missing or invalid API key |
403 | Forbidden - API key lacks required permissions |
404 | Not Found - Resource doesn't exist |
409 | Conflict - Resource already exists |
429 | Too Many Requests - Rate limit exceeded |
Server Error Codes
| Code | Description |
|---|---|
500 | Internal Server Error - Something went wrong on our end |
502 | Bad Gateway - Upstream service unavailable |
503 | Service Unavailable - System maintenance or overload |
Error Codes Reference
Detailed reference for specific error codes returned by the API.
Authentication Errors
UNAUTHORIZED401Missing or invalid API key in Authorization header.
{
"success": false,
"error": "Invalid API key",
"code": "UNAUTHORIZED"
}FORBIDDEN403API key doesn't have permission for this resource.
{
"success": false,
"error": "Domain not verified for this organization",
"code": "FORBIDDEN"
}Validation Errors
VALIDATION_ERROR400Request body contains invalid data.
{
"success": false,
"error": "Invalid email format",
"code": "VALIDATION_ERROR"
}MISSING_FIELD400Required field is missing from request.
{
"success": false,
"error": "Missing required field: subject",
"code": "MISSING_FIELD"
}DOMAIN_NOT_VERIFIED400Attempting to send from unverified domain.
{
"success": false,
"error": "Domain 'example.com' is not verified",
"code": "DOMAIN_NOT_VERIFIED"
}Rate Limit Errors
RATE_LIMITED429Too many requests. Wait before retrying.
{
"success": false,
"error": "Rate limit exceeded. Retry after 60 seconds",
"code": "RATE_LIMITED",
"retry_after": 60
}Resource Errors
NOT_FOUND404Requested resource doesn't exist.
{
"success": false,
"error": "Template not found",
"code": "NOT_FOUND"
}ALREADY_EXISTS409Resource with same identifier already exists.
{
"success": false,
"error": "Domain already registered",
"code": "ALREADY_EXISTS"
}Email Delivery Errors
RECIPIENT_SUPPRESSED400Recipient is on suppression list (bounced or complained).
{
"success": false,
"error": "Recipient is on suppression list",
"code": "RECIPIENT_SUPPRESSED"
}CAMPAIGN_PAUSED400Campaign was auto-paused due to high bounce rate.
{
"success": false,
"error": "Campaign paused due to bounce rate > 10%",
"code": "CAMPAIGN_PAUSED"
}Error Handling Best Practices
1. Check the HTTP status code first
Use status codes to determine the error category before parsing the response body.
2. Implement exponential backoff for 429 and 5xx errors
For rate limits and server errors, wait progressively longer between retries.
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);
if (response.status === 429 || response.status >= 500) {
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
await new Promise(r => setTimeout(r, delay));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}3. Log error codes for debugging
Always log the error code and message to help diagnose issues.
4. Handle validation errors gracefully
For 400 errors, display the error message to help users fix their input.