---
title: "Errors"
description: "The error shape, HTTP statuses, and what each error code means."
image: "https://docs.ordercard.io/og.png"
---

> API Reference Index
> Fetch the complete API index at: https://docs.ordercard.io/api/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

Every error has the same shape: an `error` object with a machine-readable `code` and a human-readable `message`. Some errors add fields, such as `errors` for validation problems or `transaction` for declines.

```json
{
  "error": {
    "code": "invalid_request",
    "message": "The amount field is required.",
    "errors": {
      "amount": ["The amount field is required."]
    }
  }
}
```

Branch on `code`, not on `message`: messages can be reworded.

## HTTP statuses

| Status | When |
| --- | --- |
| `200`, `201` | Success. `201` means a record was created; for charges it means money moved. |
| `401` | Missing, unknown, revoked, expired or turned-off key, or a publishable key. |
| `402` | A charge, capture, void or refund the gateway did not approve, or live mode without a plan. |
| `403` | The key lacks the permission this endpoint needs. |
| `404` | No such record for this key's team and environment. |
| `409` | The request conflicts with the record's state, for example refunding a voided charge. |
| `422` | The request is invalid. |
| `429` | Rate limited. |
| `5xx` | Something failed on our side. Retry with the same `Idempotency-Key`. |

## Declines and gateway failures

A charge, capture, void or refund that reached the gateway but was not approved answers `402`. The error carries the recorded transaction, so you can show the reason and keep its id:

```json
{
  "error": {
    "code": "card_declined",
    "message": "The card has insufficient funds.",
    "decline_code": "insufficient_funds",
    "transaction": { "object": "transaction", "id": "txn_01jaxs6q9s2u5w8y1a4c7e0g3j", "status": "declined" }
  }
}
```

`code` is one of:

| Code | Meaning |
| --- | --- |
| `card_declined` | The issuer declined. `decline_code` says why. |
| `expired_card` | The card has expired. |
| `incorrect_cvc` | The security code is wrong. |
| `incorrect_number` | The card number is wrong. |
| `processing_error` | The gateway or processor failed to process a valid request. It may work on a retry. |
| `invalid_request` | The gateway refused the request itself (an amount or field it does not accept). |
| `gateway_error` | OrderCard could not get a usable answer: the gateway was unreachable or refused your credentials. Check the gateway before retrying, because the outcome may be unknown. |

See [Declines](/payments/declines) for every `decline_code` and the AVS and CVV results.

## Other codes

| Code | Status | Meaning |
| --- | --- | --- |
| `unauthenticated` | 401 | See [Authentication](/api/authentication). |
| `forbidden` | 403 | The key lacks a permission. |
| `not_found` | 404 | No such record for this key. |
| `subscription_required` | 402 | Live mode needs an active plan. |
| `resource_missing` | 422 | A token or id in the body is not one of this key's records. `param` names the field. |
| `rate_limited` | 429 | Wait for `Retry-After` seconds. |
| `idempotency_key_reused` | 409 | The `Idempotency-Key` was used with a different request. |
| `idempotency_in_progress` | 409 | A request with this `Idempotency-Key` is still running. |
| `test_card_in_live_mode` | 422 | A sandbox test card number was sent with a live key. |
| `real_card_in_sandbox_mode` | 422 | A card number that is not one of the [test cards](/testing) was sent with a sandbox key. Sandbox never keeps a real card. |
| `payment_method_redacted` | 409 | The card was redacted and can no longer be charged or changed. |
| `payment_method_expired` | 409 | A pending token expired before it was charged or retained. Tokenize the card again. |
| `gateway_inactive` | 409 | The gateway is turned off. |
| `surcharge_changed` | 409 | The surcharge would make the total more than `max_total`. Nothing was charged. |
| `surcharge_too_high` | 422 | A surcharge you sent is above 3% of the amount. |
| `surcharge_not_allowed` | 422 | You sent a surcharge amount for a gateway that decides the surcharge itself. |
| `amount_too_large` | 422 | A capture or refund is more than what is left. `maximum_amount` says how much is. |
| `transaction_not_successful` | 409 | Only a successful transaction can be captured, voided or refunded. |
| `transaction_voided` | 409 | The transaction was voided. |
| `transaction_not_capturable` | 409 | Only an authorization can be captured. |
| `transaction_already_captured` | 409 | The authorization was already captured. |
| `transaction_not_voidable` | 409 | The transaction cannot be voided, for example because it was refunded. |
| `transaction_not_refundable` | 409 | Only a purchase or capture can be refunded. |
| `transaction_fully_refunded` | 409 | Nothing is left to refund. |
| `transaction_in_progress` | 409 | Another capture, void or refund of this transaction is running. |
| `sync_not_supported` | 409 | The gateway keeps no configuration to sync. |

Source: https://docs.ordercard.io/api/errors/index.mdx
