> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tagada.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> HTTP status codes, the error object, error types and codes of the Payments API.

The Payments API uses HTTP status codes to say whether a **request** worked. Whether a **payment** worked is a different question: a declined card is a successful request that returns a payment with `status: "failed"`.

> [!WARNING]
>
> Never treat a `200` as a successful charge. Read the payment's `status`, and `last_outcome` when it failed. See [Payment lifecycle](https://docs.tagada.io/payments-api/payment-lifecycle.md).

## The error object

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "Unsupported Payments-Version.",
    "param": "Payments-Version",
    "request_id": "req_01m5megrg1c8hmq8npj7ktjygc"
  }
}
```

| Field | Description |
| - | - |
| `type` | The error family, derived from the status code. See below. |
| `code` | A stable, lowercase code your code can branch on. New codes can appear; existing codes are never renamed. |
| `message` | A human-readable explanation. Do not parse it. |
| `param` | The parameter or header at fault, or `null`. |
| `request_id` | The request's id, also returned in the `Payments-Request-Id` header. Include it when you contact support. |
| `details` | Optional structured data. Never returned to publishable keys. |

## Status codes and types

| Status | `type` | Meaning |
| - | - | - |
| `200` | | The request worked. For a payment, read `status`. |
| `400` | `invalid_request_error` | A parameter is missing, malformed or not allowed. |
| `401` | `authentication_error` | No valid bearer key. |
| `403` | `permission_error` | The key cannot do this, or the object belongs to another store. |
| `404` | `invalid_request_error` | The object does not exist for this account and mode. |
| `409` | `conflict_error` | The request conflicts with the object's state or with another request (idempotency). |
| `429` | `rate_limit_error` | Too many requests. Wait for `Retry-After` seconds. |
| `500` | `api_error` | Something went wrong on our side. |
| `501` | `api_error` | The operation is not implemented for this case. |
| `503` | `unavailable_error` | Payments are paused for this account or the platform, or a dependency is unavailable. |

## Common codes

| Code | Status | What to do |
| - | - | - |
| `authentication_required` | 401 | Send `Authorization: Bearer <key>`. |
| `permission_denied` | 403 | Use a key of the right kind, mode and store. |
| `parameter_missing`, `parameter_invalid` | 400 | Fix the parameter named in `param`. |
| `resource_not_found` | 404 | Check the id and the key's mode (`test` or `live`). |
| `idempotency_key_reused` | 409 | The key was used with a different request. Use a new key. |
| `idempotency_key_in_progress` | 409 | The first request with this key is still running. Retry later with the same key. |
| `payment_not_confirmable` | 409 | The payment is not in a status that can be confirmed. |
| `store_not_on_payments_api` | 409 | The store still takes its payments on V2. See [Migrate from V2](https://docs.tagada.io/payments-api/migrate-from-v2.md). |
| `no_active_policy` | 409 | The store has no published payment policy to route the payment. |
| `currency_not_supported` | 400 | The currency cannot be charged on this store. |
| `rate_limited` | 429 | Back off and retry after `Retry-After`. |
| `payments_api_disabled`, `account_not_enabled` | 503 | Payments are not enabled. Do not retry in a loop. |

The complete, per-endpoint list of codes is in each operation of the [API reference](https://docs.tagada.io/payments-api/reference/introduction.md).

## Declines

A declined payment is returned as data. Its `last_outcome` explains why:

| Field | Description |
| - | - |
| `category` | `approved`, `soft_decline`, `hard_decline`, `authentication_required`, `issuer_unavailable`, `technical_error` or `unknown`. |
| `reason` | A normalized reason, for example `insufficient_funds`, `expired_card`, `do_not_honor`, `suspected_fraud`. |
| `raw_code`, `raw_message` | The processor's own code and message. |
| `bank_reached` | Whether the request reached the issuing bank. |
| `advice_code` | The network's retry advice, when the processor returns one. |

Both `category` and `reason` are open enums.

## Retries

Retry a request when it failed with a network error, a timeout, `429`, `500`, `502`, `503`, `504` or `idempotency_key_in_progress`. Reuse the same `Idempotency-Key` so a retry never creates a second payment. Do not retry `payments_api_disabled`. The browser client follows these rules for you.

## Request tracing

Every response carries `Payments-Request-Id`. It also returns `Payments-Trace-Id` and a W3C `traceparent`. You can send your own `traceparent` to tie our records to your trace.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.