EnginesHow it worksDocumentation
Console

v1

Quickstart

Submit a video and audio. Receive a webhook or poll for status and download the result

Sign in with Google or GitHub and create an API key. Keep the key on your server. Give Lips your video URL, replacement audio URL, chosen engine and, optionally, a webhook URL in one request

Environment
export LIPS_API=https://lips.sh
export LIPS_KEY='<your-api-key>'
POST /v1/renders
curl -X POST "$LIPS_API/v1/renders" \
  -H "Authorization: Bearer $LIPS_KEY" \
  -H "Idempotency-Key: render-001" \
  -H "Content-Type: application/json" \
  -d '{"video":{"url":"https://example.com/video.mp4"},"audio":{"url":"https://example.com/audio.wav"},"engines":["musetalk"],"sync_mode":"loop","webhook_url":"https://your-app.example/lips/webhook"}'

The API returns 202 Accepted with the render’s id. Save it. Processing continues asynchronously after acceptance

Choose Webhooks Or Polling

Use webhooks for a push notification, or omit webhook_url and poll the render ID from your backend. Both are supported ways to retrieve results

With webhooks, receive render.completed, render.failed or render.cancelled at your webhook. Verify the signature before trusting the event, and deduplicate its id. The render ID is in data.id

Fetch the result after the webhook
GET /v1/renders/<data.id>
Authorization: Bearer <your-api-key>

Fetch the render once after the event to get current signed download URLs in completed engines’ output.url. Download the outputs you need. A webhook is a notification, not a permanent video URL. Polling also works independently, without a webhook. Fetch the saved render ID every five seconds until its status is completed, failed or cancelled

Use WebhooksUse Polling