Short answer: the Sora API is gone. OpenAI shut down the Videos API, sora-2 and sora-2-pro on September 24, 2026, and its Deprecations page lists no recommended replacement. If you want a Sora API alternative with the same async pattern (submit a job, poll, download), the Seedance 2.5 API is a close fit. You will need to change the endpoint, the field names, how you upload images, and how you store results, and you will need to replace webhooks with polling.
This guide is for developers who had Sora 2 in production. It maps each Sora request field to its Seedance 2.5 equivalent and ends with a migration checklist.
What OpenAI officially says about the Sora API shutdown
OpenAI's Deprecations page states, verbatim: "On March 24th, 2026, we notified developers using the Videos API and Sora 2 video generation model aliases and snapshots of their deprecation and removal from the API on September 24, 2026."
The table on that page lists a shutdown date of 2026-09-24 for the Videos API, sora-2, sora-2-pro, sora-2-2025-10-06, sora-2-2025-12-08 and sora-2-pro-2025-10-06. The "Recommended replacement" column is empty ("---") for every row.
OpenAI's Sora video generation guide now opens with: "The Sora 2 models and Videos API were shut down on September 24, 2026 and are no longer available. No one-to-one replacement API is available. This guide is retained for historical reference."
Sora API vs Seedance 2.5 API: field-by-field mapping
| Task | Sora Videos API (shut down) | Seedance 2.5 API |
|---|---|---|
| Create a job | POST /videos (multipart or JSON) with model sora-2 or sora-2-pro | POST /videos (JSON) at base URL https://seedance2-5.com/api/v1, model seedance-2.5 or seedance-2.5-lite, plus a required Idempotency-Key header |
| Prompt | prompt | prompt (required, non-empty) plus a required mode: text-to-video or image-to-video |
| Duration | seconds (string); the guide says videos up to 20 seconds | parameters.duration_seconds (integer; the OpenAPI schema allows 3–30; the values each model supports come from GET /models) |
| Size | size as pixels, e.g. 1280x720; 1920x1080 / 1080x1920 on sora-2-pro | Two fields: parameters.resolution (e.g. 720p) and parameters.aspect_ratio (e.g. 16:9) |
| Reference assets | input_reference (uploaded image, or JSON with file_id / image_url); reusable characters; video extensions and edits | inputs array of {"type":"image","url":...} using URLs from POST /uploads → PUT bytes → POST /uploads/complete; parameters.image_mode = first-frame, first-last-frame or reference-image. Video/audio references and editing are not available in this API version |
| Status polling | GET /videos/{video_id}; states queued, in_progress, completed, failed; webhooks optional | GET /generations/{id}, at most once every 10 seconds; states pending, processing, success, failed, canceled, expired; no webhooks |
| Result download | GET /videos/{video_id}/content streams the MP4; variant for thumbnail or sprite sheet | outputs[].url signed URL, valid at most 15 minutes; media retained 14 days, so copy it to your own storage |
| Cost control | Not part of the request | POST /quotes returns cost_credits without charging; max_cost_credits rejects a higher quote |
What changes in your code when you leave the Sora API
Auth and idempotency
Both APIs use Authorization: Bearer. Seedance additionally requires an Idempotency-Key header (16–128 characters, letters, digits, _ or -) on every generation. After a timeout, the docs say to retry with the same key and body instead of creating a new job, which avoids a second charge.
Images must be uploaded first
Sora accepted an image file or an image URL in input_reference. Seedance does not accept external URLs, base64 or data URLs: you prepare up to five files per upload request (JPEG, PNG or WebP, at most 30 MiB each), PUT the bytes, confirm, then pass the returned URL in inputs.
Replace webhooks with polling
The Seedance 2.5 docs state: "Video/audio references, editing, webhooks and cancellation endpoints are unavailable." If your Sora integration relied on webhooks, extensions or edits, plan a polling worker and drop those features for now.
Store results yourself
Sora's content endpoint streamed the file on demand. Seedance gives a signed URL that expires within 15 minutes; query the generation again for a fresh URL, and download within the 14-day retention window.
Sora API migration: step by step
Step 1: inventory your Sora usage
Search your code for /v1/videos, videos.create, sora-2 and sora-2-pro, including Batch jobs. List which features each call uses: plain text-to-video, input_reference, characters, extensions, edits, webhooks, thumbnail or sprite-sheet downloads. That list tells you what maps directly and what has to be redesigned (see the "no equivalent" section below).
Step 2: create a key and read the model catalog
Create an API key in your Seedance 2.5 account settings; the docs say it is shown only once, so save it in a server secret manager. Then call GET /models: it returns the modes, resolutions, durations, aspect ratios and image limits your key supports. Unsupported models and options are rejected, so build your request from this response instead of hard-coding Sora-era values.
Step 3: rewrite the create call
A typical Sora create request, from OpenAI's guide:
curl -X POST "https://api.openai.com/v1/videos" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: multipart/form-data" \
-F prompt="Wide tracking shot of a teal coupe driving through a desert highway, heat ripples visible, hard sun overhead." \
-F model="sora-2-pro" \
-F size="1280x720" \
-F seconds="8"
The same job on Seedance 2.5, following the Seedance 2.5 quickstart (quote first, then create):
export SEEDANCE_BASE_URL="https://seedance2-5.com/api/v1"
cat > video.json <<'JSON'
{
"model": "seedance-2.5-lite",
"mode": "text-to-video",
"prompt": "Wide tracking shot of a teal coupe driving through a desert highway, heat ripples visible, hard sun overhead.",
"parameters": {
"duration_seconds": 8,
"resolution": "720p",
"aspect_ratio": "16:9"
},
"max_cost_credits": 80
}
JSON
curl --fail-with-body "$SEEDANCE_BASE_URL/quotes"
-H "Authorization: Bearer $SEEDANCE_API_KEY"
-H "Content-Type: application/json"
--data-binary @video.json
curl --fail-with-body "$SEEDANCE_BASE_URL/videos"
-H "Authorization: Bearer $SEEDANCE_API_KEY"
-H "Content-Type: application/json"
-H "Idempotency-Key: video-order-0001"
--data-binary @video.json
Parameter-by-parameter notes for this example
- URL:
https://api.openai.com/v1/videosbecomeshttps://seedance2-5.com/api/v1/videos. The path name is the same; the host and version prefix change. - Content type: Sora accepted
multipart/form-dataor JSON. Seedance takes JSON only, and unknown fields are rejected, so remove any leftover Sora fields. model:sora-2-probecomesseedance-2.5orseedance-2.5-lite. The example uses Lite because the docs publish its rate: 10 credits per output second, so 8 seconds quotes at 80 credits.mode: new and required. Usetext-to-videowithout images andimage-to-videowith them; Sora inferred this from whetherinput_referencewas present.prompt: moves over unchanged. The schema allows up to 30,000 characters.seconds→parameters.duration_seconds: Sora sent a string ("8"); Seedance needs an integer (8) nested underparameters.size→parameters.resolution+parameters.aspect_ratio:1280x720becomes"720p"and"16:9";1080x1920would become a 1080p resolution with a 9:16 ratio, ifGET /modelslists both for your model.max_cost_credits: new and optional. If the quote is higher than this number, the request is rejected before generation.Idempotency-Keyheader: new and required, 16–128 characters. Use one key per intended video; reuse the same key and body when retrying after a timeout.- Response: Sora returned
status: "queued"with aprogressfield. Seedance returns HTTP 202 withstatuspendingorprocessing, acredits.costvalue and an emptyoutputsarray. There is no progress percentage.
Step 4: rewrite polling and download
Replace GET /videos/{video_id} with GET /generations/{id}, wait at least 10 seconds between polls, and stop on success, failed, canceled or expired. Map Sora's completed to success. Replace GET /videos/{video_id}/content with a download of outputs[].url before its expires_at (at most 15 minutes); the docs note there is no output.video_url or status_url field.
curl --fail-with-body "$SEEDANCE_BASE_URL/generations/GENERATION_ID" \
-H "Authorization: Bearer $SEEDANCE_API_KEY"
Step 5: move image inputs to the upload flow
For image-to-video, call POST /uploads with the file name, type and byte size; PUT the exact bytes to the returned upload_url within five minutes using every returned header (and without your Bearer key); call POST /uploads/complete; then put the returned URL in inputs and set parameters.image_mode.
Step 6: handle errors, retries and storage
On a connection failure after submission, retry the exact same request and idempotency key rather than creating a new job; the docs warn that a replacement can cause another charge. Save every finished file to your own storage within the 14-day retention window.
Step 7: test, compare cost, switch traffic
Run a handful of your real Sora prompts through /quotes and /videos, review the outputs, confirm the credit cost per clip, then move production traffic.
Sora API features with no Seedance 2.5 equivalent
Based on OpenAI's Sora guide and the current Seedance 2.5 API docs, these Sora capabilities have no direct counterpart today:
- Characters (
POST /v1/videos/charactersand thecharactersarray): no reusable character object. Use reference images ininputson each request instead. - Extensions (
POST /v1/videos/extensions): Sora's guide says each extension adds up to 20 seconds, up to six times, for up to 120 seconds total. No extension endpoint exists in this Seedance API version. - Edits (
POST /v1/videos/edits): editing is listed as unavailable. - Video references: Seedance
inputsaccept only{"type":"image"}; video and audio references are unavailable. - Webhooks: unavailable; poll instead.
- Cancellation: no cancel endpoint.
progresspercentage: not in the Seedance generation object.variant=thumbnail/variant=spritesheet: Seedance returns the video URL only; make thumbnails yourself.- List and delete (
GET /videos,DELETE /videos/{video_id}): no list or delete endpoint; media expires after 14 days. - Batch API and multipart uploads: not available; send individual JSON requests.
Sora API migration checklist
- Inventory every Sora call and feature in use.
- Create a Seedance 2.5 key and store it server-side.
- Read
GET /modelsfor supported values. - Map
seconds→duration_secondsandsize→resolution+aspect_ratio; addmode. - Add an
Idempotency-Keyandmax_cost_credits; quote first. - Replace polling and the content download with
GET /generations/{id}andoutputs[].url. - Move images to the upload → complete →
inputsflow. - Remove or redesign characters, extensions, edits, webhooks and thumbnail downloads.
- Copy results to your own storage before URLs expire.
Full request examples are in the Seedance 2.5 API docs; per-model credit rates and rate limits are covered in Seedance 2.5 API pricing and limits, and per-clip budgeting in Seedance 2.5 cost per video.
Pricing note
The Seedance 2.5 docs state that Seedance 2.5 Lite costs 10 credits per output second, that the first five reference images are included and each additional image costs 7 credits, and that "Other prices depend on model parameters and follow the website." API calls use the same credit balance as the website and need an active paid subscription or remaining purchased credits. A verified failure is refunded once; queries, quotes and downloads are free.
Sora API alternative FAQ
Is the Sora API still available?
No. OpenAI's Deprecations page lists September 24, 2026 as the shutdown date for the Videos API, sora-2, sora-2-pro and three dated snapshots. OpenAI's Sora guide says the models and Videos API "are no longer available" and that it is kept for historical reference only.
Did OpenAI recommend a Sora API alternative?
No. The "Recommended replacement" column for every Sora row on OpenAI's Deprecations page is "---", and the Sora guide states "No one-to-one replacement API is available." Any Sora API alternative, including Seedance 2.5, is a third-party choice you need to evaluate yourself.
How long can a Seedance 2.5 video be compared with Sora?
OpenAI's guide said Sora 2 could generate videos up to 20 seconds. The Seedance 2.5 API schema accepts duration_seconds from 3 to 30, and the exact values each model supports are returned by GET /models, so check that call before you migrate long clips.
Can I reuse my Sora prompts in this Sora API alternative?
Yes, the prompt is a plain text field in both APIs, so prompts move over directly. Results will differ because the models differ. Reference images must be re-uploaded through the Seedance 2.5 upload flow, and Sora characters, extensions and edits have no direct equivalent in the current API version.
Does the Seedance 2.5 API support webhooks like Sora did?
No. The Seedance 2.5 API docs say webhooks and cancellation endpoints are unavailable in this version. Poll GET /generations/{id} at most once every 10 seconds and download the signed result URL before it expires.
About Seedance 2.5
This independent site offers Seedance 2.5 in the browser and through a credit-based REST API for developers, with quotes before each generation. It is not affiliated with ByteDance or OpenAI. Learn more on Seedance 2.5.
