# Gestire gli errori

> Distingui le chiamate rifiutate dalle trascrizioni non riuscite. Consulta i codici e verifica quando ha senso riprovare.

Canonical: https://transcript1.com/it/docs/errors
Language: it
Last updated: 2026-11-05

Un errore può arrivare in due momenti. Se l'API rifiuta la chiamata, ricevi subito un errore nella risposta. Se invece accetta la trascrizione e qualcosa va storto durante l'elaborazione, ritrovi la trascrizione con `status` uguale a `failed`.

## Come leggere un errore API

Quando una chiamata `/v1` non viene accettata, la risposta segue sempre questa struttura:

```json
{
  "error": {
    "code": "insufficient_minutes",
    "message": "Not enough minutes",
    "retryable": false,
    "action_url": "https://transcript1.com/dashboard/billing",
    "minutes_needed": 20,
    "minutes_remaining": 3
  }
}
```

Nel codice della tua applicazione, distingui gli errori usando `code`. Usa `message` solo per mostrare la spiegazione all'utente: il testo può cambiare. Con `retryable` uguale a `true`, puoi riprovare la stessa chiamata più tardi.

In alcuni casi trovi altri campi oltre a `retryable`:

| Campo | Codice associato | A cosa serve |
|---|---|---|
| `action_url` | `insufficient_minutes`, `no_active_plan`, `topup_needs_user` | Link per acquistare un piano o aggiungere minuti con una ricarica. |
| `minutes_needed`, `minutes_remaining` | `insufficient_minutes` | Minuti necessari per la chiamata e saldo disponibile. I minuti necessari valgono `null` se non li conosciamo ancora. |
| `reason`, `packs` | `topup_needs_user` | Perché la carta non è stata addebitata e quanti pacchetti erano stati richiesti. |
| `supported_platforms` | `unsupported_platform` | Elenco delle piattaforme accettate: `["youtube", "x", "tiktok", "instagram", "facebook", "bluesky", "twitch", "dailymotion", "pinterest", "linkedin", "snapchat"]`. |
| `missing_chunks` | `upload_incomplete` | Indici delle parti del file che devi ancora inviare. |
| `max_bytes` | `media_too_large` | Limite di dimensione del file per il tuo account, in byte. |
| `params` | `invalid_request` | Negli errori di validazione del body o della query, associa ogni campo alla spiegazione del problema. |

## Quando l'API rifiuta la chiamata

| Stato HTTP | `code` | Puoi riprovare senza modifiche? | Causa |
|---|---|---|---|
| 400, 422 | `invalid_request` | No | Manca un parametro o un campo del body, oppure il valore non è valido. Succede anche con `diarize` insieme a `source: "captions"`, con `reuse_recent` insieme a `webhook_url` o con un body che non contiene JSON valido. |
| 422 | `invalid_url` | No | Il link non è valido oppure `platform` non corrisponde al link. Usa YouTube, X, TikTok, Instagram, Facebook, Bluesky o una delle altre piattaforme in [Link e opzioni di trascrizione](https://transcript1.com/it/docs/sources-and-options). |
| 422 | `unsupported_platform` | No | Il valore di `platform` non rientra tra quelli accettati. |
| 422 | `unsupported_media` | No | L'estensione del file non è tra quelle supportate. |
| 401 | `unauthorized` | No | Manca la credenziale, oppure non è valida, è scaduta o è stata revocata. Vale anche per un token di caricamento non valido o scaduto. |
| 403 | `insufficient_scope` | No | Il token OAuth non ha lo scope `transcriptions:read` o `transcriptions:write` necessario per la chiamata. |
| 403 | `email_not_verified` | No | Devi confermare l'indirizzo email prima di creare trascrizioni o sessioni live. |
| 402 | `insufficient_minutes` | No | Hai 0 minuti utilizzabili, oppure non bastano per questa trascrizione o per un minuto iniziato di una sessione live. Se la [ricarica automatica](https://transcript1.com/it/docs/billing-and-limits#auto-top-up) è attiva, transcript1 prova prima a ricaricare. Acquista minuti da `action_url`, oppure lascia che un agente li acquisti con `POST /v1/topups` o con lo strumento MCP `top_up`. |
| 402 | `no_active_plan` | No | Per acquistare una ricarica serve un piano a pagamento attivo. Questo errore arriva da `POST /v1/topups` e dagli endpoint di fatturazione della dashboard, non dagli endpoint di trascrizione. |
| 402 | `topup_needs_user` | Solo per `pending` e `in_progress` | `POST /v1/topups` non ha addebitato la carta. `reason` spiega perché: `not_allowed` (la credenziale non può acquistare ricariche, o il suo utente non è admin del team), `cap_reached` (il limite mensile per gli agenti non ha più margine), `card_declined`, `authentication_required` o `no_card`. L'utente può acquistare i pacchetti da `action_url`. Con `pending` (il pagamento non è ancora confermato) e `in_progress` (è in corso un'altra ricarica), l'addebito potrebbe ancora andare a buon fine: riprova più tardi con lo stesso `Idempotency-Key` invece di mandare l'utente ad acquistare. |
| 404 | `not_found` | No | Nessuna trascrizione corrisponde all'ID, oppure appartiene a un altro team. |
| 409 | `upload_incomplete` | No | Il file non è completo: invia i chunk mancanti e richiama il completamento. |
| 409 | `invalid_state` | No | La trascrizione non è più in attesa del file. Non puoi inviare altri chunk né completare il caricamento. |
| 409 | `session_ended` | No | La sessione live è terminata, quindi `POST /v1/live/sessions/:id/token` non può emettere un token. Arriva anche come evento `error` del WebSocket. |
| 422 | `unsupported_language` | No | Il `language` della sessione live non è supportato. |
| 422 | `unsupported_translation` | No | La lingua `translate_to` della sessione live non è supportata, oppure la traduzione live non è disponibile. |
| 409 | `idempotency_conflict` | No | Hai già usato `Idempotency-Key` con parametri diversi. |
| 413 | `media_too_large` | No | La dimensione del file supera il limite del tuo account. Consulta [Caricare file](https://transcript1.com/it/docs/uploads). |
| 413 | `invalid_request` | No | Il body JSON supera 1 MB. Per i file, il codice corrispondente è `media_too_large`. |
| 429 | `rate_limited` | Sì | Hai superato il numero di chiamate al minuto. Aspetta quanto indicato da `Retry-After`, in secondi. |
| 429 | `too_many_active_jobs` | Sì | Hai troppe trascrizioni in corso o troppi caricamenti aperti. Aspetta quanto indicato da `Retry-After`, in secondi. |
| 429 | `too_many_live_sessions` | Sì | Le sessioni live simultanee del tuo piano sono tutte in uso. Aspetta quanto indicato da `Retry-After` (30 secondi). |
| 500 | `internal_error` | Sì | Si è verificato un errore nei nostri sistemi. Puoi riprovare tra poco. |
| 503 | `service_unavailable` | Sì | Il servizio non è disponibile al momento. Puoi riprovare tra poco. |
| 503 | `live_capacity` | Sì | Tutta la capacità live è in uso. Aspetta quanto indicato da `Retry-After` (30 secondi) e crea di nuovo la sessione. |
| 503 | `live_unavailable` | No | La trascrizione live non è disponibile al momento. |

Se il browser si autentica con un cookie di login anziché con una credenziale bearer, controlliamo anche l'origine della chiamata. Da un altro sito ricevi `403 forbidden_origin`. Il controllo non si applica alle chiamate API con l'header `Authorization`.

In tutte le risposte `429`, l'header `Retry-After` indica quanti secondi aspettare. Trovi le soglie per piano in [Costi e limiti](https://transcript1.com/it/docs/billing-and-limits).

## Quando e come riprovare

- Ripeti la chiamata senza modificarla solo con `retryable` uguale a `true`: vale per `rate_limited`, `too_many_active_jobs`, `too_many_live_sessions`, `live_capacity`, `internal_error`, `service_unavailable` e per `topup_needs_user` con `reason` `pending` o `in_progress`. Aspetta i secondi di `Retry-After`, se presente; altrimenti aumenta l'intervallo tra i tentativi.
- Per ripetere `POST /v1/transcriptions` o `POST /v1/topups`, mantieni lo stesso `Idempotency-Key`. Se la prima chiamata era riuscita, eviti un secondo addebito.
- Con gli altri codici, risolvi prima il problema della chiamata.

## Trascrizione live

`POST /v1/live/sessions` e gli altri endpoint live usano la stessa struttura di errore. Valgono anche per loro `invalid_request`, `unsupported_language`, `insufficient_minutes` e `email_not_verified`, insieme ai codici live della tabella qui sopra. Creare una sessione non è idempotente: ripetere la chiamata dopo `too_many_live_sessions` o `live_capacity` crea una nuova sessione.

Una volta creata la sessione, i problemi arrivano sul WebSocket come eventi `error` e codici di chiusura, non come errori HTTP. Tutti gli eventi sono in [Trascrizione live](https://transcript1.com/it/docs/live#websocket-protocol).

| Codice di chiusura | Significato |
|---|---|
| `1000` | Chiusura normale, dopo `session.ended`. |
| `1011` | Errore imprevisto del server. Riprendi con un nuovo token. |
| `1012` | Riavvio del server, dopo `reconnect`. Riprendi con un nuovo token. |
| `4001` | Token non valido, scaduto o già usato. |
| `4004` | Sessione non trovata o già terminata. |
| `4008` | Violazione del protocollo: un frame audio di lunghezza dispari o troppo grande. |
| `4010` | Sostituita da una connessione più recente alla stessa sessione. |

Una sessione live che termina per un motivo come `balance_exhausted` o `idle_timeout` non è un errore: invia `session.ended` con un motivo di conclusione e viene salvata. Vedi [Motivi di conclusione](https://transcript1.com/it/docs/live#end-reasons).

## Quando la trascrizione non riesce

Una trascrizione può non riuscire anche dopo che l'API ha risposto alla chiamata iniziale. In quel caso ha `status` uguale a `failed` e contiene `error: { "code", "message" }`. Controlla `error` quando leggi lo stato o ricevi il [webhook](https://transcript1.com/it/docs/webhooks) `transcription.failed`. Se una traduzione fallisce, viene inviato il webhook `transcription.translation.failed` e la trascrizione non fallisce mai per questo.

| `error.code` | Cosa è successo | Cosa fare |
|---|---|---|
| `media_unavailable` | Il video non esiste oppure non è più accessibile. | Non riprovare lo stesso link: controlla l'URL. |
| `media_private` | Non possiamo accedere al video perché è privato. | Usa un post pubblico o un video YouTube pubblico o non in elenco. |
| `login_required` | Per vedere il video serve il login sulla piattaforma. | Non riproviamo: è un errore permanente. |
| `no_audio` | Manca la traccia audio del video. | Non riproviamo: è un errore permanente. |
| `age_restricted` | La piattaforma applica un limite di età al video. | Non riprovare il link; carica il file. |
| `live_stream` | La diretta è in corso o deve ancora iniziare. | Aspetta che sia finita, poi riprova. |
| `no_captions` | Hai scelto `source` uguale a `captions`, ma manca una traccia di sottotitoli adatta. | Passa a `source: "auto"` o `"stt"`. |
| `media_too_long` | La registrazione supera il limite di 5 ore per lo speech-to-text. | Dividila in parti più brevi prima di inviarla. |
| `unsupported_media` | Non riusciamo a leggere il file, oppure manca la traccia audio. | Invia un file in un formato supportato. |
| `no_speech` | Nessun parlato rilevato. | Non riprovare la stessa registrazione. |
| `unsupported_language` | Non supportiamo la lingua della registrazione. | Correggi `language` con un codice supportato oppure `"auto"`. |
| `insufficient_minutes` | Al momento dell'addebito non avevi più abbastanza minuti e la ricarica automatica, se attiva, non è riuscita ad aggiungerne. | Dopo una ricarica. |
| `fetch_failed` | Non siamo riusciti a scaricare la registrazione dopo più tentativi. | Puoi riprovare più tardi. |
| `transcription_failed` | La trascrizione dell'audio non è riuscita dopo più tentativi. | Puoi riprovare più tardi. |

Se la trascrizione non riesce o la annulli, non paghi. Se avevamo già scalato dei minuti, li restituiamo al tuo saldo.
