PopNowDocs API
Riferimento
Contenuto principale

Errori

Ogni codice applicativo, cosa significa e quali errori vale la pena ritentare.

Quando una chiamata non va a buon fine, la risposta ti dà un numero (code) che indica il tipo di problema e una frase (msg) pensata per una persona. Decidi in base al numero; mostra o registra la frase.

L’involucro

{ "code": 40201, "msg": "Insufficient balance", "request_id": "req_…" }
  • code è un codice applicativo. 200 significa successo; tutto il resto è elencato qui sotto.
  • In caso di errore non c’è il campo data, tranne per alcuni errori della libreria di asset che aggiungono data.reason.
  • Anche lo stato HTTP è impostato (40201 arriva con HTTP 402). Decidi in base a uno dei due, senza mescolarli: ti consigliamo code, più preciso.
  • request_id è anche nell’header X-Request-Id. Indicalo quando contatti l’assistenza.

Se una risposta non è proprio JSON — una pagina HTML o di testo dalla rete intermedia —, gestiscila in base allo stato HTTP e registra l’inizio del corpo.

Lingua dei messaggi di errore

msg e l’errorMessage di un’attività fallita sono in inglese per impostazione predefinita. Invia Accept-Language con en, ja, ko, de, fr, es, pt-BR, ru, it o pl, oppure imposta la lingua degli errori API nella console, per riceverli in quella lingua; le altre tornano all’inglese. Le risposte di errore riportano Content-Language. I codici non cambiano mai con la lingua: un motivo in più per non analizzare mai msg.

Quando un modello indica un motivo preciso per il fallimento (per esempio un’immagine di riferimento illeggibile), errorMessage lo riporta in inglese, senza dettagli interni.

Codici generali

codeHTTPSignificatoRitentare?
200200 / 202Successo—
400400La richiesta o il suo input non sono validi; msg indica il problemaNo — correggi
40003400Un caricamento non corrisponde al suo ticket (dimensione, tipo o contenuto)No — nuovo ticket, nuovo caricamento
40004400Richiesta valida, ma il modello ora non può gestire questa combinazione di impostazioniNo — cambia l’impostazione citata in msg
401401Chiave mancante, sconosciuta o revocata (dettagli)No
403403Non consentito (vedi Permessi)No
404404Non esiste o appartiene a un’altra chiaveNo
409409Conflitto con lo stato attuale (quando ritentare)A volte
40901409Un preventivo è scaduto o il prezzo è cambiatoRichiedi un nuovo preventivo
413413Corpo della richiesta troppo grandeNo — carica i media invece di incorporarli
429429Troppe richiesteSì — dopo Retry-After
500500Qualcosa si è rotto da parte nostraSì — con attesa crescente
503503Un servizio di supporto è momentaneamente non disponibileSì — dopo Retry-After

Saldo e tetti

codeHTTPSignificatoCosa fare
40201402Crediti insufficienti per la trattenuta di questa attivitàAcquista crediti e reinvia
40202402È stato raggiunto un tetto di spesa della chiaveAlzalo nella console API o aspetta l’azzeramento

Permessi

codeHTTPSignificatoCosa fare
40301403Questa chiave non può chiamare questo modelloAggiungi il modello ai modelli consentiti della chiave
40302403La richiesta arriva da un indirizzo fuori dalla lista di IP consentitiAggiungi l’indirizzo o togli la restrizione
40303403Il servizio non è offerto in questa regioneNon si può aggirare
40310403L’indirizzo email dell’account non è ancora verificatoApri il link nell’email di registrazione; la chiave funziona appena è verificato

Un semplice 403 con una chiave valida significa che l’account al momento non può usare l’API; contatta l’assistenza con il request_id.

Disponibilità dei modelli

codeHTTPSignificatoRitentare?
50301503Il modello ora non può accettare attivitàSì, più tardi — o scegli un altro modello
40004400Il modello funziona, ma non con queste impostazioniNo — cambia l’impostazione

Nessuno dei due crea un’attività o trattiene crediti.

Codici di errore delle attività

Un’attività accettata che poi fallisce ha state: "failed" e uno di questi valori in errorCode. L’elenco è chiuso: tratta qualsiasi altro valore come upstream_failed.

errorCodeSignificatoRitentare?
invalid_requestIl modello non ha accettato i parametriNo — correggili
unsupported_combinationQuesta combinazione di impostazioni ora non è supportataNo — cambia un’impostazione
content_rejectedIl modello ha rifiutato questo contenutoNo — cambia il prompt o il riferimento
invalid_assetUn file di riferimento non è leggibile o non è più disponibileCaricalo di nuovo e crea una nuova attività
rate_limitedIl servizio di generazione era sovraccaricoSì, con attesa crescente
upstream_unavailableLa generazione è temporaneamente non disponibileSì, tra poco
generation_failedLa generazione è partita ma non ha prodotto nullaForse — lo stesso input spesso fallisce allo stesso modo
timeoutL’attività ha esaurito il tempoForse — prova un output più breve o a risoluzione più bassa
upstream_failedTutto il restoSì, con attesa crescente

Un’attività fallita rilascia la trattenuta e quindi non costa nulla (pochi modelli addebitano i rifiuti per contenuto e lo indicano nella loro pagina). errorMessage spiega il motivo a parole; decidi solo in base a errorCode.

Quando conviene ritentare un 409

CasoRitentare?
Due richieste con lo stesso Idempotency-Key sono arrivate insiemeSì, con la stessa chiave, dopo una breve pausa
L’Idempotency-Key è stato usato per un’altra richiesta o da un’altra chiaveNo
Un caricamento o un risultato è ancora in elaborazioneSì, dopo qualche secondo
jobs/retry su un’attività non ancora conclusaSì, quando è definitiva
jobs/retry su un’attività riuscitaNo — crea una nuova attività
Un ticket di caricamento o un file caricato è scadutoNo — caricalo di nuovo

Scrivere il nuovo tentativo

Ritenta solo ciò che può riuscire al secondo tentativo, aspetta Retry-After quando c’è e altrimenti aumenta l’attesa in modo esponenziale:

JavaScript
const RETRYABLE = new Set([429, 500, 503, 50301]);

async function call(path, init, attempts = 4) {
  for (let i = 0; i < attempts; i++) {
    const res = await fetch(`https://api.popnow.ai/api/v1${path}`, init);
    if (!res.headers.get('content-type')?.includes('json')) {
      throw new Error(`HTTP ${res.status}: ${(await res.text()).slice(0, 200)}`);
    }
    const body = await res.json();
    if (body.code === 200) return body.data;
    if (!RETRYABLE.has(body.code)) throw new Error(`${body.code} ${body.msg} (${body.request_id})`);
    const wait = Number(res.headers.get('retry-after')) * 1000 || 2 ** i * 1000 + Math.random() * 500;
    await new Promise((r) => setTimeout(r, wait));
  }
  throw new Error('out of retries');
}
Python
import random, time, requests

RETRYABLE = {429, 500, 503, 50301}

def call(method, path, attempts=4, **kwargs):
    for i in range(attempts):
        res = requests.request(method, f"https://api.popnow.ai/api/v1{path}", timeout=60, **kwargs)
        try:
            body = res.json()
        except ValueError:
            raise RuntimeError(f"HTTP {res.status_code}: {res.text[:200]}")
        if body["code"] == 200:
            return body["data"]
        if body["code"] not in RETRYABLE:
            raise RuntimeError(f'{body["code"]} {body["msg"]} ({body.get("request_id")})')
        retry_after = res.headers.get("retry-after")
        time.sleep(float(retry_after) if retry_after else 2**i + random.random() / 2)
    raise RuntimeError("out of retries")

Quando ritenti createTask, invia sempre lo stesso Idempotency-Key, così una richiesta che in realtà era riuscita non viene eseguita né addebitata due volte.

Diagnosi

  1. Annota request_id e code.
  2. Cerca l’attività nei log della console API, per ID attività o request_id.
  3. Ancora bloccato? Contatta l’assistenza con request_id, ora (UTC) e code. Non inviare mai la tua chiave API.

In questa pagina