Unified Error Catalog — Kushki ONE Connect

Kushki ONE Connect returns a structured JSON payload on any failure, whether the problem started at the terminal, in a validation, in authentication or at the acquirer. That lets you build robust integrations, automate recovery flows and stop depending solely on HTTP status codes.

This manual is your diagnostic tool: the data model structure, the catalogs by category, how we map third-party rejections and a quick guide for the common cases.

1. Error models

There are two error envelopes. Which one you get depends on whether the failure arrives in an HTTP response or in an async event.

1.1 HTTP responses: LinkFailure

Every error response shares this structure. Evaluate the type field first to classify the source of the failure, then look up the matching code.

FieldTypeAlways presentDescription
typestringError category. Identifies the source of the failure. See Section 2
codestringUnique code. Prefix plus number, for example PAR-001, TER-002, ACQ-13
paramstringThe exact field or parameter that caused the error. Used mostly in PARAMETER errors
messagestringHuman-readable description of the failure
objectobjectTraceability data: client_transaction_id, terminal_id and serial_number where applicable

The HTTP status code is consistent with the type in the body. For ACQUIRER errors we keep the status Kushki originally returned.

{
"type": "PARAMETER",
"code": "PAR-003",
"param": "amount",
"message": "Amount must be a value greater than 0",
"object": {
"client_transaction_id": "1018282",
"terminal_id": "172653",
"serial_number": "PJ715652"
}
}

1.2 Async events: failure_reason

When you integrate over async mode, failures do not arrive in an HTTP response but inside the webhook event, in the failure_reason object.

FieldTypeDescription
typestringError category, with the same values as Section 2
codestringUnique error code
messagestringHuman-readable description of the failure
{
"status": "TERMINAL_REJECTED",
"previous_status": "CARD_PRESENTED",
"client_transaction_id": "c5a3f3be-9d6f-4d39-8af5-58dbb589af79",
"failure_reason": {
"type": "TERMINAL",
"code": "TER-172",
"message": "The maximum operation time was exceeded."
}
}

2. Error categories

typeSourceDescription
PARAMETERValidationIncorrectly sent fields: required fields empty, wrong type or invalid format
TERMINALTerminalState of the physical terminal: busy, offline, not linked, incompatible mode
AUTHENTICATIONSecurityCredentials cannot be authenticated, or permissions are insufficient
NOT_FOUNDRoutingService or endpoint not found. Invalid URL
ACQUIRERAcquirerProcessing or authorization of the transaction by the Kushki acquirer. ACQ- prefix
INTERNALApplicationUnexpected errors: services down, internal failures
CONFIGURATIONDMS configurationThe operation is not enabled, or it exceeds the limits configured for the terminal
TERMINAL-PRINTERHardwareErrors from the built-in thermal printer: out of paper, cover open, paper jam
MANUFACTURERManufacturer SDKErrors from the Sunmi or Landi SDK. MAN- prefix

3. Validation errors — type: “PARAMETER”

These are generated when the request contains fields with the wrong format, values out of range or missing required fields. The param field identifies the specific field. All of them are preventable by validating the payload in your POS system before you call the API.

codeDescriptionMessage templateExample
PAR-001Required field not sentField {{field}} is requiredField amount.subtotal_iva0 is required
PAR-002Field of the wrong typeField {{field}} must be a/an {{type}}Field amount.subtotal_iva must be an integer
PAR-003Wrong format or invalid valueField {{field}} must satisfy: {{condition}}Field amount.iva must satisfy: value >= 0

When type is PARAMETER, the code can also be a numeric code in the 2001 to 2037 range, plus two special format codes.

3.1 System codes

codeDescription
BAD_FORMATJSON parsing error. The request body is not valid JSON or contains a wrong data type
BUSYThe terminal is processing another request. Retry once it becomes available

3.2 Amount and payment field validators

codeFieldMessageApplies to
2001amount.currencyInvalid currency: {value}. Expected one of: [MXN, CLP, PEN, COP]See note
2002amount.ivaamount.iva cannot be negativeAll
2003amount.subtotalIvaamount.subtotalIva cannot be negativeAll
2004amount.subtotalIva0amount.subtotalIva0 cannot be negativeAll
2005amount.tipamount.tip cannot be negative/charge and /pos_tip
2006airportTaxairportTax cannot be negativeAll
2007iaciac cannot be negativeAll
2008iceice cannot be negativeAll
2009travelAgencytravelAgency cannot be negativeAll
2012deferredMonthsdeferredMonths must be > 0 when isDeferred is true/charge
2013cashbackAmountcashbackAmount must be > 0 when isCashback is true/charge

3.3 Transaction identifier validators

codeFieldMessage
2010clientTransactionIdclientTransactionId must be a valid UUID format
2011clientTransactionIdclientTransactionId is required
2014transactionReferencetransactionReference must be a valid UUID format
2015transactionReferencetransactionReference is required

3.4 Pagination and date validators

codeFieldMessage
2016pagepage must be greater than 0
2017sizesize must be greater than 0
2018sizesize must not exceed 500
2019start_datestart_date cannot be negative
2020end_dateend_date cannot be negative
2021start_datestart_date must be before end_date

3.5 Configuration validators

codeFieldMessage
2022envenv is required
2023privateCredentialIdprivateCredentialId is required
2024countrycountry is required
2025pinTimeOutpinTimeOut cannot be negative
2026cardDetectTimeOutcardDetectTimeOut cannot be negative
2027pinKeyIndexpinKeyIndex cannot be negative
2028dataKeyIndexdataKeyIndex cannot be negative
2029timeoutSecondstimeoutSeconds cannot be negative
2030maxChipRetriesmaxChipRetries cannot be negative
2031countryCodecountryCode must be 3 uppercase letters or 3-4 digits (ISO 3166-1)
2032currencyCodecurrencyCode must be 3 uppercase letters or 3-4 digits (ISO 4217)
2033merchantIdmerchantId cannot be blank
2034terminalIdterminalId cannot be blank
2035terminalTypeterminalType cannot exceed 2 characters
2036CardInputAt least one card input method (ICC, NFC, MSR) must be enabled
2037timeoutSecondstimeoutSeconds cannot exceed 300 seconds (5 minutes)

4. Terminal errors — type: “TERMINAL”

These are generated when the physical terminal cannot accept the operation. Unlike hardware errors, they point to a state or connectivity problem, not a component failure.

codeDescriptionMessage template
TER-001Terminal not linked to the merchant accountTerminal {{serial_number}} does not exist, or is not linked to your account
TER-002Terminal not responding: offline or off the networkTerminal {{serial_number}} is not responding. It may be offline or not connected to the local network
TER-003Terminal busy processing a transactionTerminal {{serial_number}} is busy processing transaction (client_transaction_id: {{id}})
TER-004Terminal busy with an action other than a paymentTerminal {{serial_number}} is busy executing action {{action}}
TER-005Terminal in a mode incompatible with the operationThe terminal is in {{mode}} mode and does not allow the requested action
TER-006Terminal not enabled for that operation typeThe terminal is not allowed to process {{type}}

5. Authentication errors — type: “AUTHENTICATION”

These are generated when credentials are invalid or do not carry enough permissions for the requested action.

codeDescriptionMessage
AUTH-001Credentials cannot be authenticatedInvalid or expired credentials
AUTH-002Valid credentials without permission for the resourceYour credentials are valid but do not grant access to this resource
{
"type": "AUTHENTICATION",
"code": "AUTH-001",
"message": "Invalid or expired credentials"
}

6. Routing and internal errors

type: “NOT_FOUND”

codeDescriptionMessage template
NF-001Service or endpoint not foundService not found: {{url}}

type: “INTERNAL”

codeDescriptionMessage
INT-001Unexpected server or application errorInternal server error

7. Acquirer errors — type: “ACQUIRER”

Errors from the Kushki acquirer are wrapped under type: "ACQUIRER" with this mapping rule:

  • code: the original Kushki code with the ACQ- prefix. Code 13 becomes ACQ-13.
  • message: identical to Kushki’s original message.
  • object: includes client_transaction_id, terminal_id and serial_number where applicable.
  • HTTP status: we keep the one Kushki originally returned.

Original Kushki error:

{
"code": "13",
"message": "Either Invalid amount or Currency conversion field overflow"
}

Error mapped by Kushki ONE Connect, with the same 400 Bad Request:

{
"type": "ACQUIRER",
"code": "ACQ-13",
"param": "",
"message": "Either Invalid amount or Currency conversion field overflow",
"object": {
"client_transaction_id": "1018282",
"terminal_id": "172653",
"serial_number": "PJ715652"
}
}

8. Manufacturer errors — type: “MANUFACTURER”

Errors from the manufacturer SDK are wrapped with the MAN- prefix followed by the original code. Sunmi’s -2001 becomes MAN--2001.

{
"type": "MANUFACTURER",
"code": "MAN--2001",
"message": "Have no card",
"object": {
"client_transaction_id": "c5a3f3be-9d6f-4d39-8af5-58dbb589af69",
"terminal_id": "172653",
"serial_number": "SN816265"
}
}

Most frequent Sunmi codes

codeDescriptionRecommended action
MAN--2001Have no cardThe customer did not present the card. Ask for a retry
MAN--2002Multiple cardsMore than one card is in the NFC field. Ask them to remove the extras
MAN--2581User canceledThe customer canceled. Treat it as an expected cancellation
MAN--2582MSR or IC interruptedReading interrupted. Ask them not to remove the card until the terminal says so
MAN--3023DUKPT overflowDUKPT counter exhausted. Requires key reinjection. Contact support
MAN--4104Card is lockedCard blocked. The customer must contact their bank
MAN--4111Card expiredExpired card. Let the customer know
MAN--4120Amount exceeds contactless limitThe amount exceeds the NFC limit. Use chip instead
MAN--50020PIN entry cancelThe customer canceled PIN entry. Treat it as a cancellation
MAN--60001Input PIN timeoutThe customer did not enter the PIN in time. Ask for a retry

9. Configuration errors — type: “CONFIGURATION”

These are generated when the operation is not enabled for that terminal in the DMS, or when the amount exceeds the configured limits. Unlike PARAMETER errors, they are not fixed by changing the payload.

codeCauseRecommended action
-4001Tipping is not enabled on the terminalContact Kushki Operations to enable it in the DMS
-4002Cashback is not enabled on the terminalContact Kushki Operations to enable it in the DMS
-4003The cashback amount exceeds the configured limitTell the customer the available limit. Do not retry with the same amount
-4006The transaction amount exceeds the configured limitTell the customer. Contact Kushki Operations if the limit needs adjusting
{
"type": "CONFIGURATION",
"code": "-4001",
"message": "Tip is not enabled",
"object": {
"client_transaction_id": "c5a3f3be-9d6f-4d39-8af5-58dbb589af69",
"terminal_id": "172653",
"serial_number": "SN816265"
}
}

10. Kushki Printer errors — type: “TERMINAL-PRINTER”

Errors from the printing hardware. They are standardized regardless of the terminal manufacturer.

codeCauseAction for the operator
OUT_OF_PAPERNo paper rollInsert a new roll and retry
COVER_OPENPaper compartment cover openClose the cover firmly
COVER_INCOMPLETECover badly closed or roller without pressureOpen and close making sure the roller seats
PAPER_JAMPaper jammed in the mechanismRemove the jammed paper and insert a new roll
BUSYPrint queue busy with skipIfBusy: trueRetry in a few seconds
PRINTER_HOTThermal print head overheatedWait 2 or 3 minutes and retry
MOTOR_HOTFeed motor overheatedWait for it to cool down
CUTTER_ERRORCutter blade jammedRequires technical service intervention
OFFLINEThe module is not responding to the Android systemRestart the terminal
UNKNOWN_ERRORUnclassified hardware failureLog the case and escalate to technical support

11. Quick diagnostic guide

If type is…And codeThen
AUTHENTICATIONAUTH-001Check that you sign with the Business-Code and that the timestamp unit is correct
AUTHENTICATIONAUTH-002Credentials are valid but permissions are missing. Contact integrations
PARAMETERanyCheck the field named in param. Add validation in your POS before calling the API
PARAMETER2002 to 2009You most likely sent amounts with decimals instead of integers
TERMINALTER-002The terminal is offline. Check network connectivity
TERMINALTER-003 or TER-004The terminal is busy. Wait or use abort
TERMINALTER-006Capability not enabled. Contact Kushki Operations
TERMINAL-PRINTERanyPhysical hardware condition. Show the message to the operator
MANUFACTURERstarts with MAN--200Card reading problem. Ask the customer for a retry
MANUFACTURERMAN--50020 or MAN--60001The customer canceled or did not enter the PIN. Treat it as an expected cancellation
ACQUIRERanyProcessor decline. Show the message to the customer and log the code
CONFIGURATIONanyDo not retry with the same payload. Requires a DMS adjustment
INTERNAL or NOT_FOUNDanyLog the full payload and escalate to Kushki technical support

To debug a signature failure, this is the minimum logging pattern:

  • Javascript
  • Python
try {
const res = await fetch(url, { method: "POST", headers, body });
const data = await res.json();
if (!res.ok) {
logger.error("kushki_one_error", {
http: res.status,
type: data.type,
code: data.code,
transaction: data.object?.client_transaction_id,
signaturePresent: Boolean(headers.Authorization),
});
}
} catch (e) {
logger.error("kushki_one_network", { message: e.message });
}
try:
res = requests.post(url, headers=headers, json=payload, timeout=30)
data = res.json()
if not res.ok:
logger.error("kushki_one_error", extra={
"http": res.status_code,
"type": data.get("type"),
"code": data.get("code"),
"transaction": data.get("object", {}).get("client_transaction_id"),
"signature_present": "Authorization" in headers,
})
except requests.RequestException as e:
logger.error("kushki_one_network", extra={"message": str(e)})
Request authentication

Resolve AUTHENTICATION errors by reviewing the two signing mechanisms and their differences.

Async services and webhooks

Interpret the failure_reason object inside the transaction lifecycle.