Tổng Kho eSIM
Error codes · 91 published codes

Error Codes

All errors return the envelope { ok: false, error: { code, message, field?, meta?, request_id } } with semantic HTTP statuses, never 200 for failures. The table below lists all codes you may encounter across /v1 and embed channels, synchronized with backend registries.

Error Envelope Structure

http
HTTP/1.1 402 Payment Required
Content-Type: application/json
X-Request-Id: 018f2b00-0000-7000-8000-0000000000ff

{
  "ok": false,
  "error": {
    "code": "wallet.insufficient_balance",
    "message": "Số dư ví không đủ để thực hiện giao dịch.",
    "field": null,
    "meta": null,
    "request_id": "018f2b00-0000-7000-8000-0000000000ff"
  }
}
Why domain.reason instead of numeric codes 0000

HTTP-native: reverse proxies, monitoring, and REST clients already branch on HTTP statuses: using standard statuses leverages existing infrastructure.

Self-describing: reading wallet.insufficient_balance is instantly understandable without looking up tables; adding new codes does not break existing logic.

Legacy system expects numbers? The code string is immutable and acts as a stable translation key for your internal tables.

4 Error Handling Best Practices

Branch on HTTP status first, error code second
HTTP status dictates transport-level handling (retry, alert, open circuit breaker); error.code dictates user-facing messaging. Statuses remain more stable than specific codes.
Unrecognized codes must not crash workflows
New features introduce new error codes. When encountering an unknown code, handle by HTTP status, log raw code + request_id, and show a fallback message. Never throw unhandled exceptions.
Always capture and log request_id
Every response carries X-Request-Id and error envelopes mirror it. This is the sole identifier for investigating specific request logs with technical support.
Respect Retry-After on 429 and 503
Read the Retry-After header instead of hardcoding retry delays. 429 also provides X-RateLimit-Limit / Remaining / Reset headers to throttle before blocks occur.

Code ↔ HTTP Mapping Table

Grouped by domain. The API reference page also specifies which endpoints return which error branches; consult alongside to identify applicable codes.

Showing 91 / 91 codes

Authentication, keys and limits partner.*

codeHTTPMeaningRetryable?
partner.invalid_key401Invalid API key.No: verbatim retry will fail again
partner.invalid_signature401Invalid request signature.No: verbatim retry will fail again
partner.timestamp_expired401The request timestamp is too far off from the server's clock.No: verbatim retry will fail again
partner.nonce_reused401This nonce has already been used.No: verbatim retry will fail again
partner.ip_not_allowed403This IP address is not on the allow list.No: verbatim retry will fail again
partner.scope_denied403This API key does not have permission to call this endpoint.No: verbatim retry will fail again
partner.key_suspended403This API key is currently suspended.No: verbatim retry will fail again
partner.key_revoked403This API key has been revoked.No: verbatim retry will fail again
partner.endpoint_disabled503This endpoint group is temporarily out of service.Yes: retry verbatim
partner.rate_limited429Rate limit exceeded. Please try again later.Yes: retry verbatim
partner.package_not_visible404This package code is not purchasable with your key.No: verbatim retry will fail again
partner.daily_quota_exceeded429Daily request quota exceeded. Please try again tomorrow.Yes: retry verbatim
partner.wrong_host403This API key cannot be used on the requested host. Test keys (`tke_test_`) must call `https://api-testing.tongkhoesim.com`, live keys (`tke_live_`) must call `https://api.tongkhoesim.com`.No: verbatim retry will fail again

General API errors internal.*

codeHTTPMeaningRetryable?
internal.validation_failed400The submitted data is invalid.No: verbatim retry will fail again
internal.invalid_filter400Invalid filter condition.No: verbatim retry will fail again
internal.invalid_sort_field400Invalid sort field.No: verbatim retry will fail again
internal.unauthenticated401You are not signed in or your session has expired.No: verbatim retry will fail again
internal.forbidden403You do not have permission to perform this action.No: verbatim retry will fail again
internal.not_found404The requested resource was not found.No: verbatim retry will fail again
internal.route_not_found404This path does not exist. Check the method and path against the documentation.No: verbatim retry will fail again
internal.method_not_allowed405This HTTP method is not supported.No: verbatim retry will fail again
internal.conflict409State conflict — the action could not be completed.No: verbatim retry will fail again
internal.unsupported_media_type415This content type is not supported.No: verbatim retry will fail again
internal.rate_limited429You've sent too many requests. Please try again later.Yes: retry verbatim
internal.server_error500A system error occurred. Please try again later.Yes: retry verbatim
internal.service_unavailable503The service is temporarily unavailable. Please try again later.Yes: retry verbatim
internal.limit_exceeded422You've reached the allowed limit. Please remove some items and try again.No: verbatim retry will fail again
internal.money_frozen503The system has temporarily paused financial transactions for a ledger check. Please try again later.Yes: retry verbatim

Plan catalog catalog.*

codeHTTPMeaningRetryable?
catalog.cursor_mismatch400This page cursor does not match the current filters. Start again from the first page (drop the cursor parameter).No: verbatim retry will fail again

Quotes and orders order.*

codeHTTPMeaningRetryable?
order.quote_not_found404Quote not found.No: verbatim retry will fail again
order.quote_expired409This quote has expired. Please create a new one.No: verbatim retry will fail again
order.quote_already_committed409This quote has already been committed into an order.No: verbatim retry will fail again
order.package_not_allowed400This package does not exist or is not available for purchase.No: verbatim retry will fail again
order.not_deliverable409This order isn't complete yet, so this action isn't available.No: verbatim retry will fail again
order.quantity_limit_exceeded400The number of eSIMs exceeds the limit allowed per order.No: verbatim retry will fail again
order.fulfillment_config_changed409This package's fulfillment configuration has changed. Please create a new quote.No: verbatim retry will fail again
order.refund_suggestion_pending409This order has a refund suggestion pending approval. Please resolve it first.No: verbatim retry will fail again

eSIM esim.*

codeHTTPMeaningRetryable?
esim.out_of_stock409Not enough stock in inventory for this package.No: verbatim retry will fail again
esim.not_cancellable409This eSIM is not in a cancellable state.No: verbatim retry will fail again
esim.lpa_not_available409This eSIM doesn't have an LPA code yet (not activated/registered).No: verbatim retry will fail again
esim.not_eligible409This eSIM is not eligible for a top-up.No: verbatim retry will fail again
esim.not_activated409This eSIM has not been installed yet — install and enable it before topping up.No: verbatim retry will fail again
esim.topup_not_supported409This package does not support top-ups.No: verbatim retry will fail again
esim.topup_provider_mismatch409This top-up package belongs to a different provider than the one serving this eSIM. Choose a top-up package listed for that eSIM.No: verbatim retry will fail again
esim.refund_not_eligible409This eSIM is not eligible for a refund request.No: verbatim retry will fail again
esim.refund_request_pending409This eSIM already has a refund request pending.No: verbatim retry will fail again
esim.suspended409This eSIM is currently suspended — please resume it before performing this action.No: verbatim retry will fail again

Wallet wallet.*

codeHTTPMeaningRetryable?
wallet.frozen409This wallet is frozen and cannot be spent from.No: verbatim retry will fail again
wallet.velocity_hold409This wallet is on hold for review. Please contact support.No: verbatim retry will fail again
wallet.insufficient_balance402Insufficient wallet balance to complete this transaction.No: verbatim retry will fail again
wallet.deleted409The destination wallet is invalid (deleted).No: verbatim retry will fail again
wallet.velocity_exceeded429Transactions exceeded the allowed threshold in a short time. The wallet has been put on hold for review.No: verbatim retry will fail again

Refund requests refund.*

codeHTTPMeaningRetryable?
refund.note_required400Please enter a reason for rejecting this refund.No: verbatim retry will fail again

Selling prices pricing.*

codeHTTPMeaningRetryable?
pricing.no_price_for_buyer409This package doesn't have a selling price configured for you yet.No: verbatim retry will fail again

eSIM provider provider.*

codeHTTPMeaningRetryable?
provider.disabled409This package's provider is disabled and cannot be sold.No: verbatim retry will fail again
provider.api_group_disabled409This provider's service group is currently disabled.No: verbatim retry will fail again
provider.not_registered500No connector is configured for this provider.Yes: retry verbatim
provider.unsupported400This provider does not support this action.No: verbatim retry will fail again
provider.timeout504The provider took too long to respond. Please try again later.Yes: retry verbatim
provider.auth_failed502Authentication with the provider failed.Yes: retry verbatim
provider.rate_limited429The provider is rate-limiting requests. Please try again later.Yes: retry verbatim
provider.malformed_response502The provider returned invalid data.Yes: retry verbatim
provider.call_failed502The call to the provider failed.Yes: retry verbatim
provider.out_of_stock409This package is out of stock at the provider.No: verbatim retry will fail again
provider.msisdn_taken409The MSISDN being provisioned already belongs to another subscriber at the provider.No: verbatim retry will fail again
provider.msisdn_exhausted409No usable MSISDN left at the provider.No: verbatim retry will fail again

Idempotency idempotency.*

codeHTTPMeaningRetryable?
idempotency.conflict409This Idempotency-Key was already used with different content.No: verbatim retry will fail again

Provider capabilities capability.*

codeHTTPMeaningRetryable?
capability.not_supported422This package does not support the requested feature.No: verbatim retry will fail again

Test mode / simulation testmode.*

codeHTTPMeaningRetryable?
testmode.live_key_forbidden403This endpoint is available in testmode only with test API keys (prefix `tke_test_`) on host api-testing. The key you used is a live key, so simulation is not possible — switch to a test key of the same organization.No: verbatim retry will fail again
testmode.not_test_item422This eSIM is a LIVE record — testmode only operates on test eSIMs. To cancel a real order, submit a refund request for review.No: verbatim retry will fail again
testmode.invalid_scenario422Invalid simulation scenario. Send at least one of `data_used_mb`, `status`, `expire_now`, `throttled`; `status` accepts only released|installed|enabled|disabled.No: verbatim retry will fail again
testmode.no_sellable_package422The organization does not have pricing for any package to create sample data — at least one sellable package with pricing is required.No: verbatim retry will fail again

Webhook webhook.*

codeHTTPMeaningRetryable?
webhook.health_check_failed422The webhook URL did not respond validly during the health check.No: verbatim retry will fail again
webhook.url_not_allowed422This webhook URL is not allowed (it must be a public https URL).No: verbatim retry will fail again
webhook.not_configured404No webhook is configured for this API key.No: verbatim retry will fail again
webhook.delivery_not_found404Webhook delivery not found.No: verbatim retry will fail again
webhook.already_configured409This API key already has a webhook endpoint. One endpoint per key — update it with `PUT /v1/webhooks/{id}`, or remove it with `DELETE /v1/webhooks/{id}` and create a new one.No: verbatim retry will fail again
webhook.not_found404No such webhook endpoint on the calling API key.No: verbatim retry will fail again

Organization status org.*

codeHTTPMeaningRetryable?
org.invoice_profile_incomplete422Organization has incomplete invoice profile (legal name, tax code, address).No: verbatim retry will fail again
org.suspended403This organization is currently suspended.No: verbatim retry will fail again
org.closed403This organization is closed.No: verbatim retry will fail again

Public embed channel embed.*

codeHTTPMeaningRetryable?
embed.invalid_token401Invalid embed token.No: verbatim retry will fail again
embed.token_revoked410This embed channel is no longer active.No: verbatim retry will fail again
embed.rate_limited429This embed channel is calling too fast. Please try again later.Yes: retry verbatim
embed.package_not_visible404Package not found.No: verbatim retry will fail again

VAT invoices invoice.*

codeHTTPMeaningRetryable?
invoice.order_not_settled409This order hasn't settled yet (a refund is still processing), so an invoice can't be issued. Please try again in a few minutes.Yes: retry verbatim
invoice.profile_incomplete422The organization's invoicing profile is incomplete. Please fill it in fully before issuing an invoice.No: verbatim retry will fail again
invoice.already_requested409This order already has an invoice.No: verbatim retry will fail again
invoice.nothing_to_invoice409After deducting the refunded amount, there is nothing left on this order to invoice.No: verbatim retry will fail again
invoice.amount_changed409This order's amount just changed due to a new refund. Please review the amount and issue the invoice again.Yes: retry verbatim
invoice.buyer_invalid422The receiving company's details are incomplete, or the tax code format is invalid.No: verbatim retry will fail again