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

# Errors

> The Settlx API uses standard HTTP status codes. All error responses follow the same JSON structure.

## Error response format

Every error response has the same shape:

```json theme={null}
{
  "error": "Unauthorized",
  "message": "Invalid API key",
  "correlationId": "req_01abc123def456"
}
```

| Field           | Type   | Description                                                                        |
| --------------- | ------ | ---------------------------------------------------------------------------------- |
| `error`         | string | Short error category matching the HTTP status (e.g. `Bad Request`, `Unauthorized`) |
| `message`       | string | Human-readable description of what went wrong                                      |
| `correlationId` | string | Unique request ID — include this when contacting support                           |

***

## HTTP status codes

### `400 Bad Request`

The request body failed validation.

| Message                                                        | Cause                                                     |
| -------------------------------------------------------------- | --------------------------------------------------------- |
| `Amount must be greater than 0`                                | `amount` is zero, negative, or not a valid decimal string |
| `Currency is required`                                         | `currency` is missing or empty                            |
| `Expires in minutes must be greater than 0`                    | `expiresInMinutes` is zero or negative                    |
| `Invalid webhook URL format`                                   | `webhookUrl` is not a valid URL                           |
| `Webhook URL must use HTTPS in production`                     | `webhookUrl` uses HTTP in a production environment        |
| `Webhook URL cannot point to localhost or loopback addresses`  | `webhookUrl` resolves to `127.0.0.1`, `::1`, or similar   |
| `Webhook URL cannot point to private or internal IP addresses` | `webhookUrl` resolves to a private IP range               |

***

### `401 Unauthorized`

Authentication failed. Check your API key.

| Message                                                          | Cause                                                                |
| ---------------------------------------------------------------- | -------------------------------------------------------------------- |
| `Missing or invalid Authorization header. Use: Bearer <api_key>` | The `Authorization` header is absent or not in `Bearer <key>` format |
| `Invalid API key`                                                | The key was not found — it may have been deleted                     |
| `API key has been revoked`                                       | The key exists but has been explicitly revoked                       |
| `API key has expired`                                            | The key passed its expiry date                                       |

***

### `403 Forbidden`

The request was authenticated but not permitted.

| Message                                                       | Cause                                                                                                      |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `Merchant account is not active`                              | Your account is suspended or pending review                                                                |
| `API key does not have the required permission: <permission>` | The API key lacks the permission needed for this endpoint. See [API key permissions](#api-key-permissions) |

***

### `404 Not Found`

The requested resource does not exist under your account.

| Message             | Cause                                                                 |
| ------------------- | --------------------------------------------------------------------- |
| `Invoice not found` | No invoice with that ID exists, or it belongs to a different merchant |

***

### `429 Too Many Requests`

You have exceeded the rate limit for your account tier.

```json theme={null}
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded",
  "retryAfter": 12,
  "correlationId": "req_01abc123def456"
}
```

The `retryAfter` field tells you how many seconds to wait before retrying. The response also includes rate limit headers:

```http theme={null}
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1744329600
```

Rate limits by tier:

| Tier | Read      | Write     |
| ---- | --------- | --------- |
| Free | 60 / min  | 30 / min  |
| Pro  | 300 / min | 150 / min |

***

### `500 Internal Server Error`

An unexpected error occurred on our side. These are rare and transient — retry with exponential backoff. If the issue persists, contact support.

***

## API key permissions

When you create an API key in the dashboard, you can scope it to specific permissions. If a request is made with a key that lacks the required permission, you will receive:

```json theme={null}
{
  "error": "Forbidden",
  "message": "API key does not have the required permission: invoices:write",
  "correlationId": "req_01abc123def456"
}
```

| Permission         | Endpoints                                                                                 |
| ------------------ | ----------------------------------------------------------------------------------------- |
| `invoices:read`    | `GET /api/v1/invoices`, `GET /api/v1/invoices/:id`, `GET /api/v1/invoices/:id/settlement` |
| `invoices:write`   | `POST /api/v1/invoices`, `POST /api/v1/invoices/:id/cancel`                               |
| `settlements:read` | `GET /api/v1/settlements`, `GET /api/v1/settlements/:id`                                  |
| `webhooks:write`   | `POST /api/v1/webhooks/test`                                                              |

Keys with full access (no permission restrictions) can call any endpoint. `POST /api/v1/payments` requires a valid API key but no specific permission scope.
