Errors
Every error code, the product family it belongs to and what to do about it.
An error has an HTTP status and a JSON body with a stable code for your program and a message for a person. The format is the same in both product families. When an error is returned, nothing was charged.
{"error": {"code": "insufficient_balance", "message": "Your USD balance is USD 0.00; this order costs USD 8.99."}}Error codes
The Family column says where a code can appear: Both, only the gift card & software endpoints, or only the eSIM endpoints (/esim/…). Codes of the family you do not sell never reach you.
| HTTP | code | Family | Meaning | What to do |
|---|---|---|---|---|
| 401 | invalid_key | Both | Missing, wrong or revoked key. | Check the Authorization header; create a new key if needed. |
| 403 | account_not_allowed | Both | The account is not wholesale (any more), or is blocked. | Contact us. |
| 403 | ip_not_allowed | Both | The key is restricted to other IP addresses. | Add this server’s address to the key, or call from an allowed server. |
| 404 | not_found | Both | No order with that number or reference in this family. On the eSIM endpoints also: no such destination, or no eSIM with that ICCID on your account. | Check the value, and that you are asking the right family: an eSIM order is only found under /esim/orders, a gift-card order only under /orders. |
| 402 | insufficient_balance | Both | The named balance does not cover the order. | Add balance in your dashboard, or charge the other balance. |
| 409 | reference_in_use | Both | The reference already belongs to one of your orders in the other family. | Use a new reference. A reference is one order, whatever it bought. |
| 422 | currency_unavailable | Both | The product or plan has no price in that currency. | Charge the other balance. |
| 422 | invalid_request | Both | A field is missing or malformed. | Read message. |
| 422 | order_refused | Both | The order could not be placed. | Read message. |
| 429 | — | Both | Rate limit reached. | Wait a few seconds and retry. |
| 503 | api_disabled | Both | The API is switched off for maintenance. | Retry later. |
| 404 | invalid_variant | Gift cards | No such product in the API catalogue. | Refresh your copy of /products. |
| 409 | out_of_stock | Gift cards | Fewer than quantity are available. | Order fewer, or try later. |
| 422 | limit_exceeded | Gift cards | Quantity above the per-order limit. | Split into several orders, each with its own reference. |
| 422 | not_api_sellable | Gift cards | A website-only product. | Order it on novacodes.app. |
| 404 / 422 | invalid_plan | eSIMs | 404: no such plan in the API catalogue. 422: the plan cannot be ordered as asked: it went off sale, the quantity is not 1 to 30, or days is missing or outside the range of a daily plan. | Read message. Refresh the destination’s plans and order again with a new reference. |
| 422 | topup_not_allowed | eSIMs | That plan cannot be added to this eSIM: it is not one of the eSIM’s top-up plans, or the eSIM is cancelled or expired. | Choose a plan from GET /esim/esims/{iccid}/topups. |
| 409 | not_cancellable | eSIMs | The eSIM cannot be cancelled: it was installed, topped up or already cancelled, or its state could not be checked just now. | Read message. Only the “could not check” case is worth another try, a minute later. |
What is safe to retry
- Timeouts, dropped connections, 429, 5xx: retry. For every call that buys something (
POST /orders,POST /esim/orders, an eSIM top-up) keep the samereference. - 4xx with an error code: retrying unchanged gives the same answer. Fix the cause first.
- An eSIM cancel carries no reference and needs none: an eSIM is refunded once, and a second cancel answers
409 not_cancellable.
A response without the
error object is a success, also when the order's status is refunded: the order exists, and your money is back in your balance.