PopNowAPI-Doku
Erste Schritte
Hauptinhalt

Schnellstart

API-Schlüssel erstellen, die erste Anfrage senden und das Ergebnis herunterladen – in etwa fünf Minuten.

Diese Seite bringt dich mit einem Schlüssel und einer Anfrage zu deinem ersten generierten Bild. Alles Weitere – Video, Audio, Webhooks, Uploads – ist dieselbe Anfrage mit anderem model und anderem input.

Bevor du loslegst

  • Ein PopNow-Konto. Registriere dich auf popnow.ai. Die Gratis-Credits zur Anmeldung funktionieren auch mit der API; wenn du mehr brauchst, kaufst du ein Credit-Paket. Einen eigenen API-Tarif gibt es nicht.
  • Ein Terminal mit curl. Die Beispiele nutzen bash. Unter Windows nimm WSL oder Git Bash.

1. API-Schlüssel erstellen

Öffne die API-Konsole und wähle Create key. Kopiere den Schlüssel sofort – der vollständige Wert wird nur einmal angezeigt. Leg ihn dann in eine Umgebungsvariable, damit er nie im Code landet:

export POPNOW_API_KEY="sk-popnow-..."

Jeder Schlüssel beginnt mit sk-popnow- und verbraucht die Credits deines Kontos. Bewahre ihn nur auf deinem Server auf; Einschränkungen, Rotation und was bei einem Leck zu tun ist, steht unter Authentifizierung.

2. Einen Task senden

Füge das in dasselbe Terminal ein. Es bittet ein schnelles Bildmodell um ein Bild und kostet ein, zwei Credits:

POST /api/v1/jobs/createTask?wait=60
export POPNOW_API_KEY="sk-popnow-..."   # your key from the API console

curl -X POST "https://api.popnow.ai/api/v1/jobs/createTask?wait=60" \
  -H "Authorization: Bearer $POPNOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "model": "alibaba/z-image-turbo/text-to-image",
  "input": {
    "prompt": "A small red fox curled up in a teacup, soft morning light, studio photo"
  }
}'

Was die einzelnen Teile tun:

  • model ist die Modell-ID – welches Modell läuft und welche Aufgabe es erledigt. Alle IDs findest du unter Modelle.
  • input wird gegen das Eingabeschema genau dieses Modells geprüft. Unbekannte Felder werden abgelehnt, ein Tippfehler fällt also sofort auf, statt still ignoriert zu werden.
  • Idempotency-Key macht Wiederholungen sicher: Schickst du nach einem Timeout denselben Schlüssel noch einmal, bekommst du den ursprünglichen Task zurück statt einer zweiten Abbuchung. Siehe Idempotenz.
  • ?wait=60 hält die Verbindung bis zu 60 Sekunden offen, sodass ein schnelles Bild direkt in dieser Antwort zurückkommt.

3. Ergebnis lesen

Ein fertiger Task sieht so aus:

200 · recordInfo / createTask?wait=60
{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "job_01JH8Z4Q5W2N7R3K9M6P1C0VXD",
    "model": "alibaba/z-image-turbo/text-to-image",
    "state": "succeeded",
    "output": {
      "assets": [
        {
          "url": "https://…signed-link…",
          "expiresAt": "2026-10-16T09:20:00Z",
          "mime": "image/png",
          "width": 1024,
          "height": 1024
        }
      ]
    },
    "credits": 2,
    "cost": "0.02",
    "settled": true
  },
  "request_id": "req_…"
}
  • state ist succeeded. Ein Task, der nicht fertig werden konnte, steht auf failed und trägt einen errorCode; siehe Fehler.
  • output.assets[0].url ist ein signierter Link zur Datei. Er gilt etwa 20 Minuten, braucht keinen API-Schlüssel, und einen frischen bekommst du jederzeit, indem du den Task erneut liest.
  • credits ist das, was der Task tatsächlich gekostet hat, in ganzen Credits (1 Credit = 0,01 $). cost enthält denselben Betrag als US-Dollar-String.

Braucht das Modell länger als 60 Sekunden – bei Videomodellen immer –, kommt stattdessen ein 202 mit state: "queued" und einer taskId. Frag den Task ab, bis er fertig ist:

curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=job_..." \
  -H "Authorization: Bearer $POPNOW_API_KEY"

Prüfe alle paar Sekunden, bis state auf succeeded, failed oder expired steht. In Produktion übergibst du besser eine callBackUrl und lässt dich per Webhook benachrichtigen.

Dieselbe Anfrage im Code

JavaScript (Node.js 18+)
const API = 'https://api.popnow.ai/api/v1';
const headers = {
  Authorization: `Bearer ${process.env.POPNOW_API_KEY}`,
  'Content-Type': 'application/json',
};

const created = await fetch(`${API}/jobs/createTask`, {
  method: 'POST',
  headers: { ...headers, 'Idempotency-Key': crypto.randomUUID() },
  body: JSON.stringify({
    model: 'alibaba/z-image-turbo/text-to-image',
    input: { prompt: 'A small red fox curled up in a teacup, soft morning light' },
  }),
}).then((r) => r.json());
if (created.code !== 200) throw new Error(`${created.code} ${created.msg}`);

// Poll until the task reaches a final state.
let task;
do {
  await new Promise((r) => setTimeout(r, 3000));
  const res = await fetch(`${API}/jobs/recordInfo?taskId=${created.data.taskId}`, { headers });
  task = (await res.json()).data;
} while (task.state === 'queued' || task.state === 'running');

console.log(task.state, task.output?.assets?.[0]?.url);
Python (requests)
import os, time, uuid, requests

API = "https://api.popnow.ai/api/v1"
headers = {"Authorization": f"Bearer {os.environ['POPNOW_API_KEY']}"}

created = requests.post(
    f"{API}/jobs/createTask",
    headers={**headers, "Idempotency-Key": str(uuid.uuid4())},
    json={
        "model": "alibaba/z-image-turbo/text-to-image",
        "input": {"prompt": "A small red fox curled up in a teacup, soft morning light"},
    },
    timeout=30,
).json()
if created["code"] != 200:
    raise RuntimeError(f'{created["code"]} {created["msg"]}')

# Poll until the task reaches a final state.
while True:
    time.sleep(3)
    task = requests.get(
        f"{API}/jobs/recordInfo",
        headers=headers,
        params={"taskId": created["data"]["taskId"]},
        timeout=30,
    ).json()["data"]
    if task["state"] not in ("queued", "running"):
        break

print(task["state"], task.get("output", {}).get("assets", [{}])[0].get("url"))

Die Antworthülle

Jede JSON-Antwort hat dieselben vier Felder:

{ "code": 200, "msg": "success", "data": { }, "request_id": "req_…" }

code ist ein Geschäftscode, kein HTTP-Status: 200 heißt Erfolg, alles andere steht unter Fehler. Verzweige nach code, nie nach dem Wortlaut von msg. Gib beim Support die request_id an.

Wie es weitergeht

Auf dieser Seite