Skip to content

VancineAI/seedance-api-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vancine Seedance API Starter Kit

A standalone, production-quality starter kit for overseas developers who want to build on supported Seedance text-to-video and image-to-video workflows through the Vancine API.

This repository contains only developer-facing integration assets: copyable examples, importable collections, and an automation workflow. It is intentionally small, language-agnostic at the protocol level, and designed to be verified offline.

Vancine provides access to supported Seedance workflows through its documented asynchronous API. New accounts receive $1 in free credit and no credit card is required to register.

Try it instantly in Postman

Run in Postman

Published Postman documentation: https://documenter.getpostman.com/view/56666133/2sBY4Mv2Nf

The public Collection ships with an empty api_key on purpose. To make a real request, fork the Collection first, then fill in your API key through your own private (forked) or local variable. Never save a real key into the public or any shared Collection. New accounts receive $1 in free credit and no credit card is required to register.

Why this starter kit

A general product landing page tells you that an API exists. This repository is meant to help you make a working request as quickly as possible:

  1. Submit a Seedance video task and get a task_id.
  2. Poll the task status with bounded retries.
  3. Handle success, failure, and timeout explicitly.
  4. Retrieve the result URL.

If you can run one of the examples end to end, the integration path works.

Quick links

How the Vancine Seedance workflow works

Seedance requests use an asynchronous submit-and-poll workflow. Each request requires an API key sent as a bearer token.

POST /v1/video/generations
  -> { "task_id": "...", "status": "queued" }

GET /v1/video/generations/{task_id}
  -> queued -> in_progress -> completed | failed
  -> result URL once terminal

The submit call returns a task_id. You then poll the status endpoint on a fixed interval until it reaches a terminal state. Under normal conditions a video task completes within seconds to a few minutes depending on the model and payload, but your code must treat polling as bounded: a configurable interval, a maximum number of attempts or maximum wait time, and a clear exit for failure and timeout.

Requests are authenticated with an API key generated from the Vancine console:

Authorization: Bearer $VANCINE_API_KEY

Repository structure

README.md                              Product + integration guide
.env.example                           Environment variable template
.gitignore                             Default ignores
LICENSE                                 MIT License (examples)
SECURITY.md                            Reporting and handling guidance
examples/
  curl/
    generate.sh                        Submit + poll from the shell
  node/
    package.json                       Node example (ESM, native fetch)
    generate.mjs                       Submit + poll, importable functions
    generate.test.mjs                  Offline unit tests (node:test)
  python/
    requirements.txt                   Runtime dependency (requests)
    generate.py                        Submit + poll, importable functions
    test_generate.py                   Offline unit tests (unittest)
postman/
  Vancine-Seedance.postman_collection.json   Importable Seedance requests
n8n/
  vancine-seedance-workflow.json     Importable async workflow
scripts/
  validate-assets.mjs                Structure + link + secret checks

Quick start

Every example reads the API key from the environment. Copy the template first:

cp .env.example .env
# then edit .env and set VANCINE_API_KEY

To run the examples with the values from .env, load the file with set -a (so every assignment is auto-exported to the environment) before running any example, all from the repository root:

set -a
source .env
set +a

Environment variable

Variable Required Description
VANCINE_API_KEY yes API key from the Vancine console
VANCINE_BASE_URL no Override base URL (defaults to https://vancine.com)
SEEDANCE_MODEL no Model id (defaults to Doubao-Seedance-1.5-pro)
POLL_INTERVAL_SECONDS no Seconds between polls (default 5)
POLL_MAX_ATTEMPTS no Maximum poll attempts (default 120)

cURL

chmod +x examples/curl/generate.sh
./examples/curl/generate.sh

Prerequisites: curl, jq. The script is written for bash, checks both dependencies, exits cleanly on any non-2xx response, and never prints the full API key.

Node.js

cd examples/node
npm install
node cli.mjs

Requirements: Node.js 18+. The example uses native fetch and has no runtime dependencies beyond the Node standard library.

The code is split into two files on purpose:

  • examples/node/generate.mjs holds all param-driven, unit-testable logic (parsing, polling, network calls that take apiKey as a parameter). It never reads the environment, so it can be imported in tests without side effects.
  • examples/node/cli.mjs is the runnable entrypoint: it reads VANCINE_API_KEY from the environment and calls into generate.mjs.

Functions are written to be imported and tested without network access:

import {
  submitTask,
  extractTaskId,
  extractStatus,
  extractResultUrl,
  generateVideo,
} from "./generate.mjs";

Run the offline unit tests (these exercise generate.mjs only):

node --test

Python

cd examples/python
pip install -r requirements.txt
python generate.py

Requirements: Python 3.10+, requests. Parsing and polling logic is split into importable functions that can be tested without network access:

from generate import submit_task, fetch_task, extract_task_id, extract_status, extract_result_url

Run the offline unit tests:

python -m unittest test_generate.py -v

Postman

The collection is in postman/Vancine-Seedance.postman_collection.json and uses the v2.1 format.

It defines collection variables so you do not have to repeat shared values:

Variable Default Purpose
base_url https://vancine.com API host
api_key (empty — set this first) API credential
model Doubao-Seedance-1.5-pro Example model
task_id (empty) Set automatically

The collection contains two requests:

  1. Submit Seedance VideoPOST {{base_url}}/v1/video/generations
  2. Get Video Task StatusGET {{base_url}}/v1/video/generations/{{task_id}}

Import steps

  1. Open Postman.
  2. Choose Import in the top left.
  3. Select the Vancine-Seedance.postman_collection.json file.
  4. Open the collection, open the Variables tab, and set api_key to your key.
  5. Send Submit Seedance Video first.

After a successful submit, the test script on the submit request saves the task id into the task_id collection variable. The saved value comes from the first present field in this order: task_id, id, data.task_id, data.id. You can then send Get Video Task Status to poll the result. Set a bounded polling loop in your own test runner rather than relying on a single manual send.

The collection ships with an empty api_key and contains no credential.

n8n

The workflow is in n8n/vancine-seedance-workflow.json and uses standard n8n nodes: Manual Trigger, Set/Edit Fields, two HTTP Request nodes, Wait, IF, Merge, and a Code node (for state merging only — no network).

It expresses the same submit-and-poll lifecycle:

setFields
  -> submitTask (HTTP Request + Header Auth)
  -> saveTaskId (Set: extract task_id, carry config)
  -> waitInterval
  -> pollTask (HTTP Request + same Header Auth)
  -> mergeState (Code: merge response + carried state, increment poll_index)
  -> completed -> output result URL
  -> failed    -> stop with error (shows saved task_id + reason)
  -> timeout   -> stop (poll_index >= maxPolls)
  -> otherwise -> continue polling (bounded loop back to waitInterval)

Both submitTask and pollTask are real HTTP Request nodes that use generic Header Auth. You must assign the same Header Auth credential to both nodes after import — the Code node never makes network requests.

Loop state (task_id, poll_index, maxPolls, base_url) is carried on execution-scoped items via a Merge node (append mode) that combines the HTTP poll response with a parallel state-carrying Set node. This avoids n8n's stale $('NodeName') cross-node references inside loops and does not rely on global workflow staticData, so concurrent executions never overwrite each other's state.

A base_url field (default https://vancine.com) in the Set node is used by both HTTP Request nodes. No change is needed for production use.

Like the other examples, maxPolls defaults to 120 at a 5-second interval — about 10 minutes maximum — and stays user-configurable while the polling loop remains strictly bounded (poll_index >= maxPolls stops it; there is no infinite loop).

Verified in real n8n 2.30.4 against a local mock that enforces Authorization: Bearer on every request. All branches confirmed: completed (2 polls, correct result_url), failed (1 poll, error with saved task_id), timeout with maxPolls=3 (exactly 3 GETs, no 4th, no infinite loop). Two overlapping concurrent executions used different task_ids with no cross-contamination. Imports cleanly into a fresh, empty n8n database.

Import steps

  1. In n8n, open Workflows -> Import from File.
  2. Select vancine-seedance-workflow.json.
  3. Create one HTTP Header Auth credential:
    • Name: Authorization
    • Value: Bearer <YOUR_VANCINE_API_KEY>
  4. Assign that same credential to both HTTP Request nodes (submitTask and pollTask).
  5. The base_url field defaults to https://vancine.com — no change needed.
  6. Update model, prompt, and size on the Set node as needed, then run.

Compatibility

The Vancine API has grown across a few response shapes. These examples are written to accept both the current and the legacy shapes so they keep working without code changes when the upstream response format is normalized.

Task id

Resolved from the first present value in this order:

  1. top-level task_id
  2. top-level id
  3. data.task_id
  4. data.id

Task status

The values below are treated as terminal:

Current API Legacy upstream Meaning
queued Waiting
in_progress IN_PROGRESS Running
completed SUCCESS Done
failed FAILURE Failed

Examples treat completed/SUCCESS as success and failed/FAILURE as a failure.

Result URL

Resolved from the first present value in this order:

  1. metadata.url
  2. data.result_url
  3. data.data.content.video_url

Errors you should handle

Situation HTTP Typical body What to do
Authentication failed 401 error.message about the key or endpoint Verify the key and that you POST to /v1/video/generations, not a chat or TTS path
Insufficient balance 402 / 400 error.message about balance or quota Top up in the console or check your remaining credit
Invalid model or payload 400 error.message about model, prompt, size, etc. Check the model id and required parameters
Task failure 200 terminal failed/FAILURE, error.message or data.fail_reason Read the reason and adjust the prompt or inputs
Polling timeout no terminal state within the bounded window Stop polling; report the task_id for debugging
Non-2xx poll response 4xx/5xx transport-level error Stop; do not keep looping

Rules the examples follow:

  • A bounded polling loop with a configurable interval and a maximum attempt count. No infinite loop.
  • Clear, distinct handling for submission error, authentication error, insufficient balance, task failure, and timeout.
  • The full API key is never printed to logs or output.

Security

  • Always pass the API key through an environment variable. Never hard-code it.
  • This repository ships with example prompts only; no real credential is committed. See SECURITY.md for how to report a vulnerability or a committed secret.
  • Rotate the key from the Vancine console if you believe it is exposed.

Product limits

This starter kit documents access to supported Seedance workflows. It does not guarantee:

  • cheapest pricing
  • unlimited or unrestricted usage
  • guaranteed uptime
  • guaranteed output for every prompt
  • any safety-filter bypass

Vancine does not bypass model safety requirements. Model capabilities, input requirements, availability, and safety behavior follow their documented requirements. Model pricing and limits can change; the live pricing page and API documentation remain authoritative.

License

The example code in this repository is released under the MIT License.

The Seedance name and its underlying models are trademarks of their respective owners. This starter kit is an independent integration example and is not an official product of, or partnership with, those providers.