Zadania
Jak utworzyć zadanie, śledzić jego stan, odczytać wynik i korzystać z wait, listy zadań, retry i purge.
Każde generowanie to zadanie. Tworzysz je jednym wywołaniem, dalej działa samo, a wynik odbierasz, gdy jest gotowy — odpytując, czekając już przy pierwszym wywołaniu albo odbierając webhook.
POST /jobs/createTasktaskIdGET /jobs/recordInfostateGET output.assets[].url
Utwórz zadanie
curl -X POST "https://api.popnow.ai/api/v1/jobs/createTask" \
-H "Authorization: Bearer $POPNOW_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"model": "alibaba/wan-3.0/image-to-video",
"input": {
"image_url": "https://media.popnow.ai/movie/lighthouse.webp",
"prompt": "Waves roll in slowly, the camera drifts toward the lighthouse",
"resolution": "480p",
"duration_seconds": 5
},
"callBackUrl": "https://your-app.example.com/hooks/popnow"
}'Treść
| Pole | Wymagane | Co to jest |
|---|---|---|
model | Tak | ID modelu ze strony Modele |
input | Tak | Pola danego modelu, sprawdzane jego schematem wejściowym |
callBackUrl | Nie | Publiczny adres HTTPS, który odbierze gotowe zadanie. Zobacz Webhooki |
quoteId, expectedCredits | Nie | Zablokuj cenę potwierdzoną przez jobs/quote |
Nagłówki
| Nagłówek | Co to jest |
|---|---|
Authorization: Bearer sk-popnow-… | Twój klucz API |
Idempotency-Key | Bardzo zalecany. Ponowienie z tym samym kluczem zwraca pierwotne zadanie. Zobacz Idempotencja |
X-PopNow-Retention | Opcjonalny. Ile sekund przechowywać wyniki i prompt tego zadania. Może tylko skrócić przechowywanie, nigdy go nie wydłuża |
Accept-Language | Opcjonalny. Język komunikatów o błędach. Zobacz Błędy |
Odpowiedź
Nowe zadanie wraca jako HTTP 202:
{
"code": 200,
"msg": "success",
"data": {
"taskId": "job_01JH8Z4Q5W2N7R3K9M6P1C0VXD",
"state": "queued",
"estimatedCredits": 34,
"estimatedCost": "0.34",
"deadlineAt": "2026-10-16T09:40:00Z"
},
"request_id": "req_…"
}202 oznacza przyjęte, nie ukończone. estimatedCredits to kwota zablokowana na twoim saldzie — najwięcej, ile może kosztować to zadanie (estimatedCost to ta sama kwota w dolarach). Jeśli utworzenie się nie uda, nic nie powstaje i nic nie jest blokowane; powód podaje code (Błędy).
Stany
queuedrunningsucceededfailedexpired| Stan | Końcowy? | Znaczenie |
|---|---|---|
queued | Nie | Przyjęte, czeka na start |
running | Nie | W trakcie generowania |
succeeded | Tak | Gotowe; pliki są w output.assets |
failed | Tak | Nie udało się dokończyć; zobacz errorCode i errorMessage. Blokada jest zwalniana |
expired | Tak | Przekroczyło termin, nie kończąc pracy. Blokada jest zwalniana |
canceled | Tak | Tylko w starych rekordach. Przyjętego zadania nie da się dziś anulować |
Każdy nieznany stan traktuj jako „jeszcze się nie skończyło” i odpytuj dalej.
Bez odpytywania: wait
Dodaj ?wait=<sekundy> (do 60) do createTask, a połączenie zostanie otwarte, aż zadanie się skończy albo minie czas:
- Skończyło się na czas → HTTP
200z pełnym rekordem zadania, w tym samym formacie corecordInfo. Sprawdźdata.state: stan końcowy nie zawsze oznacza sukces. - Nie skończyło się → zwykłe
202, a ty odpytujesz dalej albo czekasz na webhook.
Sprawdza się przy obrazach i krótkim audio; wideo prawie zawsze trwa dłużej niż 60 sekund. Wcześniejsze zerwanie połączenia nie zatrzymuje ani nie anuluje zadania.
Odczytaj zadanie
curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=job_01JH8Z4Q5W2N7R3K9M6P1C0VXD" \
-H "Authorization: Bearer $POPNOW_API_KEY"| Pole | Znaczenie |
|---|---|
taskId, model, state | Które zadanie, który model i na jakim jest etapie |
input | Dane wejściowe w postaci, w jakiej zadanie działało, łącznie z wybranym seed, jeśli go nie podałeś |
output.assets[] | Pliki. Każdy ma url, expiresAt, mime, a gdy to ma sens także width, height, durationSeconds, bytes, role |
errorCode, errorMessage | Dlaczego zadanie się nie powiodło. Rozgałęziaj według errorCode, pokazuj errorMessage |
credits, cost, settled | Dopóki settled ma wartość false, credits to blokada; przy true — ostateczne obciążenie. cost to ta sama kwota w dolarach |
createdAt, completedAt, deadlineAt | Znaczniki czasu; deadlineAt to chwila, w której niedokończone zadanie wygaśnie |
retention.outputsExpireAt | Kiedy pliki tego zadania zostaną usunięte |
contentState | present albo expired / purged, gdy treść usunięto |
Trzy różne terminy
deadlineAt— jak długo zadanie może działać. Potem przechodzi wexpired, a blokada jest zwalniana.output.assets[].expiresAt— jak długo działa ten jeden podpisany link, około 20 minut. Odczytaj zadanie ponownie, by dostać nowy; sam plik nadal istnieje.retention.outputsExpireAt— kiedy zapisany plik zostanie usunięty. Pobierz wcześniej to, co chcesz zachować, albo zapisz to w bibliotece zasobów.
Co zawiera output
Większość zadań zwraca jeden plik. Niektóre więcej: kilka obrazów, gdy model tworzy warianty; przy przedłużaniu wideo najpierw połączony klip, a potem sam nowy fragment (role: "video", potem role: "segment"); przy rozdzielaniu na warstwy obraz bazowy i przezroczyste warstwy (każda z obiektem layer). Transkrypcja mowy trafia do output.text.
Linki do plików działają na okaziciela: każdy, kto ma URL, może pobrać plik, dopóki link nie wygaśnie. Nie wysyłaj klucza API przy pobieraniu.
Najpierw webhooki, odpytywanie awaryjnie
Odpytywanie działa, ale webhook jest tańszy dla obu stron: wiesz o wyniku od razu i nie zużywasz po drodze zapytań. Solidna integracja korzysta z obu — webhooków na co dzień i od czasu do czasu przeglądu przez recordInfo zadań, których webhook nie dotarł.
Jeśli odpytujesz, nie spiesz się: co 2–3 sekundy dla obrazów, co 10–15 sekund dla wideo, i przestań przy deadlineAt.
Lista zadań
GET /api/v1/jobs zwraca zadania utworzone tym kluczem, od najnowszych, bez danych wejściowych i wyników:
curl "https://api.popnow.ai/api/v1/jobs?state=failed&from=2026-10-01&limit=50" \
-H "Authorization: Bearer $POPNOW_API_KEY"Filtry: from i to (daty UTC, najwyżej 92 dni odstępu; domyślnie ostatnie siedem dni), state, model, limit (do 100). Gdy hasMore ma wartość true, przekaż nextCursor jako cursor z tymi samymi filtrami.
Ponów nieudane zadanie
POST /api/v1/jobs/retry z { "taskId": "…" } tworzy nowe zadanie z zadania failed lub expired, z jego pierwotnymi danymi wejściowymi i po dzisiejszej cenie. Pierwotne zadanie nigdy się nie zmienia. Dopóki zadanie źródłowe nie jest końcowe, odpowiedź to 409; zadania zakończonego sukcesem nie da się ponowić — utwórz nowe.
Usuń treść zadania
POST /api/v1/jobs/purge z { "taskId": "…" } usuwa pliki zadania, jego wynik i zapisany prompt. Wpis rozliczeniowy zostaje: kwota, model, stan i znaczniki czasu pozostają, a odpowiedź potwierdza to polem billingRetained: true. Usunąć można tylko zakończone zadania, a powtórzenie wywołania jest bezpieczne.

