PopNowAPI-Doku
Referenz
Hauptinhalt

Fehler

Jeder Geschäftscode, was er bedeutet und welche Fehler eine Wiederholung lohnen.

Wenn ein Aufruf schiefgeht, liefert die Antwort eine Zahl (code), die sagt, welche Art Problem es ist, und einen Satz (msg) für Menschen. Verzweige nach der Zahl; den Satz zeigst oder loggst du.

Die Antworthülle

{ "code": 40201, "msg": "Insufficient balance", "request_id": "req_…" }
  • code ist ein Geschäftscode. 200 heißt Erfolg, alles andere steht unten.
  • Bei Fehlern gibt es kein data-Feld – außer bei einigen Fehlern der Asset-Bibliothek, die data.reason mitliefern.
  • Auch der HTTP-Status ist gesetzt (40201 kommt mit HTTP 402). Verzweige nach einem der beiden, nicht nach einer Mischung – wir empfehlen das genauere code.
  • request_id steht auch im Header X-Request-Id. Gib sie an, wenn du den Support kontaktierst.

Ist eine Antwort gar kein JSON – etwa eine HTML- oder Textseite aus dem Netz dazwischen –, behandle sie nach HTTP-Status und logge den Anfang des Bodys.

Sprache der Fehlermeldungen

msg und die errorMessage eines fehlgeschlagenen Tasks sind standardmäßig Englisch. Schick Accept-Language mit en, ja, ko, de, fr, es, pt-BR, ru, it oder pl oder stell die API-Fehlersprache in der Konsole ein, dann kommen sie in dieser Sprache; andere Sprachen fallen auf Englisch zurück. Fehlerantworten tragen Content-Language. Die Codes ändern sich nie mit der Sprache – noch ein Grund, msg niemals zu parsen.

Meldet ein Modell einen konkreten Grund (etwa ein unlesbares Referenzbild), gibt errorMessage diesen Grund auf Englisch weiter, ohne interne Details.

Allgemeine Codes

codeHTTPBedeutungWiederholen?
200200 / 202Erfolg—
400400Anfrage oder input ungültig; msg nennt das ProblemNein – korrigieren
40003400Ein Upload passt nicht zu seinem Ticket (Größe, Typ oder Inhalt)Nein – neues Ticket, neu hochladen
40004400Gültige Anfrage, aber das Modell kann diese Kombination gerade nicht bedienenNein – die in msg genannte Einstellung ändern
401401Schlüssel fehlt, ist unbekannt oder widerrufen (Details)Nein
403403Nicht erlaubt (siehe Berechtigungen)Nein
404404Existiert nicht oder gehört zu einem anderen SchlüsselNein
409409Konflikt mit dem aktuellen Zustand (wann wiederholen)Manchmal
40901409Ein Angebot ist abgelaufen oder der Preis hat sich geändertNeu anfragen
413413Request-Body zu großNein – Medien hochladen statt einbetten
429429Zu viele AnfragenJa – nach Retry-After
500500Bei uns ist etwas kaputtgegangenJa – mit Backoff
503503Ein unterstützender Dienst ist kurz nicht erreichbarJa – nach Retry-After

Guthaben und Limits

codeHTTPBedeutungWas zu tun ist
40201402Nicht genug Credits für die Reservierung dieses TasksCredits kaufen, dann erneut senden
40202402Ein Ausgabelimit des Schlüssels ist erreichtLimit in der API-Konsole anheben oder auf den Reset warten

Berechtigungen

codeHTTPBedeutungWas zu tun ist
40301403Dieser Schlüssel darf dieses Modell nicht aufrufenModell zur Liste erlaubter Modelle hinzufügen
40302403Anfrage kam von einer Adresse außerhalb der IP-AllowlistAdresse hinzufügen oder Einschränkung entfernen
40303403Der Dienst wird in dieser Region nicht angebotenLässt sich nicht umgehen
40310403Die E-Mail-Adresse des Kontos ist noch nicht bestätigtLink aus der Anmelde-Mail öffnen; danach funktioniert der Schlüssel sofort

Ein einfaches 403 bei gültigem Schlüssel heißt, dass das Konto die API gerade nicht nutzen kann; melde dich mit der request_id beim Support.

Verfügbarkeit von Modellen

codeHTTPBedeutungWiederholen?
50301503Das Modell nimmt gerade keine Tasks anJa, später – oder ein anderes Modell wählen
40004400Das Modell läuft, aber nicht mit diesen EinstellungenNein – Einstellung ändern

Beide erzeugen keinen Task und reservieren keine Credits.

Fehlercodes von Tasks

Ein angenommener Task, der danach scheitert, hat state: "failed" und einen dieser Werte in errorCode. Die Liste ist abgeschlossen: Behandle jeden anderen Wert wie upstream_failed.

errorCodeBedeutungWiederholen?
invalid_requestDas Modell hat die Parameter nicht akzeptiertNein – korrigieren
unsupported_combinationDiese Kombination von Einstellungen wird gerade nicht unterstütztNein – eine Einstellung ändern
content_rejectedDas Modell hat diesen Inhalt abgelehntNein – Prompt oder Referenz ändern
invalid_assetEine Referenzdatei ließ sich nicht lesen oder ist nicht mehr verfügbarNeu hochladen und einen neuen Task anlegen
rate_limitedDer Generierungsdienst war ausgelastetJa, mit Backoff
upstream_unavailableGenerierung ist vorübergehend nicht verfügbarJa, gleich noch mal
generation_failedDie Generierung lief, hat aber nichts geliefertVielleicht – dieselbe Eingabe scheitert oft genauso
timeoutDer Task hatte keine Zeit mehrVielleicht – kürzere oder niedriger aufgelöste Ausgabe versuchen
upstream_failedAlles andereJa, mit Backoff

Ein gescheiterter Task gibt seine Reservierung frei und kostet also nichts (einige wenige Modelle berechnen inhaltliche Ablehnungen und sagen das auf ihrer Seite). errorMessage erklärt den Grund in Worten; verzweige nur nach errorCode.

Wann sich ein 409 zu wiederholen lohnt

FallWiederholen?
Zwei Anfragen mit demselben Idempotency-Key kamen gleichzeitig anJa, nach kurzer Pause mit demselben Schlüssel
Der Idempotency-Key wurde für eine andere Anfrage oder von einem anderen Schlüssel verwendetNein
Ein Upload oder eine Ausgabe wird noch verarbeitetJa, nach ein paar Sekunden
jobs/retry für einen Task, der noch nicht fertig istJa, sobald er beendet ist
jobs/retry für einen erfolgreichen TaskNein – einen neuen Task anlegen
Ein Upload-Ticket oder eine hochgeladene Datei ist abgelaufenNein – neu hochladen

Die Wiederholung schreiben

Wiederhole nur, was beim zweiten Mal klappen kann, warte auf Retry-After, wenn es mitkommt, und sonst exponentiell:

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")

Wenn du createTask wiederholst, schick immer denselben Idempotency-Key – sonst wird eine Anfrage, die eigentlich durchging, doppelt ausgeführt und doppelt berechnet.

Fehlersuche

  1. Notiere request_id und code.
  2. Such den Task in den Logs der API-Konsole, per Task-ID oder request_id.
  3. Kommst du nicht weiter? Kontaktiere den Support mit request_id, Uhrzeit (UTC) und code. Schick niemals deinen API-Schlüssel.

Auf dieser Seite