Avatar video progress bar: subscribe mode sends no progress events

Mode subscribe on an avatar job gets the same 30-second wait as sync, not a stream. Build progress UI from async status polling and job events.

4 min readSume
All posts

mode: "subscribe" on a Sume avatar job is an alias of sync: one bounded HTTP wait of at most 30 seconds, with no progress events and no stream. For a progress bar, submit with async and poll the job status, or read GET /v1/jobs/:id/events.

Everything here is from Jobs and results, read 2026-10-02. The page says plainly that there is no SSE or WebSocket transport on the Developer API today.

Why does subscribe sound like a stream?

The word appears on three surfaces with three different meanings, and none of them is a push stream.

Three meanings of subscribe (read 2026-10-02)
WhereWhat it isWait
Job mode subscribeAlias of sync, one bounded HTTP waitAt most 30 seconds
SDK subscribeFormatRun()Creates a Format run, then polls it client-sideMinutes, the SDK's own timeout
Format communication.modeNot a value; only async and webhook existNothing blocks

What can I build progress from?

Submit with async (the default) and you get a 202 envelope with status_url, result_url, events_url and cancel_url. Poll status_url until terminal is true, honoring next_poll_after_seconds when present and backing off otherwise, then fetch result_url once result_ready is true.

The events route is a pull snapshot with a public timeline: job.created, job.queued, job.started, generation.submitted, then a terminal event. It carries no percentage, so a bar should show stages, not numbers.

  • Queued: after job.created and job.queued.
  • Rendering: after job.started and generation.submitted.
  • Done: job.completed, with the result now readable.
  • Failed or canceled: show the public error.

What does a sync submit do when the render takes longer?

Avatar videos routinely outlast 30 seconds. The response is still 2xx and still carries the job id. sync.timed_out is true when the wait ended early, and sync.capacity_exhausted is true when Sume skipped the wait because the waiter budget was full.

You must continue with GET status_url, and you must not submit a new paid job for the same intent. A retry of the submit itself is fine if you reuse the same Idempotency-Key.

A minimal poll loop

Use the envelope fields as the contract and keep your own backoff. The example uses curl for clarity:

curl https://api.sume.com/v1/jobs/job_123/status \
  -H "Authorization: Bearer $SUME_API_KEY"

curl https://api.sume.com/v1/jobs/job_123/events \
  -H "Authorization: Bearer $SUME_API_KEY"

curl https://api.sume.com/v1/jobs/job_123/result \
  -H "Authorization: Bearer $SUME_API_KEY"

If you do not want a browser polling at all, use mode: "webhook" with a public HTTPS webhook_url and keep status polling as the backup. See the events post for debugging a slow render.

What should the UI say while it waits?

Be honest about what you know. Sume does not publish a percentage for an avatar render, so a fake percentage will stall at 90 percent and lose trust. Show the stage names from the events timeline, plus elapsed time you measure yourself.

A good pattern is three states: submitted, rendering and finished. Move to rendering on generation.submitted, and to finished when terminal is true and result_ready is true. If the job fails, show the public error from the status payload and offer a retry with a new request.

When is webhook better than polling?

A webhook is better when the person who requested the video is not watching, such as a nightly batch. A browser session is better served by polling status_url, because it needs updates now and cannot receive a callback anyway.

Many apps combine them: the server takes the webhook as the source of truth and the browser polls your own API, which reads your database. That keeps API keys off the client and keeps one place that talks to Sume.

Quick answers

Does subscribe cost more than async? The docs say the mode never changes whether a job is created, what it costs or how long it takes; it only decides how you learn the outcome. Can I cancel while a progress bar shows? Only before generation work starts; after that the job runs to completion.

Sources

Related posts

More in Sume Avatar 1.0

All Sume Avatar 1.0 posts

Written by Sume