Errors
Error response shape, error codes, and what to retry.
The API uses standard HTTP status codes, and error responses share a single JSON shape.
Error response body
{
"errorCode": "account_balance_insufficient",
"message": "Account balance is insufficient"
}errorCode— a stable, machine-readable snake_case code. Branch your error handling on this, not onmessage.message— a human-readable description; wording may change without notice.
One exception:401 Unauthorizedreturns an empty body (no JSON). Treat any 401 as an invalid or missing API key.
Error codes
Request & auth
| HTTP | errorCode | Meaning / what to do |
|---|---|---|
| 400 | invalid_request | A field is missing, malformed, or fails validation. The message names the field. |
| 400 | invalid_phone_number_format | recipient.phone_number doesn't match the product country's format. |
| 401 | (empty body) | Missing or invalid API key, or key/environment mismatch. |
| 403 | permission_denied | Your key isn't allowed to perform this operation. |
| 404 | not_found | Unknown route or resource. |
| 405 | method_not_allowed | Wrong HTTP method. |
| 429 | rate_limit_exceeded | Too many requests — see Rate limiting. |
| 500 | unhandled_error | Unexpected server error. Contact support if it persists. |
Orders
| HTTP | errorCode | Meaning / what to do |
|---|---|---|
| 400 | account_balance_insufficient | Not enough balance to place the order. Top up in the dashboard (Funding). |
| 400 | price_range_exceed | custom_amount is outside the product's min_amount–max_amount. |
| 400 | invalid_order_access | The order exists but doesn't belong to your account. |
| 400 | resend_not_allowed | Resend is only supported for EMAIL and TEXT order items. |
| 400 | acceptance_expired | The recipient's acceptance link has expired. |
| 400 | order_item_cancelled | The order item was cancelled and can't be acted on. |
| 404 | order_not_found / order_item_not_found | No such order / order item in your account. |
| 404 | order_item_not_issued | The voucher hasn't been issued yet — retry after the item completes. |
| 500 | order_retry_needed | Temporary concurrency conflict. Safe to retry — use external_reference_id so the retry is idempotent. |
Products
| HTTP | errorCode | Meaning / what to do |
|---|---|---|
| 404 | item_not_found | No such product ID. |
Retry guidance
- Retry:
429(after 1 second),500withorder_retry_needed(immediately, a few times with backoff). - Don't retry: any
400— fix the request first. - Always pass
external_reference_idwhen creating orders, so retries can never create duplicates. See Idempotency & retries.
Updated about 11 hours ago
Did this page help you?
