Kino API

Generate video with Seedance 2.0 through a simple asynchronous task API: create a task, poll for completion, download your video from a CDN URL. All requests are plain HTTPS + JSON.

Base URL: https://api.kino-api.com  ·  Console: open

Authentication

All API calls require a Bearer token. Create tokens in Console → Tokens; each token has its own balance scope and can be revoked at any time.

Authorization: Bearer sk-YOUR_TOKEN

Keep tokens server-side. Never embed them in browser or mobile apps — anyone holding a token can spend its balance.

Quickstart

# Create a task
curl -X POST https://api.kino-api.com/v1/video/generations \
  -H "Authorization: Bearer sk-YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.0-mini",
    "prompt": "Wind turbines on a green hillside at dawn, cinematic",
    "duration": 5,
    "metadata": { "resolution": "480p", "ratio": "16:9" }
  }'

# → {"task_id": "task_3ycw...", "status": "queued"}

# Poll every 3–5 seconds
curl https://api.kino-api.com/v1/video/generations/task_3ycw... \
  -H "Authorization: Bearer sk-YOUR_TOKEN"

# → {"data": {"status": "SUCCESS", "result_url": "https://.../video.mp4"}}

Models

Model IDResolutionsBest for
seedance-2.0-pro480p / 720p / 1080p / 4KHighest quality output
seedance-2.0-fast480p / 720pHigh-volume generation
seedance-2.0-mini480p / 720pDrafts, previews, iteration
seedance-1.5-pro480p / 720pBudget jobs, optional audio track
seedream-5.0-proimage · 2KTop-tier image generation
seedream-5.0-liteimage · 2KFast, low-cost images

Create Video Task

POST /v1/video/generations

Request body

FieldTypeDescription
model *stringOne of the model IDs above
prompt *stringText description of the video. Required for text-to-video; combined with inputs for image/video modes
durationintVideo length in seconds (default 5). Supported values are model-dependent
image / imagesstring / arrayImage URL(s) for image-to-video (first frame)
metadataobjectGeneration parameters — see Parameter Reference

Response

{
  "task_id": "task_3ycweCkT2zWiAQwlzTSy1Y3UlV5dYFDs",
  "status": "queued",
  "model": "seedance-2.0-mini",
  "created_at": 1785989680
}

Poll Task Status

GET /v1/video/generations/{task_id}

Poll every 3–5 seconds. Typical generation takes 30–90 seconds.

data.statusMeaning
queued / runningIn progress — keep polling
SUCCESSDone — video URL in data.result_url, balance charged
FAILUREFailed — see data.fail_reason, fully refunded
{
  "data": {
    "status": "SUCCESS",
    "result_url": "https://media.uptoken.cc/v/ut-Vc3cN2bcNVwq.mp4",
    "quota": 55702,
    "submit_time": 1785990148,
    "finish_time": 1785990233
  }
}

Download promptly. result_url is a direct CDN link that may expire. We never store your videos.

Generate Image (Synchronous)

POST /v1/images/generations

Unlike video, image generation is synchronous: one request returns the finished image in about 30 seconds — no polling needed. OpenAI-compatible request and response shape.

Request body

FieldTypeDescription
model *stringseedream-5.0-pro or seedream-5.0-lite
prompt *stringImage description
sizestringOutput size, e.g. 2048x2048 (default). Must be a resolution tier the upstream supports — invalid values return a clear 400 error

Example

curl -X POST https://api.kino-api.com/v1/images/generations \
  -H "Authorization: Bearer sk-YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedream-5.0-lite",
    "prompt": "A tiny paper boat floating in a puddle after rain, macro photography"
  }'

# → {"created": 1785998459, "data": [{"url": "https://.../image.jpg"}]}

Pricing

ModelPrice (per successful image)
seedream-5.0-pro$0.132
seedream-5.0-lite$0.052

Download promptly. Returned image URLs are time-limited CDN links (~24h). We never store your images.

Parameter Reference (metadata)

Generation parameters must be placed inside the metadata object. Top-level resolution/ratio fields are ignored.

KeyValuesDescription
resolution480p · 720p · 1080p · 4kOutput resolution (default 720p). 4K only on Pro
ratio16:9 · 9:16 · 1:1Aspect ratio (default 16:9)
generate_audioboolGenerate an audio track (1.5 Pro; affects price tier)
watermarkboolInclude upstream watermark (default false)
seedintFixed seed for reproducible results
camera_fixedboolLock camera movement

Image / Video Inputs

Image-to-video

{
  "model": "seedance-2.0-pro",
  "prompt": "The camera slowly pushes in as waves begin to move",
  "images": ["https://example.com/frame.jpg"],
  "metadata": { "resolution": "1080p" }
}

Video-reference mode

Pass a reference video through metadata.content. Video-reference tasks are billed at the higher tier (see Pricing).

{
  "model": "seedance-2.0-pro",
  "prompt": "Restyle this clip into cyberpunk anime",
  "metadata": {
    "content": [{ "type": "video_url",
                   "video_url": { "url": "https://example.com/ref.mp4" } }]
  }
}

Billing & Refunds

Billing is purely usage-based: each successful video is charged by resolution × duration at the per-second rates on the pricing table. Charges are computed from upstream usage, so you always pay exactly the listed rate — no per-call fees, no rounding up.

Failed tasks are refunded automatically and in full, the moment the upstream reports failure. Your console logs show the exact charge for every request.

Errors

ErrorCause / Fix
Invalid tokenMissing/revoked token, or wrong Authorization header
Insufficient balanceTop up in Console → Top Up
same prompt submitted too many timesUpstream anti-duplicate limit — wait or vary the prompt
Model price not configuredTransient config issue — contact support
model not availableCheck the model ID spelling against the Models table

Rate Limits & Best Practices

LimitValue
Task creationSensible per-token burst limit; contact us for volume
Status pollingEvery 3–5s per task (faster polling is cached)
Identical promptsRejected by upstream within a short window

Best practices: poll with backoff, don't retry identical prompts immediately, download result_url promptly, use separate tokens per environment.

SDK Examples

Python

import requests, time

BASE, TOKEN = "https://api.kino-api.com", "sk-YOUR_TOKEN"
H = {"Authorization": f"Bearer {TOKEN}"}

task = requests.post(f"{BASE}/v1/video/generations", headers=H, json={
    "model": "seedance-2.0-mini",
    "prompt": "Wind turbines on a green hillside at dawn",
    "duration": 5,
    "metadata": {"resolution": "480p", "ratio": "16:9"},
}).json()

while True:
    time.sleep(4)
    r = requests.get(f"{BASE}/v1/video/generations/{task['task_id']}", headers=H).json()["data"]
    if r["status"] == "SUCCESS":
        print("Video:", r["result_url"]); break
    if r["status"] == "FAILURE":
        raise RuntimeError(r["fail_reason"])

Node.js

const BASE = "https://api.kino-api.com", TOKEN = "sk-YOUR_TOKEN";
const H = { Authorization: `Bearer ${TOKEN}`, "Content-Type": "application/json" };

const t = await (await fetch(`${BASE}/v1/video/generations`, {
  method: "POST", headers: H,
  body: JSON.stringify({ model: "seedance-2.0-mini",
    prompt: "Wind turbines on a green hillside at dawn",
    duration: 5, metadata: { resolution: "480p", ratio: "16:9" } })
})).json();

while (true) {
  await new Promise(r => setTimeout(r, 4000));
  const { data } = await (await fetch(`${BASE}/v1/video/generations/${t.task_id}`, { headers: H })).json();
  if (data.status === "SUCCESS") { console.log("Video:", data.result_url); break; }
  if (data.status === "FAILURE") throw new Error(data.fail_reason);
}

Questions? Open a ticket via the console or check the FAQ.