Attività
Crea un’attività, seguine lo stato, leggi il risultato e usa wait, l’elenco delle attività, retry e purge.
Ogni generazione è un’attività. La crei con una chiamata, procede da sola e ritiri il risultato quando è pronto: chiedendolo, aspettando già nella prima chiamata o ricevendo un webhook.
POST /jobs/createTasktaskIdGET /jobs/recordInfostateGET output.assets[].url
Crea un’attività
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"
}'Corpo
| Campo | Obbligatorio | Cos’è |
|---|---|---|
model | Sì | L’ID del modello, in Modelli |
input | Sì | I campi del modello, validati con il suo schema di input |
callBackUrl | No | URL HTTPS pubblico che riceve l’attività completata. Vedi Webhook |
quoteId, expectedCredits | No | Blocca un prezzo confermato con jobs/quote |
Header
| Header | Cos’è |
|---|---|
Authorization: Bearer sk-popnow-… | La tua chiave API |
Idempotency-Key | Fortemente consigliato. Un nuovo tentativo con la stessa chiave restituisce l’attività originale. Vedi Idempotenza |
X-PopNow-Retention | Facoltativo. Per quanti secondi conservare i risultati e il prompt di questa attività. Può solo accorciare la conservazione, mai allungarla |
Accept-Language | Facoltativo. Lingua dei messaggi di errore. Vedi Errori |
Risposta
Una nuova attività torna come 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 significa accettata, non completata. estimatedCredits è l’importo trattenuto dal tuo saldo: il massimo che questa attività può costare (estimatedCost è lo stesso importo in dollari USA). Se la creazione fallisce, non viene creato né trattenuto nulla; il code ti dice perché (Errori).
Stati
queuedrunningsucceededfailedexpired| Stato | Finale? | Significato |
|---|---|---|
queued | No | Accettata, in attesa di partire |
running | No | In generazione |
succeeded | Sì | Fatto; i file sono in output.assets |
failed | Sì | Non è riuscita a terminare; vedi errorCode ed errorMessage. La trattenuta viene rilasciata |
expired | Sì | Ha superato la scadenza senza finire. La trattenuta viene rilasciata |
canceled | Sì | Solo nei vecchi record. Oggi un’attività accettata non si può annullare |
Considera ogni stato che non riconosci come «non ancora finita» e continua a interrogare.
Evita il polling con wait
Aggiungi ?wait=<secondi> (fino a 60) a createTask: la connessione resta aperta finché l’attività non termina o il tempo non scade.
- Finita in tempo → HTTP
200con il record completo dell’attività, nello stesso formato direcordInfo. Controlladata.state: finale non vuol dire sempre riuscita. - Non finita → il solito
202, e continui a interrogare o aspetti il webhook.
Adatto a immagini e audio brevi; un video supera quasi sempre i 60 secondi. Chiudere prima la connessione non ferma né annulla l’attività.
Leggi un’attività
curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=job_01JH8Z4Q5W2N7R3K9M6P1C0VXD" \
-H "Authorization: Bearer $POPNOW_API_KEY"| Campo | Significato |
|---|---|
taskId, model, state | Quale attività, quale modello, a che punto è |
input | L’input come è stato eseguito, compreso il seed scelto se non ne hai inviato uno |
output.assets[] | I file. Ognuno ha url, expiresAt, mime e, quando serve, width, height, durationSeconds, bytes, role |
errorCode, errorMessage | Perché l’attività è fallita. Decidi con errorCode, mostra errorMessage |
credits, cost, settled | Finché settled è false, credits è la trattenuta; con true è l’addebito finale. cost è lo stesso importo in dollari |
createdAt, completedAt, deadlineAt | Orari; deadlineAt è quando scade un’attività non finita |
retention.outputsExpireAt | Quando verranno eliminati i file di questa attività |
contentState | present, oppure expired / purged dopo la rimozione del contenuto |
Tre scadenze diverse
deadlineAt— per quanto tempo l’attività può girare. Oltre, diventaexpirede la trattenuta viene rilasciata.output.assets[].expiresAt— per quanto funziona quel link firmato, circa 20 minuti. Rileggi l’attività per averne uno nuovo; il file c’è ancora.retention.outputsExpireAt— quando il file salvato viene eliminato. Scarica prima ciò che vuoi tenere o salvalo nella tua libreria di asset.
Cosa contiene output
La maggior parte delle attività restituisce un file. Alcune ne restituiscono di più: più immagini quando il modello crea varianti; per l’estensione video prima la clip unita e poi il nuovo segmento (role: "video" e poi role: "segment"); per la separazione in livelli un’immagine di base più livelli trasparenti (ognuno con un oggetto layer). La trascrizione vocale arriva in output.text.
I link dei file sono link al portatore: chiunque abbia l’URL può scaricare il file fino alla scadenza. Non inviare la chiave API quando li scarichi.
Prima i webhook, il polling come riserva
Il polling funziona, ma un webhook costa meno a entrambe le parti: sai del risultato appena esiste e nel frattempo non consumi richieste. Un’integrazione solida usa entrambi: i webhook per il percorso normale e, ogni tanto, un passaggio con recordInfo sulle attività il cui webhook non è arrivato.
Se interroghi, fallo con calma: ogni 2–3 secondi per le immagini, ogni 10–15 secondi per i video, e fermati a deadlineAt.
L’elenco delle attività
GET /api/v1/jobs restituisce le attività create da questa chiave, dalle più recenti, senza input né risultati:
curl "https://api.popnow.ai/api/v1/jobs?state=failed&from=2026-10-01&limit=50" \
-H "Authorization: Bearer $POPNOW_API_KEY"Filtri: from e to (date UTC, al massimo 92 giorni di distanza; di default gli ultimi sette giorni), state, model, limit (fino a 100). Quando hasMore è true, passa nextCursor come cursor con gli stessi filtri.
Ritenta un’attività fallita
POST /api/v1/jobs/retry con { "taskId": "…" } crea una nuova attività a partire da una failed o expired, con l’input originale e il prezzo di oggi. L’attività originale non viene mai modificata. Risponde 409 finché l’attività di origine non è finale, e non può ritentare un’attività riuscita: creane una nuova.
Elimina il contenuto di un’attività
POST /api/v1/jobs/purge con { "taskId": "…" } elimina i file, il risultato e il prompt salvato dell’attività. Il record di fatturazione resta: importo, modello, stato e orari rimangono, e la risposta lo conferma con billingRetained: true. Si possono eliminare solo attività concluse, e ripetere la chiamata è sicuro.

