On this page
- Short answer
- Migrate from the Sora API in five steps
- Sora API concepts and their KreatorFlow /v1 equivalents
- KreatorFlow API video prices per second
- What happened to the Sora API?
- What should a Sora API replacement have?
- How does the KreatorFlow API map to the Sora API?
- How do I send my first request?
- How do I translate Sora's size and seconds?
- How do I poll for the result?
- How do I get webhooks instead of polling?
- How do references, remixes and characters carry over?
- What does the KreatorFlow API cost per second?
- What is different from Sora, and what will I need to change?
- Migration checklist
- Who runs the models behind the KreatorFlow API?
- Frequently asked questions
Short answer
OpenAI removed the Sora 2 Videos API on 24 September 2026 and lists no replacement; Azure's last sora-2 preview reached its retirement date on 15 October 2026. The KreatorFlow /v1 API is a close match: async create-then-poll jobs, signed webhooks and per-second pricing, running ByteDance's Seedance 2.0 at $0.110 per second for 720p.
Migrate from the Sora API in five steps
- 1
Create a key and top up
Open the developer console, create an API key with the videos:create and jobs:read scopes and top up prepaid tokens (from $20). Keep the key on your server, in an environment variable such as KREATORFLOW_API_KEY.
- 2
Point the create call at /v1/videos
Send the prompt you sent to Sora to POST https://kreatorflow.ai/v1/videos with a model alias such as kreator-video-seedance-2. Replace seconds with duration, and size with aspect_ratio plus resolution.
- 3
Swap the status call
Replace GET /v1/videos/{video_id} with GET /v1/jobs/{job_id}. The job sits in data.job; wait for completed, failed, canceled or blocked, then read the file from providerOutputUrl.
- 4
Move to webhooks
Add webhook_url to the create body and verify the X-KreatorFlow-Signature header on every callback. Keep a slow poll as the fallback for any callback you miss.
- 5
Re-test prompts, then cut over
Seedance is a different model from Sora, so run your most important prompts against your stored Sora outputs, adjust wording and lengths, and switch traffic once results and costs look right.
Sora API concepts and their KreatorFlow /v1 equivalents
Sora column as documented in OpenAI's Videos API reference; KreatorFlow column from the live /v1 API, as of October 2026.
| Sora API (OpenAI) | KreatorFlow /v1 | Notes |
|---|---|---|
| Authorization: Bearer (OpenAI key) | Authorization: Bearer (KreatorFlow API key) | Scopes: videos:create to create, jobs:read to poll and download |
| POST /v1/videos | POST https://kreatorflow.ai/v1/videos | Answers 202 with data.job and quoted_token_cost |
| model: sora-2, sora-2-pro | model: kreator-video-seedance-2, kreator-video-seedance-2-fast and other aliases | GET /v1/models lists aliases and limits, no key needed |
| prompt | prompt | Up to 16,000 characters on Seedance 2.0 |
| seconds: "4", "8" or "12" (string) | duration (number) | Seedance 2.0: 4, 5, 6, 8, 10, 12 and 15 seconds |
| size: 1280x720, 720x1280, 1792x1024, 1024x1792 | aspect_ratio (or ratio) and resolution | 480p, 720p, 1080p and 4K; 16:9, 9:16, 1:1, 4:3, 3:4 and 21:9 or adaptive |
| input_reference (image_url or file_id) | references [{ type: image_url, url, role: first_frame }] or first_frame_upload_id | Also last_frame_upload_id, reference images, video and audio references |
| file_id | POST /v1/uploads, PUT to direct_upload_url, POST /v1/uploads/complete | Returns an upload_id to reference |
| GET /v1/videos/{video_id} | GET /v1/jobs/{job_id} | Job in data.job |
| Status: queued, in_progress, completed, failed | created, queued, processing, completed, failed, canceled, blocked | The last four are terminal |
| GET /v1/videos/{video_id}/content | job.providerOutputUrl or GET /v1/jobs/{job_id}/output | The link expires at providerOutputExpiresAt |
| POST /v1/videos/{video_id}/remix, /v1/videos/edits, /v1/videos/extensions | POST /v1/video-edits with edit_mode transform, restyle or extend | Source clip by upload id or HTTPS URL |
| POST /v1/videos/characters | POST /v1/characters (mode register), then character_ids | GET and DELETE /v1/characters/{character_id} |
| Webhooks | webhook_url or callback_url on each job | Signed: X-KreatorFlow-Signature t=…,v1=HMAC-SHA256 |
| GET /v1/videos (list), DELETE /v1/videos/{video_id} | No equivalent | Store your job ids; job history is in the console |
| No audio parameter on create | generate_audio: true | Plus up to 3 audio references on Seedance 2.0 |
Sources, as checked:
- OpenAI Videos API reference (checked 17 October 2026): developers.openai.com/api/reference/resources/videos
- OpenAI API deprecations (checked 17 October 2026): developers.openai.com/api/docs/deprecations
- Microsoft Foundry model retirement schedule (checked 17 October 2026): learn.microsoft.com/en-us/azure/foundry/openai/concepts/model-retirement-schedule
- OpenAI Help: Sora discontinuation (checked 17 October 2026): help.openai.com/en/articles/20001152-what-to-know-about-the-sora-app-discontinuation
- KreatorFlow API docs (developer console): developers.kreatorflow.ai/?section=docs
KreatorFlow API video prices per second
Price per second of video and the quoted price of a 5-second clip without video input, from the same quote that bills a job (1 token = $0.05). As of October 2026.
| Model (API alias) | Resolution | Per second | 5 s clip |
|---|---|---|---|
| Seedance 2.0 (kreator-video-seedance-2) | 480p | $0.076/s | $0.40 (8 tokens) |
| Seedance 2.0 (kreator-video-seedance-2) | 720p | $0.110/s | $0.55 (11 tokens) |
| Seedance 2.0 (kreator-video-seedance-2) | 1080p | $0.240/s | $1.20 (24 tokens) |
| Seedance 2.0 (kreator-video-seedance-2) | 4K | $0.580/s | $2.90 (58 tokens) |
| Seedance 2.0 Fast (kreator-video-seedance-2-fast) | 480p | $0.058/s | $0.30 (6 tokens) |
| Seedance 2.0 Fast (kreator-video-seedance-2-fast) | 720p | $0.084/s | $0.45 (9 tokens) |
| Seedance 2.0 Fast (kreator-video-seedance-2-fast) | 1080p | $0.183/s | $0.95 (19 tokens) |
| Seedance 2.0 Mini (kreator-video-seedance-2-mini) | 480p | $0.058/s | $0.30 (6 tokens) |
| Seedance 2.0 Mini (kreator-video-seedance-2-mini) | 720p | $0.067/s | $0.35 (7 tokens) |
| Seedance 2.0 Mini (kreator-video-seedance-2-mini) | 1080p | $0.135/s | $0.70 (14 tokens) |
| Seedance 2.5 (kreator-video-seedance-2-5) | 480p | $0.143/s | $0.75 (15 tokens) |
| Seedance 2.5 (kreator-video-seedance-2-5) | 720p | $0.207/s | $1.05 (21 tokens) |
| Seedance 2.5 (kreator-video-seedance-2-5) | 1080p | $0.444/s | $2.25 (45 tokens) |
| Seedance 2.5 (kreator-video-seedance-2-5) | 4K | $0.999/s | $5.00 (100 tokens) |
Rate times seconds, rounded up to the cent and then to the next whole token. Jobs with video input are billed on input plus output seconds at 60% of the rate. Tokens for a failed job are released.
Sources, as checked:
- KreatorFlow developer console (rate card and live quotes): developers.kreatorflow.ai
What happened to the Sora API?
OpenAI shut it down. OpenAI's deprecations page says developers using the Videos API were notified on 24 March 2026 that the Videos API and every Sora 2 model (sora-2, sora-2-pro and their dated snapshots) would be removed from the API on 24 September 2026, and the replacement column for each of them is empty. The Videos API reference now opens by saying the Sora 2 models and Videos API were shut down on 24 September 2026 and that no one-to-one replacement API is available. We checked both pages on 17 October 2026.
The consumer app went first. OpenAI's help center article on the Sora discontinuation gives 26 April 2026 as the end of the Sora web and app experiences, with the API following in September.
Azure was the last route, and it has closed too. Microsoft's Foundry model retirement schedule lists sora-2 version 2025-10-06 (Preview) as retired on 15 July 2026, and sora-2 version 2025-12-08 (Preview) with a retirement date of 15 October 2026 and no replacement. Microsoft's lifecycle policy says a retired model answers every request with 410 Gone. As of October 2026, there is no first-party way to call Sora 2 from code.
So any production code that called Sora, on OpenAI or Azure, now needs another video model behind another API.
What should a Sora API replacement have?
It should keep the shape your code already has: an asynchronous job, a status you can poll, a callback when it finishes and a price you know before you send. Then the migration is a field mapping, not a rewrite. Check each of these on any provider:
- Async jobs: a create call that returns a job id straight away and a status endpoint, not a request that holds the connection open for minutes.
- Webhooks you can trust: callbacks for finished and failed jobs, signed so you can reject forgeries, with polling still available as a fallback.
- Idempotency: an Idempotency-Key header, so a network retry on your side never creates and bills a second clip.
- Pricing per second, quoted up front: the cost of a job in the create response, with clear rounding and a clear rule on whether input video is billed.
- References: image references (first frame, last frame, style or character) and, if you need them, video and audio references, which Sora's create call did not take.
- Audio: whether the model can generate sound with the clip, and how you switch it on.
- Resolutions, aspect ratios and lengths: the exact values the API accepts, so you can map Sora's size and seconds without guessing.
- Rate limits: documented behaviour on 429 responses, ideally with a Retry-After header your client can follow.
- Output delivery: how long a download link lasts and whether you can fetch the file again later.
- Support and SLA: who answers when a job fails, and whether your use case needs a written uptime commitment. Ask any provider for it in writing before you move production traffic.
How does the KreatorFlow API map to the Sora API?
Almost one to one on the common path. The KreatorFlow developer API also creates video with POST /v1/videos and returns an asynchronous job, which you check with GET /v1/jobs/{job_id} or hear about through a signed webhook. The differences are field names and values: duration instead of seconds, aspect_ratio and resolution instead of a pixel size, and a model alias that names a Seedance model instead of sora-2.
Every response uses the same envelope: success, then data on success, or code and error on failure. A create call answers 202 with data.job, your balance_tokens and quoted_token_cost, so you know what a clip costs before it renders. On Seedance 2.0, video jobs accept 4, 5, 6, 8, 10, 12 and 15 seconds, 480p, 720p, 1080p and 4K, and the aspect ratios 16:9, 9:16, 1:1, 4:3, 3:4 and 21:9 or adaptive. GET /v1/models lists every alias with its limits and needs no key, so your code can read them instead of hard-coding them.
How do I send my first request?
Swap the URL, the key and three fields. Authenticate with Authorization: Bearer and your KreatorFlow API key, post JSON to https://kreatorflow.ai/v1/videos and send an Idempotency-Key header, so a retried request returns the same job instead of creating a second one. The request below asks Seedance 2.0 for an 8-second 16:9 clip at 720p with generated audio and a webhook.
Prompts can be long: Seedance 2.0 takes up to 16,000 characters. If a field is out of range, the API answers 400 with a specific code such as duration_not_supported, aspect_ratio_not_supported or resolution_not_supported, and the message lists the allowed values, so mapping mistakes show up on the first call rather than after a render.
curl: create a video job
curl https://kreatorflow.ai/v1/videos -H "Authorization: Bearer $KREATORFLOW_API_KEY" -H "Content-Type: application/json" -H "Idempotency-Key: migrate-0001" -d '{"model":"kreator-video-seedance-2","prompt":"Slow dolly-in on a ceramic mug on a sunlit kitchen table, steam rising, shallow depth of field","duration":8,"aspect_ratio":"16:9","resolution":"720p","generate_audio":true,"webhook_url":"https://example.com/kreatorflow/webhook"}'
How do I translate Sora's size and seconds?
Split size into an aspect ratio and a resolution, and turn seconds into a number. Sora took size as a pixel string (720x1280, 1280x720, 1024x1792 or 1792x1024) and seconds as a string ("4", "8" or "12"). KreatorFlow takes aspect_ratio (or ratio) and resolution as two fields, and duration as a number from the model's list.
All three Sora lengths are valid on Seedance 2.0 (4, 5, 6, 8, 10, 12 and 15 seconds). Seedance 2.0 Fast stops at 10 seconds, so send 12-second jobs to Seedance 2.0 or shorten them. The helper below turns a stored Sora request body into a KreatorFlow one; the two larger Sora sizes map to 1080p, the closest tier above them.
JavaScript: Sora body to KreatorFlow body
const SIZE_MAP = { "1280x720": { aspect_ratio: "16:9", resolution: "720p" }, "720x1280": { aspect_ratio: "9:16", resolution: "720p" }, "1792x1024": { aspect_ratio: "16:9", resolution: "1080p" }, "1024x1792": { aspect_ratio: "9:16", resolution: "1080p" } }; function soraToKreatorFlow(sora) { const size = SIZE_MAP[sora.size ?? "720x1280"] ?? SIZE_MAP["720x1280"]; return { model: "kreator-video-seedance-2", prompt: sora.prompt, duration: Number(sora.seconds ?? 4), aspect_ratio: size.aspect_ratio, resolution: size.resolution, generate_audio: true }; }
How do I poll for the result?
Call GET /v1/jobs/{job_id} until the status is final. Sora reported queued, in_progress, completed and failed. A KreatorFlow job moves through created, queued and processing and ends as completed, failed, canceled or blocked, so treat those last four as terminal. When a job is completed, job.providerOutputUrl holds the video and job.providerOutputExpiresAt says when that link stops working; GET /v1/jobs/{job_id}/output streams the same file with your key whenever you need it again.
Polling is rate limited per key and per job. A 429 response carries a Retry-After header in seconds: wait that long and try again, as the loop below does. A failed job carries errorCode and errorMessage, and the tokens reserved for it go back to your balance.
JavaScript (fetch): create, then poll until done
async function createAndWait(body, key) { const headers = { "Authorization": `Bearer ${key}`, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() }; const created = await fetch("https://kreatorflow.ai/v1/videos", { method: "POST", headers, body: JSON.stringify(body) }).then((r) => r.json()); if (!created.success) throw new Error(created.code + ": " + created.error); let job = created.data.job; while (!["completed", "failed", "canceled", "blocked"].includes(job.status)) { await new Promise((resolve) => setTimeout(resolve, 10000)); const res = await fetch(`https://kreatorflow.ai/v1/jobs/${job.id}`, { headers: { "Authorization": `Bearer ${key}` } }); if (res.status === 429) { await new Promise((resolve) => setTimeout(resolve, Number(res.headers.get("Retry-After") ?? 5) * 1000)); continue; } job = (await res.json()).data.job; } return job; }
How do I get webhooks instead of polling?
Send webhook_url (or callback_url) with the create call, as an HTTPS address. KreatorFlow posts a JSON event to it when the job reaches a terminal state: completed, failed, canceled or blocked. The event has an id, a type such as job.completed and the job under data.job, and the request carries the headers X-KreatorFlow-Event-Id, X-KreatorFlow-Event-Type, X-KreatorFlow-Job-Id, X-KreatorFlow-Timestamp and X-KreatorFlow-Signature.
Verify every call before you trust it. The signature header reads t=<timestamp>,v1=<hex>, where the hex value is an HMAC-SHA256 of the timestamp, a dot and the raw request body, keyed with your workspace's webhook signing secret from the console. Compute it over the raw body before any JSON parsing, compare in constant time and reject old timestamps. Use the event id to ignore duplicates, and keep a slow poll running for jobs whose callback never arrives.
Node.js: verify a KreatorFlow webhook
import { createHmac, timingSafeEqual } from "node:crypto"; function verifyKreatorFlowWebhook(rawBody, signatureHeader, secret) { const parts = Object.fromEntries(signatureHeader.split(",").map((part) => part.split("="))); const expected = createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex"); const signed = typeof parts.v1 === "string" && parts.v1.length === expected.length && timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1)); const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300; return signed && fresh; }
How do references, remixes and characters carry over?
Image references become references or upload ids. Sora's input_reference took one image, by URL or file id, as the first frame. On KreatorFlow you can pass a public image as { "type": "image_url", "url": "...", "role": "first_frame" } in references, or upload the file and send first_frame_upload_id (plus last_frame_upload_id for an end frame). Seedance 2.0 takes up to 9 image references, 3 video references and 3 audio references per job; plain reference images guide appearance and style. Frame images and reference images cannot be mixed in one job, and the API says so with a 400 before anything is billed.
Files go through uploads. Where Sora used file ids, KreatorFlow uses a three-step upload: POST /v1/uploads returns a direct_upload_url and its headers, you PUT the bytes there, and POST /v1/uploads/complete gives you the upload_id to reference.
Remix, edit and extend become /v1/video-edits. Sora had remix, edits and extensions endpoints. KreatorFlow has POST /v1/video-edits with edit_mode set to transform, restyle or extend, and the source clip as source_video_upload_id or a public HTTPS URL in source_video_url. Edits need a Seedance 2 model alias.
Characters become registered characters. Register a reusable character with POST /v1/characters (mode register and an image upload_id), store the character_id it returns and pass it in character_ids on /v1/videos. GET and DELETE /v1/characters/{character_id} manage them.
What does the KreatorFlow API cost per second?
Every video job is priced by the second, at a rate set by the model and resolution. You prepay tokens (1 token = $0.05); a job costs the rate times its length, rounded up to the cent and then to the next whole token, and the create response returns that quote. Seedance 2.0 at 720p is $0.110 per second, so a 5-second clip is $0.55 (11 tokens) and a 12-second clip, Sora's longest, is $1.35. At 1080p the rate is $0.240 per second, so 10 seconds cost $2.40. Seedance 2.0 Fast at 720p is $0.084 per second, for drafts and batches.
Generated audio has no separate charge on the rate card. Video you send in does: a job with a reference video or an edit's source clip is billed on input plus output seconds at 60% of the normal rate, and never costs less than the same job without video. Its create response sets quoted_token_cost_is_maximum, because the input length is only measured once the job runs; the final charge uses the measured length and the rest is released.
For how these rates compare with other Seedance providers, setting by setting and dated, see the per-second comparison and the Seedance API pricing guide.
What is different from Sora, and what will I need to change?
Mostly naming, a few endpoints with no equivalent, and the model itself. Plan for these before you switch:
- A different model: Seedance is ByteDance's video model, not Sora, so the same prompt gives a different clip. Re-test your important prompts and expect to adjust camera and motion wording.
- Model names: aliases such as kreator-video-seedance-2, kreator-video-seedance-2-fast and kreator-video-pro replace sora-2 and sora-2-pro. Read the current list from GET /v1/models.
- Size becomes two fields: aspect_ratio (or ratio) and resolution, which also opens 1:1, 4:3, 3:4, 21:9 and 4K on Seedance 2.0.
- Audio is opt-in: set generate_audio to true when you want sound with the clip.
- Response shape: the job is in data.job with camelCase fields such as providerOutputUrl, errorCode and completedAt, inside a success envelope.
- No list or delete endpoint for video jobs: Sora had GET /v1/videos and DELETE /v1/videos/{video_id}. On KreatorFlow, store the job ids you create and look each one up by id; the console shows your job history.
- Download links expire: copy finished files to your own storage, or call GET /v1/jobs/{job_id}/output when you need a file again.
Migration checklist
Work through this before you move production traffic from Sora to the KreatorFlow API:
- Find every call to /v1/videos, /v1/videos/{id}, /v1/videos/{id}/content and any remix, edit or extension endpoint, plus any Azure sora-2 deployment.
- Create a KreatorFlow API key with videos:create and jobs:read, store it as a server-side secret and top up tokens.
- Map model, seconds, size and input_reference to model, duration, aspect_ratio, resolution and references or first_frame_upload_id.
- Send an Idempotency-Key with every create call, and reuse a key only when you retry the same request.
- Replace status polling with GET /v1/jobs/{job_id}, treat completed, failed, canceled and blocked as final, and honour Retry-After on 429.
- Add webhook_url, verify X-KreatorFlow-Signature over the raw body and de-duplicate on the event id.
- Copy finished videos from providerOutputUrl to your own storage before providerOutputExpiresAt.
- Move file uploads to POST /v1/uploads, the direct PUT and POST /v1/uploads/complete.
- Re-run your top prompts, compare them against your stored Sora outputs and update your prompt templates.
- Recalculate unit costs from quoted_token_cost and watch your balance, so jobs are never refused for lack of tokens.
Who runs the models behind the KreatorFlow API?
Seedance and Seedream are ByteDance's video and image models. KreatorFlow is an official partner of BytePlus, ByteDance's enterprise AI platform, and the developer API runs on BytePlus, ByteDance's official AI platform. The same key also covers image jobs on POST /v1/images and speech and sound on POST /v1/audio, so moving off Sora can be the start of one integration rather than three.
Moving off Sora
Run your first Seedance job on the KreatorFlow API
Create a key in the developer console, top up from $20 and send your first /v1/videos job. The price is in the create response before the clip renders.
Frequently asked questions
Is the Sora API shut down?
Yes. OpenAI's deprecations page lists the Videos API and every Sora 2 model as removed from the API on 24 September 2026, after notice on 24 March 2026, with no replacement. Microsoft's last sora-2 preview on Azure had a retirement date of 15 October 2026. Checked 17 October 2026.
Did OpenAI name a replacement for the Sora API?
No. The replacement column on OpenAI's deprecations page is empty for the Videos API and all Sora 2 models, and the Videos API reference says no one-to-one replacement API is available. You need a third-party video API.
What is the best Sora API alternative?
The one that fits your code and your clips. Look for async jobs, signed webhooks, idempotency, per-second prices quoted up front and the references and lengths you need, then test your own prompts. The KreatorFlow API covers those points with ByteDance's Seedance 2.0 and keeps Sora's create-then-poll shape.
How much does the KreatorFlow video API cost?
Seedance 2.0 at 720p is $0.110 per second: $0.55 for a 5-second clip. Each model and resolution has its own rate, listed in the price table, and every job's price is in its create response.
Does the KreatorFlow API generate audio like Sora?
It can. Set generate_audio to true on /v1/videos for sound with the clip; it stays off unless you ask for it, and the rate card has no audio surcharge. Seedance 2.0 also takes up to 3 audio references per job.
Can I keep making 12-second clips like on Sora?
Yes, on Seedance 2.0, which takes 4, 5, 6, 8, 10, 12 and 15 seconds. Seedance 2.0 Fast stops at 10 seconds. Seedance 2.5 goes up to 30 seconds.
Does the KreatorFlow API have webhooks?
Yes. Send webhook_url or callback_url with a job and KreatorFlow posts a signed event when it completes, fails, is canceled or is blocked. Verify X-KreatorFlow-Signature with your signing secret and keep polling GET /v1/jobs/{job_id} as a fallback.



