Price a multi-shot Wan 3.0 job first: Timeline plan is unbilled
Before you pay to join Wan 3.0 shots, call POST /v1/timeline-1.0/plan: it compiles the timeline and returns segment count, billable minutes and an estimate.

To check a multi-shot Wan 3.0 assembly before it costs anything, call POST /v1/timeline-1.0/plan with the same body you would send to render. According to Sume's Timeline 1.0 docs, the plan validates the schema and the Sume-host URLs, runs the compiler, and returns object: timeline_plan with duration_seconds, segment_count, billable_minutes and estimated_cost_usd_micros. It creates no job, reserves no credits and downloads no media, and Idempotency-Key is not required. It prices the assembly only: the Wan 3.0 clips themselves are priced separately, by the model catalog.
What the plan covers and what it does not
A multi-shot video has two kinds of cost. Generation is one wan-3.0 request per shot, priced per output second by resolution in the catalog (read pricing_skus from GET /v1/videos/models, as described in the Video generation docs). Assembly is the Timeline render. The docs list the public render rate as $0.10 per ceil(output minute) and tell you to confirm the live rate in GET /v1/catalog; the reserve is ceil(audio.duration_seconds / 60) minutes, and the job uses no provider inference, only worker ffmpeg.
| Part | Where the price comes from | Billed when |
|---|---|---|
| Each Wan 3.0 clip | pricing_skus on GET /v1/videos/models | You submit each generation |
| Timeline render | Public rate per ceil(output minute), confirm in GET /v1/catalog | You submit the render |
| Timeline plan | Unbilled | Never; no job, no reserve |
A plan request
Send the same audio and video[] as the render. Every URL must already be a media.sume.com artifact or asset of your workspace, so import the clips first with POST /v1/media-imports. Three Wan clips of 8, 8 and 9 seconds on a 25 second silent spine look like this:
curl -X POST https://api.sume.com/v1/timeline-1.0/plan \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"audio": {"mode": "silence", "duration_seconds": 25},
"video": [
{"source_url": "https://media.sume.com/artifacts/artf_a/s1.mp4", "start": 0, "duration": 8},
{"source_url": "https://media.sume.com/artifacts/artf_b/s2.mp4", "start": 8, "duration": 8,
"transition": {"type": "fade", "duration": 0.5}},
{"source_url": "https://media.sume.com/artifacts/artf_c/s3.mp4", "start": 16, "duration": 9,
"transition": {"type": "dissolve", "duration": 0.5}}
]
}'Read the answer, then fix the plan
Check that duration_seconds equals what you meant and that segment_count is three. The docs say render.strategy defaults to auto and chunks past 12 segments, and that Sume refuses single above 12 slots with render_strategy_unsafe, so a very long storyboard will show a different path. If a rule is broken (a first slot that does not start at 0, a transition longer than 1 second or more than half of the shorter neighbor), the plan fails in the compile step before any money moves.
One limit to remember: the docs say a plan cannot predict short-source pad or loop warnings. If a clip is shorter than its slot, the real render pads or loops it and reports a warning. Make each duration no longer than its source, and the plan and the render agree.
A routine for batches
For a storyboard of many shots, plan after every edit to the slot list, and render only once the numbers are what you expect. Keep the plan JSON in version control next to the prompts, so a change in cost has a cause you can read, and log the returned estimated_cost_usd_micros beside the final job cost so you can see how close the two stay over time. If an estimate looks high, the usual cause is the spine length: the reserve follows audio.duration_seconds, so a spine declared at 90 seconds for a 60 second cut reserves two minutes, not one. Fix the declared length and plan again. Pair it with a draft: generate at 480p, assemble, plan, review the cut, and only then regenerate the shots you keep at the final resolution.
Sources
Related posts
More in Developers
- Price guard: refuse a 30-second Seedance 2.5 render over your cap
Compute the Sume price of a clip from model, resolution and seconds before you POST, and refuse over a cap. Python code, the rates, and the 1080p cent rounding.
- Product photo to a 9:16 Reel clip in Python: 6 seconds for $0.75
POST /v1/videos with one product photo as frame_images first_frame on gemini-omni-flash-1.1: 6 seconds at 720p costs $0.75. Python polls and saves the MP4.
- Prometheus histogram buckets for Sume video jobs, up to 20 minutes
Pick histogram buckets for submit-to-terminal time on 30-second Seedance 2.5 and other Sume video jobs, so the 20-minute SDK deadline is the last bucket.
- Promise.allSettled for a wave of Sume jobs: keep the partial wins
Promise.all throws away nine good Sume videos when one job fails. Use Promise.allSettled over a wave sized to your plan's concurrency, in 30 lines of Node.
Written by Sume