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

# Errors

> The error envelope and every code the /v1 surface can return

Every error from the `/v1` surface is an OpenAI-compatible JSON envelope:

```json theme={null}
{
  "error": {
    "message": "세션 한도 100% 도달. 약 2시간 후 재시작됩니다.",
    "type": "rate_limit_error",
    "code": "session_exhausted",
    "resets_at": "2026-08-30T04:00:00.000Z"
  }
}
```

* **`message`** — human-readable; user-facing messages are written in
  Korean. Don't parse it — branch on `code`.
* **`type`** — the error family (`invalid_request_error`,
  `rate_limit_error`, `quota_exceeded`, `access_denied`,
  `overloaded_error`, `server_error`, `service_unavailable`).
* **`code`** — the stable machine-readable identifier. Branch on this.
* **`resets_at`** — extra field on `session_exhausted`,
  `weekly_exhausted`, and `abuse_cooldown` (ISO 8601).

<Note>
  Upstream failures use HTTP **500**, never 502, and `ModelOverloadedError`
  uses the non-standard **529** — make sure your client treats 529 as
  retryable.
</Note>

## Codes by status

### 400 — fix the request

| `code`                     | Meaning                                                                                      |
| -------------------------- | -------------------------------------------------------------------------------------------- |
| `model_not_found`          | Unknown model id (or one not visible to your key)                                            |
| `invalid_json`             | Body is not valid JSON                                                                       |
| `invalid_messages`         | `messages` failed validation                                                                 |
| `input_too_long`           | Input exceeds the model's `max_input_tokens`; the message carries the estimate and the limit |
| `invalid_reasoning_effort` | Value not allowed for this model; the message lists the allowed values                       |
| `tools_not_supported`      | `tools` sent to a model without `supports_tools`                                             |
| `model_not_chat`           | Embedding model sent to `/v1/chat/completions`                                               |
| `model_not_embedding`      | Chat model sent to `/v1/embeddings`                                                          |

### 401 / 403 — fix the key or account

See [Authentication](/authentication#account-states) for the full table
(`invalid_api_key`, `account_unlinked`,
`legacy_account_upgrade_required`, `guest_expired`, `email_required`,
`geo_restricted`).

### 429 — back off

| `code`                 | Scope                      | Retry at                   |
| ---------------------- | -------------------------- | -------------------------- |
| `rate_limited`         | Per-model RPM              | RPM window reset (seconds) |
| `abuse_cooldown`       | Whole account              | `resets_at`                |
| `session_exhausted`    | Session pool               | `resets_at`                |
| `weekly_exhausted`     | Weekly pool                | `resets_at`                |
| `model_quota_exceeded` | Shared per-model daily cap | 09:00 KST                  |

### 5xx / 529 — not your fault

| HTTP | `code`                         | Meaning                                                               |
| ---- | ------------------------------ | --------------------------------------------------------------------- |
| 500  | `upstream_error` (and related) | The model service failed; the message is generic by design            |
| 503  | `maintenance`                  | Operator maintenance window                                           |
| 503  | `model_disabled`               | Operator turned this model off (it also disappears from `/v1/models`) |
| 503  | `server_draining`              | Restart in progress — retry in a few seconds                          |
| 529  | `model_overloaded`             | Model's concurrency cap saturated — retry in a few seconds            |

## Streaming errors

If a stream fails **after** the first bytes were sent, the connection
ends without a JSON envelope (the HTTP status was already 200). Treat an
unexpected stream end without `data: [DONE]` as a failed request. Errors
detected before streaming starts are returned as normal JSON envelopes.

## Correlation IDs

Two response headers identify a request, on success and failure alike:

* `x-sq1-request-id` — correlation ID, present on **every** response.
  Quote this when reporting a problem.
* `x-request-id` — the completed request's log ID (chat/embeddings only).
