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 ID | Resolutions | Best for |
|---|---|---|
seedance-2.0-pro | 480p / 720p / 1080p / 4K | Highest quality output |
seedance-2.0-fast | 480p / 720p | High-volume generation |
seedance-2.0-mini | 480p / 720p | Drafts, previews, iteration |
seedance-1.5-pro | 480p / 720p | Budget jobs, optional audio track |
seedream-5.0-pro | image · 2K | Top-tier image generation |
seedream-5.0-lite | image · 2K | Fast, low-cost images |
Create Video Task
Request body
| Field | Type | Description |
|---|---|---|
model * | string | One of the model IDs above |
prompt * | string | Text description of the video. Required for text-to-video; combined with inputs for image/video modes |
duration | int | Video length in seconds (default 5). Supported values are model-dependent |
image / images | string / array | Image URL(s) for image-to-video (first frame) |
metadata | object | Generation parameters — see Parameter Reference |
Response
{
"task_id": "task_3ycweCkT2zWiAQwlzTSy1Y3UlV5dYFDs",
"status": "queued",
"model": "seedance-2.0-mini",
"created_at": 1785989680
}
Poll Task Status
Poll every 3–5 seconds. Typical generation takes 30–90 seconds.
data.status | Meaning |
|---|---|
queued / running | In progress — keep polling |
SUCCESS | Done — video URL in data.result_url, balance charged |
FAILURE | Failed — 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)
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
| Field | Type | Description |
|---|---|---|
model * | string | seedream-5.0-pro or seedream-5.0-lite |
prompt * | string | Image description |
size | string | Output 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
| Model | Price (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.
| Key | Values | Description |
|---|---|---|
resolution | 480p · 720p · 1080p · 4k | Output resolution (default 720p). 4K only on Pro |
ratio | 16:9 · 9:16 · 1:1 | Aspect ratio (default 16:9) |
generate_audio | bool | Generate an audio track (1.5 Pro; affects price tier) |
watermark | bool | Include upstream watermark (default false) |
seed | int | Fixed seed for reproducible results |
camera_fixed | bool | Lock 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
| Error | Cause / Fix |
|---|---|
Invalid token | Missing/revoked token, or wrong Authorization header |
| Insufficient balance | Top up in Console → Top Up |
same prompt submitted too many times | Upstream anti-duplicate limit — wait or vary the prompt |
| Model price not configured | Transient config issue — contact support |
model not available | Check the model ID spelling against the Models table |
Rate Limits & Best Practices
| Limit | Value |
|---|---|
| Task creation | Sensible per-token burst limit; contact us for volume |
| Status polling | Every 3–5s per task (faster polling is cached) |
| Identical prompts | Rejected 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.