Card decline reasons
The API does not return a decline reason today. Find the most likely cause from the card's status, limit and balance.
Status. Decline reasons through the API are Not yet available.
A declined payment arrives as a cards.transaction.payment webhook with transaction.status failed. It carries no reason field. Work out the most likely cause from three reads, then fix it and ask the cardholder to try again.
A money example. Ada tries to pay 45 USD and it is declined. Her card holds 30 USD, so you top it up with 20 USD and she pays. In another case, her card holds 200 USD, but its daily limit reads 0 after an update sent without limit. You set the limit back to 300 and she pays.
The webhook
{
"event_category": "cards",
"event_type": "cards.transaction.payment",
"event_group_id": "a14ec356-f33d-4384-ba68-4d9bfa19765b",
"timestamp": "2026-10-13T19:22:31.902117Z",
"event_data": {
"card": {
"customer_id": "5b0f6c1e-2a8f-4c39-9d0e-0c7e3b9a1f42",
"id": "a14ec356-f33d-4384-ba68-4d9bfa19765b",
"last4": "9351",
"name_on_card": "Ada Obi",
"network": "visa",
"status": "active"
},
"transaction": {
"amount": "45",
"currency": "USD",
"id": "f1e2d3c4-b5a6-4978-8a6b-5c4d3e2f1a0b",
"status": "failed",
"transaction_type": "card_payment"
}
},
"event_id": "0f1e2d3c-4b5a-4697-8877-665544332211"
}
transaction.amount is a string in US dollars. For each payment, Gravv sends pending, then completed or failed.
Find the cause
- Call Get card.
statusmust beactive, andspending_controls.daily_transaction_limitmust be above the amount. - Call Get card balance.
balancemust cover the amount. - Check
card_type. A physical card cannot spend today.
| What you see | Likely cause | Fix |
|---|---|---|
status freeze |
Card frozen | Unfreeze it (Manage card status) |
status blocked |
Card closed | Issue a new card |
status inactive |
A physical card not yet activated | Not yet available. See Physical card shipping |
balance below the amount |
Not enough money | Fund the card |
daily_transaction_limit below the amount, or 0 |
Over the daily limit, or you sent an update without limit |
Send the intended limit with the current status |
| Several payments today add up past the limit | Daily limit reached | Wait 24 hours or raise the limit |
| All of the above are fine | A merchant, card network or fraud rule | Contact support with the card id, amount and time |
Tell the cardholder that this is the most likely cause, because none of these reads proves the reason.
In sandbox, you cannot make a card spend or decline through the API today. Spend and decline simulation is Not yet available. To test your handler, post the example above to your own endpoint, or resend a stored event (Gravv does not sign a resend).