Error Codes
All API errors follow a consistent format:
{ "status": "error", "error": { "code": "VALIDATION_ERROR", "message": "The from_email field is required.", "details": { "from_email": ["The from_email field is required."] } }}Error reference
UNAUTHENTICATED — 401
Your API key is missing, invalid, or has been revoked.
{ "code": "UNAUTHENTICATED", "message": "Invalid or missing credential." }Fix: Check your Authorization: Bearer YOUR_API_KEY header. Ensure the credential is active and not revoked.
FORBIDDEN — 403
Your credential doesn’t have the required permission for this action.
{ "code": "FORBIDDEN", "message": "This credential does not have the 'send' permission." }Fix: Create a credential with the required permission, or add the permission to the existing one.
NOT_FOUND — 404
The requested resource doesn’t exist.
{ "code": "NOT_FOUND", "message": "Message not found." }CONFLICT — 409
The resource already exists.
{ "code": "CONFLICT", "message": "This domain is already registered." }VALIDATION_ERROR — 422
The request body failed validation. The details field contains per-field error messages.
{ "code": "VALIDATION_ERROR", "message": "The given data was invalid.", "details": { "from_email": ["The from_email field is required."], "subject": ["The subject may not be greater than 998 characters."] }}RATE_LIMITED — 429
You’ve exceeded your organization’s send rate limit.
{ "code": "RATE_LIMITED", "message": "Rate limit exceeded. Retry after 60 seconds." }The response includes a Retry-After header with the number of seconds to wait.
Fix: Implement exponential backoff and respect the Retry-After header.
ATTACHMENT_TOO_LARGE — 422
A single attachment exceeds your plan’s size limit.
{ "code": "ATTACHMENT_TOO_LARGE", "message": "Attachment \"report.pdf\" exceeds the maximum size of 10 MB."}MESSAGE_TOO_LARGE — 422
The total message size (body + all attachments) exceeds the platform limit.
{ "code": "MESSAGE_TOO_LARGE", "message": "Total message size exceeds the maximum of 25 MB."}INTERNAL_ERROR — 500
An unexpected server error occurred. These are rare and usually transient.
Fix: Retry with exponential backoff. If the error persists, contact support.
Error handling examples
const response = await fetch('https://api.emitlo.com/api/v1/messages', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ /* ... */ }),});
if (!response.ok) { const { error } = await response.json();
switch (error.code) { case 'RATE_LIMITED': const retryAfter = response.headers.get('Retry-After'); await sleep(parseInt(retryAfter) * 1000); // retry... break; case 'VALIDATION_ERROR': console.error('Validation failed:', error.details); break; default: throw new Error(`API error: ${error.message}`); }}import httpx, time
response = httpx.post( "https://api.emitlo.com/api/v1/messages", headers={"Authorization": "Bearer YOUR_API_KEY"}, json={...},)
if response.status_code == 429: retry_after = int(response.headers.get("Retry-After", 60)) time.sleep(retry_after) # retry...elif response.status_code == 422: error = response.json()["error"] print("Validation errors:", error.get("details"))elif not response.is_success: error = response.json()["error"] raise Exception(f"API error: {error['message']}")