Documentation

Error codes

Errors always use the same envelope, so you can switch on error.code rather than parsing messages.

{
  "success": false,
  "error": { "code": "QUOTA_EXCEEDED", "message": "Daily OTP quota exceeded." }
}
CodeHTTPMeaningWhat to do
INVALID_API_KEY 401 Key missing, malformed or unknown. Check the key stored in your server config.
API_KEY_DISABLED 403 Key revoked or disabled. Generate a new key in the dashboard.
ACCOUNT_SUSPENDED 403 The linked account is not active. Contact support.
METHOD_NOT_ALLOWED 405 Non-POST request. Use POST with a JSON body.
VALIDATION_ERROR 422 A field is missing or invalid. Fix the payload; the message names the field.
RESEND_COOLDOWN 429 A code was just sent to this destination. Wait for the seconds in the message / Retry-After.
QUOTA_EXCEEDED 429 Daily or monthly quota reached. Upgrade the plan or wait for the reset.
RATE_LIMIT_EXCEEDED 429 Per-IP or per-key request limit hit. Back off using the Retry-After header.
REQUEST_NOT_FOUND 404 Unknown request_id for this account. Send a new OTP and reuse the fresh ID.
OTP_EXPIRED 410 The code expired. Send a new code.
ALREADY_VERIFIED 409 The request was verified earlier. Treat the user as verified.
INVALID_OTP 401 Wrong code. Let the user retry until attempts run out.
MAX_ATTEMPTS_REACHED 429 Attempt limit for this request exhausted. Issue a new OTP request.
DELIVERY_FAILED 502 No channel accepted the message. Verify SMTP / SMS provider settings.
MAINTENANCE 503 The service is in maintenance mode. Retry shortly.
SERVER_ERROR 500 Unexpected failure. Retry once, then contact support with the request ID.

Retry guidance

  • 429 responses carry Retry-After in seconds - honour it instead of looping.
  • Never retry 4xx validation or authentication errors without changing the request.
  • Log the request_id on your side; it matches the entries in your API logs.