Sora 2 Alternative - Video Models and API Migration
Sora and the sora-2 API are gone. Replace them with Veo 3.1, Seedance 2.5, Wan 3.0 or Kling 3.0, and migrate Videos API code to one endpoint.
If you need a Sora 2 alternative, pick by the job you used it for: text-to-video with sound maps to Veo 3.1 (Quality), Seedance 2.5 (from $0.261 per second) and Wan 3.0 (from $0.0777 per second); 25-30 second shots to Seedance 2.5 and Wan 3.0; character references to Seedance 2.5 or Nano Banana Pro plus Kling 3.0; remixing a finished clip to Seedance 2.5 video editing. On Jantaris all of them run in one browser Studio and behind one API key, charged from a prepaid balance that never expires, with no subscription. Below: what happened, a feature-by-feature map, and how to port Videos API code.
What happened to Sora
OpenAI wound Sora down in two stages, as reported by The Decoder (March 28, 2026) and TechCrunch (March 24, 2026):
- March 24, 2026 - OpenAI announced it was discontinuing Sora in the app and the API.
- April 26, 2026 - the Sora app and web version (sora.chatgpt.com) closed, along with cameos and the feed.
- September 24, 2026 - the API was switched off: the Videos API and the
sora-2andsora-2-promodels, including dated snapshots. Calls fail from that day on.
According to The Decoder, Sora continues inside OpenAI as a research project on world models, while compute moves to developer tools and business customers. OpenAI has not named a replacement video model.
Sora features and their Jantaris equivalents
| Sora feature | Model on Jantaris | What to check |
|---|---|---|
| Text-to-video with sound | Veo 3.1 (Quality), Seedance 2.5, Wan 3.0 | Veo 3.1 renders a fixed 8 s clip at 720p, 1080p or 4K; Seedance 2.5 and Wan 3.0 have a generate_audio switch (on by default) |
| Longer shots, 25-30 s | Seedance 2.5 (4-30 s), Wan 3.0 (2-30 s) | Seedance 2.5 up to 1080p, Wan 3.0 up to 4K, both in a single pass |
| Character from references instead of cameos | Seedance 2.5 with references, Nano Banana Pro, then Kling 3.0 | Seedance takes up to 30 images in image_urls; Nano Banana Pro (up to 14 references) builds consistent character stills that Kling 3.0 animates from the first frame |
| Remix a finished video | Seedance 2.5 in edit mode | Pass the clip in video_urls (up to 30 s combined); duration is required and input seconds are billed on top |
| Speech in other languages | MiniMax H3, Gemini Omni 1.1 | In my Polish speech test H3 missed 1 word in 12 and Gemini Omni Flash 1.1 none; see AI video with Polish speech |
Notes on the table:
- Cameos were an app feature. You recorded yourself once and Sora placed you in scenes. Jantaris has no stored character profile; you pass reference images with each request. Only use the likeness of people who agreed to it.
- Seedance 2.5 remix means editing an uploaded clip, not remixing from a feed. Describe the change in the prompt: style, time of day, background. HappyHorse 1.0 restyles a whole clip, and Gemini Omni makes a new take based on your reference clip.
- Scenes longer than 30 s are cut together from several clips. Pass the last frame of one clip as
image_urlof the next to keep continuity.
Head-to-head pages: Veo 3.1 vs Seedance 2.5, Wan 3.0 vs Seedance 2.5, Kling 3.0 vs Seedance 2.5 and the full comparison index.
Migrating code from the Videos API
The Sora flow was: POST /v1/videos, poll GET /v1/videos/{id} until completed, then download GET /v1/videos/{id}/content. On Jantaris it is one generic endpoint for every video model, with model-specific parameters inside input:
| Sora Videos API | Jantaris |
|---|---|
POST /v1/videos | POST /v1/generate |
model: "sora-2" / "sora-2-pro" | model: "seedance-2.5", "veo-3.1", "wan-3.0", "kling-3.0"... |
prompt | input.prompt |
seconds (a string such as "8") | input.duration (an integer) |
size: "1280x720" | input.resolution: "720p" + input.aspect_ratio: "16:9" |
size: "720x1280" | input.resolution: "720p" + input.aspect_ratio: "9:16" |
size: "1792x1024" (sora-2-pro) | input.resolution: "1080p" + input.aspect_ratio: "16:9" |
size: "1024x1792" (sora-2-pro) | input.resolution: "1080p" + input.aspect_ratio: "9:16" |
input_reference (file upload) | input.image_url (public URL of the first frame) |
poll GET /v1/videos/{id} | webhook_url in the request, or GET /v1/tasks/{id} as a fallback |
status completed | status succeeded |
GET /v1/videos/{id}/content | output[0].url in the task (download it, links expire) |
Allowed values differ per model, and unknown or out-of-range fields return 422 before anything is charged:
- Seedance 2.5:
duration4-30,resolution480p,720por1080p,aspect_ratioincludes16:9,9:16,1:1andadaptive. - Veo 3.1:
durationis always 8,aspect_ratioonly16:9or9:16,resolutionup to4k. - Wan 3.0:
duration2-30,resolutionin capitals:720P,1080P,2K,4K. - Kling 3.0:
duration3-15,generate_audiois off by default.
Check the exact schema of any model at GET /v1/models/{id}.
Python: map a Sora request to Jantaris
import os
import requests
SIZE_MAP = {
"1280x720": ("720p", "16:9"),
"720x1280": ("720p", "9:16"),
"1792x1024": ("1080p", "16:9"),
"1024x1792": ("1080p", "9:16"),
}
def generate_from_sora_params(prompt, seconds="8", size="1280x720", image_url=None):
resolution, aspect_ratio = SIZE_MAP[size]
body = {
"model": "seedance-2.5",
"input": {
"prompt": prompt,
"duration": int(seconds),
"resolution": resolution,
"aspect_ratio": aspect_ratio,
"generate_audio": True,
},
"webhook_url": "https://your-server.example/hooks/jantaris",
}
if image_url:
body["input"]["image_url"] = image_url
r = requests.post(
"https://jantaris.com/v1/generate",
headers={"Authorization": f"Bearer {os.environ['JANTARIS_API_KEY']}"},
json=body,
timeout=30,
)
r.raise_for_status()
task = r.json()
return task["id"], task["estimated_cost"]
task_id, cost = generate_from_sora_params(
"A cyclist rides along a river boulevard at sunset, the camera tracks alongside, warm light on the water, city ambience",
seconds="12",
size="1280x720",
)
print(task_id, cost)The same request with curl:
curl https://jantaris.com/v1/generate \
-H "Authorization: Bearer $JANTARIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"input": {
"prompt": "A cyclist rides along a river boulevard at sunset, the camera tracks alongside, warm light on the water, city ambience",
"duration": 12,
"resolution": "720p",
"aspect_ratio": "16:9",
"generate_audio": true
},
"webhook_url": "https://your-server.example/hooks/jantaris"
}'The 202 response carries the task id and estimated_cost, so you know the price before the clip renders.
Webhook instead of polling
Polling loops were the noisiest part of most Sora integrations. With webhook_url set, Jantaris sends a POST to your endpoint when the task finishes, with the same JSON as GET /v1/tasks/{id} and an x-jantaris-signature header: a hex HMAC-SHA256 of the raw body, keyed with the webhook secret from your dashboard.
- Verify the signature on the raw bytes before parsing the JSON.
- Answer 2xx fast and download
output[0].urlin the background - result links are valid for a limited time. - Keep a slow poller on
GET /v1/tasks/{id}for tasks with no webhook after a few minutes. - Failed tasks cost nothing. A task that ends in
failedreleases its hold in full.
A full FastAPI and Node.js receiver is in async AI video with webhooks, and the reference is in the generate and webhooks docs.
What it costs
No subscription and no credits that reset. Top up from $10, the balance never expires, and each finished clip is charged from it:
| Model | Billing | 8 s clip | 30 s clip |
|---|---|---|---|
| Veo 3.1 Fast | per 8 s clip | from $0.354 per video | - |
| Veo 3.1 (Quality) | per 8 s clip | from $2.53 per video | - |
| Seedance 2.5 | per second | 8 × from $0.261 per second | 30 × from $0.261 per second |
| Wan 3.0 | per second | 8 × from $0.0777 per second | 30 × from $0.0777 per second |
| Kling 3.0 | per second | 8 × from $0.169 per second | - |
| MiniMax H3 | per second | 8 × from $0.161 per second | - |
"From" is the lowest resolution; higher resolution and audio cost more on some models. Try other settings in the AI cost calculator, see every rate on the pricing page, and compare video APIs model by model on the AI video API page.
FAQ
Does Sora still work anywhere?
No. The Sora app has been closed since April 26, 2026, and the API with sora-2 and sora-2-pro since September 24, 2026 (The Decoder). Veo 3.1, Seedance 2.5 and Wan 3.0 cover text-to-video with sound.
What happens to my Sora videos?
OpenAI asked users to download videos and images from their Sora library before the cutoff dates. According to The Decoder, user data is permanently deleted once the deadlines pass, and any extra export window would be announced by email. Check OpenAI's help center for the current status.
Will there be a Sora 3?
OpenAI has not announced a new Sora model or video product. According to The Decoder, Sora continues as a research project on world models.
Can I reuse my Sora prompts?
Mostly yes. Scene descriptions, camera moves and audio cues carry over. Adjust length and size to each model's limits, and test one clip before a batch.
Do I need to rewrite my whole integration?
No. Swap the endpoint, move parameters into input, map seconds and size as above, and replace the polling loop with a webhook. The response shape is the same for every video model, so switching between Seedance 2.5, Veo 3.1 and Wan 3.0 later is a one-field change.












