API docs

Errors

Every error comes with an HTTP status and a machine-readable code.

A failed request always answers with an error object. Branch on the code; use message only for logs and debugging, because its wording can change.

Response402 Payment Required
{
  "error": {
    "code": "insufficient_credits",
    "message": "Not enough credits.",
    "balance": 40,
    "required": 70
  }
}

Error codes

HTTPCodeMeaning
400invalid_requestThe request is wrong: a field is missing or invalid, or the body is not JSON.
401invalid_api_keyThe key is missing, unknown or revoked.
402insufficient_creditsNot enough credits. Carries balance and required.
402subscription_requiredThe trial ended or the base fee is not paid.
403forbiddenYou may not do this.
403trial_recipientA trial project can reach only its owner's confirmed phone and email.
404not_foundNothing with this id in this project, or the path is wrong.
410verification_expiredThe verification has expired.
422unsupported_numberThe number does not belong to a supported operator.
422message_too_longThe SMS is over 5 parts, the email over 256 KB, or the request over 1 MB.
422invalid_codeThe verification code is wrong. Carries attempts_remaining.
429rate_limitedToo many requests. See the Retry-After header.
429recipient_rate_limitedToo many messages to this recipient.
429max_attempts_reachedToo many wrong codes.
502provider_failedThe operator did not accept the message. Credits were refunded. Carries id.
500server_errorSomething went wrong on our side.

How to handle them

  • Do not retry a 4xx with the same request. Fix the request or tell the user. The exception is 429: wait the Retry-After seconds and send again.
  • A 502 provider_failed can be retried: the credits are back. It may be a brief operator outage.
  • After a 500 server_error or a network failure you cannot know whether the message went out. Retry with an Idempotency-Key header so it is never sent twice.