Sora Videos API removed: same submit-and-poll curl on Sume /v1/videos
OpenAI removed the Sora 2 models and Videos API on Sept 24, 2026. Sume POST /v1/videos keeps the async shape: submit, poll polling_url, download. Curl included.

If your code called the OpenAI Videos API, it broke on September 24, 2026. The loop it used (submit, poll, download) still exists on Sume at POST /v1/videos, which follows the OpenRouter video shape. Change the base URL, the key and the model id. Sora ids are not Sume catalog ids, so you pick a model from the Sume catalog.
What OpenAI removed
OpenAI's deprecations page lists the Videos API, sora-2, sora-2-pro and two dated snapshots of each as removed on September 24, 2026. The recommended replacement column is empty, so no vendor successor exists to point at (OpenAI Deprecations, read 2026-10-05). A redirect or a model-name swap on your side will not bring the old endpoint back.
The practical task is therefore to pick another video model and keep the integration shape you already have.
The loop that carries over
Sume documents the same four steps: submit to POST /v1/videos, receive an id and a polling_url, poll until status is completed, then download from unsigned_urls[0]. Authentication is a Bearer key in SUME_API_KEY. The docs say a client written from the OpenRouter video docs works after you change the base URL and key.
curl -X POST "https://api.sume.com/v1/videos" \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2",
"prompt": "A golden retriever playing fetch on a sunny beach"
}'
# poll the polling_url from the response
curl "https://api.sume.com/v1/videos/<job_id>" \
-H "Authorization: Bearer $SUME_API_KEY"What to change in your code
Three edits cover most ports. Replace the model id with a bare Sume catalog id such as seedance-2. Map the status values you branch on: /v1/videos returns pending, in_progress, completed and failed. Read the clip from unsigned_urls[0] instead of a Sora content path.
Duration and resolution are not free-form. Each model publishes supported_durations and supported_resolutions in GET /v1/videos/models, so read them before you submit rather than copying Sora's 4, 8 or 12 second values.
Pick the replacement model from the catalog
Call GET /v1/videos/models and filter on the fields your old prompts depend on. If you do not want to choose, model: "sume/auto" lets Sume select one for you. Sume does not disclose which model ran, so use it for drafts and pin a model id for work you need to reproduce.
Poll every few seconds or use a webhook, and keep the job id so a restart can resume. For the model-by-model mapping, see the migration table linked below.
Errors your old code will meet
Sume wraps errors in its public envelope with code, message and request_id, which is close enough to the OpenRouter shape that clients reading error.message keep working. The codes worth handling on a video port are below.
Log the request_id with every failure. It is safe to share with support, unlike keys or signed URLs.
| HTTP | Code | What to do |
|---|---|---|
| 400 | unsupported_capability | Value is not in the model's published list; read the catalog |
| 402 | insufficient_credits | Balance is below the reserve; add funds, do not loop |
| 404 | model_not_found | Id is not a catalog id; an id outside the catalog lands here |
| 409 | job_not_completed | Content was requested early; keep polling |
| 429 | rate_limited | Back off using retry-after |
Protect the retry
The old integration probably retried on network errors. On Sume, add an Idempotency-Key header to the submit so a retried POST returns the original job instead of creating a second paid one. The same key with a different body returns 409.
Sources
Related posts
More in Developers
- Voice model updated in place with no API change: how to detect it
Nova 2 Sonic was refreshed in place in May with no API change. If a vendor can change your voice silently, log the model id and a canary clip. Sume code inside.
- spend_approval_queue_full 429: clear pending approvals, do not retry
A thread with too many pending spend approvals gets 429 spend_approval_queue_full. Resolve the pending ones first; a 503 store_misconfigured is for support.
- spend_confirmation_required 402 on Sume: why retrying will not help
A 402 spend_confirmation_required means a person must approve the spend first. It is not a balance error: retryable is false and next_action is fix_input.
- Split a 10-minute TikTok into parts for 3 and 5-minute accounts
TikTok's API allows up to 10 minutes, but an account may be limited to 3 or 5. Split a 600-second video into 4 or 2 parts with Sume trim at $0.02 a job.
Written by Sume