Seedance 2.5 Video Generation NEW
So a 5-second 720p clip is ≈ 51 IC on Seedance 2.5 and ≈ 34 IC on Seedance 2.0. 1 IC ≈ 1 THB.
Premium feature. Seedance 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, our reseller of BytePlus Ark's Dreamina Seedance family — now including Seedance 2.5, live since 7 August 2026. 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-5-260628 | 720p max | ✓ | Newest model — strongest motion, clips to 30s, follows reference image / video / audio | ~51 IC |
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 |
All models share the same JSON contract — switch per-request via the model field.
Which generation? Seedance 2.5 is the newest model: better motion, stronger prompt adherence, clips up to 30 seconds, and up to 30 seconds of input video for reference work (2.0 accepts 15). One model handles every input — text, reference images, a reference video and even a reference audio track, all as content blocks. Seedance 2.0 remains the only option for 1080p output, and 2.0 Fast is still the cheapest way to iterate.
Pricing
The short version — cost per second of video
Every model is billed by the second of video produced, at a rate that depends on resolution. Nothing else in a text or image prompt is charged.
| Model | Resolution | Per second | 5-second clip | 10-second clip |
|---|---|---|---|---|
| Seedance 2.5 | 720p | 10.1 IC | ~51 IC | ~101 IC |
| Seedance 2.5 | 480p | 4.5 IC | ~23 IC | ~45 IC |
| Seedance 2.0 | 1080p | 16.9 IC | ~84 IC | ~169 IC |
| Seedance 2.0 | 720p | 6.8 IC | ~34 IC | ~68 IC |
| Seedance 2.0 | 480p | 3.0 IC | ~15 IC | ~30 IC |
| Seedance 2.0 Fast | 720p | 5.4 IC | ~27 IC | ~54 IC |
| Seedance 2.0 Fast | 480p | 2.4 IC | ~12 IC | ~24 IC |
1 IC ≈ 1 THB. You pay only for successful generations — a failed job, including a content-moderation rejection, costs 0 IC, and polling for the result is free.
If you send a reference video
Your input clip is billed too, because the model has to process it. The per-second rate drops when a video is attached, and it applies to input seconds + output seconds:
| Model | Resolution | Per second (input + output) |
|---|---|---|
| Seedance 2.5 | 720p | 6.3 IC |
| Seedance 2.5 | 480p | 2.8 IC |
| Seedance 2.0 | 1080p | 10.3 IC |
| Seedance 2.0 | 720p | 4.2 IC |
| Seedance 2.0 | 480p | 1.9 IC |
| Seedance 2.0 Fast | 720p | 3.2 IC |
| Seedance 2.0 Fast | 480p | 1.4 IC |
Example. A 6-second reference clip producing a 5-second 720p video on Seedance 2.5: (6 + 5) × 6.3 ≈ 69 IC.
We read the real duration of your reference video before charging, so you are billed for the clip you actually sent. If it cannot be read — an unusual container, a host that refuses range requests, or a slow response — we fall back to the model's maximum input length (15s on Seedance 2.0, 30s on Seedance 2.5) so the job is never under-billed.
For predictable pricing, use an MP4 hosted somewhere that supports range requests. Uploading through the demo above always measures correctly.
The exact formula
Under the hood Seedance bills per output token:
tokens = (input video duration + output video duration) × width × height × frame rate / 1024
Token counts are rounded up to the next 1,000. The per-second figures above are this formula evaluated at 25 fps and 16:9 for each resolution.
| Model | Resolution | Input has video? | iApp rate (IC / 1K tokens) | BytePlus reference (USD / M tokens) |
|---|---|---|---|---|
| Seedance 2.0 | 480p / 720p | no | 0.302 IC | $7.00 |
| Seedance 2.0 | 480p / 720p | yes | 0.186 IC | $4.30 |
| Seedance 2.0 | 1080p | no | 0.333 IC | $7.70 |
| Seedance 2.0 | 1080p | yes | 0.203 IC | $4.70 |
| Seedance 2.0 Fast | 480p / 720p | no | 0.242 IC | $5.60 |
| Seedance 2.0 Fast | 480p / 720p | yes | 0.143 IC | $3.30 |
| Seedance 2.5 | 480p / 720p | no | 0.45 IC | $10.70 |
| Seedance 2.5 | 480p / 720p | yes | 0.28 IC | $6.40 |
Rates use the highest BytePlus tier within each row, with a small margin to cover FX and gateway overhead. Your balance must cover the whole predicted cost before a job is accepted.
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-5-260628, 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 | 10 | Seconds. 4–15 on Seedance 2.0; up to 30 on Seedance 2.5. Must be a number — automatic ("smart") length is not accepted, see below. |
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). |
Video length
Omit duration and you get 10 seconds. Because you are billed per second, that default is worth knowing: at 720p on Seedance 2.5 it is 101.25 IC, where an explicit "duration": 4 is 40.50 IC. Send the number you want.
duration must be a number. Automatic or "smart" length — letting the model decide how long the clip should be — is rejected with DURATION_NOT_NUMERIC:
{
"message": "Field 'duration' must be a number of seconds (up to 30 on 'dreamina-seedance-2-5-260628'). Automatic or 'smart' length is not supported: the cost of a job cannot be determined before it runs.",
"error_code": "DURATION_NOT_NUMERIC"
}
This is deliberate. Your credit balance is checked before the job starts, and with an automatic length there is no number to check against — the clip could render as 4 seconds or as 30, a 7.5× spread in cost. We would have to either hold the maximum against your balance and overcharge short clips, or assume the minimum and bill you for a job you never agreed to. Requiring an explicit number means the price you are quoted is the price you pay.
A duration above the model's limit is rejected the same way, with DURATION_TOO_LONG.
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
}
}
}
Use cases
- Marketing reels — generate matching 9:16 / 1:1 / 16:9 cuts of the same scene for Instagram, TikTok, YouTube Shorts in one batch.
- Product demos — provide a hero image as
first_frameand let the model animate the camera around it. - Localised ad creatives — feed Thai-language prompts directly; no translation step needed.
- Storyboard previews — use the cheaper Fast model at 480p to iterate on direction, then re-render the chosen take at 1080p.
FAQ
Why is Seedance restricted to paid accounts? A single 1080p render can cost 60–100 IC, far more than any other API on the platform. To prevent a free signup from accidentally (or maliciously) burning through hundreds of dollars of GPU time, the endpoint requires at least one prior paid IC purchase on the account. New users can unlock everything with a one-time top-up — see Buy IC.
What happens if generation fails? You're not charged. BytePlus only bills successful renders, and we mirror that policy. Content-moderation rejections, NSFW filters, and infrastructure timeouts all return 0 IC.
How long does a render take? Typically 30–120 seconds for a 5-second 720p clip on the Fast model, and 1–4 minutes for a 1080p clip on the full model. Your client should poll every 5 seconds with a 15-minute timeout.
Are the generated videos owned by me? Yes — same as for BytePlus direct customers. You retain commercial rights to anything you generate. Avoid prompts depicting real public figures, copyrighted characters, or protected IP.
Where is the API hosted?
The upstream is BytePlus Ark in ap-southeast-1 (Singapore). Requests through api.iapp.co.th add ~10–30 ms of gateway latency.
Can I use this for live / real-time video? No. Seedance is an offline, async generator. Each clip is rendered once and the output URL is then valid for 24 hours.
Support
- Pricing or billing questions: sale@iapp.co.th
- API technical questions: Discord
- Bug reports: include the
task_idfrom the submit response — we can trace every call.