Authorization: Bearer or x-api-key), and the same per-client
rate limits and spend caps apply.
POST /v1/videos/generations— submit a job. Answers 202 with a job object containing anid.GET /v1/videos/generations/{id}— poll the job until itsstatusis terminal (succeededorfailed).
Quickstart
Request parameters
Media inputs
Image-to-video-capable models accept media inputs alongside (or instead of) the prompt.wan-2.6 and seedance-2.0 in the public table below are
text-to-video only — they reject every field in this section
synchronously with a 400 naming the unsupported fields, so nothing is ever
silently ignored. wan3.0-video accepts keyframe mode (first_frame /
last_frame) or reference mode (reference_images / reference_videos /
reference_audios, up to 10 / 5 / 5) plus resolution, ratio (adaptive,
21:9, 16:9, 4:3, 1:1, 3:4, 9:16), audio, seed and
prompt_extend; the two modes are mutually exclusive and a prompt is optional
when media is present. The ByteDance official-API Seedance models, the fal
media models, the Higgsfield models, and the (not yet available) BACH models
accept the inputs listed in their own
tables further down; other media-capable models are provisioned per account.
Some models require a prompt even with media, and accepted URL/inline formats
differ by provider — Higgsfield and BACH accept http(s) URLs only, not inline images.
These fields apply:
Inline media and retries. Requests that pass images inline (data URI or
bare Base64) are not re-submitted automatically after a transient provider
rejection — the job fails with a clear message and you should submit again.
Passing media by URL permits retries after definite transient provider rejections.
Higgsfield and BACH submissions are not retried after ambiguous timeouts or 5xx responses:
the provider may already have accepted the job and has no documented idempotency key. Inline payloads are
never persisted in stored job records, and once a job reaches a terminal
state the platform scrubs the stored request content — prompt, generation
parameters, media URLs — down to billing metadata (zero content retention;
scrubbing is deferred while an organization’s optional support-capture
window is open). The job stays readable by id:
status, result, and
error are unaffected.The job object
Both endpoints return the same shape —object is always
"video.generation.job" and status moves strictly forward:
A finished job looks like this:
- On success,
result.video.urlis an MP4 hosted on the provider’s CDN — download promptly and persist on your side; the URL is not permanent. Every model also returns the same URL asresult.videos[0], so a parser written against either field works for every provider. - Generated artifacts follow each provider’s own retention policy — no fixed deletion window is guaranteed (see the provider data-handling page for per-provider retention).
artifact_expires_atandupstream_deleted_atreport platform-scheduled deletion of the provider-side artifact where a model supports it; they arenullfor models without platform-side deletion — including every model in the table below. - Extra metadata in
resultvaries by model (for examplewan-2.6echoes width/height/duration;seedance-2.0omits them). - On failure,
erroris a human-readable string andresultstaysnull.
Models & pricing
Wan 3.0 (Higgsfield)
These three routes use Higgsfield’s direct asynchronous HTTP API, not the LiteLLM engine or a WebSocket. Integration is documented ahead of deployment; credentials, account funding, and live smoke verification remain deployment steps. Higgsfield Inc. is a US operator, not a PRC-labeled serving leg. Its standard terms permit training on inputs and outputs; an enterprise no-training carve-out has not been verified for our account. All three routes therefore require the organization administrator’s existing training and unverified-retention consents. See provider data handling.
All require a nonblank
prompt (gateway limit 32,000 characters; Higgsfield’s
published schema states no prompt maximum). Duration is an integer 2–30 seconds,
default 5. Resolution is 480p, 720p, or 1080p, default 1080p;
ratio is 16:9, 4:3, 1:1, 3:4, 9:16, or adaptive, default adaptive.
size maps to the nearest supported tier and ratio; explicit resolution and
ratio override those dimensions. audio defaults to true. Optional seed
is an integer from 0 to 2147483647. Rates above are provider list prices before
any customer discount; a 5-second 720p video is $0.50 at list price. No temporary
promotional discount is assumed.
Use publicly fetchable HTTPS URLs (http(s) URLs accepted); inline Base64/data URIs
and authenticated URLs are not supported. For i2v, send
image or first_frame,
not two different values. Reference arrays are optional, not a requirement to
provide at least one reference. Limits are 10 images, 5 videos, 5 audios.
The provider additionally enforces video lengths of 1–30 seconds each, 30 seconds
total, and audio inputs of WAV/MP3, 30 seconds total. AI Reserve validates URL
shape and counts, but does not download or inspect source media to measure duration
or format before submit. Do not mix keyframes and reference arrays.
result.video.url. Higgsfield’s upstream status
body is flat (status: "completed", video: { "url": "…" }); the adapter normalizes
it to the gateway job object. failed, nsfw, and canceled upstream states become
failed gateway jobs. The provider does not document measured duration or cost in
status results; settlement uses the submitted duration and resolution rate.
Download promptly: Higgsfield documents output availability of at least seven
days, which is not a promise to delete after seven days or a zero-retention
policy. API-specific retention/deletion controls and the account’s serving region
remain unverified. artifact_expires_at and upstream_deleted_at remain null.
Not exposed in this initial integration: Higgsfield file uploads, cancellation,
webhooks, WebSockets, image generation, Wan Prime or Seedance on Higgsfield;
enable_thinking, file_url, link_url, negative_prompt, prompt_extend,
video, and audio_url. Deep thinking remains at the upstream default false.
The similarly named fal Wan Prime route below is a different serving provider.
Contracts and list rates: text-to-video,
image-to-video,
reference-to-video,
status API,
billing and retention.
BACH (Video Rebirth)
Three routes onto Video Rebirth’s asynchronousbach-1.0 HTTP API, integrated
through the same media-job pipeline as the Higgsfield routes (submit → poll →
settle). They are not yet available. The integration ships dark: the
models are absent from GET /v1/models, and a request to any of them is
refused synchronously with 422 MODEL_NOT_CONFIGURED (a platform fault — you
are not charged, no job is created) until the platform has recorded both the
provider credentials and the provider’s list rates. No rate is published by
Video Rebirth today, so no price is quoted here; this section will gain a
pricing table when the rates are recorded, and the models will then appear
in the catalog automatically.
Video Rebirth publishes no API-content terms (training use, retention,
deletion, processing region are all pending verification), and the platform
labels it China-affiliated pending vendor diligence, so once enabled the
routes require the organization administrator’s PRC-affiliated-models and
unverified-retention consents. See
provider data handling.
prompt is required except for bach-1.0-i2v (where the frames can carry the
shot) and is capped at 10,000 characters, as is negative_prompt.
Resolution is 720p or 1080p, default 720p; ratio is 16:9, 9:16, or
1:1, default 16:9 (bach-1.0-i2v takes its aspect from the frame and does
not accept ratio). size maps to the nearest tier and ratio; explicit
resolution / ratio win. Media must be publicly fetchable http(s) URLs —
inline Base64 / data URIs are rejected. audio, seed, reference_videos,
reference_audios, and video are not accepted (audio in particular is
withheld until the provider’s audio surcharge, if any, is known — accepting it
now would price audio at the silent-video rate).
Successful polls expose
result.video.url. Upstream TASK_FAILED results
(including the provider’s content-safety rejection, “Contains sensitive
information.”) become failed gateway jobs; billing uses the submitted duration
and resolution tier. Download promptly — Video Rebirth advises callers to
transfer and store generated videos promptly and states that task results can
expire; that is not a deletion commitment, and artifact_expires_at /
upstream_deleted_at stay null. Bach submissions are not retried after
ambiguous timeouts or 5xx responses (no documented idempotency key); a
provider queue-capacity answer is retried like any transient rejection.
Enable runbook (operators, in order):
- Apply infrastructure so the two secret containers and the proxy’s access grants exist: dispatch the Infrastructure Deploy workflow from
mainwithenvironment=uat, thenenvironment=production(action=up), or runcd packages/infra && bun up:uat/bun up:production. The workflow isworkflow_dispatchonly — it does not run on merge. - Add the credential versions, UAT first:
gcloud secrets versions add BACH_ACCESS_KEY --project audacity-uat --data-file=-andgcloud secrets versions add BACH_SECRET_KEY --project audacity-uat --data-file=-; repeat with--project audacity-production. Never create the secrets themselves withgcloud— Pulumi owns them. - Once Video Rebirth’s rates are in writing, commit
packages/db/scripts/pricing-sync/update-provider-pricing-<date>-bach.tswith one row per model underprovider: "bach"—inputPricePer1mTokens= USD per 1,000,000 generated seconds at 720p,outputPricePer1mTokens= the same at 1080p,outputPricePerImage= the default-job reference for reporting. The Provider Pricing Apply workflow applies it on merge;scripts/pricing-sync/bach-pricing-parity.test.tspins the column convention. A0.000000placeholder is not a rate card — the model stays dark. - Deploy
litellm-proxy(UAT auto-deploys on merge; production through Deploy All). The adapter re-reads pricing every 60 seconds, so no restart is needed for a rate change alone. - Smoke on UAT: confirm the three ids appear in
GET /v1/models, submit abach-1.0-videojob, poll tosucceeded, and check the usage row carriesprovider: "bach"with the expected estimated cost.
Image-to-video and reference-to-video (fal)
These models start from your media instead of a bare prompt: passimage
(or first_frame) for image-to-video, or reference_images for
reference-to-video, alongside the prompt. They are served by fal in the
United States and billed per second of finished video at fal’s list price
(plus the small per-input-image fee where fal charges one).
Video-to-video utilities on fal (reframe, upscale, translate, prompt-driven
edit, background removal) bill per second of the source clip and are
provisioned per account — they are not in the public model list.
Image-to-video and reference-to-video (ByteDance official API)
The ByteDance official-API Seedance models in the table above also take media inputs — the same model ids, no separate-i2v / -reference
variants. Two modes, mutually exclusive on one request:
- Keyframe mode:
first_frame(or its aliasimage) starts the clip on your image; addlast_frameto also pin the closing frame. Images may be a public URL, adata:image/...;base64,data URI, or bare Base64 (PNG, JPEG, GIF, WebP, BMP). - Reference mode (ByteDance’s “omni reference”):
reference_images,reference_videosandreference_audios, in any combination, referenced in the prompt as “Image 1”, “Video 1”, “Audio 1”. Video editing and video extension are reference-mode requests whose prompt describes the change or the continuation of areference_videosclip. Videos and audio are http(s) URLs only.
audio (boolean) toggles the generated soundtrack and seed is forwarded.
ByteDance does not accept reference images or videos that contain real
human faces on these models. Billing stays token-metered on the finished
clip; when a request carries a reference_videos clip, ByteDance bills the
input clip’s duration as well, at a lower per-token rate, and the job’s
cost reflects the tokens ByteDance reports.
Video is billed per second of finished video at the tier actually
generated — a 5-second wan-2.6 clip at 720p is roughly $0.50. Only videos that
finish successfully are billed. Each job’s cost is metered against your key exactly like
chat and image traffic, appears in your usage reporting, and counts toward the same spend
caps.
Polling from Python
A production-shaped loop with a hard deadline: poll every few seconds, treat 5xx poll errors as transient (the job keeps running server-side), and give up after a sensible timeout. A typical 5-secondwan-2.6 clip completes in under a minute; longer
clips and higher tiers take proportionally longer.
SDK note. The SDKs do not yet ship a video-generation helper — call the
HTTP endpoints directly as above. Typed helpers in all five languages are coming in an
upcoming SDK release.
Errors
Submission errors reuse the familiar codes: 400invalid_request_error for a
malformed body, 401 invalid_api_key, 402 usage_cap_exceeded when
a spend cap is reached, and 429 rate_limit_exceeded with a
Retry-After header. Three video-specific cases:
- 400 at submit —
duration_secondsis not one of the values the model supports (for examplewan-2.6only accepts 5, 10, or 15). The message lists the allowed values; no job is created. - 502 at submit — the provider rejected the job synchronously (for example a prompt rejected by upstream validation). The response carries the provider’s message and a
job_id; the failed job remains readable by id. - 404
job_not_foundon poll — the job id is unknown or belongs to a different workspace’s key.
Content policy. Upstream video providers apply safety filtering to
prompts and outputs. A prompt that violates the provider’s content policy fails the
generation — the job lands in
failed with the provider’s message in
error (or, if rejected at submit, in the 502 response).