×
Community Blog Integrating Wan3.0 via API: Queues, Retries, and Cost Controls

Integrating Wan3.0 via API: Queues, Retries, and Cost Controls

Every platform team wiring Wan3.0 into internal tools faces the same question: how do you integrate an asynchronous video generation API without payin...

Integrating Wan3.0 via API: Queues, Retries, and Cost Controls, Wan3.0 Enterprise Video Playbook cover: the Wan3.0 key visual

A client that re-sends the create call on every timeout does not fail loudly. In the worked example below it adds $900 to a $4,000 month of Wan3.0 video, 22.5% of the bill, and no log line looks broken. The API is fine. The integration is the bill.

NAIVE CLIENT                        PRODUCTION CLIENT
create -> wait -> timeout           reserve budget -> create once
       -> create again (2 tasks)    store task_id before anything else
poll until done                     poll every 15 s, retry by status
use video_url when needed           archive the MP4 inside 24 hours
                                    settle actual seconds to the team
leak: $900 on $4,000 (22.5%)        leak: designed to be $0

Every generated second should be reserved before it is requested and accounted for after it is made.

In this guide

  • A five-part architecture for any async video generation API: intake, job store, submitter, poller, archiver
  • A fix for the orphan task, the billed generation your system never recorded
  • A retry table by task status and a rate-limit budget that accounts for polling
  • Per-team spend caps with worked math: reserve, submit, settle

01 · Why does a video generation API need a queue at all?

Wan3.0 does not answer in the same HTTP request that asks for the video.

The Wan3.0 Video Generation API Reference is explicit: you create a task with the X-DashScope-Async: enable header, receive output.task_id, then query the task until output.task_status reaches a final state (Alibaba Cloud Model Studio, Wan3.0 Video Generation API Reference, accessed Nov 13, 2026). The reference suggests polling about every 15 seconds. Task IDs and the returned video_url are valid for 24 hours, after which the video is purged.

That contract has three consequences for a platform team:

  1. State lives across minutes, not milliseconds. A request handler that blocks until the video exists will time out, and a timeout invites a retry.
  2. Money is committed at create time. Each created task can become a billable generation, priced per generated second.
  3. The output is perishable. If nobody copies the MP4 within 24 hours, it is gone, and the only way back is paying for it again.

So the unit of work is a job record with a lifecycle, not an API call. Article 06 in this series follows a video team's pipeline and review gates; this article is the code layer underneath, written for the engineer who owns it.

Wiring Wan3.0 into an internal tool this quarter? Walk through your task states, polling and archive path with the Wan team before the first producer gets an API key: Map your job states before launch →

Model the job, not the call.

02 · Draw the five-part architecture before you write the client

Five components, each with one job, keep the integration boring.

[Intake API] -> [Job store + spend ledger]
                     |
                [Submitter] --(rate limiter)--> POST video-synthesis
                     |
                 [Poller] --(every 15 s)------> GET tasks/{task_id}
                     |
                [Archiver] -> object storage + checksum + usage.duration
Component Owns Writes to the job record
Intake API Validating the request, assigning the idempotency key key, team, model, resolution, duration, prompt hash
Job store and ledger The single source of truth; reservations per team state, reserved amount, settled amount
Submitter The only code path allowed to call create task_id, request_id, submitted time
Poller Querying status on an interval, classifying results task_status, code, message
Archiver Copying the MP4 before expiry, settling cost storage path, checksum, usage.duration

Five components for a Wan3.0 integration; field names in code style come from the API reference. (Wan.)

Only the submitter can spend money. Product code never calls create directly; it inserts a job and walks away.

One code path spends; every other path reads.

03 · Make every submit idempotent and kill the orphan task

The most expensive bug in a video generation API integration is invisible.

I call it the orphan task: a generation the provider created, and can bill, whose task_id your system never recorded. The create call succeeds on the server, the response never reaches your code, and a retry creates a second task for the same take.

The reference itself says it plainly: "Do not create duplicate tasks. Instead, use polling to retrieve the result." The reference documents no idempotency field on the create request, so the guarantee has to live on your side.

# Intake: one key per intended take
key = hash(team_id, brief_id, take_no, model, resolution, duration, prompt)
INSERT job(key, state='QUEUED', ...)        # unique index on key
ON CONFLICT(key): return existing job       # a retry from the caller is a no-op

# Submitter
job = claim_one(state='QUEUED')             # row lock, so one worker wins
set job.state = 'SUBMITTING'                # written BEFORE the network call
resp = POST create(headers: X-DashScope-Async=enable,
                   body: {model, input: {prompt},
                          parameters: {resolution, duration}})
if resp has output.task_id:
    job.task_id = resp.output.task_id
    job.request_id = resp.request_id
    job.state = 'POLLING'
elif resp is a definite rejection (code + message returned):
    job.state = 'REJECTED'; release reservation
else:                                       # timeout, reset, no body
    job.state = 'UNCERTAIN'                 # never auto-resubmit

The UNCERTAIN state is the honest part. If you cannot know whether a task was created, do not guess by creating another.

Park, alert, decide. Park the job, alert its owner, and let a person decide. A stuck job costs one manual decision; a blind resubmit may cost a second billed generation.

When the create call's outcome is unknown, stop: never pay twice to find out.

04 · Retry by task status, not by habit

Each task status deserves its own action.

The reference lists six: PENDING, RUNNING, SUCCEEDED, FAILED, CANCELED and UNKNOWN.

Status Meaning for your job Action Re-create the task?
PENDING / RUNNING Work in progress Poll again in 15 s No
SUCCEEDED video_url returned Hand to the archiver now No
FAILED Generation did not complete Read code and message; classify Only if the class is transient, once
CANCELED Task ended without output Return to owner No, unless a person re-queues it
UNKNOWN Task not found or expired Check task age against 24 h No; route to UNCERTAIN review
Network error on the query Your call failed, not the task Back off and query again Never

Retry policy by Wan3.0 task status. (Wan.)

Two rules carry most of the value:

  1. A failed query is not a failed task. Back off and query again with the same task_id; re-creating would be an orphan by another name.
  2. Classify FAILED before retrying. An error caused by the input, such as a malformed parameter or a rejected reference, will fail again for the same reason. Retry only the classes you have seen succeed on a second attempt, and cap it at one.

Billing check. Before you set your retry budget, check in the billing console how failed tasks are treated for your account.

on poll_result(job, r):
    if r.output.task_status in ('PENDING', 'RUNNING'): schedule(job, 15s)
    elif r.output.task_status == 'SUCCEEDED': enqueue_archive(job, r)
    elif r.output.task_status == 'FAILED' and transient(r.code) and job.retries == 0:
        job.retries += 1; new_attempt(job)   # new key suffix, new reservation
    else: close(job, r.code, r.message); release_unspent(job)

Retry the network forever, the task once, and the input never.

05 · Budget the rate limit, including the polling tax

Wan3.0 publishes a limit of 300 requests per minute for both wan3.0-video and wan3.0-video-prime (Model Studio model pages, accessed Nov 13, 2026). Run your limiter well under it, for example at 80%: 300 x 0.8 = 240 requests per minute.

Then ask a question most teams skip: do your status queries count toward the same budget? Confirm it for your account. If they do, polling becomes the largest consumer, and I call that the polling tax.

Assumptions (illustrative). Limiter at 240 requests per minute; a 15-second poll interval means 60 / 15 = 4 queries per minute per task in flight. For the math only, assume a task stays in flight 5 minutes; measure yours.

Queries per created task      = 4 per minute x 5 minutes = 20
Requests per created task     = 1 create + 20 queries    = 21
Sustainable creates / minute  = 240 / 21                 = 11.4
A 500-job batch drains in     = 500 / 11.4               = about 44 minutes
If queries do not count       = 240 creates / minute     = about 2 minutes

Result: under these assumptions, polling is 20 of every 21 requests. Do not shorten the interval below the suggested 15 seconds to "speed things up"; it only spends the budget faster.

Three practices keep bursts from hurting:

  1. One shared token bucket across all workers, never per pod.
  2. Two lanes. Finals get a reserved share of the bucket so a draft burst cannot delay a deliverable.
  3. Back off on throttling with exponential backoff plus jitter, keeping the job QUEUED, not failed.

Spend your request budget on creates; spend your patience on polls.

06 · Archive every video before the 24-hour cliff

The returned video_url is valid for 24 hours and then purged, so the archive step belongs in the poller's success path, not in someone's afternoon.

  1. Copy on success. The moment status is SUCCEEDED, download the MP4 to your own object storage and record the path and a checksum.
  2. Verify, then mark done. Compare usage.duration and the file's actual length (with a video input, usage.duration also counts the input seconds). A job is only DONE when the archive copy exists.
  3. Sweep for stragglers. A scheduled job lists every SUCCEEDED-but-not-archived record older than, say, 12 hours and pages the owner, leaving half the window as margin.
  4. Never store the provider URL as the asset. Store it as a temporary download pointer with an expiry timestamp.

If it is not in your storage, you do not own it yet.

07 · Put per-team spend caps in the ledger: reserve, submit, settle

Spending decisions now sit with business teams: more than 80% of AI spending now sits outside enterprise IT (BCG, Applied AI Index 2026, September 2026). A shared Wan3.0 key with one monthly invoice cannot tell you which team spent what. The ledger can.

The loop is reserve, submit, settle:

  • Reserve at intake: duration x price per generated second for the requested model and resolution. Refuse the job if the team's remaining cap cannot cover it.
  • Submit only jobs holding a reservation.
  • Settle on archive: replace the reservation with usage.duration x price, and release the difference.

When duration is set to -1 (smart duration mode), reserve the maximum, 30 seconds, and let settlement return the rest.

Prices below are Alibaba Cloud Model Studio list prices, Singapore region, per generated second (accessed Nov 13, 2026): wan3.0-video $0.05 / $0.10 / $0.20 and wan3.0-video-prime $0.068 / $0.14 / $0.28 at 480P / 720P / 1080P.

Team Monthly cap Default model and resolution Price per second Reserve per 10 s job
Growth marketing $2,000 wan3.0-video, 720P $0.10 $1.00
Ecommerce catalog $1,500 wan3.0-video, 480P $0.05 $0.50
Brand finals $1,000 wan3.0-video-prime, 1080P $0.28 $2.80

Example per-team caps and reservations; smart duration on brand finals reserves 30 x $0.28 = $8.40. (Wan.)

Worked example: what the controls are worth. Assumptions (illustrative): 4,000 jobs a month, 10 seconds each, wan3.0-video at 720P; every duplicate task completes and is billed like any other.

Intended spend:     4,000 jobs x 10 s x $0.10            = $4,000
Orphan tasks:       4% of creates time out = 160 jobs,
                    each re-created twice = 320 tasks
                    320 x 10 s x $0.10                   =   $320
Expired URLs:       2% of outputs missed the 24 h window,
                    regenerated: 80 x 10 s x $0.10       =    $80
Runaway script:     one 500-job batch re-run by mistake
                    500 x 10 s x $0.10                   =   $500
                                                           ------
Leak without controls: $320 + $80 + $500                 =   $900
Leak as share of intended spend: $900 / $4,000           =  22.5%

Result: idempotency removes the $320, archiving removes the $80, and a team cap stops the $500 re-run at the cap instead of on the invoice. Alert each team at 80% of its cap and pause non-final work at 100%.

Find the leak in your own integration
Send your monthly job count, average duration, resolution mix and how your client handles timeouts today. The Wan team will walk through your orphan-task exposure, rate-limit budget and per-team caps with you. Price your Wan3.0 integration leaks →

Reserve before you request, settle after you archive.

08 · When should you not build this integration?

Not every Wan3.0 user needs a queue, a ledger and an archiver.

  1. Low, human-paced volume. A few generations a week, downloaded by hand, does not justify a job store.
  2. No internal owner. Async state machines need someone to carry the pager for UNCERTAIN jobs and straggler alerts. If no engineer owns it, a creative tool built on top of the API is the better buy. The build-or-partner reasoning is the same one we broke down in Build vs. Buy, or Both? The Enterprise AI Decision.
  3. One team, one budget. Skip per-team reservations and keep a single monthly cap with alerts; add the ledger when a second cost center appears.
  4. You need sub-second responses. Video generation runs asynchronously, so a user-facing flow must be designed around waiting: a notification, not a spinner.

Build the queue when the volume, the teams or the money demand it, not before.

09 · Ship the Wan3.0 video generation API integration this week

A one-week plan for a single engineer:

  1. Day 1: job store and keys. Create the job table with a unique idempotency key and the state machine: QUEUED, SUBMITTING, POLLING, UNCERTAIN, DONE, CLOSED.
  2. Day 2: submitter. One code path calls create with the async header and writes task_id and request_id before anything else.
  3. Day 3: poller and retry table. Poll every 15 seconds; act on status exactly as in section 04.
  4. Day 4: archiver and sweep. Copy on success, verify against usage.duration, page on anything unarchived after 12 hours.
  5. Day 5: limiter and ledger. Shared token bucket under 300 requests per minute; reserve, submit, settle per team.

Prices and rate limits are on the wan3.0-video and wan3.0-video-prime pages; durations from 2 to 30 seconds and 30 fps MP4 output are on the Video generation overview; request and response fields are in the Wan3.0 Video Generation API Reference. Plan at list price; promotions vary by platform and change over time.

Week one is plumbing; every week after is cheaper because of it.


Key takeaways

  • Kill the orphan task. The create call has no documented idempotency field, so keys, a SUBMITTING state and an UNCERTAIN lane must live in your job store.
  • Respect the clocks. Poll about every 15 seconds, archive inside the 24-hour window, and budget the 300 requests per minute for polls as well as creates.
  • Cap spend per team in the ledger. Reserve, submit, settle: in the worked example, controls close a $900 leak on a $4,000 month.

Bring your integration; leave with a hardened job lifecycle
Tell us where Wan3.0 calls happen in your stack today and which teams share the key. The Wan team will review your queue, retry policy, archive path and spend caps with you, mapped to the fields in the API reference. Get your Wan3.0 queue and caps reviewed →

See Wan3.0 in action at wan.video.


About Wan. Wan is Alibaba Cloud's generative video model family. Wan3.0 is available through Alibaba Cloud Model Studio and Qwen Cloud, with API pricing billed per generated second.

Sources: BCG, Applied AI Index 2026 (September 2026); Alibaba Cloud Model Studio, Wan3.0 Video Generation API Reference, https://www.alibabacloud.com/help/en/model-studio/wan3-video-generation-api-reference (accessed Nov 13, 2026); Alibaba Cloud Model Studio, wan3.0-video model page, https://www.alibabacloud.com/help/en/model-studio/wan3-0-video (accessed Nov 13, 2026); Alibaba Cloud Model Studio, wan3.0-video-prime model page, https://www.alibabacloud.com/help/en/model-studio/wan3-0-video-prime (accessed Nov 13, 2026); Alibaba Cloud Model Studio, Video generation overview, https://www.alibabacloud.com/help/en/model-studio/video-generation (accessed Nov 13, 2026).

By Johnny Mai, Director, Gen AI Product Strategy & GTM.


Disclaimer: This post is provided for general information only. Worked examples are illustrative and use stated assumptions; your costs will vary. Prices are Alibaba Cloud Model Studio list prices for the Singapore region as published in November 2026, vary by region, and may change over time. Figures from third-party research (BCG 2026) are quoted as published in those reports and are not independently verified by WAN or Alibaba Cloud. Product and service availability, features, and program terms vary by region and may change over time. Nothing in this post constitutes professional, legal, or investment advice. © 2026 WAN. All rights reserved.

0 0 0
Share on

Johnny Mai

21 posts | 2 followers

You may also like

Comments

Johnny Mai

21 posts | 2 followers

Related Products