// errors

Errors

Every error returns the same envelope with a stable, machine-readable code. Branch on code, not the HTTP status alone - several scenarios can share one status.

{
  "status": "error",
  "statusCode": 402,
  "code": "INSUFFICIENT_CREDITS",
  "message": "Not enough credit balance to send this message.",
  "path": "/v1/messages",
  "data": null,
  "details": { "required": 2.8, "available": 1.2 }
}

The envelope fields:

FieldDescription
statusAlways "error".
statusCodeMirrors the HTTP status.
codeThe stable discriminator to branch on.
messageHuman-readable, safe to log; override for UX copy.
pathThe request path that produced the error.
fieldErrorsPer-field messages on validation failures.
dataAlways null on errors.

Error codes

CodeHTTPMeaning
VALIDATION_ERROR422A field failed validation. See fieldErrors.
INVALID_API_KEY401The API key is missing or invalid.
API_KEY_REVOKED401The API key has been revoked.
API_KEY_SCOPE_DENIED403The key lacks the required scope for this call.
INSUFFICIENT_CREDITS402Not enough credit balance. Top up and retry.
DAILY_SPEND_CAP_EXCEEDED403This send would exceed your account's daily spend limit (resets 00:00 UTC).
PROBATION_LIMIT_EXCEEDED403New accounts can send a limited number of messages per rolling 24 hours for their first days after KYC approval. details has dailyLimit, used, remaining and endsAt. Nothing is charged.
RECIPIENT_NOT_VERIFIED403During the new-account period only numbers that confirmed an OTP for your account can be messaged. details has unverified (up to 5 numbers), unverifiedCount and endsAt. The whole request is rejected; nothing is sent or charged.
NO_VALID_RECIPIENTS400No recipient passed validation after expanding lists and numbers.
TOO_MANY_RECIPIENTS400The send resolves to more than 1000 recipients. data carries { count, max }.
CONTACT_NOT_FOUND404No contact with that id exists for your account.
LIST_NOT_FOUND404No contact list with that id exists for your account.
LIST_NAME_TAKEN409A contact list with that name already exists.
SENDER_ID_NOT_APPROVED403The sender ID is neither shared nor approved for your account. Nothing is charged.
OTP_INVALID400The code is wrong, expired, already used, or has had 5 wrong attempts. message says which; safe to show the user.
OTP_RATE_LIMITED429This number has been sent 5 codes in the last 24 hours.
IDEMPOTENCY_KEY_CONFLICT409The Idempotency-Key was reused with a different body.
PROVIDER_SEND_FAILED502The upstream network could not be reached.
RATE_LIMITED429Too many requests. Back off and retry.
NOT_FOUND404The requested resource does not exist.
INTERNAL_ERROR500An unexpected server error. Safe to retry idempotently.

Branch on code

A business 403 (API_KEY_SCOPE_DENIED) is not the same as an auth 403 (FORBIDDEN). Keying on code keeps your handling correct as the API grows.

Next: API reference