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

# Error handling

> Response formats, status codes, retries, and streaming errors across LinkModel APIs.

## Choose an error format

**Choose by endpoint, not by model provider.** A Gemini image model called through LinkModel's task API uses that task endpoint's response format, not the Gemini-native error format.

| API family | Response format | How to check for errors |
| - | - | - |
| LinkModel task APIs, such as `/v1/images/generations` and `/v1/videos/generations` | Top-level business `code`, a message field, and `data` when present | Check both HTTP status and business `code`. For asynchronous tasks, also check task status. |
| OpenAI-compatible Chat / Responses | `error` with `type`, `code`, `param`, and `message` | Check HTTP status and the OpenAI error fields. |
| Anthropic-compatible Messages | Top-level `type: "error"` and an `error` object | Check HTTP status and `error.type`. |
| Gemini-native generation / Interactions | An `error` object; fields differ between generation and Interactions | Check HTTP status and the fields for the endpoint called. |

The same format applies to gateway rejections and model-service errors on the [compatibility endpoints listed below](#compatibility-api-errors). For file APIs, legacy endpoints, Decisions, and other endpoints not listed there, follow the individual API Reference response schema.

## LinkModel task API errors

For task creation, the response uses these fields:

| Field | Meaning |
| - | - |
| `code` | Business result. `0` means the request was accepted; a nonzero value indicates failure. This is separate from the HTTP status. |
| `msg` | Human-readable message for display and diagnostics. |
| `data` | Result payload when present, such as the accepted task's `task_id`. Do not require it on errors. |
| `request_id` | Request identifier when present; include it when contacting support. |

### Example: validation failure with HTTP 200

A task creation request can return HTTP `200` with business `code: 400`. Treat it as a failed request and correct the parameters.

```json theme={null}
{
  "code": 400,
  "msg": "model is required",
  "data": {}
}
```

**An accepted request is not a completed task.** After receiving `code: 0` and a `task_id`, poll the task endpoint and inspect `data.status`. A successful query can report a failed generation task.

Message fields vary by endpoint. For example, the video task query uses top-level `message` for the query result and `data.msg` for task details or errors; task creation uses top-level `msg`. Follow the endpoint's schema rather than assuming one message field works everywhere.

The compatibility API status mappings below do not replace task API behavior. For example, task creation can return HTTP `500` for insufficient balance, while the covered compatibility endpoints use HTTP `402`.

## Compatibility API errors

Check the **HTTP status** first, then read the endpoint's **protocol error fields**. Gateway rejections use the same error format as the model service.

This section covers OpenAI Chat Completions / Responses, Anthropic Messages, and Gemini generation / Interactions. These endpoints use protocol-specific errors instead of LinkModel's task API envelope.

> [accordion] Covered endpoints and request schemas
>
> All paths below use `POST`.
>
> * **[Chat Completions](https://docs.linkmodel.ai/api-reference/chat/openai-chat-completions.md)**: `/v1/chat/completions`
> * **[Responses](https://docs.linkmodel.ai/api-reference/chat/openai-responses.md)**: `/v1/responses`
> * **Responses Compact**: `/v1/responses/compact`
> * **[Messages](https://docs.linkmodel.ai/api-reference/chat/anthropic-messages.md)**: `/v1/messages`
> * **[Gemini GenerateContent](https://docs.linkmodel.ai/api-reference/chat/gemini-generatecontent.md)**: `/v1beta/models/{model}:generateContent`
> * **Gemini StreamGenerateContent**: `/v1beta/models/{model}:streamGenerateContent`
> * **Gemini Interactions**: `/v1beta/interactions`
>
> The linked pages define request schemas. This guide covers errors for Responses Compact and Gemini Interactions, but does not define their request schemas.

**Migrating an existing client?** Replace reads of the platform's top-level `body.code` and `body.msg` with the protocol fields below. Use the HTTP status and machine-readable fields for decisions; use messages for display and diagnostics.

### Error fields by protocol

| Protocol | Fields to read |
| - | - |
| OpenAI Chat / Responses | `error.type`, `error.code`, `error.param`, `error.message`. Code and param can be `null`. |
| Anthropic Messages | Top-level `type: "error"`; `error.type`, `error.message`; optional `request_id`. |
| Gemini GenerateContent | Integer `error.code`, string `error.status`, `error.message`. |
| Gemini Interactions | String `error.code`, `error.message`. |

`error.code` is **not a universal integer code**: its type depends on the protocol. Capture request identifiers from response headers or the body when present; a body-level `request_id` is not guaranteed.

### Example: HTTP 401

> [tab] OpenAI
>
> ```json theme={null}
> {
>   "error": {
>     "type": "authentication_error",
>     "code": "invalid_api_key",
>     "param": null,
>     "message": "Authentication failed"
>   }
> }
> ```

> [tab] Anthropic
>
> ```json theme={null}
> {
>   "type": "error",
>   "error": {
>     "type": "authentication_error",
>     "message": "Authentication failed"
>   },
>   "request_id": "request_example123"
> }
> ```

> [tab] Gemini GenerateContent
>
> ```json theme={null}
> {
>   "error": {
>     "code": 401,
>     "status": "UNAUTHENTICATED",
>     "message": "Authentication failed"
>   }
> }
> ```

> [tab] Gemini Interactions
>
> ```json theme={null}
> {
>   "error": {
>     "code": "authentication",
>     "message": "Authentication failed"
>   }
> }
> ```

## Compatibility HTTP status codes

The following mappings apply to the compatibility endpoints listed above. For LinkModel task APIs, check the endpoint's HTTP responses and business `code` together.

| HTTP status | Meaning | What to do |
| - | - | - |
| 400 / 422 | Invalid or unsupported request parameters | Check the endpoint schema and correct the request. |
| 401 | Missing or invalid LinkModel credentials | Check the API key and authentication header. |
| 402 | Insufficient account balance | Add funds before retrying. |
| 403 | Access denied | Check access to the requested resource. |
| 404 | Model unavailable or route/resource not found | Check the model, endpoint path, and availability. |
| 413 | Request body too large | Reduce the payload size. |
| 429 | Rate limit exceeded or API key quota exhausted | Distinguish temporary rate limits from exhausted quota before retrying. |
| 500 | Internal service error | Record the request details; retry selectively. |
| 502 | Backend connection, upstream credentials, or response transport/decoding failure | Record the request details and retry selectively; this is not a request to replace your own API key. |
| 503 / 529 | Service unavailable or overloaded; 529 is used by the Anthropic-compatible protocol | Retry with bounded exponential backoff. |
| 504 | Backend timeout | Check whether a result or partial output was received before retrying. |

Upstream provider authentication or permission failures (`401`, `403`, or `407`) are mapped to `502`. A `401` returned to you indicates a problem with authentication at the LinkModel boundary, not a provider credential that you control.

## Quota errors and rate limits

For the OpenAI-compatible Chat / Responses endpoints listed above:

| Condition | HTTP status | `error.type` | `error.code` |
| - | - | - | - |
| Account balance exhausted | 402 | `insufficient_quota` | `insufficient_quota` |
| API key quota exhausted | 429 | `insufficient_quota` | `insufficient_quota` |
| Ordinary request rate limit | 429 | `rate_limit_error` | `rate_limit_exceeded` |

Stop automatic retries for `insufficient_quota` and resolve the balance or key limit. For a temporary rate limit, use bounded exponential backoff and honor `Retry-After` when provided.

For Anthropic-compatible endpoints, identify insufficient account balance by HTTP status `402`: its body uses `error.type: "invalid_request_error"`, which is also used for invalid requests. Do not classify this error by `error.type` alone.

Anthropic represents both kinds of 429 with `error.type: "rate_limit_error"`. Gemini GenerateContent uses `error.status: "RESOURCE_EXHAUSTED"`, and Interactions uses `error.code: "rate_limit_exceeded"` for 429. These fields alone cannot distinguish key quota exhaustion from a temporary rate limit; check your key limits and usage rather than retrying indefinitely or matching message text.

## Streaming errors

For Gemini SSE generation, use `POST /v1beta/models/{model}:streamGenerateContent?alt=sse`. The [GenerateContent reference](https://docs.linkmodel.ai/api-reference/chat/gemini-generatecontent.md) describes the separate `:generateContent` request with a JSON response; its response schema does not describe an SSE stream.

Once response headers have been sent, an SSE stream can remain HTTP 200 even if generation later fails. Handle both protocol error events and unexpected connection termination.

| Protocol | Stream error representation |
| - | - |
| Chat Completions | A `data:` event containing an `error` object instead of a normal chunk. |
| Responses | `event: error` with `type: "error"`, `code`, `message`, `param`, and `sequence_number`; also handle `response.failed` and its `response.error`. |
| Anthropic Messages | `event: error` with top-level `type: "error"`, plus `error.type` and `error.message`. |
| Gemini StreamGenerateContent (SSE) | A `data:` event containing the Gemini `error` object. |
| Gemini Interactions | `event: error` with `event_type: "error"` and an `error` object. |

Parse complete SSE events: several `data:` lines can belong to one event, terminated by a blank line. Do not treat each network chunk as a complete JSON object. A panic or broken connection after output starts can terminate the transport without a final error event. Preserve partial output as incomplete and do not treat EOF or HTTP 200 alone as success.

An interrupted or failed stream does not by itself prove zero usage or zero cost. Check usage records before retrying a request that may already have produced output.


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