> For the complete documentation index, see [llms.txt](https://thegrid.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://thegrid.ai/docs/api-reference/errors-and-rate-limits.md).

# Errors and rate limits

Both APIs return errors in a consistent JSON envelope:

```json
{
  "errors": {
    "code": "optional_machine_readable_code",
    "detail": "Error message describing the issue"
  }
}
```

The HTTP status code tells you what went wrong. The `detail` string gives the specifics. Some Trading API errors also include `code`; use it for client branching when present, but keep displaying `detail` to humans.

## Status codes

| Status | Meaning                                    | What it means                                                                                                                                                                        | What to do                                                                                                                                                                                                                  |
| ------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `307`  | Temporary redirect                         | Your request is being forwarded to the routing layer that fulfills inference. The `Location` header points to the target.                                                            | Follow the redirect with the same method, body, and `Authorization` header. Most clients do this automatically. cURL needs `-L`. See [Request routing and redirects](/docs/api-reference/request-routing-and-redirects.md). |
| `400`  | Bad request                                | Malformed body or invalid parameter types.                                                                                                                                           | Fix the request. Check required fields and parameter types against the OpenAPI block on the relevant endpoint page. Don't retry as-is.                                                                                      |
| `401`  | Unauthorized                               | Missing or invalid API key. On the Trading API, also fires for invalid signatures or stale timestamps.                                                                               | Verify the key in the dashboard. Check that your auth header is `Authorization: Bearer ...` (Consumption) or that signature, timestamp, and fingerprint headers are correct (Trading). Don't retry without fixing.          |
| `402`  | Payment required                           | Insufficient USD balance, or no token capacity available for this instrument.                                                                                                        | Add credits, enable [auto-reload](broken://pages/pdlcsdUZJSSSfhsYQcIu), or wait for the system to top up automatically. **Retry** after a short delay; the next request usually goes through once balance replenishes.      |
| `404`  | Not found                                  | Most commonly: invalid instrument string in the `model` parameter. Also fires for unknown order IDs, market IDs, etc.                                                                | Check the value against the catalog at [Current instruments](/docs/instrument-specifications/current-instruments.md) or `https://thegrid.ai/instruments.json`. Don't retry.                                                 |
| `422`  | Validation error                           | Request is well-formed but a parameter value is out of range or structurally invalid. Common causes: `temperature` outside 0–2, malformed `tools` schema, invalid `response_format`. | Read the `detail`. Fix and resubmit. Don't retry as-is.                                                                                                                                                                     |
| `429`  | Rate or concurrency limit exceeded         | You exhausted an inference concurrency slot or a Trading API submission bucket.                                                                                                      | Back off and **retry**. Honor `Retry-After` when present. Use the limit-specific headers described below to pace later requests.                                                                                            |
| `500`  | Internal server error                      | Server-side issue, often supplier transient errors surfaced through the API.                                                                                                         | **Retry** with exponential backoff. If persistent, contact <support@thegrid.ai>.                                                                                                                                            |
| `503`  | Service unavailable / balance replenishing | Temporary supplier unavailability, or the system is replenishing your balance.                                                                                                       | Wait 1 to 3 seconds and **retry**. The system handles supplier failover automatically; we don't bill your request if it doesn't complete.                                                                                   |

## Retry guidance

Always retry: `402`, `429`, `500`, `503`, and any other `5xx`. These are transient and a backoff loop fixes them. Don't retry `400`, `401`, `404`, or `422` without changing the request first; you get the same error.

A reasonable retry policy:

```python
import time, random

def call_with_retry(fn, max_attempts=5):
    for attempt in range(max_attempts):
        try:
            return fn()
        except RetryableError as e:
            if attempt == max_attempts - 1:
                raise
            delay = min(2 ** attempt + random.random(), 30)
            time.sleep(delay)
```

Cap the backoff somewhere sensible (e.g., 30 seconds) so you don't stall a worker indefinitely. Honor `Retry-After` when the server sends it.

### Backup routing transparency

We route around supplier failures automatically. If the primary supplier for an instrument is unavailable, we try the next one. Your client doesn't see which supplier served the request, and you don't need failover code in your application. If a request fails entirely or returns a response that doesn't meet the instrument's specification, we don't bill you for it.

This means you should treat `5xx` errors as transient by default. Most resolve on retry without any action on your end.

## Rate limits

The Consumption and Trading APIs enforce different limits. Do not assume a single requests-per-minute value applies to both APIs, or that every endpoint returns rate-limit headers.

### Consumption API: concurrent inference requests

When concurrency protection is active, the Consumption API limits the number of inference requests a user can have in flight at once. Chat Completions, Responses, and Anthropic Messages requests share this concurrency allowance. A request occupies one slot until it finishes, so a long-running stream holds its slot longer than a short non-streaming request.

Responses subject to the concurrency limit include:

* `x-ratelimit-limit`: your current maximum number of concurrent inference requests.
* `x-ratelimit-remaining`: the number of slots available after the current admission decision.
* `Retry-After`: on a `429`, the number of seconds to wait before trying again.

Your effective concurrency allowance can increase with funded balance. Treat `x-ratelimit-limit` as the effective value for the current user rather than hard-coding a tier value. A Consumption API concurrency `429` uses the machine-readable code `concurrency_limit_exceeded`.

### Trading API: order submissions

Create-order submissions are limited per user and market. The Trading and Exchange order-creation routes share that bucket, so switching routes does not provide a second allowance. The limit counts submissions, not fills, and does not accumulate unused burst capacity.

Before placing orders, call `GET /v1/account/limits?market_id=...` with the exact `market_id` returned by `GET /v1/markets`. Pace create-order requests from `order_rate_limits.max_orders_per_second`. `max_orders_per_minute` is the corresponding derived minute value, not a separate fill counter.

Create-order responses subject to this limit include:

* `x-ratelimit-limit`: the maximum accepted create-order submissions per second for this user and market.
* `x-ratelimit-remaining`: the submissions remaining in the current one-second window.
* `Retry-After`: on a `429`, the number of seconds to wait before retrying.

Bulk cancellation has a separate account-wide throttle and does not consume the create-order bucket. Pace bulk-cancel requests from their response headers. Trading reads and other endpoints are not guaranteed to return order-submission headers.

When you hit a `429`:

1. Read `Retry-After` if present and wait at least that long.
2. If absent, use exponential backoff with jitter starting at 1 second.
3. For inference, reduce parallel requests or queue them client-side.
4. For order creation, refresh `GET /v1/account/limits?market_id=...` and pace each user-market pair independently.
5. Make retries idempotent. For order creation, reuse a deterministic `client_order_id` so a lost response cannot create a duplicate order.

## Trading API specifics

The Trading API surfaces the same error shape, with a few extras:

* `401` from the Trading API is most often a signing error. Check timestamp drift first (your clock vs. server time), then the message format you signed (`<timestamp><METHOD><path><body>`), then the fingerprint header. See [Authentication](/docs/api-reference/authentication.md).
* `409` fires on order operations with state conflicts (e.g., cancelling an already-cancelled order). Don't retry; the state is final.
* `422` on order placement usually means a price or quantity violates instrument rules. Limit-order `price` must be a decimal string such as `"0.68"`, not a JSON number. Common `code` values include `validation_error`, `quantity_below_min_order_size`, `quantity_above_max_order_size`, `lot_size_violation`, `tick_size_violation`, `insufficient_available_balance`, and `insufficient_inventory_or_funds`. Order-control 422s include `errors.detail`, `errors.code`, and `errors.context` with submitted `price` / `quantity`, `client_order_id` when supplied, and limits such as `min_order_size`, `lot_size`, and `tick_size`.
* `422 price_collar_violation` means a limit price was outside an active server-side reference-price band. Refresh `/v1/markets` to read `price_collar_pct` and submit a price inside the band. Keep independent client-side price bounds; a collar is a backstop, not a complete trading-safety policy.
* `422` on `GET /v1/orders?status=...` means the filter value is not recognized. Supported order status filters include `open`, `active`, `pending`, `partially_filled`, `cancellation_pending`, `filled`, `closed`, `cancelled`, `expired`, and `rejected`.
* `403` with `auto_mode_trading_restricted` means the account is still in Auto Mode. Switch to Advanced Mode before placing, updating, or cancelling orders.

Trading order limits count create-order submissions, not fills. Read the effective per-user, per-market value from `GET /v1/account/limits?market_id=...`, pace against `order_rate_limits.max_orders_per_second`, and honor `retry-after` on 429.

The full Trading API error catalog is documented in the OpenAPI blocks on the [Trading API](/docs/api-reference/trading-api.md) page.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://thegrid.ai/docs/api-reference/errors-and-rate-limits.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
