Developers

Sync vs async API for video generation: Sume's four submit modes

Sume's submit modes are async, sync, subscribe, and webhook. sync and subscribe wait 30 s at most, so for video, submit async and poll, or take a webhook.

5 min readSume
All posts

For video generation on Sume, use async or a webhook, not sync: sync holds the request open for at most 30 seconds, and most video work outlasts that wait. The submit mode changes only how you learn a job's outcome, never the job, its cost, or its run time, and POST /v1/videos is always asynchronous.

These rules come from Sume's Jobs and results page, with route details from Image generation, Video Generation, and the live OpenAPI reference, read on 2026-09-26.

What are the four submit modes?

Submit endpoints take mode, webhook_url, and wait_timeout_seconds where the OpenAPI schema documents them. POST /v1/videos takes none of the three; see the routes section below.

  • Omit mode and you get async, except on POST /v1/images, which defaults to sync. Send webhook_url (or its alias callback_url) without a mode and you get webhook.
  • On routes that answer with Sume's job envelope, every mode returns the job id in its first response. A 2xx envelope means the job exists and paid work is in flight, not that it finished; read terminal and result_ready to tell.
Communication modes, from Jobs and results, read 2026-09-26.
ModeFirst responseServer waitsWhat you do next
async (default)202 with the job envelope and polling URLsNoPoll status_url until terminal is true, then read result_url.
syncThe same envelope, after waiting up to wait_timeout_seconds for a terminal stateAt most 30 s, less when waiter capacity is unavailableTerminal: read the job off the response. Not terminal: poll, and do not resubmit.
subscribeIdentical to syncSame as syncSame as sync.
webhook202 with the job envelope; the callback is storedNoWait for the signed terminal callback and keep polling as a backup.

What does the 30-second wait bound?

wait_timeout_seconds is clamped to 0–30. It bounds how long the HTTP request blocks, not how long the job may take. Image jobs often finish inside it; video, avatar-video, and face-swap jobs routinely do not.

When the budget runs out, or the API process has no waiter capacity and skips the wait, the response is still 2xx with the job id. It carries status_url, result_url, events_url, cancel_url, and a sync object. Wait exhaustion is not an admission failure.

How do I read the sync object?

sync reports how the wait ended. It is null on async and webhook responses.

  • Not terminal? Continue with GET status_url, honoring next_poll_after_seconds when present.
  • Do not submit a new paid job for the same intent. If you retry the submit itself, reuse the same Idempotency-Key so the retry returns the original job; see idempotency keys for AI video APIs.
The sync object, from Jobs and results and the OpenAPI reference, read 2026-09-26.
FieldMeaning
timed_outThe wait returned before the job reached a terminal state.
capacity_exhaustedSume skipped the blocking wait because the per-process waiter budget was full. Poll status_url instead.
terminalThe job is completed, failed, or canceled.
succeeded, failed, canceledOne per terminal status; succeeded means completed.
result_ready, completedA GET to result_url can return the completed result. completed is a backward-compatible success flag.
wait_timeout_secondsThe wait budget you requested.

Is subscribe a stream?

No. sync and subscribe run the same bounded waiter and return the same envelope. subscribe exists because clients ported from other queue APIs reach for it. It is not a long-lived subscription, an event stream, or a longer wait, and brings no progress events. The Developer API has no SSE or WebSocket transport today, and GET /v1/jobs/{id}/events is a pull snapshot.

The word means three things on Sume; none is a push stream:

  • Job mode: "subscribe": an alias of sync, capped at 30 seconds.
  • SDK subscribeFormatRun(): creates a Format run, then polls it client-side for minutes.
  • A run's communication.mode: only async and webhook, which behave identically. Supplying webhook_url is what arms delivery.

Which routes behave differently?

POST /v1/videos is always asynchronous. Its request schema has no mode, webhook_url, or wait_timeout_seconds: it answers 202 with a job id and a polling URL, and takes callback_url for a terminal webhook.

POST /v1/images defaults to sync, and wait_timeout_seconds defaults to 30 on that route. It answers 200 with the images when they finish inside the wait, 502 when the generation fails inside it, and 202 with the standard job envelope when the wait runs out or you send mode: "async" (or "webhook" with a webhook_url). Check the status code, not the body shape. This request asks for the job envelope at once:

curl -X POST "https://api.sume.com/v1/images" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sume/auto",
    "prompt": "Product hero shot of a matte black bottle on marble",
    "mode": "async"
  }'

Which mode should I use for video?

sync and subscribe remain supported and are not going anywhere, but for anything that can outlast 30 seconds, use one of the two paths below. Where to set your own deadline is covered in AI video API timeouts.

  • async and a poll loop: the wait lives in your client, for minutes if needed. See how to poll a video generation job.
  • webhook, or callback_url on POST /v1/videos: Sume sends only a terminal job.completed, job.failed, or job.canceled event to a public HTTPS URL, signed with HMAC SHA-256. Keep polling for missed deliveries; see signed webhooks.

Sources

Related posts

Written by Sume