Skip to main content

Errors

The Arsel API uses standard HTTP status codes and returns errors in a consistent JSON format.

Error Response Format

All errors follow this structure:

{
"status_code": 422,
"name": "validation_error",
"message": "to must be an array, each value in to must be an email"
}
FieldTypeDescription
status_codenumberThe HTTP status code
namestringA machine-readable error identifier in snake_case
messagestringA human-readable description of what went wrong

Status Codes

Successful responses are 200 OK (reads and updates), 201 Created (creates), and 202 Accepted (a send that has been queued). Everything below carries the error envelope above.

CodeNameWhen It Happens
400bad_requestThe request body is malformed, the sender email is not on a verified domain, or an account-level rule rejects the send. See Common Send Errors below.
401unauthorizedThe API key is missing, invalid, expired, or revoked
403forbiddenThe API key does not have permission for this action
404not_foundThe requested resource does not exist
409conflictThe request conflicts with the current state of the resource
422validation_errorThe request body failed validation (e.g., invalid email format)
429rate_limit_exceededYou have exceeded the per-second request limit
429monthly_quota_exceededYour organization has used its monthly email (or SMS) quota. See Common Send Errors.
500internal_server_errorAn unexpected error occurred on our end

Common Send Errors

A successful authentication and well-formed request can still be rejected at send time — for example, because the sender domain isn't verified or the organization's quota is exhausted. These are returned with 400 / name: bad_request unless stated otherwise.

ScenarioStatusnameExample message
Sender domain not verified400bad_requestSender email domain is not verified. Verify the domain in Settings > Domains.
Sender email format invalid or not allowed400bad_requestSender email is required / Invalid sender email
Recipient list empty or address invalid400bad_requestAt least one recipient is required.
Total recipients (to + cc + bcc) exceeds 50400bad_requestToo many recipients. Maximum 50 allowed, but N provided.
Attachment MIME type blocked or extension blocked400bad_requestAttachment type 'application/x-msdownload' is not allowed
Organization suspended (high bounce/complaint rate)400bad_requestEmail sending is suspended for this organization due to high bounce/complaint rates. Please contact an admin to review and unsuspend.
Monthly email quota exhausted429monthly_quota_exceededMonthly email quota exceeded
note

monthly_quota_exceeded is distinct from rate_limit_exceeded. The first means you've used your plan's allotment for the month; the second means you're sending faster than the per-second limit. Retrying the quota error won't help until the next billing period or a plan upgrade.

Validation Errors

When a request fails validation, the message field contains a comma-separated list of all validation issues:

{
"status_code": 422,
"name": "validation_error",
"message": "from must be an email, to should not be empty, subject must be shorter than or equal to 998 characters"
}

Handling Errors

Check status_code first to determine the category of error. Use name for programmatic error handling, and message for logging or displaying to users.

const response = await fetch("https://api.arsel.sa/v1/email/send", options);
const data = await response.json();

if (response.status >= 400) {
switch (data.name) {
case "unauthorized":
// Refresh or rotate your API key
break;
case "validation_error":
// Fix the request payload
break;
case "rate_limit_exceeded":
// Back off and retry
break;
default:
// Log and alert
console.error(`API error: ${data.name}${data.message}`);
}
}