AI video client timeout: the Sume job still runs and still bills
A timeout on your HTTP client does not cancel a Sume job. Save the job id, poll the polling_url, and cancel only before generation starts. Python example.

Does a client timeout cancel my Sume video job?
No. The job keeps running and still bills. A timeout on your side only means you stopped listening. Resubmitting is the costly reaction, because it creates a second job. The right reaction is to keep the job id and poll its status, or retry the submit with the same Idempotency-Key, which replays the original job.
Long clips make this easy to hit. ByteDance Seed describes up to 30 seconds per Seedance 2.5 generation and Alibaba's Wan 3.0 page says native 30 seconds. Sume's sync wait is capped at 30 seconds and is a budget for the HTTP request, not for the job.
So the question is never "how do I stop it" but "how do I find it again". Two handles do that: the job id from the 202 response, and the idempotency key you sent with the submit. Keep both in your own database next to the order, written before you start waiting, and a crash or a timeout becomes a lookup instead of a second charge.
What to do in each situation
| Situation | Job state | Do this |
|---|---|---|
| Your client timed out after submit | Still running | Poll the status route |
| Sync wait ended with sync.timed_out | Still running | Poll, do not resubmit |
| You lost the submit response | Unknown | Retry submit with the same Idempotency-Key |
| You want to stop the job | Only before generation starts | Cancel; later it is 409 job_generation_already_started |
Submit once, poll the URL
The submit returns 202 with a polling_url and a status of pending. The poll uses the OpenRouter-shaped states pending, in_progress, completed, failed and cancelled. A timeout on a poll is harmless, so the loop below treats it as a reason to try again.
import json, os, time, urllib.request
H = {"x-api-key": os.environ.get("SUME_API_KEY", ""), "content-type": "application/json"}
def call(method, url, body=None, key=None):
h = dict(H)
if key:
h["idempotency-key"] = key
data = json.dumps(body).encode() if body else None
req = urllib.request.Request(url, data, h, method=method)
with urllib.request.urlopen(req, timeout=20) as r:
return json.load(r)
def run(prompt: str, order_id: str) -> dict:
body = {"model": "wan-3.0", "prompt": prompt, "duration": 30, "resolution": "720p"}
job = call("POST", "https://api.sume.com/v1/videos", body, key=f"order-{order_id}")
while True:
try:
s = call("GET", job["polling_url"])
except (TimeoutError, OSError):
s = {"status": "in_progress"} # our timeout, not the job's
if s["status"] in ("completed", "failed", "cancelled"):
return s
time.sleep(5)Cancel is not a timeout handler
Cancel works only before generation starts. After that the answer is 409 job_generation_already_started with details.cancelable set to false, and the job finishes and bills. A job that completes after your client gave up is yours to collect: store the job id with your order so a later poll or a webhook can pick the result up.
Set the HTTP timeout on the submit shorter than you think. The /v1/videos submit returns a 202 with a polling_url, so a 20 second timeout is generous, and a long hang usually points at the network rather than at the generation. Reserve the long waits for the poll loop, where a timeout is cheap and safe to retry.
Sources
Related posts
More in Developers
- Sume SDK 402 insufficient credits: it is returned, not thrown
Generated Sume SDK calls resolve with data, error and response. Turn a 402 into SumeInsufficientCreditsError with toSumeApiError and stop retrying.
- Sume SDK idempotencyKey: null sends no key, so POST retries stop
subscribeFormatRun mints a UUID Idempotency-Key by default. Pass null and the create call carries no key, so the SDK will not retry it on a 429 or 5xx.
- Sume SDK maxRetries: 0 when your job queue already retries the call
The SDK retries 408, 429 and 5xx twice by default. Under a queue with five attempts that is up to 15 tries. Set maxRetries to 0 and let one layer retry.
- Does the Sume SDK retry a failed video submit? Only with a key
createSumeClient retries GET and HEAD by default and retries a POST only when an Idempotency-Key header is set. See what is retried, what is not, and why.
Written by Sume