Sync mode returned queued on a 30-second video: the 30 s cap

mode sync waits at most 30 seconds on the HTTP call, not on the job. A 30-second clip returns a job id with sync.timed_out true; keep polling, never resubmit.

5 min readSume
All posts

The 30 seconds in mode: "sync" is how long the submit request may block, not how long the job may run. A 30-second Seedance 2.5 or Wan 3.0 clip will not finish in that window, so you get a normal 2xx envelope with the job id and sync.timed_out: true, and you keep polling.

The word clash is easy to miss: 30 s of output length and 30 s of wait budget are unrelated limits that happen to share a number.

What the response tells you

wait_timeout_seconds is clamped to 0-30. When the budget ends, or when the API process has no waiter capacity left, the response is still a success and still carries status_url, result_url, events_url, and cancel_url. sync.timed_out means the wait returned before a terminal state. sync.capacity_exhausted means Sume skipped the wait because its waiter budget was full.

subscribe is an alias of sync with the same cap. It is not a stream, and there is no SSE or WebSocket transport on the Developer API.

Communication modes for video submits (read 2026-10-07)
ModeBlocksRight for a 30 s clip?
async (default)NoYes, poll status_url
webhookNoYes, with a poll as backup
syncAt most 30 secondsNo
subscribeAt most 30 secondsNo, same as sync

Branch on the envelope

Read terminal first. If it is false, hand the job id to your poller and return. If you retry the submit itself after a network failure, send the same Idempotency-Key.

import os, requests
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}",
     "Idempotency-Key": "sync-demo-001"}
r = requests.post("https://api.sume.com/v1/video-router/generate", headers=H,
    timeout=45, json={"model": "wan-3.0", "prompt": "Steam over a bowl of ramen",
                      "duration": 30, "resolution": "480p",
                      "mode": "sync", "wait_timeout_seconds": 30})
r.raise_for_status()
d = r.json()["data"]
if d["job"]["status"] == "completed":
    print("done in the wait", d["result_url"])
else:
    print("keep polling", d["status_url"], (d.get("sync") or {}).get("timed_out"))

Use async for video

Sume recommends async or webhook for new integrations. Keep sync for short image work that usually fits the wait. A gateway or function with its own shorter timeout makes this worse, so check the limit of every hop between you and the API.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume