Sociaro

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>", … }
  • status is processing, completed or failed, and every one of them arrives with HTTP 200.
  • completed always carries media_url. Download it within the hour, with no Authorization header, 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.
  • failed carries error.code, error.message and, 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_frame or last_frame and any reference_* is refused with a 400 before anything is prepared. Send the frames without references, or the references without frames.
  • At most one first_frame and one last_frame per 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).

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 400 with Gateway.InputDownloadFailed, naming the part, for example reference image 2. That number is the part's position among ALL the media you sent, in content order, 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 503 Gateway.InputPreparationBusy with Retry-After.
  • Time: preparing your files stops at 40 s at the latest (a 503 with Retry-After), and every submit is answered within about 100 s.