Skip to main content

Overview

When a card purchase is declined, the API call that reports it still succeeds. You get HTTP 200, and the decline travels inside the response body in the decline_reason object. Decline codes and API error codes are two separate catalogs. A decline code never appears in the code field of an error response, and an error code never appears in decline_reason.
Do not treat a decline as a failed request. A declined purchase is a successful read of a transaction whose outcome was “declined”. If you retry the API call, you get the same declined transaction back.

Where you see it

The decline_reason object

REST responses carry three fields:
string
The decline code. This is the only field you should branch on.
string
A short human-readable label for the code. Suitable for display, not for parsing.
string
A longer human-readable sentence. It repeats simple_reason when no additional detail was recorded.
Webhook payloads carry five fields: the three above plus response_code and description, which duplicate code and simple_reason. Those two exist for backwards compatibility with older integrations — read code and simple_reason instead.

decline_reason can be null

decline_reason is nullable. It is null both when no reason was recorded for the decline and when the recorded reason is not one that CryptoMate exposes. Nothing in the response tells those two cases apart.
Always null-check decline_reason before reading code. A declined transaction with decline_reason: null is a normal response — not a bug, and not an incomplete record.

detailed_reason is not a contract

detailed_reason is free text written for humans. Its wording changes without notice, it differs in shape between codes, and for some codes it is a copy of simple_reason.
Never parse detailed_reason, and never derive amounts, balances or limits from it. Any figure in that sentence renders internal state at the moment of the decline — it is not a value you can reconcile against. Branch on code, and read balances and limits from the endpoints that own them.

Decline codes

Balance

Spending limits

M204 reports two different limits. Its short label cites a 5,000 USD ceiling while its detailed text cites 25,000 USD. The two disagree, and this page does not state which one governs. Do not derive a limit value from an M204 decline.

Velocity rules

Risk evaluation

Card security

Merchant category

Processing

C020 is a broad bucket, not a specific cause. It is not limited to declines that arrived without an identifiable reason — a decline can surface as C020 even when a more specific cause exists upstream. Treat it as “could not be processed”.

Unknown

Declines that block the card

Two codes report that the card was blocked as part of the decline: M210 and C101. A blocked card declines every subsequent purchase until you unblock it. Every other code in this catalog leaves the card usable.
Version 2 of the card transaction search does not report declines. It omits both decline_reason and status, and it folds declined purchases into the PURCHASE operation. In version 2 a declined purchase is indistinguishable from a completed one. If you need to identify declines, stay on version 1 of the search or read the transaction detail endpoint.
Branch on code and keep a default case — the catalog grows. Show simple_reason if you need a message for your users, and log code alongside your own request identifiers so a decline can be traced later.