# Seedance 2 UGC (ugc) > Seedance 2 UGC makes an ad clip from a scene frame or from an ordered reference set on the fast Seedance tier. It runs at 480p and 720p. Status: roasOS API v1.1. Catalog `model-catalog@2026-10-06.v5`, pricing `customer-pricing@2026-11-05.v15`. The endpoint `POST /v1/ugc/seedance-2` is live. `POST /v1/generations` has no `ugc` type, so this endpoint is the only path to this model. ## Endpoint POST https://api.roasos.com/v1/ugc/seedance-2 Auth: Authorization: Bearer roasos_sk_… (scope api:write). Idempotency-Key required. quote_only / quote_id / webhook_url as in https://docs.roasos.com/llms.txt. ## Good at A quick draft or a variant sweep. Native audio. Reference mode takes a saved person, a saved product and your own style references. Use /v1/ugc/seedance-2-pro when the cut must be 1080p or 4K. ## Pricing Unit: clip. Pricing key: `seedance-2`. | request | credits | |---|---| | `4s_720p` | 12 | | `10s_720p` | 30 | | `15s_720p` | 44 | | `4s_720p_no_audio` | 12 | Credits come from the roasOS pricing table (`MODEL_COSTS`) through the catalog. No other field changes the price. ## Modes - `standard` - `reference` The worker derives the mode from the media fields of the request. Provider endpoints: `bytedance/seedance-2.0/fast/image-to-video` · `bytedance/seedance-2.0/fast/reference-to-video`. ## Request fields | field | type | required | default | rule | |---|---|---|---|---| | `aspect_ratio` | enum | no | `9:16` | `9:16`, `1:1`, `3:4`, `4:3`, `16:9`, `21:9` | | `avatar_id` | string | no | — | UUID; only in `reference` | | `avatar_upload` | string | no | — | https URL; ≤ 4,096 characters; only in `reference` | | `duration_seconds` | integer enum | no | `5` | `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15` | | `generate_audio` | boolean | no | `true` | — | | `product_id` | string | no | — | UUID; only in `reference` | | `prompt_mode` | enum | no | — | `wrapped`, `exact` | | `quote_id` | string | no | — | UUID | | `quote_only` | boolean | no | `false` | — | | `references` | string[] | no | — | ≤ 9 items; only in `reference` | | `resolution` | enum | no | `720p` | `480p`, `720p` | | `scene_id` | string | no | — | UUID; only in `standard` | | `scene_image` | string | no | — | https URL; ≤ 4,096 characters; only in `standard` | | `script` | string | yes | — | ≥ 1 character; ≤ 10,000 characters | | `wait_timeout_seconds` | integer | no | `0` | 0–60 | | `webhook_url` | string | no | — | https URL; ≤ 4,096 characters | The schema is strict: a field that is not in this table returns `400 unsupported_option`. Field names are the roasOS role names, one name per role across every family. ## Media - `avatar_id` — identity; the saved character reference sheet, with a derived portrait only where the model requires a single face or source frame - `product_id` — product; resolves to the product image list - `references` — style and appearance references - `scene_id` — first frame — a scene this workspace owns - `scene_image` — first frame — a CDN image | role | items | max size | content types | duration | |---|---|---|---|---| | `references` | ≤ 9 | 10 MB | `image/jpeg`, `image/png`, `image/webp` | — | | `scene_image` | ≤ 1 | 10 MB | `image/jpeg`, `image/png`, `image/webp` | — | - Refused: `elements`, `product_images`, `reference_images`, `image_url`, `end_image_url`, `video_urls`, `video_url`, `audio_urls`, `audio_url`, `voice_id`. A refused role returns `400 unsupported_option`. - Every URL must be an immutable object on `https://cdn.roasos.com/…` that your workspace owns; any other URL is `400 reference_media_not_workspace_owned`. Upload with `POST /v1/uploads` (direct POST of the bytes to `put_url`, or a `source_url` import), then use the returned CDN URL. ## Prompt - Standard mode: the worker appends the UGC facts block ("Use the supplied first frame … The requested format is a UGC video ad; preserve the supplied script/action …") to the script. - Reference mode: no facts block. Write no `@Image` tags yourself; the worker binds every reference. - Write the words to be spoken in quotes: says exactly with warm energy: "…". - Describe motion as physics: "Realistic hand movements, she lifts the jar to chest height." - Anchor the hands to an object. A contact point holds hands and fabric better. - Use a static camera for a talking head. Use one subject and one action for each clip. - Do not write claims, camera moves or music that the product does not have. - Seedance reads the ordered `@ImageN` tags. The worker writes them for you; do not write them yourself. ## Not exposed - `bitrate_mode`: pinned to `standard on every UGC request`. - `aspect_ratio`: pinned to `auto`. - `end_user_id`: not accepted by this public endpoint. - `video_urls`: not accepted by this public endpoint. - `references`: values not exposed — `BMP`, `TIFF`, `GIF`, `HEIC`, `HEIF`. - `avatar_id`: not accepted by this public endpoint. - `product_id`: not accepted by this public endpoint. - `seed`: pinned to `output only`. - `negative_prompt`: not accepted by this public endpoint. - `audio_urls`: not accepted by this public endpoint. - `end_image_url`: not accepted by this public endpoint. ## Result Result kind `ugc`. Always present: `url`. ```json { "data": { "id": "gen_…", "kind": "ugc", "model": "seedance-2", "status": "completed", "result": {"url":"https://cdn.roasos.com/workspaces/ws_01/result"} } } ``` Files live on `https://cdn.roasos.com` and are immutable; a result URL can be a media input to the next call. Poll `GET /v1/jobs/{id}/status` → `{ id, status, updated_at }`, then `GET /v1/jobs/{id}/result` (`409 run_not_completed` until the job is `completed`, `failed` or `canceled`). Statuses: `queued → processing → completed | failed | canceled`. ## Example ```bash # 1. quote — nothing is spent curl -X POST https://api.roasos.com/v1/ugc/seedance-2 \ -H "Authorization: Bearer roasos_sk_live_…" \ -H "Idempotency-Key: 0f1c9e2a-seedance-2-0001" \ -H "Content-Type: application/json" \ -d '{"quote_only":true,"script":"Two drops, morning and night. That is the whole routine."}' # → 200 { "data": { "kind": "quote", "quote_id": "q_7Hk…", "credits": 12, "expires_at": "…", "confirmation": { "model": "seedance-2", "example": "4s_720p" } } } # 2. run — the same body and the same Idempotency-Key, quote_id instead of quote_only curl -X POST https://api.roasos.com/v1/ugc/seedance-2 \ -H "Authorization: Bearer roasos_sk_live_…" \ -H "Idempotency-Key: 0f1c9e2a-seedance-2-0001" \ -H "Content-Type: application/json" \ -d '{"quote_id":"q_7Hk…","script":"Two drops, morning and night. That is the whole routine."}' # → 201 { "data": { "id": "gen_…", "kind": "ugc", "model": "seedance-2", "status": "queued", "credits_reserved": 12, "links": { "status": "/v1/jobs/gen_…/status", "result": "/v1/jobs/gen_…/result" } } } # 3. poll curl https://api.roasos.com/v1/jobs/gen_…/status -H "Authorization: Bearer roasos_sk_live_…" curl https://api.roasos.com/v1/jobs/gen_…/result -H "Authorization: Bearer roasos_sk_live_…" ``` ## Today The app route `POST /api/generate/ugc-ads { sceneId | sceneImage, script, model: "seedance-2", async: true }` sends the same request. Use this endpoint instead: it is live. ## See also https://docs.roasos.com/models/ugc/seedance-2 · https://api.roasos.com/v1/catalog/ugc/seedance-2 · bytedance/seedance-2.0/fast/image-to-video · bytedance/seedance-2.0/fast/reference-to-video