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

# Errors

> Error format, error codes by category, and how to handle them.

## Error format

Every `/mm/v1` error returns a JSON body with a stable `error` code and a fixed message:

```json theme={null}
{ "error": "INSUFFICIENT_FUNDS", "message": "The available USDC balance does not cover the order." }
```

`RISK_LIMIT` also names the limit that was hit:

```json theme={null}
{ "error": "RISK_LIMIT", "message": "The order would exceed an External MM limit.", "limit": "MAX_RESTING_ORDERS" }
```

Write your logic against `error` (and `limit`). The `message` is for people and may change. A `401` also carries `WWW-Authenticate: Bearer realm="mm/v1"`.

## Error codes

### Authentication

| HTTP | `error` | Meaning |
| - | - | - |
| 401 | `AUTH_REQUIRED` | No `Authorization` header. |
| 401 | `INVALID_API_KEY` | The credential is not a valid key, or the key is no longer usable. |
| 401 | `API_KEY_REVOKED` | The key has been revoked. |

### Authorization and trading availability

| HTTP | `error` | Meaning |
| - | - | - |
| 403 | `INSUFFICIENT_SCOPE` | The key does not have the scope this route needs, or is not authorized to place orders. |
| 403 | `DEALER_SUSPENDED` | Your account is suspended. Reads and new orders are refused. Cancel and cancel-all still work. |
| 403 | `TRADING_DISABLED` | Trading is not enabled for your account right now. New orders only. See [Trading availability](https://docs.d1.exchange/market-makers/trading-rules.md#trading-availability). |

### Request validation

| HTTP | `error` | Meaning |
| - | - | - |
| 400 | `MALFORMED_REQUEST` | Unknown, missing, repeated or malformed parameter or body field; out-of-range value; malformed id or path; unexpected query string on a `POST`; missing `Content-Type: application/json`; body over 4 KiB. |
| 400 | `INVALID_CURSOR` | The cursor does not belong to this route, these filters, or this cursor version. |
| 400 | `INVALID_PRICE` | The price is not valid for this market, for example not a multiple of `priceTick`. |
| 400 | `INVALID_QUANTITY` | The quantity is not valid for this market, for example not a multiple of `quantityStep`. |

### Not found and market state

| HTTP | `error` | Meaning |
| - | - | - |
| 404 | `NOT_FOUND` | Read routes: unknown instrument, or an order that does not exist or is not yours. Also any unknown path under `/mm/v1/orders/` on a `POST`. |
| 404 | `UNKNOWN_INSTRUMENT` | Placement: the instrument does not exist. |
| 404 | `ORDER_NOT_FOUND` | Cancel: the order does not exist or is not yours. |
| 409 | `MARKET_NOT_TRADING` | The market is not accepting orders, for example because it reached expiry. |
| 409 | `MARKET_PAUSED` | Trading on this market is paused. |

### Order policy

| HTTP | `error` | Meaning |
| - | - | - |
| 422 | `INSUFFICIENT_FUNDS` | Your available USDC does not cover the `BUY`. |
| 422 | `INSUFFICIENT_POSITION` | The `SELL` exceeds your unreserved long position. Option writing is not available. |
| 422 | `RISK_LIMIT` | The order would exceed `MAX_OPEN_EXPOSURE`, `MAX_RESTING_ORDERS` or `MAX_RESTING_ORDERS_PER_INSTRUMENT`. See [Order limits](https://docs.d1.exchange/market-makers/trading-rules.md#order-limits). |

### Idempotency and state conflicts

| HTTP | `error` | Meaning |
| - | - | - |
| 409 | `IDEMPOTENCY_CONFLICT` | The `clientOrderId` was already used with different order terms. |
| 409 | `ORDER_NOT_CANCELLABLE` | The order is in a final state other than cancelled, for example `FILLED`. |

### Rate limiting

| HTTP | `error` | Meaning |
| - | - | - |
| 429 | `RATE_LIMITED` | The request was not admitted. Wait `Retry-After` seconds. See [Rate Limits](https://docs.d1.exchange/market-makers/rate-limits.md). |

### Server errors

| HTTP | `error` | Meaning |
| - | - | - |
| 500 | `INTERNAL` | D1 could not complete the request. |

A path or method that is not part of the API returns a plain `404` from the router, not this JSON envelope.

## How to handle errors

| Status | What to do |
| - | - |
| **400** | Fix the request. Retrying it unchanged will fail again. For `INVALID_CURSOR`, drop the cursor and restart from the first page. |
| **401** | Credential problem. Stop and alert. Check that the key is configured correctly. For `API_KEY_REVOKED`, switch to your other active key or ask D1 for a new one. |
| **403** | The operation is not permitted. `TRADING_DISABLED`: stop placing, keep reading and cancelling, and poll `GET /mm/v1/status`. `DEALER_SUSPENDED`: stop placing, cancel your orders and contact D1. `INSUFFICIENT_SCOPE`: use the right key. Do not retry in a loop. |
| **404** | Expected for unknown ids. Do not retry. For `UNKNOWN_INSTRUMENT`, refresh your market catalog. |
| **409** | `IDEMPOTENCY_CONFLICT`: a bug in how you generate or reuse `clientOrderId`s. Do not retry. `ORDER_NOT_CANCELLABLE`: the order is already final; reconcile it. `MARKET_NOT_TRADING` or `MARKET_PAUSED`: stop quoting that market until its status changes. |
| **422** | The order does not fit your funds, position or limits. Change the order. Retrying it unchanged will fail again unless your account state changes. |
| **429** | Wait at least `Retry-After` seconds, add jitter, and retry the same request. |
| **500** | **Unknown result.** For a placement, the order may or may not exist. Retry the identical request with the same `clientOrderId`. Never create a new intent with a new ID. For reads, back off and retry. For [`/executions`](https://docs.d1.exchange/market-makers/executions#checkpointing-and-reconnects), keep your checkpoint unchanged. |

Any refusal of a placement (`400`, `403`, `404`, `409`, `422`) creates nothing. See [Building a reliable client](https://docs.d1.exchange/market-makers/reliability.md) for the full retry rules.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.