Timeline mode sync for a 30-second Short: handle both 200 and 202

Sume Timeline mode sync waits up to 30 seconds and returns 200 if the render finished, else 202. Why a Short client must handle both, with a Python poll loop.

5 min readSume
All posts

Timeline defaults to async and returns a job. Passing mode: "sync" waits up to 30 seconds for a finished job and returns 200 with it; if the render is not done by then you get 202 and poll. The docs promise the wait cap, not a render time, so a client must handle both. Read from the Timeline docs on 2026-10-06.

Why handle both codes for a short render?

A short clip may finish inside 30 seconds on a quiet day and not on a busy one. Code that assumes 200 breaks the first time a render is slower. A 2xx also means a paid job exists, so a retry of the submit must reuse the same Idempotency-Key; that returns the original job rather than billing a second one.

How do I poll?

import os, time, requests

H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}
body = {"mode": "sync", "audio": {"mode": "silence", "duration_seconds": 20},
        "video": [{"source_url": "https://media.sume.com/artifacts/artf_demo/a.mp4",
                   "start": 0, "duration": 20}]}
r = requests.post("https://api.sume.com/v1/timeline-1.0/render",
                  headers={**H, "Idempotency-Key": "short-001"}, json=body, timeout=60)
job = r.json()
while r.status_code == 202:
    time.sleep(3)
    s = requests.get(f"https://api.sume.com/v1/jobs/{job['request_id']}/status", headers=H).json()
    if s.get("status") == "result_ready":
        break
res = requests.get(f"https://api.sume.com/v1/jobs/{job['request_id']}/result", headers=H).json()
print(res.get("video_url"))

Which fields carry the result?

The result is kind: timeline_render with video_url, duration_seconds, segment_count, billable_minutes and optional warnings[]. Read the warnings before you upload.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume