Errors and rate limits
Error shape, status codes, and how to pace requests.
Errors are structured JSON:
{"error": "invalid email address", "code": "INVALID_INPUT"}
Status codes
| Status | code |
What to do |
|---|---|---|
| 400 | INVALID_INPUT |
Fix the request body or parameters |
| 401 | UNAUTHORIZED |
Check the key; create a new one if revoked |
| 403 | FORBIDDEN |
The key or plan is not allowed this operation |
| 404 | NOT_FOUND |
The job or resource does not exist |
| 409 | INVALID_STATE |
The job is not in a state that allows this action (for example pausing a finished job) |
| 429 | RATE_LIMITED |
Per-minute limit hit; back off until X-RateLimit-Reset |
| 429 | QUOTA_EXCEEDED |
Monthly quota or credits exhausted; top up or upgrade |
| 429 | RERUN_COOLDOWN |
Unknown-rerun was used less than 30 minutes ago; wait and retry |
| 500 | INTERNAL_ERROR |
Retry with backoff; if it persists, check the status page |
Pacing
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. Plan throughput from them instead of retrying blindly. Per-minute limits by plan: Free 10, Starter 60, Pro 200, Business 500, Enterprise 1,000. For large lists, bulk upload is faster and kinder than looping over single calls.