How to Access Seedance 2.0 via API: Step-by-Step Integration Guide

How to Access Seedance 2.0 via API: Step-by-Step Integration Guide

Seedance 2.0 is ByteDance's quad-modal video generation model, and accessing it programmatically is straightforward through CCAPI's OpenAI-compatible API. This step-by-step guide walks you through everything from account creation to advanced batch processing and webhook callbacks. You will be generating AI videos from your application in under 10 minutes.

Prerequisites

Before you begin, make sure you have:

  • A programming environment with Python 3.8+ or Node.js 18+
  • Basic familiarity with REST APIs and async patterns
  • A CCAPI account (free to create, includes trial credits)

No ByteDance account, Chinese phone number, or specialized SDK is required. CCAPI handles all provider authentication and routing on your behalf.

API request flow — from client through auth, billing, routing, to provider and back

Step 1: Create Your CCAPI Account

  1. Visit ccapi.ai/dashboard and click Sign Up
  2. Create your account using email, Google, or GitHub authentication
  3. Your account is instantly provisioned with free trial credits --- enough to generate several test videos

CCAPI is an AI API gateway that provides a single, OpenAI-compatible endpoint for multiple providers including ByteDance, Kuaishou, OpenAI, Google, and more. This means you do not need separate accounts for each AI provider.

Step 2: Get Your API Key

  1. Navigate to your API Keys page in the CCAPI dashboard
  2. Click Create New Key
  3. Give your key a descriptive name (e.g., "seedance-dev")
  4. Copy the key immediately --- it will not be shown again
  5. Store it securely (environment variable, secrets manager, or .env file)
# Add to your .env file
CCAPI_API_KEY=sk-your-api-key-here

Your API key works across all models available on CCAPI, not just Seedance 2.0. You can use the same key to access Kling 3.0, Sora 2, Veo 3.1, and all LLM models.

Step 3: Install Dependencies

CCAPI is fully compatible with the official OpenAI SDK. You do not need a custom library.

Python:

pip install openai python-dotenv

Node.js:

npm install openai dotenv

cURL:

No installation needed. cURL is pre-installed on macOS and most Linux distributions.

Step 4: Make Your First API Call

Here is the simplest possible Seedance 2.0 generation request. This creates a 5-second video from a text prompt.

Python:

import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()

client = OpenAI(
    api_key=os.getenv("CCAPI_API_KEY"),
    base_url="https://api.ccapi.ai/v1"
)

# Submit a video generation job
response = client.chat.completions.create(
    model="bytedance/seedance-2.0",
    messages=[
        {
            "role": "user",
            "content": "A golden retriever running through autumn leaves in slow motion, cinematic lighting, shallow depth of field"
        }
    ]
)

print("Job submitted:", response)

Node.js / TypeScript:

import OpenAI from "openai";
import "dotenv/config";

const client = new OpenAI({
  apiKey: process.env.CCAPI_API_KEY,
  baseURL: "https://api.ccapi.ai/v1",
});

async function generateVideo() {
  const response = await client.chat.completions.create({
    model: "bytedance/seedance-2.0",
    messages: [
      {
        role: "user",
        content:
          "A golden retriever running through autumn leaves in slow motion, cinematic lighting, shallow depth of field",
      },
    ],
  });

  console.log("Job submitted:", response);
}

generateVideo();

cURL:

curl -X POST https://api.ccapi.ai/v1/video/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $CCAPI_API_KEY" \
  -d '{
    "model": "bytedance/seedance-2.0",
    "prompt": "A golden retriever running through autumn leaves in slow motion, cinematic lighting",
    "duration": 5,
    "aspect_ratio": "16:9"
  }'

Step 5: Handle the Response

Video generation is an asynchronous process. The initial API call returns a job ID, which you then poll until the video is complete.

Async video generation lifecycle — submit, poll, and retrieve the completed video

Python polling example:

import time
import requests

def poll_video_job(job_id: str, api_key: str, max_wait: int = 120) -> dict:
    """Poll a video generation job until completion or timeout."""
    url = f"https://api.ccapi.ai/v1/video/generations/{job_id}"
    headers = {"Authorization": f"Bearer {api_key}"}

    elapsed = 0
    poll_interval = 5  # seconds

    while elapsed < max_wait:
        response = requests.get(url, headers=headers)
        data = response.json()

        if data["status"] == "completed":
            print(f"Video ready: {data['result_urls'][0]}")
            return data
        elif data["status"] == "failed":
            raise Exception(f"Generation failed: {data.get('error', 'Unknown error')}")

        print(f"Status: {data['status']} ({elapsed}s elapsed)")
        time.sleep(poll_interval)
        elapsed += poll_interval

    raise TimeoutError(f"Job {job_id} did not complete within {max_wait}s")

Node.js polling example:

async function pollVideoJob(
  jobId: string,
  apiKey: string,
  maxWait = 120000
): Promise<any> {
  const url = `https://api.ccapi.ai/v1/video/generations/${jobId}`;
  const headers = { Authorization: `Bearer ${apiKey}` };
  const pollInterval = 5000; // 5 seconds
  let elapsed = 0;

  while (elapsed < maxWait) {
    const res = await fetch(url, { headers });
    const data = await res.json();

    if (data.status === "completed") {
      console.log("Video ready:", data.result_urls[0]);
      return data;
    }
    if (data.status === "failed") {
      throw new Error(`Generation failed: ${data.error || "Unknown error"}`);
    }

    console.log(`Status: ${data.status} (${elapsed / 1000}s elapsed)`);
    await new Promise((r) => setTimeout(r, pollInterval));
    elapsed += pollInterval;
  }

  throw new Error(`Job ${jobId} did not complete within ${maxWait / 1000}s`);
}

A typical Seedance 2.0 generation takes 30-60 seconds for a 5-second video. Longer durations and higher resolutions take proportionally longer.

Advanced: Batch Processing

For production workflows that need multiple videos, process them concurrently:

import asyncio
import aiohttp

async def generate_batch(prompts: list[str], api_key: str) -> list[dict]:
    """Generate multiple videos concurrently."""
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }

    async with aiohttp.ClientSession() as session:
        # Submit all jobs
        tasks = []
        for prompt in prompts:
            payload = {
                "model": "bytedance/seedance-2.0",
                "prompt": prompt,
                "duration": 5,
                "aspect_ratio": "16:9"
            }
            tasks.append(
                session.post(
                    "https://api.ccapi.ai/v1/video/generations",
                    json=payload,
                    headers=headers
                )
            )

        responses = await asyncio.gather(*[t for t in tasks])
        jobs = [await r.json() for r in responses]
        print(f"Submitted {len(jobs)} jobs")

        # Poll all jobs until completion
        results = await asyncio.gather(*[
            poll_async(session, job["id"], headers)
            for job in jobs
        ])

    return results

# Usage
prompts = [
    "Product showcase: sleek headphones on marble surface, rotating slowly",
    "Social media ad: coffee being poured in slow motion, warm lighting",
    "Brand intro: logo animation with particle effects, modern and clean",
]

results = asyncio.run(generate_batch(prompts, api_key))

Batch processing is particularly useful for A/B testing different prompts, generating product videos at scale, and building content libraries. Be mindful of rate limits when submitting large batches.

Advanced: Webhook Callbacks

Instead of polling, you can configure webhooks to receive a notification when your video is ready. This is more efficient for production systems:

import requests

def submit_with_webhook(prompt: str, api_key: str, webhook_url: str) -> dict:
    """Submit a video generation job with webhook callback."""
    response = requests.post(
        "https://api.ccapi.ai/v1/video/generations",
        headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        },
        json={
            "model": "bytedance/seedance-2.0",
            "prompt": prompt,
            "duration": 5,
            "aspect_ratio": "16:9",
            "webhook_url": webhook_url,
            "webhook_events": ["completed", "failed"]
        }
    )
    return response.json()

Your webhook endpoint will receive a POST request with the job status and video URLs when the generation completes.

Error Handling Best Practices

Robust error handling is essential for production API integrations. Here are the most common error scenarios and how to handle them:

from openai import OpenAI, APIError, RateLimitError, APITimeoutError

client = OpenAI(
    api_key=os.getenv("CCAPI_API_KEY"),
    base_url="https://api.ccapi.ai/v1"
)

def generate_video_safe(prompt: str, retries: int = 3) -> dict:
    """Generate a video with retry logic and error handling."""
    for attempt in range(retries):
        try:
            response = client.chat.completions.create(
                model="bytedance/seedance-2.0",
                messages=[{"role": "user", "content": prompt}]
            )
            return response

        except RateLimitError:
            wait = 2 ** attempt  # Exponential backoff
            print(f"Rate limited. Retrying in {wait}s...")
            time.sleep(wait)

        except APITimeoutError:
            print(f"Request timed out. Attempt {attempt + 1}/{retries}")

        except APIError as e:
            if e.status_code == 402:
                raise Exception("Insufficient credits. Top up at ccapi.ai/pricing")
            raise

    raise Exception(f"Failed after {retries} retries")
Error Code Meaning Action
401 Invalid API key Check your API key at /dashboard/apikey
402 Insufficient credits Add credits at /pricing
429 Rate limit exceeded Wait and retry with exponential backoff
500 Server error Retry after a short delay
503 Service unavailable The upstream provider is temporarily down

Rate Limits and Quotas

CCAPI enforces rate limits to ensure fair usage across all users:

Tier Requests/Minute Concurrent Jobs Max Monthly Volume
Free 5 2 50 videos
Starter 20 5 500 videos
Pro 60 15 5,000 videos
Enterprise Custom Custom Unlimited

For higher limits, contact the CCAPI team or upgrade your plan.

Frequently Asked Questions

Do I need a ByteDance account to use Seedance 2.0?

No. CCAPI handles all provider authentication. You only need a CCAPI account and API key. No Chinese phone number, ByteDance account, or specialized SDK is required.

How long does video generation take?

A 5-second Seedance 2.0 video typically generates in 30-60 seconds. Longer durations and higher resolutions take proportionally more time. A 15-second 2K video may take 2-3 minutes.

Can I use the same API key for other models?

Yes. Your CCAPI API key works with all available models, including Kling 3.0, Sora 2, Veo 3.1, and all LLM models (GLM-5, MiniMax M2.5, DeepSeek). Just change the model parameter.

What formats does the API return?

Video output is returned as an MP4 URL. The URL is valid for 24 hours. You should download and store the video in your own storage if you need permanent access.

How is billing calculated?

CCAPI uses credits-based billing. 1 credit = $0.01 USD. A 5-second 1080p Seedance 2.0 video costs approximately 30 credits ($0.30). Credits are deducted only upon successful generation --- failed jobs are not charged.