# Errors & Status Codes
# Error Format
Every error response uses the same envelope:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description"
}
}
Validation errors include an extra details field with per-field messages:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "The given data was invalid",
"details": {
"email": ["The email field is required."],
"per_page": ["The per page must be between 1 and 100."]
}
}
}
# HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Request succeeded |
| 201 | Resource created — returned by POST /contact |
| 400 | Bad request — invalid parameter format (e.g. malformed tag_ids list) |
| 401 | Unauthorized — missing or invalid API key |
| 403 | Forbidden — your key does not have access to this resource |
| 404 | Not found — the requested resource does not exist |
| 409 | Conflict — the resource already exists (e.g. duplicate contact email) |
| 422 | Unprocessable — validation failed; see error.details for field-level errors |
| 429 | Too many requests — you have exceeded the rate limit (600 requests/minute) |
| 500 | Server error — something went wrong on our end |
# Error Codes
| Code | HTTP | When it occurs |
|---|---|---|
UNAUTHORIZED | 401 | API key is missing, invalid, or disabled |
FORBIDDEN | 403 | The API key does not have access to the requested resource |
NOT_FOUND | 404 | Contact, tag, or sequence not found — or doesn't belong to your account |
CONTACT_EXISTS | 409 | POST /contact — a contact with that email already exists |
VALIDATION_ERROR | 400/422 | Validation failed. 400 when a list field (tag_ids, sequence_ids) is malformed — no details. 422 for standard field errors — includes details. |
SERVER_ERROR | 500 | Unexpected server-side error |
# Rate Limiting (429)
When you exceed 600 requests per minute (≈ 10 requests per second), the API responds with:
{
"message": "Too Many Attempts."
}
HTTP status: 429 Too Many Requests
Implement an exponential back-off or a request queue on your side to stay within limits.
# Tips
- Always check
successbefore readingdata. - On a 422, iterate over
error.detailsto surface per-field validation messages to your users. - On a 429, wait at least 60 seconds before retrying.
- On a 5xx, log the full response and retry after a short delay — these are transient.