# Erros

Todo endpoint falha da mesma forma: um status HTTP e um envelope 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"
  }
}
```

| Campo | Significado |
|---|---|
| `type` | Classe geral do erro. Decida o que fazer com base nisso. |
| `code` | Motivo exato, estável e legível por máquina. Cada código tem uma seção abaixo; `doc_url` aponta para ela. |
| `message` | Explicação legível, segura para registrar ou mostrar a um desenvolvedor. |
| `param` | O parâmetro de entrada ou cabeçalho com problema, quando houver. |
| `details` | Para erros de entrada, todos os problemas encontrados: `[{ "param", "message" }]`. |
| `request_id` | A requisição à qual se refere, quando existir. |

Nada é cobrado por uma chamada que retorna um erro. Uma requisição que falha *depois* de ser aceita permanece com o status
`failed`, contém `error: { "type", "code", "message" }` no objeto da requisição e recebe reembolso automaticamente.

## Tipos

| Tipo | Status HTTP | O que fazer |
|---|---|---|
| `invalid_request` | 400, 413 ou 422 | Corrija a requisição. Tentar a mesma chamada novamente falhará. |
| `authentication_error` | 401 | Envie uma chave válida em `Authorization: Bearer <key>`. |
| `permission_error` | 403 | Use uma chave com o escopo necessário. |
| `not_found` | 404 | Verifique o id do modelo ou da requisição. |
| `insufficient_credits` | 402 | Faça uma recarga do saldo da API (`top_up_url` no erro). |
| `budget_exceeded` | 402 | O limite da própria chave foi atingido. Final: peça ao proprietário da chave para aumentá-lo. |
| `conflict` | 409 | O recurso não está em um estado que permita essa chamada. |
| `rate_limited` | 429 | Aguarde `Retry-After` segundos e tente novamente. |
| `upstream_error` | 502 | O backend do modelo falhou. É seguro tentar novamente com a mesma `Idempotency-Key`: a execução ocorrerá outra vez; você não foi cobrado. |
| `service_unavailable` | 503 | A API está pausada ou uma dependência está indisponível. Tente novamente mais tarde. |
| `internal_error` | 500 | Um erro nosso. Tente novamente; se persistir, entre em contato com o suporte informando o horário e o `request_id`. |

## Códigos

### `invalid_request`

Requisição malformada genérica (400).

### `invalid_json`

O corpo não é um JSON válido (400).

### `invalid_body`

O corpo é um JSON válido, mas não é um objeto; a entrada do modelo deve ser um objeto JSON (400).

### `body_too_large`

O corpo é maior que 16 MB (413). Envie arquivos grandes e passe a URL deles em vez disso (consulte [Arquivos](https://doitong.com/developers/docs/files)).

### `invalid_parameter`

Um parâmetro de consulta tem um valor incorreto, por exemplo, `limit` fora de 1 a 100, `wait` não é um número, um
`status` ou `category` desconhecido, ou `storage` diferente de `permanent` / `temporary` (400). `param` informa qual é.

### `invalid_category`

`GET /openapi.json?category=` indica uma categoria que não existe (400). `GET https://api.doitong.ru/v1/categories` lista as categorias.

### `invalid_cursor`

O `cursor` de uma chamada de listagem não pertence a esta lista (400). Comece novamente sem um cursor.

### `invalid_idempotency_key`

O cabeçalho `Idempotency-Key` está vazio ou tem mais de 255 caracteres (400).

### `invalid_arguments`

Uma chamada de ferramenta MCP tem um argumento ausente ou malformado (somente MCP). `param` informa qual é o argumento.

### `invalid_input`

A entrada do modelo não passa pela validação (422): um parâmetro desconhecido (a mensagem sugere o nome válido mais próximo),
um parâmetro obrigatório ausente, um tipo incorreto, um valor fora da lista ou do intervalo permitido, ou tanto o nome canônico quanto o
nome nativo informados com valores diferentes. `param` é o primeiro parâmetro problemático e `details` lista todos eles.
Nada é cobrado.

### `unsupported_file`

Um arquivo tem um tipo que não aceitamos (422), por exemplo, um upload com uma extensão não compatível ou um `content_type`
que não corresponde à extensão.

### `invalid_webhook_url`

`webhook_url` não é uma URL pública `https://` (422). Endereços privados, locais e simples `http://` são recusados.

### `missing_api_key`

O endpoint precisa de uma chave de API e nenhuma foi enviada (401).

### `invalid_api_key`

A chave é desconhecida, revogada ou expirou (401).

### `insufficient_scope`

A chave não tem o escopo necessário para esta chamada (403), por exemplo, `models:run` para uma execução ou `models:read` para ler
requisições e o saldo. Consulte [Autenticação](https://doitong.com/developers/docs/authentication#scopes).

### `account_disabled`

A conta foi encerrada ou suspensa (403). As chaves dela não funcionam mais.

### `not_found`

O caminho não existe (404).

### `model_not_found`

Nenhum modelo público tem este id (404). Liste os modelos com `GET https://api.doitong.ru/v1/models`.

### `request_not_found`

Não existe uma requisição com este id na sua conta (404). Requisições de outras contas nunca ficam visíveis.

### `insufficient_credits`

O **saldo da API** da conta (créditos de API, 1.000 créditos de API = $ 1 — não os créditos dos aplicativos Doitong) não cobre o
preço desta chamada (402). A resposta é enviada antes de qualquer cobrança. O erro contém `top_up_url`; adicione dinheiro
em [https://doitong.ru/developers/dashboard#balance](https://doitong.ru/developers/dashboard#balance) e tente novamente.

```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`

A chamada excederia o próprio limite da chave de API em créditos de API (402). O limite é definido pelo proprietário da chave; tentar novamente não
ajudará até que ele o aumente.

### `conflict`

A chamada entra em conflito com o estado atual do recurso (409).

### `idempotency_mismatch`

A `Idempotency-Key` já foi usada com um corpo diferente (409). Use uma chave nova para uma nova operação.

### `idempotency_in_progress`

Uma requisição com a mesma `Idempotency-Key` está sendo criada neste momento (409). Tente novamente em instantes para obtê-la.

### `request_active`

A requisição ainda está `queued` ou `running`, portanto ainda não há arquivos para excluir (409). Exclua-os quando ela terminar.

### `not_cancelable`

A requisição já está `succeeded` ou `failed` e não pode ser cancelada (409).

### `rate_limited`

A chave fez requisições demais na janela atual (429). Consulte os cabeçalhos `X-RateLimit-*` e `Retry-After`.

### `too_many_inflight`

A conta já tem 10 requisições `queued` ou `running` (429). Inicie a próxima quando uma delas terminar.

### `upstream_error`

O backend do modelo recusou ou não conseguiu processar a requisição (502 na execução ou `failed` com este código na requisição). Os créditos de API são
reembolsados. Se o próprio backend rejeitar a entrada, a chamada retornará `422 invalid_input` com a mensagem correspondente.

### `upstream_lost`

O backend do modelo não conhece mais a requisição, portanto nenhum resultado chegará. Ela termina como `failed` com este código
(tipo `upstream_error`) e recebe reembolso. Execute-a novamente.

### `timeout`

A requisição foi executada por mais tempo que o limite (15 minutos para imagens, 60 para vídeo, 30 nos demais casos) e foi interrompida. Ela termina como
`failed` com este código e recebe reembolso.

### `service_unavailable`

A API está temporariamente pausada ou uma dependência, como uploads de arquivos, está indisponível (503). Tente novamente mais tarde.

### `internal_error`

Algo deu errado do nosso lado (500). Tente novamente; se persistir, entre em contato com o suporte.

### `charge_failed`

Não foi possível cobrar a conta devido a um problema interno (500). A requisição é marcada como `failed`; nada foi debitado. Tente novamente.

### `pricing_unavailable`

O preço do modelo não está configurado, portanto ele não pode ser calculado nem executado neste momento (500).
