How long can a Sume Format run take? The expires_at deadline
A Sume Format run is force-finalized as failed 90 minutes after it was created, or sooner if it goes silent. How to read expires_at and set your own timeout.

A Sume Format run has a hard deadline: a run that is still not terminal is force-finalized as failed 90 minutes after created_at, or sooner when the run is older than 25 minutes and has been silent for 10. Every non-terminal receipt carries that deadline as expires_at.
The rules are from Runs and results, read 2026-09-29. The docs also say long-form video is 15 to 30 minutes of work, so the deadline is a ceiling, not an expected time.
Where do I read the deadline?
On the receipt from GET /v1/format-runs/{run_id} and on the smaller poll payload at status_url. It is null once the run is terminal. Set your own client timeout from expires_at rather than inventing a number.
That matters for job runners: if your worker gives up after ten minutes, the run keeps going and keeps spending. Give up only after expires_at has passed, or cancel the run explicitly with a key that carries formats:write.
| Field | What it tells you |
|---|---|
expires_at | The deadline past which a non-terminal run is force-finalized as failed; null when terminal |
queue.state | waiting while pickup is inside the normal window; runtime_unavailable once it has waited past it with nothing claiming it |
queue.retry_after_seconds | How long to back off when queue.state is runtime_unavailable |
queue.position | Always null; Sume does not publish queue depth |
How do I poll without wasting requests?
A fixed one-second poll wastes requests on a run that takes tens of minutes. Double the gap up to a minute. A 429 or 503 during the loop is transient: the run is still executing and still spending, so wait and poll again instead of treating it as failed. Stop on any status that is not queued or processing.
RUN_ID="arun_demo"
SLEEP=5
while :; do
RUN=$(curl -sS "https://api.sume.com/v1/format-runs/$RUN_ID" \
-H "Authorization: Bearer $SUME_API_KEY")
STATUS=$(echo "$RUN" | jq -r '.data.status')
case "$STATUS" in
queued|processing) sleep "$SLEEP"; SLEEP=$(( SLEEP < 60 ? SLEEP * 2 : 60 )) ;;
*) break ;;
esac
done
echo "$RUN" | jq '{status: .data.status, error: .data.error}'Why does my run stay queued?
Read queue. While queue.state is waiting, pickup is inside the normal window. Once it is runtime_unavailable, the run has waited past that window with nothing claiming it, and retry_after_seconds says how long to back off. The docs say a runtime_unavailable that lasts more than a few minutes is worth a support ticket with the request_id from the receipt.
What happens to spend if the run hits the deadline?
The run ends failed and artifacts[] still carries whatever was made. The docs say generation that finished before a cancel or a failure is billed, and a later step failing does not refund it; the run's usage reports the amount. For the cap side of the same question, see the spend cap post.
If you would rather not poll, register a communication.webhook_url on the create and take the one terminal webhook; see the lifecycle post.
Sources
Related posts
More in Formats
- 403 workspace_key_required: call a team Format with a team key
A 403 workspace_key_required means a personal key called a team workspace's Format. Create a key inside that workspace; details.workspace_id names it.
- Which model runs a Sume Format? The model field on a run
The model field on a Sume Format run picks the LLM that orchestrates it, default gpt-6-sol. It does not pick the image, video or audio models. Rules and errors.
- White label AI video generator: build it on an API
Sume documents no white-label program, but its API lets you run AI video for your clients under your brand: one server key, per-run caps, files you host.
- Ready-made Formats for product video: the Sume Format catalog
Sume ships ready-made Formats for product and UGC-style video and images, each callable from your backend with one HTTP request at the reserved sume handle.
Written by Sume