# Seedance 2.0 AI Public API Base URL: https://www.seedance2ai.io/api/v1 ## Authentication ```http Authorization: Bearer sk_live_your_api_key Content-Type: application/json Idempotency-Key: a-unique-id-per-request ``` Create an API key in the dashboard: https://www.seedance2ai.io/app/api ## Rules - Calls spend credits from the key owner's personal balance. Team credits are not used. - Do not send teamSlug or provider — the server picks the provider automatically. - Media URLs must be public HTTPS URLs. asset:// URLs are not accepted. - Send an Idempotency-Key on every POST so retries never create duplicate paid tasks. - Submitting returns a task id (sd2_… / gpt25_… / gpt2_… / nbp_… / nb2_… / nb2l_…). Poll GET /tasks/{id} until status is completed or failed. - Every task response includes `result_urls`, a flat array of the result file URLs, alongside the model-specific `output`. - GET /tasks lists recent tasks, GET /balance returns the spendable credits, GET /models returns the model catalogue. ## Seedance 2.0 Video — POST /api/v1/video/seedance2 | Parameter | Type | Required | Default | Allowed values | |-----------|------|----------|---------|----------------| | mode | string | No | text-to-video | text-to-video, image-to-video, media-to-video | | quality_tier | string | No | standard | mini, standard, pro | | channel | string | No | standard | standard, real, wild | | prompt | string | Yes | — | 3–10000 characters | | aspect_ratio | string | No | 16:9 | 1:1, 21:9, 4:3, 3:4, 16:9, 9:16, adaptive | | duration | string | No | 5 | 4–15 (seconds) | | resolution | string | No | 720p | 720p, 1080p; pro: 1080p-plus, 4k | | image_url | string (URL) | image-to-video only | — | public https URL (start frame, max 30 MB) | | end_image_url | string (URL) | No | — | public https URL (optional end frame, max 30 MB) | | media_urls | string[] (URL) | media-to-video only | — | up to 12 public https image/video URLs; images max 30 MB; video URLs must support Range duration probing | | generate_audio | boolean | No | true | true, false | | fixed_lens | boolean | No | false | true, false | | seed | integer | No | — | -1 to 4294967295 | ```bash curl -X POST https://www.seedance2ai.io/api/v1/video/seedance2 \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: demo-video-001" \ -d '{ "mode": "text-to-video", "quality_tier": "standard", "prompt": "A cinematic shot of a glass train crossing a snowy mountain bridge", "aspect_ratio": "16:9", "duration": "5", "resolution": "720p" }' ``` Submit response — the `credits_used` values in these examples are illustrative. Actual usage is calculated when the task is submitted and returned by the API: ```json { "id": "sd2_xxxxx", "status": "processing", "model": "seedance2", "quality_tier": "standard", "channel": "standard", "credits_used": 30 } ``` ## Seedance 2.5 Video — POST /api/v1/video/seedance25 Seedance 2.5 is a separate endpoint with its own contract. It does not accept quality_tier or seed. **Account requirement:** the API key owner must have at least one successful credits or plan purchase. Free welcome, referral, or promotional credits alone do not unlock this endpoint. Calls from an account without a qualifying purchase return purchase_required with HTTP 403. | Parameter | Type | Required | Default | Allowed values | |-----------|------|----------|---------|----------------| | mode | string | No | text-to-video | text-to-video, image-to-video, media-to-video | | channel | string | No | standard | standard, real, wild | | prompt | string | Yes | — | 3–10000 characters | | aspect_ratio | string | No | 16:9 | 1:1, 21:9, 4:3, 3:4, 16:9, 9:16, adaptive (image-to-video always follows the start frame; editing or extending a video requires adaptive) | | duration | string | No | 5 | auto, or 4–30 (seconds) | | resolution | string | No | 720p | 720p, 1080p, 1080p-plus | | image_url | string (URL) | image-to-video only | — | public https URL (start frame, max 30 MB, 300–6000 px per side) | | end_image_url | string (URL) | No | — | public https URL (optional end frame, same limits as image_url) | | media_urls | string[] (URL) | media-to-video only | — | up to 30 images, 10 videos, 10 audio clips (audio-only input is supported); each image max 30 MB, video max 200 MB and 2–30 s, audio max 15 MB and 2–30 s; total reference video/audio duration max 30 s; video URLs must support Range duration probing | | generate_audio | boolean | No | true | true, false | Use `resolution: "1080p-plus"` to request the website's 2K tier; API responses return the same canonical value. `"2K"`, `"2k"`, and `"4k"` are not accepted. With `duration: "auto"` the output length is decided during generation. Credits are reserved at the 30-second ceiling on submit, and the difference is refunded automatically once the clip is ready — GET /tasks/{id} then reports the final `credits_used` plus the refunded amount in `credits_refunded`. Use `channel: "real"` when your reference images or videos contain real people — it routes the request through the material pipeline that accepts realistic human faces. For `resolution: "1080p-plus"`, the highest-tier per-billable-second rates are: | Channel | With video | Without video | |---------|------------|---------------| | standard | 51 | 85 | | real | 61.2 | 102 | | wild | 51 | 85 | With video input, billable seconds are `max(4, ceil(input video seconds)) + output seconds`; without video input, they are the output seconds. The result is rounded to the nearest 5 credits. A task keeps the pricing version selected when it was created, including `duration: "auto"` tasks that finish later. Tasks created between `2026-08-14T06:00:00.000Z` (inclusive) and `2026-09-17T06:00:00.000Z` (exclusive) used a promotional price book (37 with video and 61 without for standard and wild; 44.4 and 73.2 for real) and report `pricing.version` `sd25-2k-rate-v4-promo` with `promotion_applied: true`. New requests use the rates above. Submit and task responses include the frozen `pricing` contract. Historical Seedance 2.5 tasks created before this contract may return `pricing: null`. An insufficient balance always returns HTTP 402 with an `insufficient_credits` error. When the server has already completed an authoritative quote, the error may also include `required_credits`, `available_credits`, `pricing_version`, and `promotion_applied`. Reference-media requests with no usable balance stop before remote media inspection, so those quote fields are not guaranteed. ```bash curl -X POST https://www.seedance2ai.io/api/v1/video/seedance25 \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: demo-video-25-001" \ -d '{ "mode": "text-to-video", "prompt": "A cinematic shot of a glass train crossing a snowy mountain bridge", "aspect_ratio": "16:9", "duration": "5", "resolution": "1080p-plus" }' ``` Submit response — `credits_used` below is illustrative; the exact cost depends on duration, resolution, the length of any reference video, and your plan: ```json { "id": "sd2_xxxxx", "status": "processing", "model": "seedance25", "duration": "5", "resolution": "1080p-plus", "credits_used": 425, "pricing": { "version": "sd25-2k-rate-v5-regular", "promotion_applied": false, "promotion_ends_at": null, "unit_rate_credits": 85, "billable_seconds": 5, "account_multiplier": 1 } } ``` Poll it with the same GET /api/v1/tasks/{id} endpoint as Seedance 2. ## Seedance Prompt Guide Seedance prompts work best as concrete director instructions, not adjective piles. Write who is in the scene, where they are, what they do, how the camera moves, and the order of events. ### Asset mapping - Use `image_url` for the opening frame and `end_image_url` for the closing frame. - Use `media_urls[]` for character references, camera-motion references, style references, source videos for editing, or prior clips for extension. - Describe each asset's role in natural language inside `prompt`. Do not put raw asset ids, `asset://` URLs, or in-app-only labels such as `@图片1` in the final API prompt. - Set `mode` to match the assets: `text-to-video` for no assets, `image-to-video` when using `image_url`, and `media-to-video` when using `media_urls`. ### Task wording - Reference task: "Use the supplied character reference as the lead..." or "Match the supplied camera-motion reference..." - Edit task: "Strictly edit the supplied source video; replace X with Y while preserving Z." - Extension task: "Continue from the supplied previous clip..." The `duration` is the added segment length. - Combination task: "Use the supplied style reference while strictly editing the supplied source video..." ### Prompt structure For simple scenes or single edit/extension tasks, use one compact paragraph: ```text [task wording], [subject and asset role], [scene and action], [style and constraints] ``` For complex multi-shot scenes, use three parts: 1. Overall setup and asset roles. 2. Ordered shots: Shot 1, Shot 2, Shot 3. Prefer ordered shots over exact timestamps unless timed beats are required. 3. Style and constraints. ### Quality constraints Include concise safeguards when relevant: high detail, cinematic quality, stable faces, natural motion, no deformation, no watermarks, no logos, no subtitles unless text is intended. For multi-person scenes, add anti-duplicate-character constraints and clear left/right positioning. For anime or non-realistic looks, explicitly anchor the visual style. ## Check Seedance 2.0 Task Status — GET /api/v1/tasks/{id} ```bash curl https://www.seedance2ai.io/api/v1/tasks/sd2_xxxxx \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` Completed response: ```json { "id": "sd2_xxxxx", "type": "video", "status": "completed", "model": "seedance2", "quality_tier": "standard", "channel": "standard", "resolution": "720p", "credits_used": 30, "credits_refunded": 0, "output": { "video_url": "https://...", "last_frame_url": "https://...", "seed": 123 }, "result_urls": ["https://..."], "error": null, "created_at": "2026-06-03T10:00:00.000Z", "updated_at": "2026-06-03T10:03:12.000Z" } ``` `status` is one of: `processing`, `completed`, `failed`. `resolution` is the canonical value used when the task was created; older tasks may return `null`. ## Check Seedance 2.5 Task Status — GET /api/v1/tasks/{id} ```bash curl https://www.seedance2ai.io/api/v1/tasks/sd2_xxxxx \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` Completed response: ```json { "id": "sd2_xxxxx", "type": "video", "status": "completed", "model": "seedance25", "quality_tier": "standard", "channel": "standard", "resolution": "1080p-plus", "credits_used": 425, "credits_refunded": 0, "pricing": { "version": "sd25-2k-rate-v5-regular", "promotion_applied": false, "promotion_ends_at": null, "unit_rate_credits": 85, "billable_seconds": 5, "account_multiplier": 1 }, "output": { "video_url": "https://...", "last_frame_url": "https://...", "seed": null }, "result_urls": ["https://..."], "error": null, "created_at": "2026-06-03T10:00:00.000Z", "updated_at": "2026-06-03T10:03:12.000Z" } ``` `status` is one of: `processing`, `completed`, `failed`. `resolution` is the canonical value used when the task was created; older tasks may return `null`. ## GPT Image 2.5 — POST /api/v1/image/gpt-image-2-5 | Parameter | Type | Required | Default | Allowed values | |-----------|------|----------|---------|----------------| | type | string | Yes | — | text-to-image, image-to-image | | prompt | string | Yes | — | 3–20000 characters | | variant | string | No | flare | flare, sunburst | | aspect_ratio | string | No | auto | auto, 1:1, 3:2, 2:3, 4:3, 3:4, 16:9, 9:16, 21:9, 27:16, 16:27, 9:8, 8:9 | | resolution | string | No | 1K | 1K, 2K, 4K | | channel | string | No | standard | standard, economy, stable | | image_urls | string[] (URL) | image-to-image only | — | 1–16 public https URLs | `variant: "flare"` balances speed and quality; `variant: "sunburst"` emphasizes fine detail and takes longer. `channel: "economy"` is lower-cost and requires a successful credits or plan purchase; without one it returns purchase_required with HTTP 403. `channel: "stable"` is the most reliable choice at busy times and, for accounts with a purchase, costs more than standard; it needs a fixed `aspect_ratio` (`"auto"` returns invalid_request). ```bash curl -X POST https://www.seedance2ai.io/api/v1/image/gpt-image-2-5 \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: demo-gpt-image-25-001" \ -d '{ "type": "text-to-image", "prompt": "A hand-lettered poster for a night market, warm tungsten light", "variant": "flare", "aspect_ratio": "3:4", "resolution": "1K" }' ``` Submit response — `credits_used` is illustrative; the charge depends on the resolution, the channel and whether the account has made a purchase, and the actual amount is returned here: ```json { "id": "gpt25_xxxxx", "status": "processing", "model": "gpt-image-2.5", "credits_used": 8 } ``` ## Check GPT Image 2.5 Task Status — GET /api/v1/tasks/{id} ```bash curl https://www.seedance2ai.io/api/v1/tasks/gpt25_xxxxx \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` Completed response: ```json { "id": "gpt25_xxxxx", "type": "image", "status": "completed", "model": "gpt-image-2.5", "credits_used": 8, "credits_refunded": 0, "output": ["https://..."], "result_urls": ["https://..."], "error": null, "created_at": "2026-06-03T10:00:00.000Z", "updated_at": "2026-06-03T10:01:24.000Z" } ``` `status` is one of: `processing`, `completed`, `failed`. ## GPT Image 2 — POST /api/v1/image/gpt-image-2 | Parameter | Type | Required | Default | Allowed values | |-----------|------|----------|---------|----------------| | type | string | Yes | — | text-to-image, image-to-image | | prompt | string | Yes | — | 3–20000 characters | | resolution | string | Yes | — | 1K, 2K, 4K | | aspect_ratio | string | Yes | — | auto, 1:1, 5:4, 9:16, 21:9, 16:9, 4:3, 3:2, 4:5, 3:4, 2:3, 2:1, 1:2, 3:1, 1:3, 9:21 | | channel | string | No | standard | standard, economy | | batch_count | integer | No | 1 | 1–4 | | image_urls | string[] (URL) | image-to-image only | — | 1–10 public https URLs | ```bash curl -X POST https://www.seedance2ai.io/api/v1/image/gpt-image-2 \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: demo-gpt-image-001" \ -d '{ "type": "text-to-image", "prompt": "Editorial product photo of a transparent running shoe on chrome", "resolution": "1K", "aspect_ratio": "1:1" }' ``` Submit response: ```json { "id": "gpt2_xxxxx", "status": "processing", "model": "gpt-image-2", "credits_used": 8, "remaining_credits": 120 } ``` When `batch_count` > 1, the response also returns `batch_task_ids`, `batch_success`, and `batch_failed`. ## Check GPT Image 2 Task Status — GET /api/v1/tasks/{id} ```bash curl https://www.seedance2ai.io/api/v1/tasks/gpt2_xxxxx \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` Completed response: ```json { "id": "gpt2_xxxxx", "type": "image", "status": "completed", "model": "gpt-image-2", "credits_used": 8, "credits_refunded": 0, "output": ["https://..."], "result_urls": ["https://..."], "error": null, "created_at": "2026-06-03T10:00:00.000Z", "updated_at": "2026-06-03T10:01:24.000Z" } ``` `status` is one of: `processing`, `completed`, `failed`. ## Nano Banana Pro — POST /api/v1/image/nano-banana-pro | Parameter | Type | Required | Default | Allowed values | |-----------|------|----------|---------|----------------| | type | string | Yes | — | text-to-image, image-to-image | | prompt | string | Yes | — | 3–10000 characters | | image_size | string | No | auto | 1:1, 9:16, 16:9, 3:4, 4:3, 3:2, 2:3, 5:4, 4:5, 21:9, auto | | output_format | string | No | png | png, jpeg | | resolution | string | No | 1K | 1K, 2K, 4K | | image_urls | string[] (URL) | image-to-image only | — | 1–8 public https URLs | ```bash curl -X POST https://www.seedance2ai.io/api/v1/image/nano-banana-pro \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: demo-nbp-001" \ -d '{ "type": "text-to-image", "prompt": "A premium packaging mockup for an AI video studio", "image_size": "1:1", "resolution": "1K", "output_format": "png" }' ``` Submit response: ```json { "id": "nbp_xxxxx", "request_id": "req_xxxxx", "status": "processing", "model": "nano-banana-pro", "credits_used": 12, "remaining_credits": 120 } ``` ## Check Nano Banana Pro Task Status — GET /api/v1/tasks/{id} ```bash curl https://www.seedance2ai.io/api/v1/tasks/nbp_xxxxx \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` Completed response: ```json { "id": "nbp_xxxxx", "type": "image", "status": "completed", "model": "nano-banana-pro", "credits_used": 12, "credits_refunded": 0, "output": { "images": [ { "url": "https://..." } ] }, "result_urls": ["https://..."], "error": null, "created_at": "2026-06-03T10:00:00.000Z", "updated_at": "2026-06-03T10:01:42.000Z" } ``` `status` is one of: `processing`, `completed`, `failed`. ## Nano Banana 2 — POST /api/v1/image/nano-banana-2 | Parameter | Type | Required | Default | Allowed values | |-----------|------|----------|---------|----------------| | type | string | Yes | — | text-to-image, image-to-image | | prompt | string | Yes | — | 3–20000 characters | | image_size | string | No | auto | 1:1, 1:4, 1:8, 2:3, 3:2, 3:4, 4:1, 4:3, 4:5, 5:4, 8:1, 9:16, 16:9, 21:9, auto | | output_format | string | No | png | png, jpeg | | resolution | string | No | 1K | 1K, 2K, 4K | | google_search | boolean | No | false | true, false | | image_urls | string[] (URL) | image-to-image only | — | 1–8 public https URLs | ```bash curl -X POST https://www.seedance2ai.io/api/v1/image/nano-banana-2 \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: demo-nb2-001" \ -d '{ "type": "text-to-image", "prompt": "A current weather infographic for Shanghai", "image_size": "16:9", "resolution": "2K", "output_format": "png", "google_search": true }' ``` Submit response: ```json { "id": "nb2_xxxxx", "request_id": "req_xxxxx", "status": "processing", "model": "nano-banana-2", "credits_used": 11, "remaining_credits": 120 } ``` ## Check Nano Banana 2 Task Status — GET /api/v1/tasks/{id} ```bash curl https://www.seedance2ai.io/api/v1/tasks/nb2_xxxxx \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` Completed response: ```json { "id": "nb2_xxxxx", "type": "image", "status": "completed", "model": "nano-banana-2", "credits_used": 11, "credits_refunded": 0, "output": { "images": [ { "url": "https://..." } ] }, "result_urls": ["https://..."], "error": null, "created_at": "2026-06-03T10:00:00.000Z", "updated_at": "2026-06-03T10:01:42.000Z" } ``` `status` is one of: `processing`, `completed`, `failed`. ## Nano Banana 2 Lite — POST /api/v1/image/nano-banana-2-lite | Parameter | Type | Required | Default | Allowed values | |-----------|------|----------|---------|----------------| | type | string | Yes | — | text-to-image, image-to-image | | prompt | string | Yes | — | 3–20000 characters | | aspect_ratio | string | No | auto | 1:1, 1:4, 1:8, 2:3, 3:2, 3:4, 4:1, 4:3, 4:5, 5:4, 8:1, 9:16, 16:9, 21:9, auto | | image_urls | string[] (URL) | image-to-image only | — | 1–10 public https URLs | ```bash curl -X POST https://www.seedance2ai.io/api/v1/image/nano-banana-2-lite \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: demo-nb2-lite-001" \ -d '{ "type": "text-to-image", "prompt": "Fast cinematic product key visual on a clean studio floor", "aspect_ratio": "auto" }' ``` Submit response: ```json { "id": "nb2l_xxxxx", "request_id": "req_xxxxx", "status": "processing", "model": "nano-banana-2-lite", "credits_used": 6, "remaining_credits": 120 } ``` ## Check Nano Banana 2 Lite Task Status — GET /api/v1/tasks/{id} ```bash curl https://www.seedance2ai.io/api/v1/tasks/nb2l_xxxxx \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` Completed response: ```json { "id": "nb2l_xxxxx", "type": "image", "status": "completed", "model": "nano-banana-2-lite", "credits_used": 6, "credits_refunded": 0, "output": { "images": [ { "url": "https://..." } ] }, "result_urls": ["https://..."], "error": null, "created_at": "2026-06-03T10:00:00.000Z", "updated_at": "2026-06-03T10:01:42.000Z" } ``` `status` is one of: `processing`, `completed`, `failed`. ## List tasks — GET /api/v1/tasks Returns the tasks this account created through the API in the last 30 days, newest first. Each item has the same shape as GET /api/v1/tasks/{id}. | Query parameter | Type | Default | Notes | |-----------------|------|---------|-------| | limit | integer | 20 | 1–50 | | before | string | — | Pass the previous page's next_cursor to fetch the next page | ```bash curl "https://www.seedance2ai.io/api/v1/tasks?limit=20" \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` ```json { "data": [{ "id": "sd2_xxxxx", "type": "video", "status": "completed", "model": "seedance2", "result_urls": ["https://..."] }], "has_more": false, "next_cursor": null } ``` ## Check balance — GET /api/v1/balance ```bash curl https://www.seedance2ai.io/api/v1/balance \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` ```json { "credits": 1200, "subscription_credits": 1000, "subscription_credits_expire_at": "2026-07-01T00:00:00.000Z" } ``` `credits` is the total the key owner can spend through the API. `subscription_credits` is the part of that total that came from a plan and expires at `subscription_credits_expire_at`. ## List models — GET /api/v1/models Returns every model the API serves with its endpoint, accepted modes, and task id prefix. ```bash curl https://www.seedance2ai.io/api/v1/models \ -H "Authorization: Bearer $SEEDANCE_API_KEY" ``` ## Errors All errors share this shape: ```json { "error": { "code": "invalid_request", "message": "Invalid request body: prompt: String must contain at least 3 character(s)" } } ``` | Code | HTTP | Meaning | |------|------|---------| | unauthorized | 401 | Missing, invalid, or revoked API key. | | invalid_request | 400 | Bad input or unsupported field. The message names the first field that failed; details lists them all. | | purchase_required | 403 | Seedance 2.5 requires a successful credits or plan purchase; free promotional credits alone do not unlock it. The GPT Image 2.5 economy channel has the same requirement. | | insufficient_credits | 402 | Not enough credits on the key owner's balance. | | credits_frozen | 403 | Credit spending is temporarily unavailable for this account. Topping up will not lift it. | | rate_limited | 429 | Too many requests for this account. Submissions are limited to 30 per 60 seconds; reads (task status, task list, balance, models) have a separate limit of 120 per 60 seconds. Seedance requests that validate reference media are limited to 3 per 60 seconds per account and source IP, with a project-wide safety cap. Retry after the Retry-After header (in seconds). | | idempotency_conflict | 409 | Same Idempotency-Key reused with a different body, or still running. | | service_busy | 503 | Temporary upstream or credit-concurrency issue. Retry. | | not_found | 404 | Task does not exist or does not belong to this key owner. | | internal_error | 500 | Unexpected server-side failure. | ## Downloadable agent skill Download the one-file Seedance skill directly from the website: ```bash mkdir -p ~/.claude/skills/seedance curl --fail --location -H "Authorization: Bearer $SEEDANCE_API_KEY" https://www.seedance2ai.io/downloads/seedance-skill.md -o ~/.claude/skills/seedance/SKILL.md.tmp && mv ~/.claude/skills/seedance/SKILL.md.tmp ~/.claude/skills/seedance/SKILL.md ``` Direct URL: https://www.seedance2ai.io/downloads/seedance-skill.md ## Claude Code / Codex integration prompt Use the Seedance 2 AI Public API. Read this document, ask the user for SEEDANCE_API_KEY if missing, submit generation jobs with an Idempotency-Key header, and poll GET /tasks/{id} until status is completed or failed. Never send provider, teamSlug, or asset:// URLs.