Loading states for a Generate clip button: pending to cancelled
Map Sume's five video job statuses to five UI states, handle the 409 job_not_completed case, and poll at the interval the API suggests instead of a fixed timer.

A Generate clip button on top of Sume needs five states, one per job status: pending, in_progress, completed, failed and cancelled. Show a queued message for pending, a progress state for in_progress, the video for completed, a retry button for failed and a quiet reset for cancelled. Sora's UI had four, because it had no cancelled.
Five states
Keep copy short and honest. Rendering a clip takes longer than a typical web request, so say that it is running, show elapsed time, and tell the user they can leave the page. A progress bar with a fake percentage invites distrust when it sticks at 90.
| Status | What the user sees | Button |
|---|---|---|
| pending | Waiting for a slot | Cancel disabled or hidden |
| in_progress | Rendering, with elapsed time | Disabled |
| completed | The clip, with download | Generate again |
| failed | The error text and no charge note | Retry |
| cancelled | Nothing was produced | Generate |
What changes from the Sora states
OpenAI's Sora guide, read 2026-10-07, listed queued, in_progress, completed and failed. Rename queued to pending in your state machine, and add the fifth state. If the same screen also reads /v1/jobs, which spells it processing and canceled, normalize both into one internal enum first.
Persist the id
Rendering takes long enough that the screen must survive a reload. Store the job id the moment the 202 arrives and resume polling from it on the next visit. The route returns a polling_url, so the client never has to build one.
Error codes in the UI
A job that is not finished answers a content request with 409 job_not_completed, which is retryable. A failed job answers with 409 job_failed, which is not. Show the first as still working and the second as a retry choice.
- 409 job_not_completed: keep the spinner.
- 409 job_failed: show the error and stop polling.
- 402 insufficient_credits: show a top-up message before any job exists.
- 429 rate_limited or queue_full: wait and try again.
Poll politely
Poll /v1/jobs/{id}/status and honor next_poll_after_seconds where it is returned, instead of a fixed 2 second timer. It cuts needless requests and follows the server's guidance as it changes. Stop on terminal true. Jobs and results lists the fields.
On failure, show the error text from the job rather than a generic message. The failed status carries an error field, and your support inbox will thank you when users can quote it.
Away from the page
A webhook can update your database while the user is away, so the page shows the finished clip on return. The Sora polling post compares the two approaches.
Sources
Related posts
More in Use cases
- Localize one video ad into many languages with Sume batches
Two ways to localize one ad on Sume: a bulk Format batch with one item per language, or burn translated cue captions onto the existing video for $0.20 per job.
- Lock the look with one image, then animate it on three video models
Make one approved image, then use it as first_frame on wan-3.0, kling-3 and minimax-h3-max. Same start, three motions, one prompt, so you can compare.
- Lofi rain-on-window loop with sound: Gemini Omni 10 seconds
Make a 10-second lofi rainy window clip with Gemini Omni on Sume. Ambient audio wording, one image as first and last frame for a loop, and the cost to draft.
- Cut a long talk into short vertical clips with the Sume API
Turn one long recording into short clips on Sume: video-inspect for a sentence transcript, video-trim per range, video-captions to burn the words. Rates inside.
Written by Sume