Guide
Errori
Tutti i codici di errore e gli stati HTTP dell’API CheaperGen — 400, 401, 402, 404, 409, 429, 502 e 503 — con le relative cause e indicazioni per gestire o riprovare ogni errore.
L’API usa i codici di stato HTTP convenzionali: 2xx indica un esito positivo, 4xx che la richiesta deve essere modificata e 5xx un problema da parte nostra o di un servizio a monte. Tutte le risposte di errore hanno lo stesso formato JSON, così puoi gestirle in un unico punto.
Formato degli errori#
{
"error": {
"code": "invalid_request",
"message": "\"resolution\" must be one of: 480p, 720p",
"param": "resolution"
}
}code— una stringa stabile e leggibile dalle macchine. Usala per le condizioni nel codice, non il messaggio.message— una spiegazione leggibile dalle persone e sicura da registrare nei log. La formulazione può cambiare.param— presente quando l’errore è causato da un campo specifico della richiesta.
Codici di errore#
| HTTP | codice | Descrizione | Cosa fare | Riprova? |
|---|---|---|---|---|
| 400 | invalid_request | Il corpo non è JSON valido, manca un campo obbligatorio, un valore è fuori intervallo o non è consentito, il corpo contiene un parametro sconosciuto, un riferimento nel prompt non punta a nulla, oppure un file video/audio di riferimento non è leggibile o supera i limiti del modello (durata, dimensioni, risoluzione, frequenza dei fotogrammi). param indica il campo che ha causato l’errore. | Correggi la richiesta: il messaggio spiega esattamente cosa non va. | Dopo aver corretto |
| 401 | unauthorized | La chiave API manca, non è valida o è stata revocata. | Controlla l’intestazione Authorization: Bearer e verifica che la chiave sia attiva. | Dopo aver corretto |
| 402 | insufficient_balance | Il saldo non copre il prezzo di questa generazione. Non è stato addebitato nulla. | Aggiungi crediti o attiva la ricarica automatica in Dashboard → Fatturazione. Consulta Fatturazione. | Dopo aver corretto |
| 404 | not_found | L'ID dell'endpoint, il modello o la generazione non esiste oppure la generazione appartiene a un altro account. | Confronta l’ID con l’elenco dei modelli. | No |
| 409 | conflict | La richiesta è in conflitto con lo stato della risorsa, in genere perché si tenta di annullare una generazione già in esecuzione o terminata. | Leggi la generazione per verificarne lo stato attuale. | No |
| 410 | model_delisted | Il modello non è più disponibile. Non è stato inviato né addebitato nulla; le generazioni precedenti restano consultabili. | Scegli un altro modello dall’elenco dei modelli. | No |
| 429 | rate_limited | Troppe richieste al secondo, oppure la tua coda di generazioni in attesa di partire è piena. | Attendi un po’ e riprova. Consulta Limiti di frequenza. | Riprova con backoff |
| 500 | internal_error | Si è verificato un errore da parte nostra. | Riprova con backoff. Se il problema persiste, contatta l'assistenza indicando l'ora della richiesta. | Riprova con backoff |
| 501 | direct_upload_unavailable | I caricamenti diretti (con URL prefirmati) non sono disponibili in questa distribuzione. | Carica invece con multipart/form-data. Consulta Caricamenti. | No |
| 502 | — | Errore del gateway o della rete prima che la richiesta raggiungesse la nostra API (raro). Gli errori dei modelli a monte non vengono restituiti come errori HTTP: la generazione non va a buon fine e include un motivo. | Riprova con backoff. Non è stato addebitato nulla. | Riprova con backoff |
| 503 | model_unavailable | Il modello al momento non accetta nuove generazioni. | Riprova più tardi o cambia modello. Controlla la pagina di stato. | Riprova con backoff |
| 503 | pricing_unavailable | Non è stato possibile leggere i prezzi per un breve periodo, quindi la richiesta non è stata prezzata. Non è stato inviato né addebitato nulla. | Riprova la stessa richiesta dopo qualche secondo (la risposta include l'intestazione Retry-After), usando lo stesso Idempotency-Key. | Riprova con backoff |
| 503 | fallback_price_declined | La capacità abituale non è disponibile: al momento è disponibile solo il prezzo di emergenza (al massimo il prezzo ufficiale) e hai inviato allow_fallback_price: false. Non è stato addebitato nulla; il messaggio mostra entrambi i prezzi. | Riprova più tardi per ottenere il prezzo standard, oppure invia allow_fallback_price: true (predefinito) per accettare il prezzo di emergenza. | Riprova con backoff |
| 400 | max_cost_exceeded | Il prezzo, incluso quello di emergenza, supera il tuo max_cost_usd. Non è stato addebitato nulla. | Riduci la risoluzione o la durata, oppure verifica il prezzo e aumenta max_cost_usd. | Dopo aver corretto |
Errori durante una generazione#
Un errore HTTP indica che la richiesta è stata rifiutata e non è stato addebitato nulla. È diverso da una generazione accettata che non riesce in seguito: la chiamata API è riuscita (anche se POST /run restituisce 202 quando un job fallisce subito) e lo status della generazione diventa failed con un oggetto error. L’importo bloccato viene rimborsato automaticamente. Lo stesso oggetto compare in GET /generations, nel payload di webhook e nei risultati degli strumenti MCP.
{
"status": "failed",
"error": {
"code": "generation_failed",
"message": "ByteDance's safety review for Seedance 2.0 Fast rejected this request (the prompt or an input file).",
"reason": "content_blocked",
"hint": "Describe the character's look instead of naming a copyrighted character or real person, keep it non-explicit, or try another model.",
"retryable": false,
"refunded": true,
"detail": "La richiesta non ha superato il controllo di sicurezza dei contenuti. Modifica il prompt e riprova."
}
}code è la categoria generale (i quattro valori documentati sin dal lancio). reason indica il motivo esatto: usalo nel codice e mostra message e hint agli utenti. retryable indica se un nuovo invio della stessa richiesta può funzionare, param specifica il campo da modificare quando riusciamo a identificarlo e detail contiene la formulazione del fornitore del modello.
| error.reason | error.code | Cosa è successo | Cosa fare | Reinviare così com'è? |
|---|---|---|---|---|
content_blocked | generation_failed | Il filtro di sicurezza del fornitore del modello ha rifiutato il prompt, un file di input o il risultato generato (per esempio un personaggio protetto da copyright, una persona reale o contenuti espliciti). Il messaggio indica a chi appartiene il filtro. | Riformula il prompt (descrivi l’aspetto invece di citare un personaggio, un marchio o una persona reale), usa altri file di input oppure prova un modello di un altro fornitore. Se invii di nuovo la richiesta senza modificarla, verrà rifiutata allo stesso modo. | No — modificalo prima |
invalid_input | generation_failed | Il modello non ha potuto accettare uno degli input o delle impostazioni: un file troppo grande, in un formato non supportato, con dimensioni o proporzioni errate, troppo lungo oppure un valore non supportato. param indica il campo, se riusciamo a identificarlo. | Correggi il campo indicato (consulta i limiti del modello nella relativa pagina API) e invia di nuovo la richiesta, oppure prova un altro modello. | No — modificalo prima |
input_unreachable | generation_failed | Non è stato possibile scaricare un URL di input: richiede l'accesso, il link firmato è scaduto, non punta direttamente al file oppure il server che lo ospita ha rifiutato la richiesta. Quando il servizio di generazione non riesce a scaricare un file, di solito lo scarichiamo noi e riproviamo usando la nostra copia; quindi, nella maggior parte dei casi, significa che non è stato possibile scaricare affatto il file. | Usa un URL pubblico che punti direttamente al file (oppure caricalo con POST /api/v1/uploads) e invia di nuovo la richiesta. | No — modificalo prima |
upstream_unavailable | upstream_error | Il fornitore del modello era non disponibile, sovraccarico o senza capacità; abbiamo provato tutti i percorsi idonei. | Riprova tra un minuto o due oppure usa un altro modello. | Sì |
upstream_error | upstream_error | Il fornitore ha riscontrato un errore interno durante la generazione, dopo che abbiamo provato tutti i percorsi idonei. | Riprova: di solito questi errori sono temporanei. Se il problema persiste, prova un altro modello. | Sì |
timeout | timeout | La generazione non è terminata in tempo (per il limite del fornitore o il nostro limite di 40 minuti). | Riprova. Le clip più brevi o a risoluzione inferiore si completano prima. | Sì |
output_unavailable | upstream_error | Il modello ha terminato, ma non ha restituito un file utilizzabile oppure non è stato possibile scaricare e salvare il risultato. | Retry. | Sì |
model_unavailable | model_unavailable | Il modello, o questa sua modalità, ha smesso di essere disponibile mentre la generazione era in corso. | Scegli un altro modello oppure riprova più tardi. | No — modificalo prima |
canceled | upstream_error | Il fornitore ha annullato o fatto scadere il job prima del completamento. (Una generazione che annulli tu ha stato canceled e non ha errori.) | Retry. | Sì |
generation_failed | generation_failed | Il modello si è interrotto senza restituire un risultato né spiegare il motivo. | Riprova una volta; se fallisce di nuovo, semplifica il prompt o gli input oppure prova un altro modello. | Sì |
Gli errori causati dalla richiesta — content_blocked, un file rifiutato in invalid_input, input_unreachable — non vengono riprovati presso altri fornitori, perché verrebbero rifiutati di nuovo. Prima vengono riprovate le interruzioni del servizio e gli errori dei fornitori su tutti i percorsi idonei, allo stesso prezzo. Consulta Errori e rimborsi.
Se il servizio di generazione non riesce a scaricare uno dei file di input, di solito proviamo a scaricarlo noi. Se ci riusciamo, il job viene ripetuto usando una copia ospitata da noi, allo stesso prezzo e senza che tu debba fare nulla; la generazione continua a mostrare gli URL che hai inviato e la copia viene eliminata insieme alla generazione secondo il relativo periodo di conservazione. Quindi input_unreachable di solito significa che non è stato possibile scaricare affatto il file: richiede l'accesso, il link firmato è scaduto, non punta direttamente al file oppure il server che lo ospita ha rifiutato la richiesta. Copiamo immagini fino a 30 MB, video fino a 200 MB e audio fino a 50 MB; un file più grande o illeggibile genera l'errore invalid_input.
Riprovare in sicurezza#
Riprova 429, 500, 502 e 503 con backoff esponenziale e jitter. Non riprovare senza modifiche gli altri errori 4xx: falliranno allo stesso modo.
L'invio non è idempotente
Ogni POST /run/{endpoint} riuscito crea e addebita una nuova generazione. Se l’invio va in timeout per un problema di rete e non sai se la richiesta è stata accettata, controlla le tue generazioni recenti prima di inviarla di nuovo.
const RETRYABLE = new Set([429, 500, 502, 503]);
export async function postWithRetry(url, headers, body, attempts = 5) {
let resp;
for (let attempt = 0; attempt < attempts; attempt++) {
resp = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) });
if (!RETRYABLE.has(resp.status)) break;
// exponential backoff with jitter: ~1s, 2s, 4s, 8s…
await new Promise((r) => setTimeout(r, Math.min(2 ** attempt, 30) * 1000 + Math.random() * 1000));
}
const data = await resp.json();
if (!resp.ok) throw new Error(`${resp.status} ${data.error.code}: ${data.error.message}`);
return data;
}Esempi di convalida#
I messaggi di convalida indicano il campo e i valori consentiti, così puoi mostrarli direttamente agli sviluppatori:
[
{
"error": {
"code": "invalid_request",
"message": "\"prompt\" is required",
"param": "prompt"
}
},
{
"error": {
"code": "invalid_request",
"message": "Unknown parameter \"resoluton\"",
"param": "resoluton"
}
},
{
"error": {
"code": "not_found",
"message": "Unknown endpoint \"bytedance/seedance-2.0-fast/text-to-gif\". See GET /api/v1/models."
}
}
]Puoi anche calcolare il prezzo senza eseguire la richiesta: POST /api/v1/quote/{endpoint} convalida i campi che incidono sul prezzo e restituisce il costo. Consulta il Riferimento API.
Qualcosa non è chiaro o manca? Scrivi a support@cheapergen.com: leggiamo ogni messaggio.