Halloween sale · up to 40% off your first month + bonus credits, claimable daily

Claim it

Official BytePlus partnerBuilt on BytePlus, ByteDance's official AI platform

API

Seedance API quickstart: your first AI video in five minutes

Generate your first Seedance video through the KreatorFlow API: key, one request in curl, Node or Python, polling, downloading the MP4, errors and per-second costs.

KreatorFlow8 min read
A developer typing on a backlit keyboard at night with a glowing film frame of an ocean wave floating above the keys
On this page
  1. Short answer
  2. Your first video in five steps
  3. Seedance API price per second (17 October 2026)
  4. What do you need before the first request?
  5. What does the first request look like?
  6. How do I create, poll and download in Node.js?
  7. How do I do the same in Python?
  8. What do the job statuses mean?
  9. Which errors should my code handle?
  10. Why send an Idempotency-Key?
  11. How do I add images, clips or audio as references?
  12. How much does the Seedance API cost?
  13. Frequently asked questions

Short answer

To generate a Seedance video by API, create a key in the KreatorFlow developer console, top up tokens (from $20), send POST /v1/videos with a model, prompt, duration and resolution, then poll GET /v1/jobs/{id} until it completes and download /v1/jobs/{id}/output. Seedance 2.0 at 720p costs $0.110 per second.

Updated:

Your first video in five steps

  1. 1

    Create an API key

    Open the developer console, create a key with the videos:create and jobs:read scopes, and store it on your server as KREATORFLOW_API_KEY. Never ship it to a browser or a mobile app.

  2. 2

    Top up tokens

    The API is prepaid: 1 token is $0.05 and top-ups start at $20. A job reserves its quoted cost when it is accepted and returns the quote in the create response.

  3. 3

    Send POST /v1/videos

    Pick a model alias (kreator-video-seedance-2, kreator-video-seedance-2-fast, kreator-video-seedance-2-mini or kreator-video-seedance-2-5), write a prompt and set duration, aspect_ratio and resolution. Add an Idempotency-Key header so a retried request never creates a second job.

  4. 4

    Poll the job

    GET /v1/jobs/{id} returns the status: created, queued, processing, completed, failed, canceled or blocked. Poll every 10 seconds or so, or pass a webhook_url and let KreatorFlow call you when the job ends.

  5. 5

    Download the MP4

    When the status is completed, GET /v1/jobs/{id}/output with the same key returns the file. Save it to your own storage: the output link is for fetching, not for permanent hosting.

Seedance API price per second (17 October 2026)

From the KreatorFlow developer API rate card: the per-second rate for each model and resolution, and the quoted cost of a 5-second clip without a video input.

Model (alias)ResolutionPer second5-second 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)

What do you need before the first request?

An account, an API key and a token balance. Everything else is a plain HTTPS JSON API at https://kreatorflow.ai/v1 with the key sent as "Authorization: Bearer <key>". There is no SDK to install; curl, fetch or requests are enough. KreatorFlow is an official BytePlus partner, and the video models are ByteDance's Seedance family.

Keys carry scopes. For video you need videos:create to submit and jobs:read to poll and download; images:create, audio:create, uploads:create and models:read cover the other endpoints. A request without the right scope returns 403 scope_missing.

What does the first request look like?

One POST to /v1/videos. The only required fields are model and prompt (up to 16,000 characters for Seedance 2.0); duration, aspect_ratio (ratio also works), resolution and generate_audio shape the clip. Seedance 2.0 takes 4, 5, 6, 8, 10, 12 and 15 seconds. Seedance 2.5 goes up to 30 seconds in one take.

The response is JSON with success: true and data.job (its id and status), plus balance_tokens and quoted_token_cost. The 8-second 720p clip below is quoted at 18 tokens ($0.90).

curl

curl https://kreatorflow.ai/v1/videos \ -H "Authorization: Bearer $KREATORFLOW_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: quickstart-0001" \ -d '{ "model": "kreator-video-seedance-2", "prompt": "Slow dolly-in on a ceramic mug on a sunlit kitchen table, steam rising", "duration": 8, "aspect_ratio": "16:9", "resolution": "720p", "generate_audio": true }'

How do I create, poll and download in Node.js?

The script below creates a 5-second vertical clip, polls every 10 seconds, waits out a 429 using the Retry-After header, and writes clip.mp4 when the job completes. It runs on Node 18 or later, which has fetch built in.

Node.js (ESM)

const KEY = process.env.KREATORFLOW_API_KEY; const BASE = "https://kreatorflow.ai/v1"; const auth = { Authorization: `Bearer ${KEY}` }; const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); async function createVideo(prompt) { const res = await fetch(`${BASE}/videos`, { method: "POST", headers: { ...auth, "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() }, body: JSON.stringify({ model: "kreator-video-seedance-2", prompt, duration: 5, aspect_ratio: "9:16", resolution: "720p" }), }); const body = await res.json(); if (!body.success) throw new Error(`${body.code}: ${body.error}`); return body.data.job; } async function waitForJob(job) { const done = ["completed", "failed", "canceled", "blocked"]; while (!done.includes(job.status)) { await sleep(10000); const res = await fetch(`${BASE}/jobs/${job.id}`, { headers: auth }); if (res.status === 429) { await sleep(Number(res.headers.get("Retry-After") ?? 5) * 1000); continue; } job = (await res.json()).data.job; } return job; } const job = await waitForJob(await createVideo("A paper boat drifting down a rainy street at dusk")); if (job.status === "completed") { const file = await fetch(`${BASE}/jobs/${job.id}/output`, { headers: auth }); const { writeFile } = await import("node:fs/promises"); await writeFile("clip.mp4", Buffer.from(await file.arrayBuffer())); } else { console.error(job.status, job.errorCode, job.errorMessage); }

How do I do the same in Python?

The same flow with the requests library. In production, swap the polling loop for a webhook so you are not holding a worker open while the clip renders.

Python 3

import os, time, uuid, requests KEY = os.environ["KREATORFLOW_API_KEY"] BASE = "https://kreatorflow.ai/v1" AUTH = {"Authorization": f"Bearer {KEY}"} created = requests.post( f"{BASE}/videos", headers={**AUTH, "Idempotency-Key": str(uuid.uuid4())}, json={"model": "kreator-video-seedance-2", "prompt": "Aerial shot over a misty pine forest at sunrise", "duration": 5, "aspect_ratio": "16:9", "resolution": "720p"}, ).json() if not created["success"]: raise RuntimeError(f'{created["code"]}: {created["error"]}') job = created["data"]["job"] while job["status"] not in ("completed", "failed", "canceled", "blocked"): time.sleep(10) res = requests.get(f'{BASE}/jobs/{job["id"]}', headers=AUTH) if res.status_code == 429: time.sleep(int(res.headers.get("Retry-After", "5"))) continue job = res.json()["data"]["job"] if job["status"] == "completed": with open("clip.mp4", "wb") as out: out.write(requests.get(f'{BASE}/jobs/{job["id"]}/output', headers=AUTH).content) else: print(job["status"], job.get("errorCode"), job.get("errorMessage"))

What do the job statuses mean?

created and queued mean the job is accepted and waiting; processing means the model is rendering; completed means the file is ready at /v1/jobs/{id}/output. failed, canceled and blocked are final: the job carries errorCode and errorMessage, and tokens reserved for a job that did not complete are released.

Treat every final status as an answer. Resending a failed job with the same Idempotency-Key returns the same failed job, so send it again with a new key and, if the error points at the prompt or a reference, change the input first.

  • created, queued: accepted, not started
  • processing: rendering
  • completed: download /v1/jobs/{id}/output
  • failed, canceled, blocked: final; read errorCode and errorMessage

Which errors should my code handle?

Errors come back as JSON with success: false, a machine-readable code and a readable error. The ones worth handling explicitly:

  • 400 prompt_required or model_not_found: fix the request; nothing was charged
  • 402 insufficient_balance: top up tokens, then resend
  • 403 scope_missing: the key lacks videos:create or jobs:read
  • 429 rate_limited: wait for the Retry-After header, then try again
  • 500 internal_error or 503 dispatch_disabled: try again later with a new Idempotency-Key

Why send an Idempotency-Key?

Networks drop responses. If your create call times out and you send it again with the same Idempotency-Key, KreatorFlow returns the job it already created (marked idempotent_replay: true) instead of starting and charging a second one. Use a fresh UUID per intended clip and reuse it only when resending that same request.

How do I add images, clips or audio as references?

Public HTTPS URLs can go straight into the request (reference_image_urls, reference_video_urls, reference_audio_urls, or a content array). For your own files, upload first: POST /v1/uploads returns a direct_upload_url, you PUT the bytes there, then POST /v1/uploads/complete and use the returned upload id. Limits are 50 MB for images, 200 MB for video and 15 MB for audio. Seedance 2.0 takes up to 9 images, 3 clips and 3 audio files per job.

A reference video's seconds are billed too: input plus output seconds at 60% of the per-second rate, and never less than the same job without the video. first_frame_upload_id and last_frame_upload_id pin the opening and closing frame.

How much does the Seedance API cost?

Video is billed per second of output at a rate set by model and resolution, rounded up to the cent and then to the next whole token. As of 17 October 2026: Seedance 2.0 is $0.110 per second at 720p and $0.240 at 1080p. Seedance 2.0 Fast is $0.084 per second at 720p, for drafts. The full table is below; the create response always carries the exact quote.

Frequently asked questions

Is there a free tier for the Seedance API?

No. The API is prepaid: tokens cost $0.05 each and top-ups start at $20. Each job's exact cost is quoted in the create response before it runs.

Which model alias should I start with?

Seedance 2.0 (kreator-video-seedance-2) for final clips with references, Seedance 2.0 Fast for quick drafts, and Seedance 2.5 for long single takes. GET /v1/models lists every alias your key can use.

How long does a video take?

Usually a few minutes, longer for long or high-resolution clips. Poll every 10 seconds or so, or set webhook_url to be told when the job finishes; do not hold a browser request open while it renders.

Can I call the API from the browser?

No. The key is a secret: call the API from your server or a serverless function and give your users the finished file or your own URL for it.

What happens if a job fails?

Its status becomes failed, blocked or canceled with errorCode and errorMessage, and the tokens reserved for it are released. Fix the input if the error points at it, then send the request again with a new Idempotency-Key.

Does the API add a watermark?

Set watermark: false on the request. The output is the clip you asked for at the resolution you requested.

Where do I store the finished videos?

In your own storage. /v1/jobs/{id}/output is a private download that needs your API key and does not last forever, so copy each finished file to your own bucket (S3, R2, B2 or similar) when the job completes and serve it from there. The storage guide shows how.

Is there an MCP server too?

Yes. Claude, ChatGPT and other MCP clients can generate through KreatorFlow; the AI video in Claude and ChatGPT guide shows how to connect it.

Ship your first clip today

Create a key, top up from $20 and send one request. Every job is quoted before it runs.

More guides