Video
Create and poll video generation tasks, storyboard edit/advanced modes, and pricing.
Video generation shares the authentication, uploads, callbacks and errors documented in the Overview.
Create a video task
POST /api/v3/contents/generations/tasks — creates a task and reserves the price from your balance.
curl -s -X POST "$TOKENSTORE_URL/api/v3/contents/generations/tasks" \
-H "Authorization: Bearer sk-..." \
-H "Content-Type: application/json" \
-d '{
"model": "seahorse-480p",
"content": [
{"type": "text", "text": "a seahorse dancing through neon waves"},
{"type": "image_url", "image_url": {"url": "https://example.com/ref.jpg"}},
{"type": "image_url", "image_url": {"url": "https://example.com/start.jpg"}, "role": "first_frame"},
{"type": "image_url", "image_url": {"url": "https://example.com/end.jpg"}, "role": "last_frame"}
],
"ratio": "16:9",
"duration": 5,
"callback_url": "https://example.com/webhooks/nureta-developer"
}'
# => {"id": "cgt-..."}Fields
| Field | Required | Notes |
|---|---|---|
model | yes | seahorse-480p, seahorse-720p, or seahorse-1080p — or a direct Seedance model, seedance2.0-fast / seedance2.0-pro (see Models & pricing). |
resolution | no | Direct Seedance models only: 480p, 720p (default), or 1080p — price follows the resolution. The seahorse-<res> models have their resolution baked into the id. |
content | yes | Non-empty array. Include exactly one text item. |
content[].type | yes | text, image_url, or audio_url. |
image_url.url | for image_url | HTTPS/HTTP asset URL consumed by Seahorse — your own hosted URL, or the assetUrl returned by Upload a reference image. At most 9 image items. |
role | no | Set to first_frame or last_frame on one image_url item to pin the opening or closing frame. A pinned frame is mutually exclusive with reference images: when you send a frame, the request renders frame-conditioned and any role-less reference images (and preset assets) are ignored — use a frame OR reference images, not both. |
audio_url.url | for audio_url | HTTPS or HTTP asset URL. At most one audio item. |
ratio | no | Default 16:9. Allowed: 16:9, 9:16, 4:3, 3:4, 1:1, 21:9, adaptive. |
duration | no | Default 5. Single clip: 5, 8, 10, 12, or 15s. Longer videos render as a stitched multi-segment scene: any integer from 16 to 180s (3 min). Direct Seedance models are single-clip only (max 15s). |
generate_audio | no | Default true. |
mode | no | Default auto (fully automated). Set edit to get an editable storyboard draft before rendering (see Storyboard modes). Video only, >15s. |
segments | no | Advanced mode: your own storyboard as an array of {script, duration_seconds?, first_frame?, last_frame?, explicit?}. Per-segment duration_seconds is 4–15 (default 9); the segments must total 16–180s, which becomes the video duration. Video only. |
callback_url | no | HTTPS endpoint to POST the terminal task response to. See Callback webhook. |
callback_secret | no | 8–256 character shared secret used to sign the callback body. Requires callback_url. |
Retrieve a video task
GET /api/v3/contents/generations/tasks/:id — poll until status is succeeded or failed. On success the response carries content.video_url; on failure it carries an error and a refund is issued automatically.
curl -s "$TOKENSTORE_URL/api/v3/contents/generations/tasks/cgt-..." \
-H "Authorization: Bearer sk-..."Progress (step). Every video generation task response carries a step object with the current execution phase, so you can show real progress while status is still pending (image tasks are a single step — poll status):
"step": { "code": "rendering", "done": 3, "total": 5 }code is a stable machine string — one of queued, generating_script, generating_visuals, pending_rendering (edit mode only — the draft is parked awaiting your render), rendering, stitching, done, failed, cancelled, reexpanding (edit mode — a structured re-expansion is running), or reexpand_failed (edit mode — the last re-expansion failed; re-edit before rendering). done/total appear only while rendering (clips completed / total). Terminal codes track status. Map the codes to your own labels — the API never sends display text. The step lags the true phase by up to ~30s (it is refreshed on a background poll).
Storyboard modes
Videos longer than 15s render as a stitched multi-shot "scene". By default (mode: "auto") the director plans and renders the whole thing for you. Two optional modes give you control over the storyboard first — both are video-only and require a duration over 15s.
Advanced — bring your own storyboard: pass a segments array instead of relying on the director. Each segment is one stitched clip. Per-segment duration_seconds is 4–15 (default 9), and the segments must total 16–180s (that total becomes the video's duration and price). With mode: "auto" (or omitted) it renders immediately:
curl -s -X POST "$TOKENSTORE_URL/api/v3/contents/generations/tasks" \
-H "Authorization: Bearer sk-..." -H "Content-Type: application/json" \
-d '{
"model": "seahorse-480p",
"content": [{ "type": "text", "text": "a moonlit rooftop encounter" }],
"ratio": "9:16",
"segments": [
{ "script": "she steps onto the rooftop, city lights behind her", "duration_seconds": 8 },
{ "script": "he joins her at the railing; they kiss", "duration_seconds": 10, "explicit": false },
{ "script": "the payoff shot", "duration_seconds": 12, "explicit": true }
]
}'What explicit means (read this). Per segment, explicit answers one question: does a real sex act happen in this shot? The model (Seedance) has no built-in knowledge of sex acts or anatomy, so shots that should show sex are routed through a separate anatomy-reference pipeline that attaches real anatomy references — otherwise the model can only render soft/suggestive motion. So:
explicit: true— this shot depicts sex. You must describe the act concretely in thescript/beat(what each body is doing — e.g. position, penetration). A vague line like "they get closer" on an explicit shot produces no references and renders soft.explicit: false— build-up / story shot (a look, a touch, undressing, afterglow). Rendered from text only; no anatomy references are attached (and shouldn't be — you don't want sex bleeding into a build-up shot).
Mark explicit: true only on the shots that should actually show sex, and make those shots' text spell out the act. (In edit mode the AI director sets this for you; override it per shot if it guessed wrong.)
Edit — review and tweak the storyboard before spending on the full render. Submit with mode: "edit" (with or without your own segments). The task is charged at submit and drafts a storyboard, then parks at status: "planned" with the draft under a scene field: segmentCount, a characterImage preview URL, and segments[] — each with index, script, durationSeconds, explicit, a people-free backgroundImage preview URL, and any firstFrame/lastFrame. Poll the task until status is planned:
curl -s -X POST "$TOKENSTORE_URL/api/v3/contents/generations/tasks" \
-H "Authorization: Bearer sk-..." -H "Content-Type: application/json" \
-d '{ "model": "seahorse-480p", "duration": 60, "mode": "edit",
"content": [{ "type": "text", "text": "a slow bedroom scene" }] }'Edit the parked draft with PUT …/tasks/:id/plan. Send only the segments you're changing, matched by their 1-based index; each may set script, duration_seconds (4–15), or a first_frame/last_frame URL (pass null to clear a frame). The response returns the refreshed scene.
Frames vs. the character reference. Pinning a shot's first_frame/last_frame renders that shot frame-conditioned: the frame replaces that shot's character/background reference for the render (the two can't be combined), so the shot's identity comes from the frame image itself. Pin a frame that already shows your character — or leave frames unset and let the shared character reference keep every shot consistent.
curl -s -X PUT "$TOKENSTORE_URL/api/v3/contents/generations/tasks/cgt-.../plan" \
-H "Authorization: Bearer sk-..." -H "Content-Type: application/json" \
-d '{ "segments": [
{ "index": 1, "script": "a tighter opening, close on her face", "duration_seconds": 8 },
{ "index": 2, "first_frame": "https://.../frame.jpg" }
] }'Structured edit (recommended). Instead of writing the full expanded prompt yourself, edit each scene's short action beat with PUT …/tasks/:id/plan/structured and let the server re-expand it. The segments array is the authoritative ordered set — segments are reconciled by index (a missing index is removed, an entry without index is inserted, array order is the final order), so reorder / add / remove are free. Each segment sends a beat (required), and optionally explicit, duration_seconds (4–15), first_frame/last_frame, and background_image — a hosted people-free image URL that replaces that shot's background plate (null to drop it; a shot pinned with a frame ignores its background). Optional top-level world, wardrobe, and character override the shared style (changing any re-expands every non-explicit scene). GET surfaces the current shared world/wardrobe/character on scene, plus each segment's beat, read-only setting, and backgroundImage preview — so a resumed editor seeds every field.
Re-expansion runs asynchronously: the call returns 202 with sceneStatus: "reexpanding". Poll GET …/tasks/:id until sceneStatus is planned again and scene.reexpandStatus is "ready" (or "failed" with scene.reexpandError); the refreshed scene.segments[].script holds the expanded prompts. Edit mode never reprices — the scene durations must keep summing to the fixed (paid) total (scene.lockedDurationSeconds), and both this edit and render reject a plan whose total drifts.
curl -s -X PUT "$TOKENSTORE_URL/api/v3/contents/generations/tasks/cgt-.../plan/structured" \
-H "Authorization: Bearer sk-..." -H "Content-Type: application/json" \
-d '{ "wardrobe": "a red silk slip",
"segments": [
{ "index": 1, "beat": "she wakes and stretches toward the window", "duration_seconds": 10 },
{ "beat": "a new insert: close on her hands", "duration_seconds": 5 },
{ "index": 2, "beat": "she crosses to the door", "duration_seconds": 5 }
] }'When you're happy, submit it for rendering with POST …/tasks/:id/render. The task then proceeds like any other (poll to succeeded for content.video_url). A draft you never render is refunded automatically after 24 hours.
curl -s -X POST "$TOKENSTORE_URL/api/v3/contents/generations/tasks/cgt-.../render" \
-H "Authorization: Bearer sk-..."Changed your mind before rendering? Cancel a parked draft with POST …/tasks/:id/cancel to get the full charge refunded immediately (rather than waiting for the 24h auto-refund). Only an edit-mode draft that has not started rendering can be cancelled — the task moves to the distinct terminal status cancelled (not failed), and a second cancel (or cancelling a task already rendering/done) returns 409.
curl -s -X POST "$TOKENSTORE_URL/api/v3/contents/generations/tasks/cgt-.../cancel" \
-H "Authorization: Bearer sk-..."Models & pricing
GET /api/v3/models (public) returns the current models with per-second and per-5s USD prices plus the price for each allowed duration. Three resolutions are offered; price scales linearly with duration (single clip 5/8/10/12/15s, or any integer 16–180s as a stitched multi-segment scene). Legacy seahorse-fast-<res> ids still work as aliases.
| Model | Resolution | USD / sec | USD / 5s |
|---|---|---|---|
seahorse-480p | 480p | $0.1888 | $0.9440 |
seahorse-720p | 720p | $0.2773 | $1.3864 |
seahorse-1080p | 1080p | $0.5428 | $2.7139 |
Direct Seedance models
seedance2.0-fast and seedance2.0-pro call the Seedance 2.0 API directly: your prompt and reference media are forwarded verbatim — no prompt enhancement, no scene direction, no reference retrieval. Use them when you want full control over exactly what Seedance receives (and the only lane where Seedance 2.0 Pro is available).
Differences from the seahorse-<res> models:
resolutionis a request parameter (480p,720p, or1080p; default720p) and the price follows it.- Single clips only:
durationmust be 5, 8, 10, 12, or 15 seconds. No multi-segment scenes, nomode/segments. - No enhancement fee — you pay the raw generation cost plus the standard margin.
| Model | Resolution | USD / sec | USD / 5s |
|---|---|---|---|
seedance2.0-fast | 480p | $0.0885 | $0.4425 |
seedance2.0-fast | 720p | $0.1770 | $0.8850 |
seedance2.0-fast | 1080p | $0.4425 | $2.2124 |
seedance2.0-pro | 480p | $0.1770 | $0.8850 |
seedance2.0-pro | 720p | $0.3540 | $1.7699 |
seedance2.0-pro | 1080p | $0.8850 | $4.4248 |
curl -s -X POST "$TOKENSTORE_URL/api/v3/contents/generations/tasks" \
-H "Authorization: Bearer sk-..." \
-H "Content-Type: application/json" \
-d '{
"model": "seedance2.0-pro",
"resolution": "1080p",
"content": [
{"type": "text", "text": "your exact Seedance prompt, sent as-is"},
{"type": "image_url", "image_url": {"url": "https://example.com/ref.jpg"}}
],
"duration": 5
}'