# Errori

Ogni endpoint fallisce nello stesso modo: uno stato HTTP e un unico involucro 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 | Significato |
|---|---|
| `type` | Classe generale dell'errore. Decidi cosa fare in base a questo. |
| `code` | Motivo esatto, stabile e leggibile dalle macchine. Ogni codice ha una sezione qui sotto; `doc_url` contiene il collegamento. |
| `message` | Spiegazione leggibile, sicura da registrare o mostrare a uno sviluppatore. |
| `param` | Il parametro di input o l'header in errore, quando presente. |
| `details` | Per gli errori di input, ogni problema rilevato: `[{ "param", "message" }]`. |
| `request_id` | La richiesta a cui si riferisce, quando presente. |

Non viene addebitato nulla per una chiamata che restituisce un errore. Una richiesta che fallisce *dopo* essere stata accettata mantiene lo stato
`failed`, contiene `error: { "type", "code", "message" }` nell'oggetto della richiesta e viene rimborsata automaticamente.

## Tipi

| Tipo | Stato HTTP | Cosa fare |
|---|---|---|
| `invalid_request` | 400, 413 o 422 | Correggi la richiesta. Riprovare la stessa chiamata fallisce di nuovo. |
| `authentication_error` | 401 | Invia una chiave valida in `Authorization: Bearer <key>`. |
| `permission_error` | 403 | Usa una chiave con lo scope necessario. |
| `not_found` | 404 | Controlla l'id del modello o della richiesta. |
| `insufficient_credits` | 402 | Ricarica il saldo API (`top_up_url` nell'errore). |
| `budget_exceeded` | 402 | Il budget della chiave è esaurito. Definitivo: chiedi al proprietario della chiave di aumentarlo. |
| `conflict` | 409 | La risorsa non è in uno stato che consente questa chiamata. |
| `rate_limited` | 429 | Attendi `Retry-After` secondi, quindi riprova. |
| `upstream_error` | 502 | Il backend del modello ha fallito. Puoi riprovare con lo stesso `Idempotency-Key`: verrà eseguito di nuovo; non ti è stato addebitato nulla. |
| `service_unavailable` | 503 | L'API è in pausa o una dipendenza non è disponibile. Riprova più tardi. |
| `internal_error` | 500 | Un nostro bug. Riprova; se persiste, contatta l'assistenza indicando l'ora e `request_id`. |

## Codici

### `invalid_request`

Richiesta generica malformata (400).

### `invalid_json`

Il corpo non è JSON valido (400).

### `invalid_body`

Il corpo è JSON valido ma non è un oggetto; l'input del modello deve essere un oggetto JSON (400).

### `body_too_large`

Il corpo supera 16 MB (413). Carica i file di grandi dimensioni e passa invece il loro URL (vedi [File](https://doitong.com/developers/docs/files)).

### `invalid_parameter`

Un parametro di query ha un valore errato, ad esempio `limit` fuori dall'intervallo 1–100, `wait` non numerico, uno
`status` o `category` sconosciuto, oppure `storage` diverso da `permanent` / `temporary` (400). `param` lo identifica.

### `invalid_category`

`GET /openapi.json?category=` indica una categoria inesistente (400). `GET https://api.doitong.com/v1/categories` elenca le categorie.

### `invalid_cursor`

Il `cursor` di una chiamata di elenco non appartiene a questo elenco (400). Ricomincia senza cursor.

### `invalid_idempotency_key`

L'header `Idempotency-Key` è vuoto o supera 255 caratteri (400).

### `invalid_arguments`

Una chiamata a uno strumento MCP ha un argomento mancante o malformato (solo MCP). `param` identifica l'argomento.

### `invalid_input`

L'input del modello non supera la convalida (422): un parametro sconosciuto (il messaggio suggerisce il nome valido più vicino),
un parametro obbligatorio mancante, un tipo errato, un valore fuori dall'elenco o dall'intervallo consentito, oppure sia il nome canonico sia quello
nativo con valori diversi. `param` è il primo parametro errato e `details` li elenca tutti.
Non viene addebitato nulla.

### `unsupported_file`

Un file ha un tipo non accettato (422), ad esempio un caricamento con estensione non supportata o un `content_type`
che non corrisponde all'estensione.

### `invalid_webhook_url`

`webhook_url` non è un URL pubblico `https://` (422). Gli indirizzi privati, locali e in semplice `http://` vengono rifiutati.

### `missing_api_key`

L'endpoint richiede una chiave API e non ne è stata inviata alcuna (401).

### `invalid_api_key`

La chiave è sconosciuta, revocata o scaduta (401).

### `insufficient_scope`

Alla chiave manca lo scope richiesto da questa chiamata (403), ad esempio `models:run` per un'esecuzione o `models:read` per leggere
le richieste e il saldo. Vedi [Autenticazione](https://doitong.com/developers/docs/authentication#scopes).

### `account_disabled`

L'account è chiuso o sospeso (403). Le sue chiavi non funzionano più.

### `not_found`

Il percorso non esiste (404).

### `model_not_found`

Nessun modello pubblico ha questo id (404). Elenca i modelli con `GET https://api.doitong.com/v1/models`.

### `request_not_found`

Nel tuo account non esiste alcuna richiesta con questo id (404). Le richieste di altri account non sono mai visibili.

### `insufficient_credits`

Il **saldo API** dell'account (crediti API, 1000 crediti API = 1 $ — non i crediti delle app Doitong) non copre il
prezzo di questa chiamata (402). La risposta viene inviata prima di qualsiasi addebito. L'errore contiene `top_up_url`; aggiungi denaro
su [https://doitong.com/developers/dashboard#balance](https://doitong.com/developers/dashboard#balance) e riprova.

```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.com/developers/dashboard#balance",
             "top_up_url": "https://doitong.com/developers/dashboard#balance", "doc_url": "https://doitong.com/developers/docs/errors#insufficient_credits" } }
```

### `budget_exceeded`

La chiamata supererebbe il budget della chiave API in crediti API (402). Il budget è impostato dal proprietario della chiave; riprovare non
serve finché non lo aumenta.

### `conflict`

La chiamata è in conflitto con lo stato attuale della risorsa (409).

### `idempotency_mismatch`

`Idempotency-Key` è già stato usato con un corpo diverso (409). Usa una nuova chiave per una nuova operazione.

### `idempotency_in_progress`

In questo momento è in corso la creazione di una richiesta con lo stesso `Idempotency-Key` (409). Riprova tra poco per ottenerla.

### `request_active`

La richiesta è ancora `queued` o `running`, quindi non ha ancora file da eliminare (409). Eliminali quando sarà terminata.

### `not_cancelable`

La richiesta è già `succeeded` o `failed` e non può essere annullata (409).

### `rate_limited`

La chiave ha effettuato troppe richieste nella finestra corrente (429). Vedi gli header `X-RateLimit-*` e `Retry-After`.

### `too_many_inflight`

L'account ha già 10 richieste `queued` o `running` (429). Avvia la successiva quando una di esse termina.

### `upstream_error`

Il backend del modello ha rifiutato o non è riuscito a elaborare la richiesta (502 durante l'esecuzione, oppure `failed` con questo codice nella richiesta). I crediti API vengono
rimborsati. Se il backend ha rifiutato direttamente l'input, la chiamata restituisce invece `422 invalid_input` con il relativo messaggio.

### `upstream_lost`

Il backend del modello non riconosce più la richiesta, quindi non arriverà mai alcun risultato. Termina come `failed` con questo codice
(tipo `upstream_error`) e viene rimborsata. Eseguila di nuovo.

### `timeout`

La richiesta è durata più del limite (15 minuti per le immagini, 60 per il video, 30 negli altri casi) ed è stata interrotta. Termina come
`failed` con questo codice e viene rimborsata.

### `service_unavailable`

L'API è temporaneamente in pausa oppure una dipendenza, come il caricamento dei file, non è disponibile (503). Riprova più tardi.

### `internal_error`

Si è verificato un problema dal nostro lato (500). Riprova; se persiste, contatta l'assistenza.

### `charge_failed`

Non è stato possibile addebitare l'account a causa di un problema interno (500). La richiesta viene contrassegnata come `failed`; non è stato
prelevato nulla. Riprova.

### `pricing_unavailable`

Il prezzo del modello non è configurato, quindi al momento non può essere calcolato né eseguito (500).
