Vidu, Wan 3.0 and Sume job states in one poller

Vidu says created/queueing/processing/success/failed, Wan says PENDING/RUNNING/SUCCEEDED/FAILED, Sume says pending/in_progress/completed. One mapping table.

4 min readSume
All posts

If you poll more than one video API, normalize the state names once and branch on your own words. Vidu Q4 Preview reports created, queueing, processing, success or failed; Alibaba's Wan 3.0 reports PENDING, RUNNING, SUCCEEDED or FAILED; a Sume /v1/videos job reports pending, in_progress, completed, failed or cancelled.

Which state names does each API use?

Both vendor lists come from their own API pages. The Sume list comes from the video generation docs.

Task states by API (vendor pages and Sume docs read 2026-10-09)
MeaningVidu Q4 PreviewWan 3.0 (Model Studio)Sume /v1/videos
Accepted, not startedcreated, queueingPENDINGpending
GeneratingprocessingRUNNINGin_progress
Done, file availablesuccessSUCCEEDEDcompleted
FailedfailedFAILEDfailed
Canceled before startnot listed on the pagenot listed on the pagecancelled

Why is the spelling worth a mapping table?

Sume has two vocabularies. The video endpoint says pending and in_progress. The generic jobs endpoint, GET /v1/jobs/:id/status, lists queued and processing as non-terminal and completed, failed and canceled as terminal (one l). A poller written for one will spin forever on the other if it only checks for completed.

What does the mapping look like in code?

Keep the raw value for logs and branch on the normalized one. Unknown strings fall through unchanged, so a new vendor state does not crash the loop.

NORMAL = {
    "created": "pending", "queueing": "pending", "queued": "pending",
    "processing": "in_progress", "in_progress": "in_progress",
    "success": "completed", "completed": "completed",
    "failed": "failed",
    "canceled": "cancelled", "cancelled": "cancelled",
    "PENDING": "pending", "RUNNING": "in_progress",
    "SUCCEEDED": "completed", "FAILED": "failed",
}
DONE = {"completed", "failed", "cancelled"}

def normalize(raw):
    return NORMAL.get(raw, raw)

for raw in ["queueing", "RUNNING", "success", "cancelled", "weird"]:
    s = normalize(raw)
    print(raw, "->", s, "stop" if s in DONE else "keep polling")

Which state should end the loop?

Stop on any terminal value: completed, failed or cancelled. Read the download URL only after completed; the video generation docs list the job statuses and what each one means.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume