Error reference
One canonical place for everything that can go wrong.
Every error from the Commerce API is returned with the same envelope. The HTTP status code tells you the broad category, the error field gives you a stable machine-readable code, and message is a human-readable string suitable for logs but not for cardholders.
{
"error": "INVALID_REQUEST",
"message": "The 'amount' field must be a positive integer",
"requestId": "req_01JQXYZA7B8C9D",
"details": {
"field": "amount",
"value": -100,
"constraint": "minimum"
}
}Severity classes
- transientThe operation might succeed if retried with the same Idempotency-Key. Examples: terminal busy, network blip, rate limit, internal error.
- terminalThe operation will not succeed without operator intervention — re-tap the card, switch entry method, replace the card.
- fatalThe request itself is wrong. Do not retry. Fix the request and try again.
Atlas error codes
Every code in this table maps to a single, stable string in the error field of the response envelope.
INVALID_REQUEST400Request body or parameters failed validation. Inspect details.field.
MISSING_FIELD400A required field was omitted.
INVALID_AMOUNT400Amount is missing, negative, or exceeds the merchant ceiling.
INVALID_CURRENCY400Currency is not in the merchant's supported set.
UNAUTHORIZED401Missing or invalid X-Api-Key / bearer token.
FORBIDDEN403API key is valid but lacks permission for this operation.
NOT_FOUND404transactionId or other resource does not exist.
IDEMPOTENCY_CONFLICT409Same Idempotency-Key was reused with a different request body.
TERMINAL_BUSY409Another transaction is already in progress on this terminal.
RECONCILIATION_IN_PROGRESS409Reconciliation is already running.
RATE_LIMITED429API rate limit exceeded. Retry after the time in Retry-After.
INTERNAL_ERROR500Unexpected server error. Retries are safe with the same Idempotency-Key.
TIMEOUT504Upstream timeout. Retries are safe with the same Idempotency-Key.
CARD_READ_ERROR503Card could not be read — typically a chip or contactless failure.
UNSUPPORTED_CARD503Card scheme or AID is not enabled on this terminal.
COMMUNICATION_ERROR503Terminal lost connectivity to the cloud relay or acquirer host.
TERMINAL_UNAVAILABLE503Terminal is offline, asleep, or not provisioned.
ISO 8583 issuer response codes
When the issuer authorizes (or declines) a transaction, the responseCode on the TransactionResponse is the raw ISO 8583 code from the card scheme. "00" means approved; everything else is some flavor of decline. The Retry column tells you what to do programmatically — but always show the cardholder the message printed on their receipt, never the raw code.
00Approved
no01Refer to issuer
advise03Invalid merchant
no04Pick up card
no05Do not honor
advise12Invalid transaction
no13Invalid amount
no14Invalid card number
no15No such issuer
no30Format error
no41Lost card — pick up
no43Stolen card — pick up
no51Insufficient funds
advise54Expired card
no55Incorrect PIN
advise57Transaction not permitted to cardholder
no58Transaction not permitted to terminal
no61Exceeds withdrawal limit
advise62Restricted card
no65Exceeds withdrawal frequency
advise75PIN tries exceeded
no91Issuer unavailable
yes96System malfunction
yesRetry policy in one diagram
- Network error before response — retry with same Idempotency-Key. Safe.
- 5xx with transient code — retry with same Idempotency-Key. Safe.
- 408 / 504 — retry with same Idempotency-Key. Safe.
- 429 RATE_LIMITED — honor Retry-After header, then retry.
- 409 TERMINAL_BUSY — wait 1–2s, retry, or call /v1/transaction/{id}/abort first.
- 409 IDEMPOTENCY_CONFLICT — fix the request body. Do not retry.
- 4xx (other) — do not retry. Fix the request.
- 2xx with DECLINED status — the transaction completed cleanly — the issuer just said no. Show the cardholder.
Rate limits
Rate limits are enforced per API key (or per JWT subject) and apply to all endpoints. When you exceed a limit the API returns 429 RATE_LIMITED with a Retry-After header indicating how many seconds to wait before retrying.
10 req/s120 req/minPer terminal. Exceeding burst returns 429.20 req/s300 req/minPer terminal.5 req/s60 req/minPer merchant (not per terminal).5 req/s30 req/minPer client_id. Aggressive retries trigger a 5-minute lockout.——No rate limit on your receiver. Atlas delivers as fast as you can 200.Limits are generous enough that a single terminal will never hit them during normal operation. If your integration runs concurrent requests across a fleet of terminals from a single API key, you may need to request a limit increase from your account manager.