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

# Error handling

> Uniform error structure of the Facade API and catalog of codes.

All Facade API errors have the **same shape**, regardless of the resource or the endpoint. This makes your integration predictable: you parse the error response once and reuse it across the entire API.

## Uniform structure

```json theme={null}
{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "Validation failed: amount must be a positive amount in pesos (e.g. 1500.50).",
    "details": [
      { "field": "amount", "issue": "amount must be a positive amount in pesos (e.g. 1500.50)." }
    ]
  },
  "requestId": "req_3f8a1c9e2b"
}
```

<ResponseField name="error.code" type="string">
  Stable, machine-readable code. Use it to branch your error-handling logic (do not parse the `message`).
</ResponseField>

<ResponseField name="error.message" type="string">
  Human-readable message. It may change over time: do not use it to make decisions in your code.
</ResponseField>

<ResponseField name="error.details" type="array">
  Present in validation errors. A list of `{ field, issue }` that indicates which field failed and why.
</ResponseField>

<ResponseField name="requestId" type="string">
  Unique identifier of the request. Share it with support to trace exactly what happened.
</ResponseField>

## Catalog of codes

| HTTP  | Code                      | When it occurs                                                                                                                                                                                   |
| ----- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400` | `INVALID_REQUEST`         | The payload did not pass validation: a missing or invalid field, `autopay` together with `paymentMethods`, a malformed date, etc.                                                                |
| `401` | `AUTHENTICATION_FAILED`   | The TAPI token is missing, invalid, or expired. See [Authentication](/en/authentication).                                                                                                        |
| `404` | `RESOURCE_NOT_FOUND`      | The referenced resource (debt, product, contact, route) does not exist.                                                                                                                          |
| `409` | `RESOURCE_CONFLICT`       | The external key already exists: a repeated `Idempotency-Key`/`externalRequestId`, a duplicate `externalSubscriptionId` or `externalPaymentLinkId`. See [Idempotency](/en/concepts/idempotency). |
| `422` | `RESOLUTION_ERROR`        | TapiPay could not resolve your internal configuration (organization or modalities). This is a configuration problem on the system side, not in your request.                                     |
| `422` | `BUSINESS_RULE_VIOLATION` | The action is not allowed by the state of the resource or a business rule: updating a debt that is not in `PENDING`, canceling an already-paid debt, paying an expired payment link, etc.        |
| `429` | `RATE_LIMITED`            | Too many requests in a short time. Retry with backoff.                                                                                                                                           |
| `500` | `INTERNAL_ERROR`          | Unexpected server failure. Not attributable to your request.                                                                                                                                     |
| `502` | `SQS_PUBLISH_ERROR`       | A temporary failure while queuing the internal processing of a charge. Retry with your `Idempotency-Key` so as not to duplicate.                                                                 |

<Note>
  `RESOLUTION_ERROR` indicates that the organization associated with your token is not properly configured in the system (for example, it is missing active modalities). If you see it persistently, contact support with the `requestId`.
</Note>

<Note>
  The `401` can arrive in two shapes. If the failure happens at the API Gateway (a missing or invalid `x-api-key` or token), the response is `{"message":"Unauthorized"}`, without the `error` object. If the request passes the gateway but the Facade rejects authentication, it uses the standard shape with `error.code: AUTHENTICATION_FAILED`.
</Note>

## Recommendations

<CardGroup cols={2}>
  <Card title="Branch by code" icon="code-branch">
    Decide your logic with `error.code`, never with the text of `message`.
  </Card>

  <Card title="Save the requestId" icon="bookmark">
    Log the `requestId` in your logs: it is the fastest way for support to trace a request.
  </Card>

  <Card title="Retry with idempotency" icon="rotate">
    On `429`, `500`, or `502`, retry with the same `Idempotency-Key` to avoid duplicates.
  </Card>

  <Card title="Validate before sending" icon="circle-check">
    Use `error.details` to show your users which field to fix on `400` errors.
  </Card>
</CardGroup>
