# 오류

모든 엔드포인트는 동일한 방식으로 실패합니다. HTTP 상태 코드와 하나의 JSON 봉투를 반환합니다.

```json
{
  "error": {
    "type": "invalid_request",
    "code": "invalid_input",
    "message": "duration must be one of 5, 10.",
    "param": "duration",
    "details": [ { "param": "duration", "message": "duration must be one of 5, 10." } ],
    "request_id": null,
    "doc_url": "https://doitong.com/developers/docs/errors#invalid_input"
  }
}
```

| 필드 | 의미 |
|---|---|
| `type` | 오류의 광범위한 분류입니다. 이를 바탕으로 처리 방법을 결정합니다. |
| `code` | 정확한 원인으로, 안정적이며 기계가 읽을 수 있습니다. 모든 코드에는 아래에 섹션이 있으며 `doc_url`이 해당 섹션으로 연결됩니다. |
| `message` | 개발자에게 로그로 기록하거나 표시해도 안전한 사람이 읽을 수 있는 설명입니다. |
| `param` | 문제가 있는 입력 매개변수 또는 헤더입니다. 해당하는 경우에만 포함됩니다. |
| `details` | 입력 오류의 경우 발견된 모든 문제입니다: `[{ "param", "message" }]`. |
| `request_id` | 관련 요청입니다. 존재하는 경우에만 포함됩니다. |

오류를 반환하는 호출에는 요금이 부과되지 않습니다. 수락된 *후* 실패한 요청은 상태가
`failed`로 유지되고, 요청 객체에 `error: { "type", "code", "message" }`가 포함되며, 자동으로 환불됩니다.

## 유형

| 유형 | HTTP 상태 | 처리 방법 |
|---|---|---|
| `invalid_request` | 400, 413 또는 422 | 요청을 수정합니다. 동일한 호출을 다시 시도해도 다시 실패합니다. |
| `authentication_error` | 401 | `Authorization: Bearer <key>`에 유효한 키를 보냅니다. |
| `permission_error` | 403 | 필요한 scope가 있는 키를 사용합니다. |
| `not_found` | 404 | 모델 id 또는 요청 id를 확인합니다. |
| `insufficient_credits` | 402 | API 잔액을 충전합니다(오류의 `top_up_url`). |
| `budget_exceeded` | 402 | 키 자체의 한도를 모두 사용했습니다. 최종 조치: 키 소유자에게 한도 상향을 요청합니다. |
| `conflict` | 409 | 리소스가 이 호출을 허용하는 상태가 아닙니다. |
| `rate_limited` | 429 | `Retry-After`초 동안 기다린 다음 다시 시도합니다. |
| `upstream_error` | 502 | 모델 백엔드가 실패했습니다. 동일한 `Idempotency-Key`로 다시 시도해도 안전합니다. 다시 실행되며 요금은 부과되지 않습니다. |
| `service_unavailable` | 503 | API가 일시 중지되었거나 종속 서비스가 중단되었습니다. 나중에 다시 시도합니다. |
| `internal_error` | 500 | 저희 측의 버그입니다. 다시 시도하고, 계속되면 시간과 `request_id`를 함께 지원팀에 문의합니다. |

## 코드

### `invalid_request`

형식이 잘못된 일반 요청입니다(400).

### `invalid_json`

본문이 유효한 JSON이 아닙니다(400).

### `invalid_body`

본문은 유효한 JSON이지만 객체가 아닙니다. 모델 입력은 JSON 객체여야 합니다(400).

### `body_too_large`

본문이 16 MB보다 큽니다(413). 큰 파일을 업로드하고 대신 URL을 전달합니다([파일](https://doitong.com/developers/docs/files) 참조).

### `invalid_parameter`

쿼리 매개변수의 값이 잘못되었습니다. 예를 들어 `limit`이 1~100 범위를 벗어났거나, `wait`가 숫자가 아니거나, 알 수 없는
`status` 또는 `category`이거나, `storage`가 `permanent` / `temporary` 이외의 값인 경우입니다(400). `param`에 해당 이름이 표시됩니다.

### `invalid_category`

`GET /openapi.json?category=`가 존재하지 않는 category를 지정합니다(400). `GET https://api.doitong.ru/v1/categories`에 목록이 표시됩니다.

### `invalid_cursor`

목록 호출의 `cursor`가 이 목록에 속하지 않습니다(400). cursor 없이 다시 시작합니다.

### `invalid_idempotency_key`

`Idempotency-Key` 헤더가 비어 있거나 255자를 초과합니다(400).

### `invalid_arguments`

MCP 도구 호출에 누락되었거나 형식이 잘못된 인수가 있습니다(MCP만 해당). `param`에 인수 이름이 표시됩니다.

### `invalid_input`

모델 입력이 검증을 통과하지 못했습니다(422). 알 수 없는 매개변수(메시지에 가장 가까운 유효한 이름이 제안됨),
필수 매개변수 누락, 잘못된 유형, 허용된 목록 또는 범위를 벗어난 값, 또는 표준 이름과 네이티브 이름이 서로 다른 값으로 함께 지정된 경우입니다. `param`은
처음 발견된 문제가 있는 매개변수이며 `details`에 모든 문제가 표시됩니다.
요금은 부과되지 않습니다.

### `unsupported_file`

파일 유형을 허용하지 않습니다(422). 예를 들어 지원되지 않는 확장자로 업로드했거나 `content_type`이
확장자와 일치하지 않는 경우입니다.

### `invalid_webhook_url`

`webhook_url`이 공개 `https://` URL이 아닙니다(422). 비공개, 로컬 및 일반 `http://` 주소는 거부됩니다.

### `missing_api_key`

엔드포인트에 API 키가 필요하지만 전송되지 않았습니다(401).

### `invalid_api_key`

키를 알 수 없거나 취소되었거나 만료되었습니다(401).

### `insufficient_scope`

키에 이 호출에 필요한 scope가 없습니다(403). 예를 들어 실행에는 `models:run`이, 요청과 잔액을 읽으려면
`models:read`가 필요합니다. [인증](https://doitong.com/developers/docs/authentication#scopes)을 참조하세요.

### `account_disabled`

계정이 폐쇄되었거나 정지되었습니다(403). 해당 계정의 키는 더 이상 작동하지 않습니다.

### `not_found`

경로가 존재하지 않습니다(404).

### `model_not_found`

이 id를 가진 공개 모델이 없습니다(404). `GET https://api.doitong.ru/v1/models`로 모델을 나열합니다.

### `request_not_found`

계정에 이 id를 가진 요청이 없습니다(404). 다른 계정의 요청은 절대 표시되지 않습니다.

### `insufficient_credits`

계정의 **API 잔액**(API 크레딧, 1,000 API 크레딧 = $1 — Doitong 앱의 크레딧과 다름)으로는 이 호출의
가격을 충당할 수 없습니다(402). 요금이 부과되기 전에 응답이 전송됩니다. 오류에 `top_up_url`이 포함되며,
[https://doitong.ru/developers/dashboard#balance](https://doitong.ru/developers/dashboard#balance)에서 금액을 추가한 다음 다시 시도합니다.

```json
{ "error": { "type": "insufficient_credits", "code": "insufficient_credits",
             "message": "This request costs 560 API credits ($0.56); the API balance is 120 API credits ($0.12). Top up at https://doitong.ru/developers/dashboard#balance",
             "top_up_url": "https://doitong.ru/developers/dashboard#balance", "doc_url": "https://doitong.com/developers/docs/errors#insufficient_credits" } }
```

### `budget_exceeded`

호출하면 API 키 자체의 API 크레딧 한도를 초과하게 됩니다(402). 한도는 키 소유자가 설정하며, 소유자가 한도를
높이기 전에는 다시 시도해도 해결되지 않습니다.

### `conflict`

호출이 리소스의 현재 상태와 충돌합니다(409).

### `idempotency_mismatch`

`Idempotency-Key`가 이미 다른 본문과 함께 사용되었습니다(409). 새 작업에는 새 키를 사용합니다.

### `idempotency_in_progress`

동일한 `Idempotency-Key`를 사용하는 요청이 지금 생성 중입니다(409). 잠시 후 다시 시도하여 요청을 가져옵니다.

### `request_active`

요청이 아직 `queued` 또는 `running` 상태이므로 삭제할 파일이 없습니다(409). 요청이 완료된 후 삭제합니다.

### `not_cancelable`

요청이 이미 `succeeded` 또는 `failed` 상태이므로 취소할 수 없습니다(409).

### `rate_limited`

현재 윈도우에 키가 너무 많은 요청을 보냈습니다(429). `X-RateLimit-*` 및 `Retry-After` 헤더를 참조하세요.

### `too_many_inflight`

계정에 이미 `queued` 또는 `running` 상태의 요청이 10개 있습니다(429). 그중 하나가 완료되면 다음 요청을 시작합니다.

### `upstream_error`

모델 백엔드가 요청을 거부했거나 실패했습니다(실행 시 502 또는 요청에서 이 코드와 함께 `failed`). API 크레딧은
환불됩니다. 백엔드 자체가 입력을 거부한 경우에는 대신 메시지와 함께 `422 invalid_input`이 반환됩니다.

### `upstream_lost`

모델 백엔드가 더 이상 요청을 알지 못하므로 결과가 도착하지 않습니다. 이 코드를 포함한 `failed` 상태
(유형 `upstream_error`)로 종료되고 환불됩니다. 다시 실행하세요.

### `timeout`

요청이 제한 시간(이미지는 15분, 동영상은 60분, 그 외에는 30분)을 초과하여 실행되다가 중지되었습니다. `failed` 상태와
이 코드로 종료되며 환불됩니다.

### `service_unavailable`

API가 일시적으로 중지되었거나 파일 업로드와 같은 종속 서비스가 중단되었습니다(503). 나중에 다시 시도합니다.

### `internal_error`

저희 측에서 문제가 발생했습니다(500). 다시 시도하고, 계속되면 지원팀에 문의하세요.

### `charge_failed`

내부 문제로 계정에 요금을 청구할 수 없습니다(500). 요청은 `failed`로 표시되며 요금은 차감되지 않습니다.
다시 시도하세요.

### `pricing_unavailable`

모델 가격이 구성되지 않아 지금은 가격을 산정하거나 실행할 수 없습니다(500).
