Errors & Rate Limiting
Error Format
All API errors return a consistent JSON structure:
For validation errors, the response includes field-level details:
HTTP Status Codes
| Status | Description |
|---|
200 | OK - Request succeeded |
201 | Created - Resource was created |
202 | Accepted - Request accepted for processing (email queued) |
204 | No Content - Resource was deleted |
401 | Unauthorized - Missing or invalid API key |
403 | Forbidden - API key does not have access to the resource |
404 | Not Found - Resource does not exist or belongs to another project |
422 | Unprocessable Entity - Validation failed or business rule violated |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Something went wrong on our end |
Common Error Codes
| Code | Description |
|---|
campaign_not_draft | Attempted to modify or delete a non-draft campaign |
no_enrollments | Attempted to activate a campaign with no enrolled contacts |
Rate Limiting
API requests are rate-limited to 60 requests per minute per API key.
When you exceed the rate limit, you'll receive a 429 response with a Retry-After header indicating how many seconds to wait before retrying.
Rate Limit Headers
Every API response includes rate limit headers:
| Header | Description |
|---|
X-RateLimit-Limit | Maximum requests per minute |
X-RateLimit-Remaining | Requests remaining in the current window |
Retry-After | Seconds to wait before retrying (only on 429 responses) |
Example Rate Limit Response
Best Practices
- Cache responses when possible to reduce API calls
- Use exponential backoff when retrying after rate limit errors
- Batch operations where possible (e.g., enroll multiple contacts at once)
- Monitor rate limit headers to avoid hitting limits