Real people in videos
Seedance can build a video around real people: their faces, their clips, their voices. On the ordinary Seedance route, a reference that appears to show a real person is refused before anything is generated:
{"error": {"code": "InputImageSensitiveContentDetected.PrivacyInformation",
"message": "The request failed because the input image 'content[1]' may contain real person."}}
POST /v1/generations/refs is our supported way to do it. Every picture, clip, sound and frame you send is
prepared before the generation is submitted, so the generator accepts real people in each of those roles. Use it
only with material you have the right to use, of people who have agreed to it.
Getting access
Real people are switched on per organisation, by us. Ask support. Until it is on, a submit answers 403:
{"error": {"code": "Gateway.RealFacesNotEnabled", "message": "not enabled for your organisation; contact support"}}
Nothing is prepared and nothing is charged. The key must also be allowed the model. If it is not, the answer is
403 with "this key is not granted access to this model".
Models
| model | resolutions | video length | reference images | reference clips | reference sounds |
|---|---|---|---|---|---|
bytedance/seedance-2.0 |
480p, 720p, 1080p, 4k | 4–15 s | up to 9 | up to 3 | up to 3 |
bytedance/seedance-2.0-fast |
480p, 720p | 4–15 s | up to 9 | up to 3 | up to 3 |
bytedance/seedance-2.0-mini |
480p, 720p | 4–15 s | up to 9 | up to 3 | up to 3 |
bytedance/seedance-2.5 |
480p, 720p, 1080p | 4–30 s | up to 30 | up to 10 | up to 10 |
The limits on each file are the generator's own:
| pictures (references and frames) | clips | sounds | |
|---|---|---|---|
| formats | jpeg, png, webp, bmp, tiff, gif, heic, heif | mp4, mov | wav, mp3 |
| size | under 30 MB | up to 200 MB | up to 15 MB |
| dimensions | 300–6000 px a side, aspect 0.4–2.5 | 300–6000 px a side, aspect 0.4–2.5, 407,696–8,295,044 pixels in all, 24–60 fps | — |
| length on the 2.0 models | — | 2–15 s each, 15 s in total | 2–15 s each, 15 s in total |
length on bytedance/seedance-2.5 |
— | 2–30 s each (4–30 s when the video edits the clip), 30 s in total | 2–30 s each, 30 s in total |
bytedance/seedance-2.5 also takes sound alone. The 2.0 models need at least one picture or clip beside it.
The door
Submit, with Authorization: Bearer <your-api-key>:
curl https://api.sociaro.com/v1/generations/refs \
-H "Authorization: Bearer $SOCIARO_API_KEY" -H "Content-Type: application/json" \
-d '{ "model": "bytedance/seedance-2.0",
"content": [
{ "type": "text", "text": "the woman from [Image 1] walks along a rainy street at night, smiling" },
{ "type": "image_url", "image_url": {"url": "https://your-cdn.example.com/her.jpg"},
"role": "reference_image" }
],
"resolution": "720p", "duration": 5 }'
# -> { "job_id": "cgt-…", "status": "submitted" }
The answer comes once your files are prepared and the job is submitted: usually in a few seconds. Preparing your files stops at 40 s at the latest, and every submit is answered within about 100 s, so give your client a timeout of at least 100 s.
Poll the job until it is finished. Poll every 5–10 s:
curl https://api.sociaro.com/v1/generations/$JOB_ID -H "Authorization: Bearer $SOCIARO_API_KEY"
# -> { "job_id": "…", "status": "processing" }
# -> { "job_id": "…", "status": "completed", "model": "bytedance/seedance-2.0",
# "media_url": "https://api.sociaro.com/v1/media/<id>", … }
statusisprocessing,completedorfailed, and every one of them arrives with HTTP200.completedalways carriesmedia_url. Download it within the hour, with noAuthorizationheader, because the link is the credential. Copy the video into your own storage.- The answer also carries the generator's own fields, such as
usage. failedcarrieserror.code,error.messageand, when the generator gave one,error.provider_code.
The request
| field | type | what it is |
|---|---|---|
model |
string | one of the ids in the table above |
content |
array | the parts, below; at least one picture, clip, sound or frame |
resolution |
string | a tier from the table; default 720p |
duration |
integer | seconds, within the model's video length, or -1 to let the generator choose; default 5 on the 2.0 models, -1 on bytedance/seedance-2.5 |
ratio |
string | 21:9, 16:9, 4:3, 1:1, 3:4, 9:16 or adaptive (default); on bytedance/seedance-2.5 a request with frames keeps the first frame's shape, so only adaptive applies there |
generate_audio |
boolean | let the generator compose a soundtrack |
watermark |
boolean | default false on this door |
seed |
integer | similar, not identical, results for the same seed |
return_last_frame |
boolean | the closing still beside the clip, at no extra cost |
output_format |
string | mp4; mov on bytedance/seedance-2.5 only |
bitrate_mode |
string | standard or high, at the same price |
omni_reference_task_type |
string | bytedance/seedance-2.5 only: auto, reference, edit or extend |
user |
string | your own end-user id, recorded with the charge |
An unknown field is refused with a 400 naming it. callback_url is refused: poll for the result. Drafts are not
offered on this route: draft (other than false) and a draft_task part are refused with a 400
Gateway.InvalidRequest, "drafts are not offered on this route", before anything is prepared or charged.
Each part of content:
| what you send | type |
role |
where the link goes |
|---|---|---|---|
| your prompt | text |
— | text |
| a picture of the person or object | image_url |
reference_image |
image_url.url |
| a clip | video_url |
reference_video |
video_url.url |
| a voice or a sound | audio_url |
reference_audio |
audio_url.url |
| the first frame of the video | image_url |
first_frame |
image_url.url |
| the last frame of the video | image_url |
last_frame |
image_url.url |
Each role
A face, or several: reference_image
Send one picture per person, up to the model's ceiling for pictures. Name each person in the prompt by the picture's number: Image 1 is the first picture you sent, Image 2 the second (see Writing the prompt).
curl https://api.sociaro.com/v1/generations/refs \
-H "Authorization: Bearer $SOCIARO_API_KEY" -H "Content-Type: application/json" \
-d '{ "model": "bytedance/seedance-2.5",
"content": [
{ "type": "text", "text": "the man from @Image 1 and the woman from @Image 2 dance together in a sunlit kitchen" },
{ "type": "image_url", "image_url": {"url": "https://your-cdn.example.com/him.jpg"},
"role": "reference_image" },
{ "type": "image_url", "image_url": {"url": "https://your-cdn.example.com/her.jpg"},
"role": "reference_image" }
],
"resolution": "720p", "duration": 8 }'
A clip: reference_video
A clip carries motion, a camera move or a performance for the video to follow.
curl https://api.sociaro.com/v1/generations/refs \
-H "Authorization: Bearer $SOCIARO_API_KEY" -H "Content-Type: application/json" \
-d '{ "model": "bytedance/seedance-2.0",
"content": [
{ "type": "text", "text": "the man from [Image 1] performs the dance from [Video 1] on a rooftop at sunset" },
{ "type": "image_url", "image_url": {"url": "https://your-cdn.example.com/him.jpg"},
"role": "reference_image" },
{ "type": "video_url", "video_url": {"url": "https://your-cdn.example.com/dance.mp4"},
"role": "reference_video" }
],
"resolution": "720p", "duration": 5 }'
A voice: reference_audio
"generate_audio": true asks for a video with sound. On the 2.0 models a sound needs a picture or a clip beside
it; bytedance/seedance-2.5 also takes a sound alone.
curl https://api.sociaro.com/v1/generations/refs \
-H "Authorization: Bearer $SOCIARO_API_KEY" -H "Content-Type: application/json" \
-d '{ "model": "bytedance/seedance-2.0",
"content": [
{ "type": "text", "text": "the woman from [Image 1] says good morning to the camera in the voice from [Audio 1]" },
{ "type": "image_url", "image_url": {"url": "https://your-cdn.example.com/her.jpg"},
"role": "reference_image" },
{ "type": "audio_url", "audio_url": {"url": "https://your-cdn.example.com/voice.mp3"},
"role": "reference_audio" }
],
"generate_audio": true, "resolution": "720p", "duration": 5 }'
The first frame: first_frame
The video starts on exactly this picture.
curl https://api.sociaro.com/v1/generations/refs \
-H "Authorization: Bearer $SOCIARO_API_KEY" -H "Content-Type: application/json" \
-d '{ "model": "bytedance/seedance-2.0",
"content": [
{ "type": "text", "text": "she turns towards the camera and smiles" },
{ "type": "image_url", "image_url": {"url": "https://your-cdn.example.com/first.jpg"},
"role": "first_frame" }
],
"resolution": "720p", "duration": 5 }'
First and last frame: first_frame + last_frame
The video starts on the first picture and ends on the second. If the two differ in shape, the last one is cropped to the first one's.
curl https://api.sociaro.com/v1/generations/refs \
-H "Authorization: Bearer $SOCIARO_API_KEY" -H "Content-Type: application/json" \
-d '{ "model": "bytedance/seedance-2.0",
"content": [
{ "type": "text", "text": "she walks from the door to the window" },
{ "type": "image_url", "image_url": {"url": "https://your-cdn.example.com/first.jpg"},
"role": "first_frame" },
{ "type": "image_url", "image_url": {"url": "https://your-cdn.example.com/last.jpg"},
"role": "last_frame" }
],
"resolution": "720p", "duration": 5 }'
Combining them
- Pictures, clips and sounds can be mixed in one request, up to each model's ceilings.
- Frames and references cannot be mixed. A request with
first_frameorlast_frameand anyreference_*is refused with a400before anything is prepared. Send the frames without references, or the references without frames. - At most one
first_frameand onelast_frameper request. - Every request needs at least one picture, clip, sound or frame. A prompt alone is refused with a
400.
Writing the prompt
Name each reference by its kind and its number: Image 1, Video 1, Audio 1. The number counts only the parts of
that kind, in content order, from 1, so Image 2 is the second picture you sent however many clips or sounds
come between. This is the generator's own rule. Say what each reference gives the video (a face, a motion, a voice)
and what it should not take from it. The generator's examples write [Image 1] for the 2.0 models and @Image 1
for bytedance/seedance-2.5:
The woman from [Image 1] performs the dance from [Video 1] on a rooftop and sings along to [Audio 1].
Our error messages number parts differently, among all your media together (see below).
Links you send
Send public https links. Signed links work if they stay valid until your submit has been answered.
- Do not send
http, inline base64, or a private or internal address. - A server-side fetch is refused by firewalls, bot filters and links that expire within seconds. Those come back as a
400withGateway.InputDownloadFailed, naming the part, for example reference image 2. That number is the part's position among ALL the media you sent, incontentorder, so reference image 2 is the second media part, which is a picture (the same rule as on the other reference routes).
Errors
On the submit
| status | error.code |
what to do |
|---|---|---|
400 |
Gateway.InputUrlInvalid |
the link is not a public https url: fix it |
400 |
Gateway.InputDownloadFailed |
we could not fetch that link: make it reachable from the public internet |
400 |
Gateway.InvalidRequest |
the file itself was refused (too short, too small); the message says why |
400 |
— | the request is wrong (frames with references, an unknown field, a missing part); the message says what |
400 |
Gateway.InvalidRequest |
also: a draft (draft, or a draft_task part); drafts are not offered on this route |
401 |
— | the key is missing or wrong |
403 |
Gateway.RealFacesNotEnabled |
your organisation does not have real people switched on: contact support |
413 |
— | the body is over 256 KiB: send media as links, never inline |
422 |
Gateway.InputPreparationFailed |
one file could not be prepared; the message names it by its position among your media and its role, for example "the reference image at position 2 could not be prepared: …", with the reason, and provider_code carries the generator's code when it gave one. Replace or re-encode that file |
429 |
— | out of balance or too many requests; the message says which |
503 |
Gateway.InputPreparationBusy, Gateway.InputPreparationTimeout |
preparation is busy, or a file did not become usable in time: retry after Retry-After seconds |
503 |
Gateway.UpstreamUnavailable |
the generator is unavailable to us (here: its answer could not be read). It comes WITHOUT Retry-After: the outcome at the generator is unknown, so do not resubmit automatically. You hold no job id and are not charged for it |
503 |
— | temporarily unavailable on our side; the message says why: retry later |
| the generator's | the generator's | it refused the request itself; its own code and message, vendor names replaced (below) |
None of these is charged to you.
Refusals by the generator
A refusal of the request itself, such as an input it will not take, comes back on the submit at once, with the
generator's status, error.code and message, and nothing is charged. A refusal after rendering arrives on the poll as
status: "failed", with the generator's reason and provider_code, for example:
{"error": {"code": "provider_failed",
"provider_code": "OutputAudioSensitiveContentDetected.PolicyViolation",
"message": "The request failed because the output audio may be related to copyright restrictions."}}
A soundtrack the generator composed is checked after the video renders. "generate_audio": false removes that whole
class of failure. A failed job is not charged.
When the answer is an HTML page, not JSON
A 502, 504 or 524 with an HTML body is our edge (Cloudflare), not the gateway: it replaces an error body from
us, or (524) cut a request held for about 120 s.
- On the submit you hold no job id. Resubmit only once your Logs show no job for the first attempt: rarely it was accepted, and then it is charged.
- On a poll, nothing changed: poll the same id again.
Billing
Charged per job at the same rates as the ordinary Seedance route. Preparing your files costs nothing extra. The charge is metered from what the generator reports it rendered, and a job with a video input has a minimum. A job the generator failed is not charged, and neither is a refused submit. Your Logs show each charge.
Limits
- Body: 256 KiB. Send media as links.
- Preparation: 120 file uploads a minute across the gateway; up to 12 files of one request are prepared at once. There is no per-key limit
on this door; under load you get
503Gateway.InputPreparationBusywithRetry-After. - Time: preparing your files stops at 40 s at the latest (a
503withRetry-After), and every submit is answered within about 100 s.