Error Reference
HTTP status codes, error response format, and troubleshooting common errors.
Error responses use the same envelope as successful responses, with status: "error" and an error field:
{
"status": "error",
"time": "2026-04-06T10:00:00.000000000Z",
"request_id": "01jqk...",
"error": "contact not found"
}
The request_id is useful for correlating errors with server logs.
HTTP status codes
| Code |
Meaning |
When |
400 |
Bad Request |
Invalid JSON, missing required fields, validation failure |
401 |
Unauthorized |
Missing or invalid API key |
404 |
Not Found |
Contact, template, or resource doesn't exist |
409 |
Conflict |
Duplicate contact (same number or reference) |
410 |
Gone |
A file link whose file expired or was deleted |
429 |
Too Many Requests |
Rate limit exceeded (100 req/min for API) |
500 |
Internal Server Error |
Unexpected server error |
Common errors
Authentication
| Error |
Cause |
Fix |
unauthorized |
Missing Authorization header |
Add Authorization: Bearer <key> header |
unauthorized |
Invalid or revoked API key |
Check the key is correct and not revoked |
| Error |
Cause |
Fix |
contact not found |
ID doesn't exist or belongs to another org |
Verify the contact ID |
duplicate contact |
Number or reference already exists in this org |
Use a unique number/reference |
number: field is required |
number is missing |
Provide the contact's phone number in E.164 format |
reference: contains a NUL character |
reference contains \u0000 |
Remove the NUL character |
number: invalid phone number format |
number is not in E.164 format |
Send a plus sign followed by 2 to 15 digits, for example +14155552671 |
Messages
| Error |
Cause |
Fix |
template not found |
Template name doesn't match any template |
Check the template name spelling |
missing required placeholder |
A required {{placeholder}} has no value in data |
Add the missing placeholder value |
invalid file |
file_id does not name a file uploaded by this organization |
Upload the file with POST /v1/files and use the returned id |
file expired or deleted |
file_id names a file past its expires_at or already deleted |
Upload the file again |
data: contains a NUL character |
A key or value in data contains \u0000 |
Remove the NUL character from the placeholder data |
contact not found |
The contact_id doesn't exist |
Verify the contact exists |
Files
| Error |
Cause |
Fix |
multipart body with a file part is required |
The request is not multipart, or has no part named file |
Send multipart/form-data with a file part |
file is empty |
The file part has no bytes |
Send a non-empty file |
file too large (HTTP 413) |
The file exceeds the configured limit |
Stay under the limit, 10 MB by default |
invalid file name |
The file name is empty, longer than 255 bytes, or not valid text |
Send a plain file name |
file not found (HTTP 404) |
DELETE /v1/files/{id} names a file this organization does not own |
Check the id |
Rate limiting
| Error |
Cause |
Fix |
HTTP 429 |
Exceeded 100 requests/minute |
Wait for the rate limit window to reset |
Troubleshooting
"unauthorized" on every request
- Confirm your API key starts with
atc_
- Check the key hasn't been revoked in the dashboard
- Verify the
Authorization header format: Bearer <key> (note the space)
"template not found" but template exists
- Template names are case-sensitive — check exact spelling
- Confirm the template belongs to your active organization
- Verify the template has at least one channel body
Messages stuck in "pending"
- Check your delivery policy is configured in the workflow editor
- Verify at least one delivery channel has valid credentials
- Check the server logs for orchestrator errors
Contact updates are not supported via the API. Each POST /v1/contacts creates a new contact. If you need to change a contact's details, manage them through the dashboard.