API reference
Errors
Errors share one shape. Branch on the code; the message is for people and may change.
{
"error": {
"code": "sender_not_approved",
"message": "sender ID \"Shop\" is not approved for this account; register it in the console"
}
}Codes#
| HTTP | code | When | What to do |
|---|---|---|---|
| 400 | invalid_json | The body isn't JSON, is over 64 KiB, has a field of the wrong type, or a field we don't know | Fix the request; the message says what's wrong |
| 400 | invalid_idempotency_key | Idempotency-Key over 255 bytes | Use a shorter key |
| 400 | invalid_limit | limit isn't 1–200 | Fix the parameter |
| 401 | unauthorized | No Authorization header, or an unknown or revoked key | Check the key on the API keys page |
| 401 | key_expired | The key is past its expiry date | Make a new key, or change the date on the API keys page |
| 402 | insufficient_balance | Your balance and credit limit don't cover the price | Add credits in the console |
| 403 | account_pending | Your account is waiting for approval | Wait for the review; you'll get an email |
| 403 | account_suspended | Your account is suspended | Contact support |
| 403 | service_suspended | Sending is suspended for the whole service | Contact support |
| 403 | ip_not_allowed | The key was used from an address it doesn't allow | Add the address to the key, or call from an allowed one. See Limiting a key |
| 403 | permission_denied | The key doesn't have the permission this endpoint needs | Give the key that permission on the API keys page |
| 403 | trial_number | On trial credits, the number isn't one of your verified test numbers | Add credits, or verify the number in the console |
| 403 | country_not_allowed | The number is in a country your account doesn't send to (Fraud protection) | Add the country under Fraud protection in the web app |
| 403 | unsafe_link | A link in the text is on a public phishing or malware list | Remove the link. If you're sure it's safe, the check can be turned off under Fraud protection, Content and links |
| 403 | content_blocked | The text matches one of your content rules | Change the text, or the rule under Fraud protection, Content and links |
| 403 | spending_limit_reached | Your account reached its daily or monthly spending limit | Wait for the reset (retry_after), or raise the limit under Fraud protection |
| 404 | not_found | No such message, or no such endpoint | Check the id and the path |
| 405 | method_not_allowed | The path exists under another method, such as POST /v1/balance for GET /v1/balance; the Allow header names it | Use the method the message names |
| 409 | idempotency_key_reused | The Idempotency-Key was used for a message with another to, from or body | Use a new key for a new message |
| 422 | invalid_to | Not a valid number in international format | Send +, the country code and the number |
| 422 | invalid_from | Not a possible sender ID | See Sender IDs |
| 422 | sender_not_approved | The sender ID isn't approved for your account | Register it and wait for approval |
| 422 | invalid_body | The text is empty | Send some text |
| 422 | body_too_long | The text needs more than 10 parts | Shorten it; see Encoding |
| 422 | destination_not_enabled | Your account doesn't send to that country or network | Ask us to enable it |
| 422 | invalid_callback_url | callback_url isn't an absolute http(s) URL | Fix the URL |
| 422 | invalid_template_id | No template of yours has that template_id | Check the id with GET /v1/templates |
| 422 | missing_variables | The text has a {{variable}} with no value in variables | Send a value for each variable the message names |
| 422 | invalid_validity_period | validity_period isn't 10 to 86,400 seconds | Fix the value |
| 422 | invalid_client_reference | client_reference is over 256 characters or has line breaks | Shorten it |
| 422 | invalid_messages | A batch's messages is empty or holds more than 100 | Split it into batches of 100 |
| 400 | invalid_country | country on GET /v1/prices isn't a two-letter code | Send an ISO 3166-1 code, such as GB |
| 429 | rate_limited | Over your account's messages per second | Retry after the Retry-After header's seconds (also retry_after in the error); see Rate limits |
| 500 | internal_error | Something went wrong on our side | Retry with the same Idempotency-Key |
A message we accepted and then couldn't deliver isn't an API error: the send answered 201, and the outcome comes later as its status and error code.