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

# Limits & Errors

> Rate limits, error codes, and retry guidance for the Ratio API.

## Rate limits

| Tier         | Requests per second | Burst         | Applies to                                          |
| ------------ | ------------------- | ------------- | --------------------------------------------------- |
| **Standard** | 10 req/s            | 20 req burst  | Default for all partners                            |
| **Premium**  | 50 req/s            | 100 req burst | High-volume partners (configured during onboarding) |

When you exceed your rate limit, the API returns HTTP `429` with a `Retry-After` header indicating how many seconds to wait before retrying.

```json theme={null}
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests",
    "timestamp": "2026-02-27T10:00:00Z",
    "request_id": "req_abc123"
  }
}
```

## Error response format

All errors follow a consistent JSON structure:

```json theme={null}
{
  "error": {
    "code": "QUOTE_EXPIRED",
    "message": "Quote has expired; please re-request",
    "corridor": "USD-IDR",
    "timestamp": "2026-02-27T10:05:00Z",
    "request_id": "req_abc123"
  }
}
```

<ResponseField name="code" type="string">
  Machine-readable error code.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable description of the error.
</ResponseField>

<ResponseField name="corridor" type="string">
  Affected corridor, if applicable (e.g. `USD-IDR`).
</ResponseField>

<ResponseField name="timestamp" type="string">
  ISO 8601 server timestamp.
</ResponseField>

<ResponseField name="request_id" type="string">
  Unique request identifier. Include this when escalating to support.
</ResponseField>

## FX Engine errors

These errors originate from the FX Engine and indicate conditions specific to quote and execution flows.

| HTTP  | Code                         | Description                                                  | Retry guidance                 |
| ----- | ---------------------------- | ------------------------------------------------------------ | ------------------------------ |
| `400` | `BELOW_MIN_TRANSACTION_SIZE` | Amount is below the corridor minimum                         | No — increase the amount       |
| `400` | `DIRECTION_BLOCKED`          | Trade direction not permitted under the current system state | Wait for state recovery        |
| `400` | `ARB_CHECK_FAILED`           | Quote failed internal arbitrage validation                   | Re-request a new quote         |
| `400` | `QUOTE_EXPIRED`              | Firm quote has expired before execution                      | Request a new firm quote       |
| `422` | `NO_VIABLE_RFQ_QUOTE`        | No acceptable external quote available                       | Reduce size or wait            |
| `422` | `CROSS_LEG_INSUFFICIENT`     | Insufficient cross-corridor liquidity                        | Reduce size                    |
| `503` | `ORACLE_STALE`               | Oracle price data is outdated                                | Wait a few seconds, then retry |
| `503` | `ORACLE_DEVIATION`           | Oracle sources have diverged beyond threshold                | Wait for convergence           |
| `503` | `QUOTE_HALTED`               | System is in HALT state; no new quotes accepted              | Monitor `/v1/system/state`     |

## General API errors

| HTTP  | Code             | Description                                | Retry guidance                                |
| ----- | ---------------- | ------------------------------------------ | --------------------------------------------- |
| `401` | `UNAUTHORIZED`   | Missing or invalid Bearer token            | No — check your credentials                   |
| `403` | `FORBIDDEN`      | Insufficient permissions for this resource | No — request access from your account manager |
| `404` | `NOT_FOUND`      | Resource does not exist                    | No — verify the endpoint path                 |
| `429` | `RATE_LIMITED`   | Too many requests                          | Yes — respect the `Retry-After` header        |
| `500` | `INTERNAL_ERROR` | Unexpected server error                    | Yes — use exponential backoff                 |

## Retry guidance

| HTTP range | Recommended action                                                                        |
| ---------- | ----------------------------------------------------------------------------------------- |
| **400**    | Do not retry with the same parameters. Fix the request or request a new quote.            |
| **422**    | Reduce size, try a different corridor, or wait for liquidity to recover.                  |
| **429**    | Wait for the duration in the `Retry-After` header, then retry.                            |
| **500**    | Retry with exponential backoff: 1s → 2s → 4s → 8s. Contact support if the error persists. |
| **503**    | Wait 5–30 seconds. Check `/v1/system/state` before retrying.                              |
