> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.epaygames.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.epaygames.io/_mcp/server.

# Error Handling

## Standard HTTP Status Codes

Both APIs rely on default framework exception handling — there's no custom error-code scheme layered on top. Expect the standard HTTP status codes for their standard meanings:

| Status                      | Meaning                                                                                                                                   |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `200 OK`                    | Request succeeded.                                                                                                                        |
| `401 Unauthorized`          | Missing, invalid, or expired bearer token.                                                                                                |
| `403 Forbidden`             | Authenticated, but not allowed to perform the action.                                                                                     |
| `404 Not Found`             | Route or resource doesn't exist (e.g., looking up a transaction that isn't there).                                                        |
| `405 Method Not Allowed`    | Wrong HTTP verb for the endpoint.                                                                                                         |
| `422 Unprocessable Entity`  | Validation failed on the request payload.                                                                                                 |
| `429 Too Many Requests`     | Rate limit hit — only applicable to the Disbursement API's Testing → `Repost Transaction` endpoint (see [Rate Limiting](/rate-limiting)). |
| `500 Internal Server Error` | Unhandled server-side error.                                                                                                              |

## Default Error Bodies

Since there's no custom error formatting, failure responses follow the framework's out-of-the-box shapes:

**Validation errors (`422`)** — the standard validation-error format, an `errors` object keyed by field name, each holding an array of messages:

```json
{
  "message": "The given data was invalid.",
  "errors": {
    "amount": [
      "The amount must be between 0.01 and 50000."
    ]
  }
}
```

**Authentication errors (`401`)** — the standard unauthenticated response:

```json
{
  "message": "Unauthenticated."
}
```

**Everything else (`403`, `404`, `405`, `500`, etc.)** — a plain `message` string describing the error, with no `data` or `errors` key:

```json
{
  "message": "..."
}
```

On success, responses follow the `message` / `data` envelope described in [Request & Response Format](/request-response-format). On failure, expect one of the shapes above instead — check the HTTP status code first, then fall back to `errors` (if present) for field-level detail.

## Recommended Client-Side Handling

#### Check the HTTP status code first

A non-2xx status is the primary signal that a request failed — don't rely solely on inspecting the body.

#### Parse the JSON body

On `422`, read the `errors` object to surface field-level validation messages. On other error statuses, fall back to `message`.

#### Handle 401 by re-authenticating

Treat a `401` as a signal to obtain a fresh bearer token rather than retrying the same request (see [Authentication](/authentication)).

#### Confirm at the JSON-body level

Never assume a token or transaction is valid just because a request "completed" at the transport level.

## Known Failure Conditions (Called Out in the Collection)

Beyond the generic HTTP behavior above, a few specific failure conditions are explicitly documented per-endpoint:

* **Get Authorization** — returns an error if the authorization code is **invalid, expired, or already consumed**. Always validate the code with this endpoint before attempting to process the associated disbursement.
* **Generate Transaction / Process Disbursement** — these don't raise a distinct error for a failed payment/payout; instead, the transaction itself settles into a **`cancelled`** (Payments) or **`failed`** (Disbursement) status. You detect this via `Get Transactions` or your webhook callback, not via an HTTP error — see [Transaction & Payout Statuses](/transaction-statuses).

## Validation Constraints to Handle Proactively

Some documented field constraints will produce a `422` if violated, so validate them client-side before calling the API:

* **`Generate Transaction` → `amount`**: must be between **0.01 and 50,000**.
* **`Calculate Total w/ Fee` → `amount`**: must be between **0.01 and 50,000**.
* **`Process Disbursement` → `amount`**: minimum of **0.01**; maximum **depends on the channel**.
* **`Process Disbursement` → `fields`**: required, and its shape **depends on the channel** — e.g., an e-wallet channel expects different sub-fields than a bank-transfer channel. Sending the wrong shape for a given channel is a likely source of validation errors.
* **URL fields** (`success_redirect_url`, `failure_redirect_url`, `callback_webhook_url`) **must be valid URLs** when provided.