Seedance 2.0 API examples: how to call ByteDance text-to-video and image-to-video
Seedance 2.0 API — text-to-video and image-to-video examples
At a glance
- What is it?
- The apiframe-ai/seedance-2.0-api repository is a set of Python and JavaScript examples for calling Seedance 2.0 through Apiframe's hosted endpoint. It is not a model release, and the README is thin on pricing, rate limits and error handling.
- Who is it for?
- Adopt this repository if you want working Python and JavaScript calls against Apiframe's hosted Seedance 2.0 endpoint and you already have an Apiframe key. Do not adopt it if you need self-hosted inference, a documented price per clip, or a published error contract; the README covers none of those.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 58 days ago.
- What is it written in?
- GitHub does not report a main language for this repository.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Seedance 2.0 through Apiframe actually gives you
Seedance is a closed ByteDance model, and the repository says so plainly: it does not host model weights. What it ships is a set of example scripts that call Apiframe's hosted endpoint, POST /v2/videos/generate, with model set to "seedance-2". The README also lists seedance-2.5, seedance-2-fast and seedance-2-mini as related model ids on the same endpoint.
The audience is narrow and practical. You are a developer who wants generated video clips and does not want to run a diffusion stack. The README describes the output as 4 to 15 second clips at 480p, 720p, 1080p or 4K, with native synchronized audio, covering text-to-video, image-to-video and multimodal reference-to-video from images, video and audio. If your work is prompt engineering, product prototyping or pipeline integration, the examples are the point. If your work is model training or evaluation, this repository is not aimed at you.
The request, job and polling model behind the examples
Every example follows the same three-step flow, and the flow is the most useful thing the repository documents.
First, a POST to /v2/videos/generate with a JSON body containing model, prompt and a seedanceParams object. The response is a job handle, read as job['jobId'] in the Python sample. Second, a GET to /v2/jobs/{jobId} with the same headers, which returns a status field. The Python loop breaks when status is COMPLETED or FAILED and sleeps two seconds between checks. Third, the finished payload is read from the result field, which the README shows as a videoUrl pointing at a CDN host.
Authentication is a header, not a query parameter: X-API-Key carries the value of the APIFRAME_API_KEY environment variable, alongside Content-Type: application/json. The README notes that you can pass webhookUrl on the generate call instead of polling. That is the only asynchronous option it mentions, and it does not describe the webhook payload shape. The JavaScript path hides the loop behind client.jobs.waitFor(jobId), which is a convenience wrapper over the same polling, not a different transport.
Installing the examples and running a first text-to-video job
There is nothing to build. The Python examples need the requests package; the JavaScript examples need the SDK published as @apiframe-ai/sdk, which the README installs at the @next tag.
Set the API key first. The repository ships a .env.example containing a single line, APIFRAME_API_KEY=afk_your_api_key_here, and the README shows the same variable exported in the shell.
export APIFRAME_API_KEY=afk_your_api_key_hereInstall the Python dependency and run the text-to-video example. The README's own sequence copies .env.example to .env, asks you to set APIFRAME_API_KEY, then runs the script.
pip install requests
cp .env.example .env
python examples/text_to_video.pyFor JavaScript, install the SDK and call the same endpoint through the client.
npm i @apiframe-ai/sdk@nextimport { Apiframe } from "@apiframe-ai/sdk";
const client = new Apiframe({ apiKey: process.env.APIFRAME_API_KEY });
const { jobId } = await client.videos.generate({
model: "seedance-2",
prompt: "A cinematic slow-motion shot of a golden eagle soaring through a mountain valley at sunrise.",
seedanceParams: { duration: 8, resolution: "720p", aspect_ratio: "16:9", generate_audio: true },
});
const job = await client.jobs.waitFor(jobId);
console.log(job.result);What you should see is a jobId returned immediately, then a result object whose videoUrl points to an .mp4 on the CDN host shown in the README. If you would rather not poll, add webhookUrl to the generate call.
seedanceParams: the controls worth knowing before you spend a job
The parameter table is where the model's real constraints live, and several defaults are worth reading twice.
duration is an integer in seconds from 4 to 15, defaulting to 8. resolution accepts 480p, 720p, 1080p or 4k, defaulting to 720p. Note the casing inconsistency in the README: the table lists 4k in lower case while the prose says 4K. aspect_ratio defaults to 16:9 and also accepts 21:9, 4:3, 1:1, 3:4, 9:16 and adaptive. generate_audio defaults to true, so a job produces synchronized audio unless you turn it off.
For image-to-video there are start_image and end_image URL fields. For reference-to-video there are reference_image_urls capped at 9, reference_video_urls capped at 3 and reference_audio_urls capped at 3. seed gives reproducible generations, camera_fixed locks the camera and defaults to false, and web_search grounds the prompt with search and defaults to false.
One line in the README deserves attention: start/end frames and reference media are mutually exclusive on Seedance 2.5, but on Seedance 2.0 they can be combined, with the advice to keep inputs consistent. That is a behavioural difference between model versions on the same endpoint, and it is the kind of thing that will bite you when you switch the model id without rereading the table.
Where these examples stop being enough
The README gives no price per clip, no rate limit, no concurrency guidance and no error taxonomy. It shows COMPLETED and FAILED as terminal statuses but does not list other states, retry semantics or what a FAILED job returns in the result field. For a paid, asynchronous video API, that is the gap that matters most in production: you cannot size a queue or a retry policy from this repository alone.
The polling loop in the Python example is also a starting point, not a pattern to ship. It sleeps two seconds forever until a terminal status arrives, with no timeout and no backoff. A job that never reaches COMPLETED will hold that loop open indefinitely. The JavaScript waitFor helper may handle this differently, but the README does not document its timeout behaviour, so treat it as unverified.
Finally, the repository does not host weights, so it is the wrong tool entirely if your requirement is self-hosted or offline inference, or if you need to pin a model snapshot for reproducibility. The only reproducibility control exposed here is seed, and that is a parameter of the hosted service, not a local artefact.
Calling ByteDance's model directly instead of through Apiframe
The real alternative is going straight to ByteDance's own Seedance access rather than through a reseller. The difference is not the model, since Seedance is ByteDance's either way, but the surface you integrate against. Apiframe gives you one endpoint, POST /v2/videos/generate, one header for auth, a jobId to poll and a videoUrl back, with model ids like seedance-2, seedance-2.5, seedance-2-fast and seedance-2-mini selected by a single field. That means one integration can swap model versions without changing code.
A direct integration means ByteDance's own account, quota and SDK conventions, which this repository does not describe. The trade-off is control versus convenience: direct access may expose capacity or configuration the reseller does not, while the reseller route keeps a single key and a single request shape across model versions. If you are already standardized on Apiframe for other models, the examples here fit that pattern. If you need ByteDance-specific features that Apiframe does not surface, the README offers no bridge, and you would be integrating elsewhere.
Licence, maintenance and what upgrading costs you
The licence field for this repository is unknown, and the README's own licence section says only that the example code is provided as-is, that Seedance outputs are subject to ByteDance's terms, and that Seedance is a trademark of ByteDance Ltd. That is not a software licence grant, and it does not address redistribution or commercial use of the example code. If you plan to vendor these scripts into a product, the repository does not answer the question for you, and the absence of a licence file at the top level is itself the finding. Nothing here is legal advice; it is a description of what the repository does and does not state.
On maintenance, the last push was on 2026-08-14, which is recent enough that the examples reflect the current endpoint shape, but there are no tagged releases, so there is no version history to pin against. Upgrading means tracking the main branch and the README table. Watch the model-version differences: the mutual-exclusion rule for start/end frames versus reference media applies on Seedance 2.5 but not on Seedance 2.0, so a model id change is a behavioural change, not just a string swap. Budget for rereading the parameter table whenever you move between seedance-2, seedance-2.5, seedance-2-fast and seedance-2-mini.
Editorial conclusion
Adopt this repository if you want working Python and JavaScript calls against Apiframe's hosted Seedance 2.0 endpoint and you already have an Apiframe key. Do not adopt it if you need self-hosted inference, a documented price per clip, or a published error contract; the README covers none of those. Verify first that your account can reach POST /v2/videos/generate, that your prompt and reference media pass the provider's content rules, and what your Apiframe plan bills per generation, because the repository itself does not state a cost.
Frequently asked questions
Does Seedance 2.0 have an API?
Yes. The README states that inference runs on POST /v2/videos/generate with model set to "seedance-2", and that the repository provides Python and JavaScript examples for calling it through Apiframe. Seedance itself is a closed model, and the repository does not host model weights.
How much does the Seedance 2.0 API cost?
The README does not state a price per generation, a credit cost or a plan tier. It documents the request shape, the parameter table and the returned videoUrl, so any cost figure has to come from your Apiframe account rather than this repository.
Where can I find an API key for Seedance 2.0?
The examples read the key from the APIFRAME_API_KEY environment variable, and the repository ships a .env.example with the placeholder line APIFRAME_API_KEY=afk_your_api_key_here. The README does not explain where to obtain a real key, so that step is outside the repository.
How do I use the Seedance 2.0 API?
Send a POST to https://api.apiframe.ai/v2/videos/generate with the X-API-Key header and a JSON body containing model, prompt and seedanceParams, then poll GET /v2/jobs/{jobId} until status is COMPLETED or FAILED and read the result field. The README also notes you can pass webhookUrl on the generate call instead of polling.
Is the Seedance 2.0 API free?
The README does not describe a free tier, trial credits or any pricing at all. It only shows how to call the endpoint with an Apiframe key, so nothing in the repository confirms or denies free access.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/apiframe-ai-seedance-2-0-api)