Sume media tools: which wait for a 200 and which always return 202

Video inspect defaults to sync; trim, filter, detach, compose and timeline to async; frames is always 202. The 30 s wait and where each result is read.

5 min readSume
All posts

The Sume media tools do not share a default communication mode. Video inspect defaults to sync, waits up to 30 seconds, and returns 200 if it finishes in that time. Video trim, video filter, audio detach, timeline compose, timeline audio and Timeline 1.0 render default to async. Video frames pins async and always returns 202, so mode: "sync" does not change anything on it. Every tool that accepts mode: "sync" uses the same 30-second window, and returns 202 when the work is not done by then.

The table

Reading the result also differs. Some tools have a resource route and some only have the job envelope, so the polling code you write for one will not fit all.

Default mode and result route per Sume media tool, from the Sume docs (read 2026-10-07)
ToolDefault modeSync allowedRead the result at
video inspectsync (30 s max)yesGET /v1/video-inspect/:id
video trimasyncyes, 30 sGET /v1/jobs/:id/result
video filterasyncyes, 30 sGET /v1/jobs/:id/result
audio detachasyncyes, 30 sGET /v1/jobs/:id/result
video framesasync, pinnedno, always 202GET /v1/video-frames/:id
timeline composeasyncyes, 30 sGET /v1/jobs/:id/result
timeline audioasyncyes, 30 sGET /v1/jobs/:id/result
Timeline 1.0 renderasyncyes, 30 sGET /v1/jobs/:id/result

A handler that covers all of them

Write one function for the response: if the status code is 200, the body is the result; if it is 202, read the job ID from request_id and poll GET /v1/jobs/:id/status until result_ready, then GET /v1/jobs/:id/result. Frames and inspect also expose their own resource reads, but the job envelope works as the common path. The hosted MCP flow is the same shape: the write tool, then jobs_wait, then the read tool or jobs_result.

import os, time, json, urllib.request

BASE = "https://api.sume.com"


def call(method, path, body=None):
    data = json.dumps(body).encode() if body is not None else None
    req = urllib.request.Request(BASE + path, data=data, method=method, headers={
        "Authorization": f"Bearer {os.environ['SUME_API_KEY']}",
        "Content-Type": "application/json",
        "Idempotency-Key": "trim-demo-001",
    })
    with urllib.request.urlopen(req) as resp:
        return resp.status, json.load(resp)


if __name__ == "__main__":
    status, body = call("POST", "/v1/video-trim", {
        "video_url": "https://media.sume.com/artifacts/artf_demo/long.mp4",
        "start": 0, "duration": 60, "mode": "sync"})
    print(status, body.get("request_id"))

Why it matters for agents and short timeouts

Hosts that cut off a call at 60 seconds, or gateways that do so at 30, are safe with sync because the tool's own wait is capped at 30 seconds and falls back to 202. The sync default on video inspect also means a probe-only call with frames: false often returns the answer in one request, with no polling.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume