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

# Errors

> The standard error envelope and what each status code means.

Wayex uses conventional HTTP status codes and returns a consistent JSON error envelope on every failure.

```json theme={null}
{
  "type": "authentication_error",
  "code": "missing_api_key",
  "message": "A human-readable explanation of what went wrong",
  "requestId": "req_e43037e6-8149-4297-9a94-9bcf11a59dbb"
}
```

| Field       | Description                                                                       |
| ----------- | --------------------------------------------------------------------------------- |
| `type`      | The error category (e.g. `validation_error`, `authorization_error`, `not_found`). |
| `code`      | A stable, machine-readable code you can branch on.                                |
| `message`   | A human-readable explanation. Do not parse this — use `code`.                     |
| `requestId` | The unique id for this request. **Include it when contacting support.**           |

## Status codes

| Status        | Meaning                                                                                                                             |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `200` / `201` | Success.                                                                                                                            |
| `400`         | Malformed request.                                                                                                                  |
| `401`         | Missing or invalid API key.                                                                                                         |
| `403`         | Authenticated, but not allowed to perform this action.                                                                              |
| `404`         | The resource does not exist (or is out of your scope).                                                                              |
| `409`         | Conflict — e.g. an illegal state transition, or an `Idempotency-Key` reused with different parameters (`idempotency_key_conflict`). |
| `422`         | Validation failed (a semantically invalid value, e.g. a developer fee above the cap).                                               |
| `429`         | Rate limited — honor the `Retry-After` header, then retry with backoff. See [Rate limits](#rate-limits).                            |
| `5xx`         | A Wayex-side error. Safe to retry idempotent requests with backoff.                                                                 |

## Rate limits

Each API key is a **token bucket**, not a fixed window: it refills continuously at a **sustained
rate of 25 requests/second** and can hold up to **50 requests** of burst capacity (defaults —
your account may be configured differently). A request spends one token; an empty bucket returns
`429` until the bucket refills.

Responses include three headers you can use to pace your integration:

| Header                  | Meaning                                                                                    |
| ----------------------- | ------------------------------------------------------------------------------------------ |
| `X-RateLimit-Limit`     | The bucket's burst capacity (the largest instantaneous burst it admits).                   |
| `X-RateLimit-Remaining` | How many tokens remain in the bucket right now.                                            |
| `X-RateLimit-Reset`     | Seconds until the bucket refills to full capacity at the sustained rate — not a timestamp. |

Exceeding the limit returns `429` with code `rate_limited` and a `Retry-After` header (in
seconds). Wait at least that long, then retry with backoff.

## Common API codes

| Code                          | Status | Meaning                                                                                                                                                                                                 |
| ----------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `idempotency_key_required`    | `400`  | The write is missing its `Idempotency-Key` header. See [Idempotency](/idempotency).                                                                                                                     |
| `unsupported_asset_network`   | `400`  | The asset does not settle on the requested network, or Wayex cannot send or receive it there. Choose another network — this is not transient.                                                           |
| `invalid_request`             | `400`  | The body failed schema validation. One case worth coding for: free-form maps reject the reserved key `@@wxtype` (and any `@@wxtype.esc…` variant). See [Reserved metadata key](#reserved-metadata-key). |
| `secret_key_required`         | `403`  | A publishable key was used on an endpoint that requires a secret key.                                                                                                                                   |
| `insufficient_scope`          | `403`  | The API key's scope list does not include the scope this endpoint needs. The message names the scope.                                                                                                   |
| `ip_not_allowed`              | `403`  | The request came from outside the key's `allowedIps` networks.                                                                                                                                          |
| `step_up_required`            | `403`  | The action needs a recent second-factor (MFA) confirmation from a console session. Re-confirm and retry.                                                                                                |
| `idempotency_key_conflict`    | `409`  | The `Idempotency-Key` was reused with different parameters. Use a fresh key for a different request.                                                                                                    |
| `idempotency_key_in_progress` | `409`  | The original request with this key is still executing. Honor `Retry-After`, then retry with the *same* key.                                                                                             |
| `rate_limited`                | `429`  | Too many requests this second. Honor `Retry-After`, then retry with backoff.                                                                                                                            |

## Common Treasury codes

| Code                              | Status | Meaning                                                                                                                |
| --------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------- |
| `treasury_configuration_required` | `409`  | This tenant account has no effective Treasury configuration. Contact Wayex before retrying.                            |
| `sumsub_evidence_required`        | `403`  | The payout does not have current accepted KYC evidence.                                                                |
| `sumsub_token_invalid`            | `422`  | Sumsub could not accept the single-use share token. Request a fresh token for this beneficiary.                        |
| `insufficient_balance`            | `422`  | This account's wallet has insufficient available funds after existing reservations.                                    |
| `asset_network_unavailable`       | `422`  | The asset/network is not enabled for this account and available at runtime.                                            |
| `settlement_network_required`     | `400`  | A conversion quote from AUD to a stablecoin omitted `settlementNetwork`. Name the chain the stablecoin settles onto.   |
| `conversion_route_conflict`       | `409`  | The named `settlementNetwork` differs from the settlement route Wayex has pinned for that asset. Use the pinned chain. |
| `quote_expired`                   | `409`  | The Treasury conversion quote expired before acceptance. Create a new quote.                                           |
| `sumsub_provider_unavailable`     | `502`  | Reusable-KYC validation is temporarily unavailable. Retry the same idempotent request with backoff.                    |
| `destination_screening_required`  | `403`  | The stablecoin destination is not yet eligible for withdrawal. Use an active validated destination.                    |

## Treasury operation statuses

| Status      | Meaning                                                                                                                                         |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `accepted`  | KYC and policy checks passed and the source amount was durably reserved. Provider submission may still be pending or have an unknown outcome.   |
| `held`      | The effective manual-review or threshold policy requires operator approval before the operation can continue.                                   |
| `submitted` | Funds remain reserved and the bank or blockchain instruction was submitted. This is not settlement.                                             |
| `settled`   | The downstream bank or blockchain leg completed and the reservation was captured.                                                               |
| `failed`    | The operation did not complete. Inspect wallet movements to confirm the reservation release or any recovery action.                             |
| `returned`  | A previously submitted or settled payout was returned. The effective return-loss policy determines the client credit and any recovery exposure. |

Some responses also include more specific settlement detail or a `nextAction`. An unknown or
reconciling external outcome is not a failure: keep the original operation and reservation intact
until its real outcome is established. See
[Operations and reconciliation](/treasury/operations-and-reconciliation).

## Treasury hold reasons

A `held` operation carries a `statusReason` naming why it is parked. Show it, and use it to decide
whether waiting will help. Most reasons describe a review or capacity condition that Wayex clears;
this one describes your request and will not clear on its own:

| `statusReason`                | Meaning                                                                                                                                                       | What to do                                                                                               |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `withdrawal_network_not_held` | The stablecoin withdrawal names a network this account has no credited deposit and no settled conversion for. The source debit is reserved; nothing was sent. | Withdraw on a network you have funded, or convert onto that network first. Wayex releases genuine cases. |

Treat `statusReason` as an informational string, not a closed set — new reasons can appear. Branch on
`status` and `nextAction`, and surface the reason to your operators verbatim.

## Reserved metadata key

Free-form maps you send us — `metadata` on customers and counterparties, and `partyContext`,
`businessIdentity`, and `glMapping` on Treasury requests — reserve one key name: `@@wxtype`, and any
`@@wxtype.esc…` variant of it. Wayex uses it internally to encode stored values.

A map containing that key is refused with `400` `invalid_request` and nothing is written — including
on a `PATCH` that would otherwise merge. Near misses such as `wxtype`, `@@wxtypes`, or `my@@wxtype`
are ordinary keys and are accepted. Nothing else about these maps changed.

<Note>
  Always log the `requestId` from failed responses. It is the fastest way for support to trace
  exactly what happened.
</Note>
