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

# Error codes and HTTP statuses

> Remitflex API error response format, HTTP status codes, and retry guidance.

All API errors return a JSON envelope with an HTTP status code.

## Error response structure

```json theme={null}
{
  "status": "error",
  "message": "Payment route not found"
}
```

Validation errors (`422`) include an `errors` object with per-field messages from Zod:

```json theme={null}
{
  "status": "error",
  "message": "Validation failed",
  "errors": {
    "amount": "Amount must be greater than zero"
  }
}
```

<Tip>
  Branch error-handling logic on HTTP status and `message` strings. Validation errors should inspect the `errors` object.
</Tip>

## HTTP status codes

| Status | Meaning                                      | Retry?                         |
| ------ | -------------------------------------------- | ------------------------------ |
| `400`  | Bad request (e.g. missing `Idempotency-Key`) | Fix request, then retry        |
| `401`  | Invalid or missing auth token/key            | Fix credentials                |
| `403`  | Forbidden (missing scope, suspended org)     | Fix scopes or contact support  |
| `404`  | Resource not found                           | Do not retry                   |
| `409`  | Conflict (e.g. payment route already active) | Do not retry same operation    |
| `422`  | Validation or business rule failure          | Fix input, then retry          |
| `429`  | Rate limit exceeded                          | Retry with backoff             |
| `500`  | Server error                                 | Retry with exponential backoff |

## Common messages

### Authentication

| HTTP  | Message                              | Resolution                                             |
| ----- | ------------------------------------ | ------------------------------------------------------ |
| `401` | `No token provided`                  | Add `Authorization: Bearer ...` header                 |
| `401` | `Invalid API key`                    | Check key value and prefix (`rmf_test_` / `rmf_live_`) |
| `401` | `Token invalid or expired`           | Refresh dashboard JWT or use a valid API key           |
| `403` | `Missing required scopes: api:write` | Create a key with the required scopes                  |

### Idempotency

| HTTP  | Message                                                        | Resolution                                  |
| ----- | -------------------------------------------------------------- | ------------------------------------------- |
| `400` | `Idempotency-Key header is required for mutating API requests` | Add `Idempotency-Key` header on POST/DELETE |
| `422` | `Idempotency-Key must be 255 characters or fewer`              | Use a shorter unique key                    |

### Payment routes

| HTTP  | Message                                | Resolution                             |
| ----- | -------------------------------------- | -------------------------------------- |
| `404` | `Payment route not found`              | Verify route ID                        |
| `422` | Corridor or currency validation errors | Check chain IDs and currency addresses |

## Rate limits

Global: **200 requests per 15 minutes**. Auth endpoints: **20 per 15 minutes**.

On `429`, back off and retry. There is no `X-RateLimit-*` header today.

## Idempotency and retries

When using API keys, mutating requests require `Idempotency-Key`. Retrying with the **same** key returns the cached success response — safe for network failures.

Use a **new** idempotency key for each distinct operation.

```bash theme={null}
curl -X POST https://api.remitflex.io/v1/payment-routes \
  -H "Authorization: Bearer rmf_test_xxxx" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"Supplier collection","originChainKey":"tron","destinationChainKey":"base","destinationCurrency":"USDC","destinationAddress":"..."}'
```

## Example error handler (JavaScript)

```javascript theme={null}
async function apiRequest(url, options) {
  const res = await fetch(url, options);
  const body = await res.json();

  if (body.status === "error") {
    if (res.status === 429) {
      // backoff and retry
    }
    if (res.status === 422 && body.errors) {
      // surface field errors to user
    }
    throw new Error(body.message);
  }

  return body.data;
}
```
