kepa
GETTING STARTED

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.

Code
HTTP
Meaning
Severity
INVALID_REQUEST400

Request body or parameters failed validation. Inspect details.field.

fatal
MISSING_FIELD400

A required field was omitted.

fatal
INVALID_AMOUNT400

Amount is missing, negative, or exceeds the merchant ceiling.

fatal
INVALID_CURRENCY400

Currency is not in the merchant's supported set.

fatal
UNAUTHORIZED401

Missing or invalid X-Api-Key / bearer token.

fatal
FORBIDDEN403

API key is valid but lacks permission for this operation.

fatal
NOT_FOUND404

transactionId or other resource does not exist.

fatal
IDEMPOTENCY_CONFLICT409

Same Idempotency-Key was reused with a different request body.

fatal
TERMINAL_BUSY409

Another transaction is already in progress on this terminal.

transient
RECONCILIATION_IN_PROGRESS409

Reconciliation is already running.

transient
RATE_LIMITED429

API rate limit exceeded. Retry after the time in Retry-After.

transient
INTERNAL_ERROR500

Unexpected server error. Retries are safe with the same Idempotency-Key.

transient
TIMEOUT504

Upstream timeout. Retries are safe with the same Idempotency-Key.

transient
CARD_READ_ERROR503

Card could not be read — typically a chip or contactless failure.

terminal
UNSUPPORTED_CARD503

Card scheme or AID is not enabled on this terminal.

terminal
COMMUNICATION_ERROR503

Terminal lost connectivity to the cloud relay or acquirer host.

transient
TERMINAL_UNAVAILABLE503

Terminal is offline, asleep, or not provisioned.

transient

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.

Code
Meaning
Retry?
00

Approved

no
01

Refer to issuer

advise
03

Invalid merchant

no
04

Pick up card

no
05

Do not honor

advise
12

Invalid transaction

no
13

Invalid amount

no
14

Invalid card number

no
15

No such issuer

no
30

Format error

no
41

Lost card — pick up

no
43

Stolen card — pick up

no
51

Insufficient funds

advise
54

Expired card

no
55

Incorrect PIN

advise
57

Transaction not permitted to cardholder

no
58

Transaction not permitted to terminal

no
61

Exceeds withdrawal limit

advise
62

Restricted card

no
65

Exceeds withdrawal frequency

advise
75

PIN tries exceeded

no
91

Issuer unavailable

yes
96

System malfunction

yes

Retry policy in one diagram

  • Network error before responseretry with same Idempotency-Key. Safe.
  • 5xx with transient coderetry with same Idempotency-Key. Safe.
  • 408 / 504retry with same Idempotency-Key. Safe.
  • 429 RATE_LIMITEDhonor Retry-After header, then retry.
  • 409 TERMINAL_BUSYwait 1–2s, retry, or call /v1/transaction/{id}/abort first.
  • 409 IDEMPOTENCY_CONFLICTfix the request body. Do not retry.
  • 4xx (other)do not retry. Fix the request.
  • 2xx with DECLINED statusthe 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.

Scope
Burst
Sustained
Notes
Transaction endpoints (sale, refund, void, pre-auth, granular)10 req/s120 req/minPer terminal. Exceeding burst returns 429.
Device endpoints (health, display, input, print)20 req/s300 req/minPer terminal.
Settlement + reconciliation endpoints5 req/s60 req/minPer merchant (not per terminal).
Token endpoint (auth.atlas-softpos.com)5 req/s30 req/minPer client_id. Aggressive retries trigger a 5-minute lockout.
Webhook delivery (outbound from Atlas)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.