Skip to main content

Error code catalog

Every code the /v1 API can return, one section each. code is stable and safe to branch on; the message accompanying it is not.

Retryable means retrying the identical request may succeed without any other change. Where it says not retryable, retrying will fail identically — fix the request, the state, or the credential.

Every error carries a doc_url pointing at its own section on this page:

{
"error": {
"type": "validation_error",
"code": "kyc_not_approved",
"message": "Cardholder chd_01HX8ZQ2K4M7P9RSTV is not verified (status not_started).",
"param": "card_id",
"doc_url": "https://developer.aletaplanet.com/api-reference/errors/error-code-catalog#kyc_not_approved",
"request_id": "req_01HX8ZQ2K4M7P9RSTV"
}
}

The fragment is always the code itself, so you can build the link for any code here without waiting for an error to hand you one. Surfacing doc_url in your own logs and support tooling turns a code into a page an engineer can read.

type is the broad category — decide how to handle a failure from it, and what happened from code. See the error object for the envelope and HTTP status mapping for what each status means on its own.

Token endpoint — RFC 6749 shape​

POST /oauth/token does not use the ErrorObject envelope. It answers with the flat body OAuth client libraries expect, and carries no code or doc_url:

{ "error": "invalid_client", "error_description": "…" }
StatuserrorMeaning and fix
401invalid_clientThe client is unknown or revoked, the assertion's signature did not verify, it was signed for the other environment, or the source address is not on the allowlist. The description says which — but only once the signature is proven; before that, every refusal reads the same on purpose
400invalid_grantThis assertion's jti was already redeemed. Sign a fresh one
400invalid_scopeA requested scope is not held by the client, or is not a scope at all
400invalid_requestThe assertion is not a well-formed JWT, or a required form field is missing
400unsupported_grant_typegrant_type was not client_credentials
500server_errorNot the request's fault — an unexpected failure on our side. Log the request and retry once; treat a second server_error as a real outage, not a mistaken assertion

An assertion that has expired, or is more than five minutes from expiring, is just invalid_client with the same uninformative description every other pre-signature failure gets — the clock skew is not named, on purpose. A clock more than sixty seconds off is the most common cause, so check the signing host's time before anything else, even though the error will not point you there.

Request​

Malformed or unacceptable input, refused before anything was done with it.

invalid_request_body​

400 · invalid_request_error · not retryable

Body is not valid JSON, or not an object where one was required.

missing_parameter​

400 · invalid_request_error · not retryable

A required field is absent. param names it.

program_id on POST /v1/accounts is the one to watch: it is required even if your organization holds a single program, because defaulting to your only one would be right until the day a second product went live. GET /v1/programs lists the ids you may send, for the environment your token names.

invalid_parameter​

400 · invalid_request_error · not retryable

Wrong type, format, or out of range. param names it. This is also the code a 422 falls back to when several fields fail at once — errors[] then carries one entry per field.

unknown_parameter​

400 · invalid_request_error · not retryable

A field in the body is not one this endpoint accepts. param names it. Unknown fields are refused rather than ignored, so a typo cannot silently do nothing.

invalid_public_key​

400 · invalid_request_error · not retryable

The RSA key supplied for card details is malformed, or weaker than 2048-bit.

Authentication​

The credential itself. See authentication for how tokens are obtained.

missing_credentials​

401 · authentication_error · not retryable

No Authorization header. Send Bearer <access token>.

invalid_access_token​

401 · authentication_error · not retryable

The token is expired, unknown, or its client has been revoked. Get a new one from the token endpoint; if that is refused too, the client itself is the problem. Tokens live fifteen minutes — treat this as "fetch a new token, then retry once", and a second 401 as final.

Permission​

The credential is valid and is not allowed to do this.

insufficient_scope​

403 · permission_error · not retryable

The client does not hold the scope this endpoint needs. Scopes are frozen at token issue, so add it to the client in Cockpit and get a new token.

ip_not_allowed​

403 · permission_error · not retryable

The source address is not on the allowlist. Two lists apply: your organization's and the client's own. A client can only ever be more restricted than its organization.

environment_mismatch​

403 · permission_error · not retryable

This token was issued for the other environment. Sandbox tokens start at_test_, production at_live_; both use the same base URL.

Not found​

A resource that exists but belongs to another organization answers exactly as one that does not exist. The two are indistinguishable by design.

not_found​

404 · invalid_request_error · not retryable

No route matches this path. Simulator endpoints answer this way in production, where they do not exist.

cardholder_not_found​

404 · invalid_request_error · not retryable

No cardholder with this id in this environment.

account_not_found​

404 · invalid_request_error · not retryable

No account with this id in this environment.

card_not_found​

404 · invalid_request_error · not retryable

No card with this id in this environment.

authorization_not_found​

404 · invalid_request_error · not retryable

No authorization with this id in this environment.

transaction_not_found​

404 · invalid_request_error · not retryable

No transaction with this id in this environment.

dispute_not_found​

404 · invalid_request_error · not retryable

No dispute with this id in this environment.

esim_package_not_found​

404 · invalid_request_error · not retryable

No eSIM package with this id in this environment.

esim_order_not_found​

404 · invalid_request_error · not retryable

No eSIM order with this id in this environment. If you are recovering from a timed-out create and never saw an id, look the order up by your own reference instead.

esim_not_found​

404 · invalid_request_error · not retryable

No eSIM with this id in this environment.

token_not_found​

404 · invalid_request_error · not retryable

No network token with this id in this environment.

A key minted under one program answers this way when presented against a card in another — from that card's side the key genuinely does not exist, and saying so is the same answer as for an id that was never issued. If you run more than one program, mint the key with the card's own program_id.

Idempotency​

See idempotency for how keys are matched.

idempotency_key_reuse​

409 · invalid_request_error · not retryable

Same Idempotency-Key, different body. Almost always a bug in your retry logic.

idempotency_request_in_progress​

409 · invalid_request_error · retryable

The original request is still running. Retry after a short backoff. Also returned when a credit or debit carrying the same client_transaction_id is still in flight.

adjustment_already_applied​

409 · invalid_request_error · not retryable

A credit or debit with this client_transaction_id was already applied to the account with a different amount or direction. The message says what was applied. A repeat with the same amount is not an error — it returns 200 with Idempotent-Replay: true and moves nothing.

Cardholders​

identity_document_required​

422 · validation_error · not retryable

A card cannot be issued to a cardholder with no identity_document. Set it when creating the cardholder; only the number and type are held, and neither ever comes back out of the API.

address_required​

422 · validation_error · not retryable

The cardholder has no address, and the card is registered to it. Add one with PATCH /v1/cardholders/{id}. Not the same as delivery_address_required, which is about the address on the issuance request.

kyc_not_approved​

422 · validation_error · not retryable

kyc_status is not approved. Report an approved attestation before issuing a card.

cardholder_already_exists​

409 · invalid_request_error · not retryable

Another cardholder in your organization already has this email or phone. param names which.

address_change_requires_kyc​

422 · validation_error · not retryable

This program's processor cannot take an address change through PATCH /v1/cardholders/{id}. Report a KYC attestation that carries the new address instead.

kyc_identity_required​

422 · validation_error · not retryable

The program's processor runs its own identity verification, and the cardholder's current attestation carries no identity. Report one through POST /v1/cardholders/{cardholder_id}/kyc before opening the account — an attestation reporting only an outcome is a valid record, and not enough here.

The same code answers an attestation whose supporting documents are no longer held. Report a fresh one with the documents attached.

Accounts​

insufficient_funds​

402 · validation_error · not retryable

available_balance is too low for this debit. Credit the account, then retry. Note the 402: retrying after funding is correct, where retrying a 422 never is.

account_blocked​

422 · validation_error · not retryable

The account is blocked and cannot fund a card or take this operation. Unblock it first.

currency_mismatch​

422 · validation_error · not retryable

Currencies differ across the operation. Nothing is converted implicitly — a cardholder needing two currencies needs two accounts.

account_cardholder_mismatch​

422 · validation_error · not retryable

The account belongs to a different cardholder than the one named. Both objects exist and both are yours, so this is a genuine mismatch rather than a tenancy failure.

account_not_provisioned​

422 · validation_error · not retryable

The account does not exist at the processor yet, so it cannot hold a card. has_upstream_reference reports this on the account.

account_not_fundable​

422 · validation_error · not retryable

This account cannot take a credit in its current state.

Cards​

card_invalid_state​

422 · validation_error · not retryable

The card's status does not permit this operation: not yet issued or activated, frozen, expired, or already in the state asked for.

card_already_activated​

422 · validation_error · not retryable

Activate card was called on a card that is already active. The card is usable; there is nothing to repeat.

card_closed​

422 · validation_error · not retryable

Closure is not reversible, by any call. Issue a new card.

card_not_provisioned​

422 · validation_error · not retryable

The processor has not issued the card yet, so the operation cannot reach it. Wait for card.issued, then try again.

card_limit_reached​

422 · validation_error · not retryable

The cardholder already has a card with the processor behind this program, which holds one card per cardholder.

unsupported_form_factor​

422 · validation_error · not retryable

The program does not issue the form factor asked for. message lists the ones it does issue.

embossed_name_required​

422 · validation_error · not retryable

embossed_name is required for every card, virtual or physical. It is fixed when the card is issued.

delivery_address_required​

422 · validation_error · not retryable

Every card needs a complete delivery_address on the request, virtual or physical. It is fixed when the card is issued. Not the same as address_required, which is the cardholder having no address at all.

card_type_not_configured​

422 · validation_error · not retryable

Your program has no card product for the card_type asked for — most often credit on a debit-only program. Nothing was sent to the processor. A configuration change on our side, so raise it with your account contact.

PIN​

pin_invalid​

422 · validation_error · not retryable

The PIN is unusable, and message says why: it is not the program's PIN length, it is not all digits, or it was not encrypted to the key you were given. Nothing was sent to the processor.

Transactions and tokens​

transaction_not_refundable​

422 · validation_error · not retryable

The transaction's state does not permit a refund: not settled, or already fully refunded.

refund_exceeds_original​

422 · validation_error · not retryable

The refund is larger than what remains of the transaction.

token_invalid_state​

422 · validation_error · not retryable

The token's status does not permit this operation.

token_deleted​

422 · validation_error · not retryable

Deletion is terminal. The cardholder must add the card to the wallet again.

Program and controls​

program_not_provisioned​

422 · validation_error · not retryable

No program is attached to your organization in this environment, or the one you named cannot be served by the deployment that answered you. A configuration matter on our side — raise it with your account contact rather than retrying.

program_not_configured​

422 · validation_error · not retryable

Your program's processor configuration does not cover the operation you asked for — a PIN operation on a program with no PIN key, for example. Nothing was sent to the processor. A configuration matter on our side; raise it with your account contact rather than retrying. Card issuance reports its own case as card_type_not_configured.

Most endpoints reach this without you naming a program at all. A program is named once, on POST /v1/accounts, and every card and account operation afterwards resolves it through the account — so a program that has stopped being serviceable by the deployment answering you surfaces here rather than at the call that named it.

spend_control_unsupported​

422 · validation_error · not retryable

A control in the request is one no upstream operation can enforce. Accepting it would tell you the card is restricted when nothing is restricting it.

operation_unsupported​

422 · validation_error · not retryable

The processor behind your program has no such operation. This is a fact about which program you are pointed at rather than something failing, so repeating the request returns the identical answer.

It appears in the simulator: some events cannot be injected because they originate outside the platform — a chargeback begins with a cardholder at another bank, and arrives here only as a notification — and no request of yours causes one. The simulator route itself is mounted because your program's processor offers simulation generally; this is one event its sandbox has no injector for.

eSIM​

esim_package_unavailable​

422 · validation_error · not retryable

The package exists but is not on sale — we have frozen or withdrawn it. Read the package to see its status; a frozen one may return, a withdrawn one will not.

esim_top_up_unavailable​

422 · validation_error · not retryable

This add-on cannot be bought on this eSIM. Either it has stopped being sold, or the package it extends is not running — a package that has never reached a network has nothing under way to add to. List the eSIM's top-ups for what it can take right now.

esim_inventory_exhausted​

422 · validation_error · retryable once stock returns

The package is on sale and your request is valid — we have no eSIM left to provision it onto. Nothing was charged.

This is about our inventory, not about the package, which is why it is a distinct code: reading the package will show it perfectly healthy, and ordering a different one will not help, because the shortage is upstream of the catalog. Retry later. If it persists, raise it with us rather than working around it — a pool that stays empty is ours to refill.

esim_order_reference_exists​

409 · invalid_request_error · not retryable

An order in your organization already carries this reference — package orders and top-ups share one ledger, so a reference spent on either is spent. Either the purchase went through and you are seeing your own earlier order, or the id was reused by mistake — check before sending a different one. Retrying an ambiguous request belongs to Idempotency-Key, not to a new reference.

Rate limits​

rate_limited​

429 · rate_limit_error · retryable

Too many requests. Wait for Retry-After, then retry with jitter.

Server​

None of these are your request's fault, and all three are safe to retry. A write that timed out must be retried with the same Idempotency-Key — see retrying 504 and network timeouts.

processor_unavailable​

502 · api_error · retryable

A system we depend on failed or timed out. Its own error is never passed through; the request_id on the response is the reference to quote.

processor_permission_denied​

502 · api_error · retryable

We were refused by a system we depend on. Not something you can fix from your side — send us the request_id.

internal_error​

500 · api_error · retryable

An unexpected failure on our side. Retry with backoff; if it persists, send us the request_id.

Codes not on this page​

Cockpit's own API — sign-in, team management, credential management — has its own codes, which a /v1 client never sees. They are not published here because nothing you integrate against can raise them.