Lip sync
A SEPARATE endpoint from /v1/videos —
deliberately not one more request shape bolted onto it. Re-syncs a face to a driving audio track: either
animating a still image, or dubbing an existing video's mouth to new speech. See the
Lip sync guide for the full model list and
worked examples.
POST/v1/lipsync
Two modes — which one you get depends only on which model you pick, and correspondingly whether you pass image_url or video_url alongside audio_url. There is no prompt field on this endpoint at all.
Parameters
audio_urlstringRequired, every model. Public https:// URL to the driving audio track (mp3/wav/etc, model-dependent). Output duration is dictated entirely by this file's real length — there is no duration_secs field.image_urlstringRequired for image-mode models (e.g. fal/h3-max-lipsync, atlascloud/infinitetalk) — a still photo of the face to animate. Rejected on video-mode models.video_urlstringRequired for video-mode models (e.g. fal/sync-lipsync-v3) — an existing clip whose mouth gets re-synced to audio_url. Rejected on image-mode models.resolutionstringOptional, only meaningful on the 2 tiered models (fal/h3-max-lipsync: 480P/768P/1080P/2K; atlascloud/infinitetalk: 480p/720p). Ignored by every flat-priced row.provider / failoverobjectOptional. Same provider-preference shape as /v1/videos' own — most lip-sync models are singly-hosted today, so there's usually nothing to fail over to yet.Example response (202, job just created)
{
"id": "fal:...",
"status": "queued",
"data": null,
"error": null
}
Billed once, in full, at creation time from the driving audio's real probed duration (video-mode models: max(video_secs, audio_secs), never undercharged) — polling is free. A model with no confirmed maximum input length refuses the request outright (502 pricing_unavailable) rather than guess, if your audio/video file can't be probed (unreachable URL, oversized file, non-media content).
GET/v1/lipsync/{id}
Unbilled — the full cost was already charged at creation time. Identical job-id scheme and settlement logic as GET /v1/videos/{id} (a lip-sync job is still a video job once submitted).
Parameters
idstring (path)The id returned by POST /v1/lipsync.Example response (status: "completed")
{
"id": "fal:...",
"status": "completed",
"data": [{ "url": "https://..." }],
"error": null
}
status is one of queued → in_progress → completed/failed. On failure, error carries the provider's message and data is null.