Seedance 2.0 Video Generation NEW
Reference video example: a 5-second 720p clip with text-only input ≈ 33 IC ≈ 33 THB.
Premium feature. Seedance 2.0 is reserved for accounts that have purchased any iApp credit (IC) package at least once. Free signup credits do not unlock it — buy a one-time package to access all premium APIs.
Welcome to iApp Seedance 2.0, our reseller of BytePlus Ark's Dreamina Seedance 2.0 family. You get the same Singapore-region throughput, the same model quality, and a single OpenAI-style billing channel through your existing iApp API key — no separate BytePlus account, no foreign-currency invoice, no PII leaving Thailand-friendly billing.
Try the live demo
Try Seedance 2.0 Video Generation
Login to your iApp account to use this premium video-generation demo.
Example Prompts
Choosing a model
| Model | Max resolution | Audio | Best for | Approx. cost (5 s, 720p, no input video) |
|---|---|---|---|---|
dreamina-seedance-2-0-260128 | 1080p | ✅ | Hero ads, marketing reels, anything needing sharpest output | ~41 IC |
dreamina-seedance-2-0-fast-260128 | 720p max | ✅ | Drafts, social-format content, batch generation, A/B variants | ~33 IC |
Both models share the same JSON contract — switch tiers per-request via the model field.
Pricing (per 1,000 output tokens)
Seedance bills per output token, where tokens roughly equal (input video duration + output video duration) × width × height × frame rate / 1024. Longer or higher-resolution videos use more tokens. Input prompt tokens are not separately billed.
| Model | Resolution | Input has video? | iApp rate (IC / 1K tokens) | BytePlus reference (USD / M tokens) |
|---|---|---|---|---|
| Seedance 2.0 | 480p / 720p | no | 0.302 | $7.00 |
| Seedance 2.0 | 480p / 720p | yes | 0.186 | $4.30 |
| Seedance 2.0 | 1080p | no | 0.333 | $7.70 |
| Seedance 2.0 | 1080p | yes | 0.203 | $4.70 |
| Seedance 2.0 Fast | 480p / 720p | no | 0.242 | $5.60 |
| Seedance 2.0 Fast | 480p / 720p | yes | 0.143 | $3.30 |
Rates use the highest BytePlus tier within each row, with a small margin to cover FX and gateway overhead. You only pay for successful generations — failed jobs (e.g. content-moderation rejection) cost 0 IC. Polling the status endpoint is also free.
Endpoints
The API is asynchronous: you POST to submit a task, then poll GET until the status is succeeded.
POST /v3/store/video/seedance/tasks — submit a job
Headers:
| Header | Value |
|---|---|
apikey | Your iApp API key |
Content-Type | application/json |
Body schema:
{
"model": "dreamina-seedance-2-0-fast-260128",
"content": [
{ "type": "text", "text": "<your prompt>" },
{ "type": "image_url", "image_url": { "url": "https://..." }, "role": "reference_image" },
{ "type": "video_url", "video_url": { "url": "https://..." }, "role": "reference_video" },
{ "type": "audio_url", "audio_url": { "url": "https://..." }, "role": "reference_audio" }
],
"generate_audio": true,
"ratio": "16:9",
"duration": 5,
"watermark": false,
"resolution": "720p"
}
| Field | Type | Default | Notes |
|---|---|---|---|
model | string | required | dreamina-seedance-2-0-260128 or dreamina-seedance-2-0-fast-260128 |
content | array | required | At minimum one text block. Optional image_url / video_url / audio_url blocks add reference media. |
content[].role | string | — | For images: reference_image (subject/style), first_frame, or last_frame. For videos: reference_video. For audio: reference_audio. |
generate_audio | boolean | true | Produce a soundtrack alongside the video. |
ratio | string | 16:9 | One of 16:9, 9:16, 1:1, 4:3, 3:4, 21:9. |
duration | integer | 5 | Seconds. Range 4–15 (BytePlus minimum is 4 for Seedance 2.0). |
watermark | boolean | false | If true, BytePlus stamps a watermark on the output. |
resolution | string | model-default | 480p, 720p, or 1080p (1080p is not supported by the Fast model). |
Response (HTTP 200):
{ "id": "task_abc123" }
GET /v3/store/video/seedance/tasks/{task_id} — poll status
Free to call; returns the task's current status. Recommended polling interval: 5 seconds.
Response when complete:
{
"id": "task_abc123",
"status": "succeeded",
"content": {
"video_url": "https://...mp4"
},
"usage": { "completion_tokens": 135000 }
}
Status values: queued, processing, succeeded, failed, cancelled, expired.
⚠️ The
video_urlexpires after about 24 hours. Download the MP4 immediately and host it yourself if you need to keep it.
Authentication
Use any active key from your API Keys dashboard. The same key works for every iApp API.
Code examples
cURL
# 1. Submit
curl -X POST 'https://api.iapp.co.th/v3/store/video/seedance/tasks' \
-H "apikey: $IAPP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dreamina-seedance-2-0-fast-260128",
"content": [{ "type": "text", "text": "A cat surfs a wave at sunset, cinematic, 24fps" }],
"duration": 5,
"ratio": "16:9",
"resolution": "720p",
"generate_audio": true
}'
# → {"id":"task_abc123"}
# 2. Poll until succeeded
curl -s 'https://api.iapp.co.th/v3/store/video/seedance/tasks/task_abc123' \
-H "apikey: $IAPP_API_KEY" | jq .
Python
import os, time, requests
API = "https://api.iapp.co.th/v3/store/video/seedance/tasks"
HEADERS = {"apikey": os.environ["IAPP_API_KEY"], "Content-Type": "application/json"}
# 1. Submit
r = requests.post(API, headers=HEADERS, json={
"model": "dreamina-seedance-2-0-fast-260128",
"content": [{"type": "text", "text": "A cat surfs a wave at sunset, cinematic, 24fps"}],
"duration": 5,
"ratio": "16:9",
"resolution": "720p",
"generate_audio": True,
})
r.raise_for_status()
task_id = r.json()["id"]
print("submitted:", task_id)
# 2. Poll
while True:
s = requests.get(f"{API}/{task_id}", headers=HEADERS).json()
print("status:", s["status"])
if s["status"] == "succeeded":
video_url = s["content"]["video_url"]
break
if s["status"] in ("failed", "cancelled", "expired"):
raise SystemExit(f"task ended: {s}")
time.sleep(5)
# 3. Download
mp4 = requests.get(video_url).content
open("output.mp4", "wb").write(mp4)
print("saved output.mp4")
Node.js
const apiKey = process.env.IAPP_API_KEY;
const base = "https://api.iapp.co.th/v3/store/video/seedance/tasks";
const sub = await fetch(base, {
method: "POST",
headers: { "apikey": apiKey, "Content-Type": "application/json" },
body: JSON.stringify({
model: "dreamina-seedance-2-0-fast-260128",
content: [{ type: "text", text: "A cat surfs a wave at sunset, cinematic" }],
duration: 5, ratio: "16:9", resolution: "720p", generate_audio: true,
}),
});
const { id } = await sub.json();
let result;
while (true) {
await new Promise(r => setTimeout(r, 5000));
result = await (await fetch(`${base}/${id}`, { headers: { apikey: apiKey } })).json();
if (result.status === "succeeded") break;
if (["failed", "cancelled", "expired"].includes(result.status)) throw result;
}
console.log("video:", result.content.video_url);
Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
api := "https://api.iapp.co.th/v3/store/video/seedance/tasks"
key := os.Getenv("IAPP_API_KEY")
body, _ := json.Marshal(map[string]any{
"model": "dreamina-seedance-2-0-fast-260128",
"content": []map[string]string{{"type": "text", "text": "A cat surfs a wave"}},
"duration": 5,
"ratio": "16:9",
"resolution": "720p",
"generate_audio": true,
})
req, _ := http.NewRequest("POST", api, bytes.NewReader(body))
req.Header.Set("apikey", key)
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
var sub struct{ ID string }
json.NewDecoder(resp.Body).Decode(&sub)
for {
time.Sleep(5 * time.Second)
r2, _ := http.NewRequest("GET", fmt.Sprintf("%s/%s", api, sub.ID), nil)
r2.Header.Set("apikey", key)
res, _ := http.DefaultClient.Do(r2)
var p struct {
Status string
Content struct{ VideoURL string `json:"video_url"` }
}
json.NewDecoder(res.Body).Decode(&p)
res.Body.Close()
if p.Status == "succeeded" {
fmt.Println("video:", p.Content.VideoURL)
return
}
if p.Status == "failed" || p.Status == "cancelled" || p.Status == "expired" {
io.Copy(os.Stderr, res.Body)
return
}
}
}