Error reference

Every error the API can return, its HTTP status, what triggers it, and how to fix it. Branch your client on the HTTP status code, not the body shape.

Two error-object shapes

View-returned errors (most business errors) are a plain object with exactly two keys and no is_error field:

View error
{ "code": "UNKNOWN_SERVICE", "message": "Unknown service_code 'line-registered'." }

Framework-raised errors (bad/expired key, rate limit) are routed through the DRF exception handler, which adds is_error:

Framework error
{ "message": "invalid api key", "code": "authentication_failed", "is_error": true }

All error codes

CodeHTTPShapeEndpointsMeaningHow to fix
INVALID_API_KEY401viewallThe X-Reseller-API-Key header is missing entirely.Send the header on every request. Body is {code, message} with no is_error field.
authentication_failed401frameworkallThe key is malformed (wrong prefix / shorter than 16 chars) or unknown / inactive / revoked.Check the key value and that it is still active. Body is {message, code, is_error:true} and the response carries WWW-Authenticate: X-Reseller-API-Key.
throttled429frameworkallYou exceeded the rate limit (120/min, per API key).Back off. The message states how many seconds to wait ("Expected available in N seconds.").
UNKNOWN_SERVICE400viewPOST /ordersservice_code is not one of the 11 catalog codes.Use a code from GET /services (e.g. tg-active). Web-only codes like line-registered are not resellable.
UNKNOWN_COUNTRY400viewPOST /orderscountry (after trim + uppercase) is not a supported ISO-2 code.Use a code from GET /countries. Values are uppercased server-side, so "us" and "US" both work.
VALIDATION_ERROR400viewPOST /ordersThe file field is missing, or the Idempotency-Key header is longer than 64 characters.Attach a file part named "file", and keep any Idempotency-Key at most 64 chars.
FILE_TOO_LARGE400viewPOST /ordersThe uploaded file exceeds 20 MB.Split the list into files ≤ 20 MB and submit them as separate orders.
MIN_NUMBERS400viewPOST /ordersFewer than 2000 valid numbers remain after normalization + dedup. Nothing is charged.Submit at least 2000 unique, valid numbers for the chosen country. The message reports the count you sent.
INSUFFICIENT_BALANCE402viewPOST /ordersYour wallet balance is too low to charge the job. No order is created.Top up (arranged with your account manager), then retry. Check GET /balance first.
NOT_QUEUEABLE409viewPOST /ordersThe order could not be queued (rare internal state).Retry the submit. If it persists, contact support.
ORDER_REF_CONFLICT503viewPOST /ordersThe server could not allocate a unique order id after bounded retries (extremely rare). No charge is made.Safe to retry — the atomic block rolled back, so no order was created and no wallet debit occurred.
NOT_FOUND404viewGET /orders/{order_id}, GET /orders/{order_id}/resultNo order matches that id for your account (never existed, malformed id, or belongs to another tenant).Use the exact order_id string returned by POST /orders.
NOT_READY409viewGET /orders/{order_id}/resultThe order is not completed yet. The message includes the current status.Keep polling GET /orders/{order_id}; only download once status == "completed".
RESULT_UNAVAILABLE500viewGET /orders/{order_id}/resultThe order is completed but the result payload could not be retrieved (missing export file and no inline text).Retrying will not help — contact support with the order_id.

Validation order on POST /orders

Submit-time checks run in a fixed order and the first failure wins: an existing Idempotency-Key replay short-circuits first, then UNKNOWN_SERVICE → UNKNOWN_COUNTRY → VALIDATION_ERROR (missing file) → FILE_TOO_LARGE → MIN_NUMBERS, then charging (INSUFFICIENT_BALANCE / NOT_QUEUEABLE), and finally the rare ORDER_REF_CONFLICT on id-allocation exhaustion.

Retry guidance

  • 401 / 400 / 402 — do not retry blindly; fix the credential, request, or balance first.
  • 429 — back off for the number of seconds in the message, then retry.
  • 409 NOT_READY — keep polling; the order is not finished yet.
  • 503 ORDER_REF_CONFLICT — safe to retry immediately (no charge was made).
  • 500 RESULT_UNAVAILABLE — retrying will not help; contact support with the order_id.