Ported Sora wrapper blocked until done? Sume sync stops at 30 s
A wrapper that blocks until the video is done will time out on Sume sync mode, which waits at most 30 seconds. Return the job id and poll, never resubmit.

Some Sora wrappers exposed one blocking call: create, poll inside the function, return the file. On Sume, do not turn that into mode: "sync". The jobs guide says sync waits up to wait_timeout_seconds, capped at 30, and that video jobs routinely take longer. When the wait runs out you still get a 2xx with the job id, a sync.timed_out flag and status URLs. Keep polling that job. Never submit a second paid job for the same request.
Four modes, one rule
The mode decides how you learn the outcome. It never changes cost or run time.
| Mode | Server blocks | Best for video? |
|---|---|---|
| async (default) | No | Yes, then poll |
| sync | Up to 30 s | Rarely |
| subscribe | Same as sync; an alias | No |
| webhook | No | Yes, plus polling as a backup |
What a safe blocking wrapper looks like
If callers truly need one function that returns a finished clip, build it on async. Submit with an Idempotency-Key, then loop on GET /v1/jobs/{id}/status, honoring next_poll_after_seconds when present and backing off otherwise, until terminal is true. Set the overall deadline in your client; the docs suggest 20 minutes is reasonable for video. Then read GET /v1/jobs/{id}/result once result_ready is true.
- Deadline lives in your client, not in wait_timeout_seconds.
- A client timeout does not cancel the job; it keeps running and billing.
- On deadline, return the job id to the caller so it can resume.
The gateway trap
If your wrapper runs behind an HTTP gateway or serverless function with its own timeout, a long wait fails for a reason that has nothing to do with Sume. Split the call: one request that submits and returns the job id, and a second that reads status. A webhook can then notify your system when the terminal event is ready, as in the webhooks guide.
Surprises worth knowing
The docs say that if the API process has no waiter capacity left, it skips the blocking wait entirely and sets sync.capacity_exhausted. A caller that assumed a sync response was finished would break. Always read terminal and result_ready from the envelope, not the HTTP status. For TypeScript users, the SDK's waitForJob runs this loop; see the video generation docs for the submit shape.
Sources
Related posts
More in Developers
- Pre-flight tool access: tools_list on Sume's MCP
Notion added a tool that reveals connection-scoped capabilities before requests. Sume's MCP does the same job with tools_list, tools_schema and mcp_health.
- Prism mock server from Sume's openapi.json: test without spending
Download api.sume.com/reference/json, run prism mock -d on port 4010 and point your client at it. What a mock proves and what it cannot.
- Prometheus counters for Sume API errors, split by code and status
Wrap every Sume call in a counter and histogram labeled by route template, status and error.code, never by job id or request id, then alert on retryable rates.
- Export Sume job counts by status to Prometheus with a Python gauge
A small exporter pages GET /v1/jobs with next_cursor and sets a prometheus_client Gauge labelled by status, so a dashboard shows queued and failed jobs.
Written by Sume