API Reference
Lipsync + Drama
API Reference

SyncMonster API

Generate lip-sync and expression editing on videos. Find Face detects scenes and faces in video segments and returns the same. Generate then produces lip-sync, drama, or both on the faces you choose by face_id.

REST API JSON + Multipart API Key Auth Per-Scene Faces
Base URL https://studio.syncmonster.ai/neuralgarage/saas/api/v1/clients

🔑 Authentication

Every request must include your API key in the request headers. Keep this key secret and never expose it in client-side code.

Header Value Description
x-api-key YOUR_API_KEY Pass your secret key here
cURL · Example Request
curl -X GET \
  https://api.syncmonster.ai/neuralgarage/saas/api/v1/clients/list-assets \
  -H "x-api-key: YOUR_API_KEY"

🔀 How It Works

The pipeline runs in two stages. Find Face handles scene detection and face detection; Generate drives the chosen faces with lip-sync and/or drama.

1
POST/find-face
Scene + face detect
2
GET/find-face/status
Poll until done
3
GET/get-face
Faces per scene
4
POST/generate
Lip-sync &/or drama
5
GET/get-status
Poll until done
6
GET/get-file
Download video
ℹ️ Single face in a scene? You can skip selection and go straight to /generate — that one face is used automatically. Selection matters when a scene has multiple faces.
Or skip the whole first stage. Pass skip_find_face=1 directly to POST /generate with the video attached — steps 1–3 above run inline automatically (scene detect, face detect, auto-select) and you get back a single request_id. Faster for the common case; use the multi-step flow when you need to preview/choose a specific face first via /get-face.
Credits

All steps are billed per second of video.

Find Face
0.5 credit / sec
/find-face
Lip-sync
1 credit / sec
is_lipsync
Drama
1 credit / sec
is_drama
💡 Running lip-sync and drama together bills both rates — 2 credits per second.

📡 Status Codes

All API responses include a status field and a corresponding HTTP status code. Use these to handle responses programmatically.

Status Name Description
success Success The request was successful.
created Created The request has been fulfilled and a new resource has been created.
in_progress In Progress The request is being processed.
pending Pending The request is pending and awaiting processing.
invalid_request Invalid Request The request is invalid.
failed Failed The request failed to process.
unauthorized Unauthorized Authentication is required and has failed.
forbidden Forbidden You do not have permission to access this resource.
not_found Not Found The requested resource was not found.
internal_error Internal Server Error An unexpected error occurred on the server.
1 Find Face

🔍 Find Face

Find Face detects scenes and faces in video segments and returns the same. This runs one time per video — submit, poll for status, then fetch the faces to drive in generation.

POST
/find-face
Run scene detection and face detection on a video
201 Created
💡 Scene detection is included. Returns a find_face_id you poll on /find-face/status, then read with /get-face.
Request Parameters
Parameter Type Required Description
assets array Required (JSON) Video asset with url or asset_id
video file Required (Form) Video file upload — .mp4 or .mov
video_asset_id integer Optional Existing video asset ID (alternative to upload)
options.scene_threshold float Optional Scene split sensitivity
options.min_scene_length integer Optional Minimum frames between scene cuts
Request · JSON (Asset ID)
JSON
{
  "assets": [
    { "type": "video", "asset_id": 123 }
  ],
}
Request · Multipart (Upload)
multipart/form-data
video=@/path/to/video.mp4
Success Response · 201
JSON
{
  "status": "success",
  "message": "Find-face job created",
  "data": {
    "find_face_id": "ff_740006cb51da497fa1930dfe10520cc4",
    "video_asset_id": 123,
    "credit_details": { "rate_per_sec": 0.5 }
  }
}
💳 Find Face is billed at 0.5 credit per second of video.
GET
/find-face/status
Poll the current status of a find-face request
200 OK
Query Parameters
Parameter Type Required Description
find_face_id string Required Find-face ID from POST /find-face
Request
GET /v2/find-face/status?find_face_id=ff_740006cb51da497fa1930dfe10520cc4
Success Response · 200
JSON
{
  "status": "success",
  "message": "Status fetched",
  "data": {
    "find_face_id": "ff_740006cb51da497fa1930dfe10520cc4",
    "status": "in_progress",
    "status_code": 102
  }
}
GET
/get-face
Fetch detected faces per scene for a completed find-face request
200 OK
🎯 Each scene lists the faces detected inside it. Use the detected global_face_id to select a face in /generate.
Query Parameters
Parameter Type Required Description
find_face_id string Required Find-face ID
Request
GET /v2/get-face?find_face_id=ff_740006cb51da497fa1930dfe10520cc4
🎞️ The response returns a flat list of faces for the request. Each face is identified by global_face_id and includes a base64-encoded representative image in representative_face_base64.
Per-Face Fields
Field Type Description
global_face_id integer Unique identifier for the face across the find-face response
representative_face_base64 string Base64-encoded representative image for the detected face
Success Response · 200
JSON
{
  "status": "success",
  "message": "Faces fetched",
  "data": {
    "find_face_id": "ff_740006cb51da497fa1930dfe10520cc4",
    "video_asset_id": 264,
    "faces": [
      {
        "global_face_id": 0,
        "representative_face_base64": "base64code"
      },
      {
        "global_face_id": 1,
        "representative_face_base64": "base64code"
      }
    ]
  }
}
Reading the Result · Face Selection
Multiple faces

The response can return several faces, each with global_face_id and representative_face_base64. Pick which face(s) to drive in /generate.

No face

The faces array is empty. In that case, there is nothing to select and the request has no face-based output to drive.

Single face

Only one face is returned. You can skip selection and go straight to lip-sync or drama generation — that face is used automatically.

2 Generate

🎬 Generate

Generate is used to produce lip-sync, drama, or both on the face you selected.

POST
/generate
Generate lip-sync and/or drama from a find-face result
201 Created
⚙️ Enable is_lipsync, is_drama, or both. Combine them to apply emotional performance on top of lip-sync. Select a single face with global_face_id and tune intensity via options.
One-shot mode: set skip_find_face=1 to skip POST /find-face entirely. Send the video directly to /generate and scene detection, face detection and clustering all run inline, then a face is auto-selected — global_face_id defaults to 0 if omitted. One request in, one request_id out. Trade-off: you don't get to preview detected faces via /get-face before dubbing, so use it when you already know which face you want (or the video only has one).
Request Parameters
Parameter Type Required Description
skip_find_face boolean Optional (default 0) Set to 1 for one-shot mode — provide video directly instead of find_face_id. See the one-shot example below.
find_face_id string Required unless skip_find_face=1 Completed find-face request ID (the find_face_id from POST /find-face)
video file Required if skip_find_face=1 (Form) Video upload for one-shot mode — alternative to video_asset_id or a video entry in assets (JSON)
video_asset_id integer Optional (Form, skip_find_face=1) Existing video asset ID, reused instead of re-uploading
is_lipsync boolean Required Enable lip-sync
is_drama boolean Required Enable drama. May be combined with lip-sync
model string Required if is_lipsync=true Lip-sync model — e1 Pro (recommended), e2 Adaptive, e3 Legacy
assets array Required (JSON) Audio input with url or asset_id — plus a video entry when skip_find_face=1
audio file Required (Form) Audio upload — .mp3 or .wav
global_face_id integer Required unless skip_find_face=1 Selected face ID returned from /get-face. With skip_find_face=1 this is optional and defaults to 0 (a face is auto-selected for you).
drama_params object Optional if is_drama=true Same shape as drama below — {"happy":0.8,"sad":0.2,...}. Accepted as an alternate key name (e.g. in form-data).
audio_asset_id integer Optional Existing audio asset ID
options.intensity float Optional if is_lipsync=true Lip-sync strength: 0.5 to 3.5. Sent in options.
drama.happy float Optional if is_drama=true Happy intensity: 0 to 1
drama.sad float Optional if is_drama=true Sad intensity: 0 to 1
drama.excited float Optional if is_drama=true Excited intensity: 0 to 1
drama.angry float Optional if is_drama=true Angry intensity: 0 to 1
ℹ️ Modes are independent. Set is_lipsync and is_drama in any combination. At least one must be true. Use global_face_id to select a face and send intensity in options.
Lip-sync + Drama Together (JSON + asset_id)
JSON
{
  "find_face_id": "ff_740006cb51da497fa1930dfe10520cc4",
  "is_lipsync": true,
  "is_drama": true,
  "model": "e2",
  "assets": [
    { "type": "audio", "asset_id": 124 }
  ],
  "drama": {
    "happy": 0.8,
    "sad": 0.2,
    "excited": 0.6,
    "angry": 0.1
  },
  "options": {
    "intensity": 2.0
  }
}
Lip-sync Only (JSON)
JSON
{
  "find_face_id": "ff_740006cb51da497fa1930dfe10520cc4",
  "is_lipsync": true,
  "is_drama": false,
  "model": "e2",
  "assets": [
    { "type": "audio", "asset_id": 124 }
  ],
  "options": { "intensity": 1.5 }
}
Drama Only (JSON + URL)
JSON
{
  "find_face_id": "ff_740006cb51da497fa1930dfe10520cc4",
  "is_lipsync": false,
  "is_drama": true,
  "assets": [
    { "type": "audio", "url": "https://example.com/audio.wav" }
  ],
  "drama": { "happy": 0.7, "excited": 0.5 }
}
One-Shot — skip_find_face=1 (JSON)
No find_face_id or global_face_id needed — send the video straight in, and lip-sync/drama get applied to face global_face_id=0 (the auto-selected face) in a single call.
JSON
{
  "skip_find_face": 1,
  "is_lipsync": true,
  "is_drama": true,
  "model": "e1",
  "assets": [
    { "type": "video", "url": "https://example.com/podcastSarvam.mp4" },
    { "type": "audio", "url": "https://example.com/podcastSarvam.mp3" }
  ],
  "drama_params": { "excited": 1 },
  "options": { "intensity": 2.0 }
}
Success Response · 201
JSON
{
  "status": "success",
  "message": "Job Created",
  "data": {
    "request_id": "9fdfaf1a24d14db2b6e6821a69add99b",
    "assets": [
      { "type": "video", "asset_id": 536 },
      { "type": "audio", "asset_id": 537 }
    ],
    "auto_find_face": true
  }
}
💳 Credits aren't in this response. The job is billed asynchronously once processing finishes — face detection (0.5 credit/sec of full video, one-shot mode only) plus lip-sync/drama (1 credit/sec per mode enabled, additive, charged only for the scenes that actually matched the selected face). Poll GET /get-request?request_id=... and read credit_details.credits_deducted once status is Success. auto_find_face tells you which billing path applied: true = one-shot (face detection + lip-sync/drama), false = two-step (face detection already billed by the earlier /find-face call, only lip-sync/drama billed here).
Error Response
JSON
{
  "status": "failed",
  "message": "Invalid audio format '.txt'. Allowed: .mp4, .mov, .wav, .mp3",
  "data": {
    "error_code": "ERR_008",
    "error_name": "INVALID_FORMAT",
    "message": "Invalid file type. Supported types are: .mp4, .mov"
  }
}

🎭 Lipsync & Drama Parameters

is_lipsync · Lip-sync is_drama · Drama
Lip-sync

Drives mouth movement to match the supplied audio. Requires a model — pick one of the three modes below; lipsync_intensity tunes how pronounced the sync is.

Models
Recommended
e1
Pro Mode
V9

Ideal for frontal faces. Delivers natural output with high precision.

e2
Adaptive Mode
V10

Handles a wide range of angles with balanced realism.

e3
Legacy Mode
V1

Generalized model designed for overall coverage across consistency and sync.

e1 (Pro Mode) is recommended for most videos. Model keys remain e1, e2, e3.
Lip-sync Parameters
Parameter Type Range Description
model string e1 / e2 / e3 Lip-sync model — e1 Pro, e2 Adaptive, e3 Legacy. Required when is_lipsync=true. e1 recommended
intensity float 0.5 – 3.5 Sync strength: lower is subtle, higher is more pronounced
Drama

Adds emotional performance to the driven faces. Each emotion is a float in 0 – 1 acting as its intensity. Combine emotions to shape the delivery.

😊happy
0.01.0
😢sad
0.01.0
🤩excited
0.01.0
😠angry
0.01.0
happy
← inversely proportional →
sad

Raising happy effectively lowers sad, and vice versa — they sit on the same axis.

Parameter Type Range Description
drama.happy float 0 – 1 Happy intensity (inverse of sad)
drama.sad float 0 – 1 Sad intensity (inverse of happy)
drama.excited float 0 – 1 Excited intensity
drama.angry float 0 – 1 Angry intensity
Face Selection · global_face_id

After /get-face returns the detected faces, choose the face to drive using global_face_id. Send lip-sync intensity inside options.

JSON
{
  "find_face_id": "65bf2dc3926d48498ac76c7aae539647",
  "global_face_id": 0,
  "options": { "intensity": 2.5 }
}
GET
/get-status
Poll the current status of a generation job
200 OK
Query Parameters
Parameter Type Required Description
request_id string Required The job request ID returned from POST /generate
Request
GET /get-status?find_face_id=a1b2c3d4e5f6g7h8
Success Response · 200
JSON
{
  "status": "success",
  "message": "Request status fetched",
  "data": {
    "request_id": "a1b2c3d4e5f6g7h8",
    "status": "Success",
    "status_code": "success",
    "assets": { "video": 38, "audio": 45 }
  }
}
Error Response
JSON
{
  "status": "failed",
  "message": "Request ID not found"
}
GET
/get-file
Download the final processed video for a completed job
200 OK · Binary
Query Parameters
Parameter Type Required Description
request_id string Required The completed job request ID
Request
GET /get-file?request_id=a1b2c3d4e5f6g7h8
Success Response · 200
Response Headers
Content-Type: video/mp4
Content-Disposition: attachment; filename="output.mp4"

// Binary video data stream
Job Still Processing
JSON
{
  "status": "success",
  "data": {
    "request_id": "a1b2c3d4e5f6g7h8",
    "status": "in_progress",
    "status_code": 102,
    "message": "Job is still processing. Please try again later."
  }
}

📦 Assets & Requests

Utility endpoints for listing and inspecting requests and uploaded assets.

GET
/list-requests
Retrieve a paginated list of all job requests
200 OK
Query Parameters
Parameter Type Default Description
limit integer 10 Records to return per page
offset integer 0 Starting offset for pagination
type string all Optional filter: generate, find-face, or omit to return all requests
Example Requests
Request
GET /list-requests?limit=10&offset=0&type=generate
GET /list-requests?limit=10&offset=0&type=find-face
GET /list-requests?limit=10&offset=0
Success Response · 200
JSON
{
  "status": "success",
  "message": "Requests fetched",
  "data": {
    "requests": [
      {
        "request_id": "eca2322beafb427fb26fe39d90714ef5",
        "type": "generate",
        "status": "Success",
        "status_code": "success",
        "created_at": "2026-07-10T11:44:23",
        "completed_at": "2026-07-10T11:50:26"
      }
    ],
    "total_requests": 19,
    "end_of_records": false
  }
}
💡 Use type=generate or type=find-face to filter the list; omitting the parameter returns the combined list.
GET
/get-request
Fetch full details and metadata for a single request
200 OK
📄 Returns the complete record for any request — mode flags, parameters, assets, timing, and credits — useful for auditing or rebuilding a job.
Query Parameters
Parameter Type Required Description
request_id string Required Find-face or generate request ID
Request
GET /get-request?request_id=a1b2c3d4e5f6g7h8
Success Response · 200
JSON
{
  "status": "success",
  "message": "Request fetched",
  "data": {
    "request_id": "a1b2c3d4e5f6g7h8",
    "type": "generate",
    "status": "Success",
    "status_code": "success",
    "is_lipsync": true,
    "is_drama": true,
    "model": "e2",
    "assets": { "video": 123, "audio": 124 },
    "created_at": "2026-04-07T04:13:23",
    "completed_at": "2026-04-07T04:14:04",
    "credit_details": { "credits_deducted": 2 }
  }
}
GET
/list-assets
Retrieve all uploaded assets for the authenticated user
200 OK

No parameters required. Returns all assets associated with your API key.

Request
GET /list-assets
Success Response · 200
JSON
{
  "status": "success",
  "message": "Assets listed",
  "data": [
    { "asset_id": 123, "media_type": "video" },
    { "asset_id": 124, "media_type": "audio" },
    { "asset_id": 125, "media_type": "video" }
  ]
}
GET
/get-asset
Retrieve details for a specific asset by ID
200 OK
Query Parameters
Parameter Type Required Description
asset_id integer Required The asset ID to retrieve
Request
GET /get-asset?asset_id=123
Success Response · 200
JSON
{
  "status": "success",
  "message": "Asset Fetched",
  "data": {
    "asset_id": 123,
    "media_type": "video"
  }
}
Error Response
JSON
{
  "status": "failed",
  "message": "Asset not found"
}

🛠️ Utility Endpoints

Check your credit balance and confirm that the service is healthy.

GET
/get-credits
Fetch the current available credits for the authenticated user
200 OK
🔐 Requires the same x-api-key header used by the rest of the API.
Response
JSON
{
  "status": "success",
  "message": "Credits fetched",
  "data": {
    "credits": 1234.0
  }
}
GET
/health
Check the service health status
200 OK
Response
JSON
{
  "status": "success",
  "message": "OK",
  "data": {
    "status": "healthy"
  }
}

⚙️ Processing Phases

PHASE 01
Scene Detection
Detects scene boundaries in the video. Runs as part of /find-face and can be skipped if the video was already processed.
PHASE 02
Face Detection
Processes all detected scenes in parallel. Extracts faces, keyframes, crops, and coordinates per scene for selection.
PHASE 03
Generation
Creates lip-sync and/or drama on the selected faces. Scenes with no face are passed through untouched.
PHASE 04
Export
Merges all processed scenes into the final output video, combining original and generated content.

⚠️ Error Codes

Code Name Description
ERR_003 INTERNAL_SERVER_ERROR An internal server error occurred
ERR_004 NO_FACE_FOUND No face was detected in the provided video
ERR_006 INSUFFICIENT_CREDITS Not enough credits to complete the request
ERR_007 DATA_CORRUPTED Uploaded data is corrupted or invalid
ERR_008 INVALID_FORMAT Unsupported file type. Accepted: .mp4, .mov, .mp3, .wav
ERR_009 LIMIT_EXCEEDS Video duration exceeds the limit.

📁 Supported File Formats

Video
.mp4·MPEG-4 Video
.mov·QuickTime Movie
Audio
.mp3·MPEG Audio
.wav·Waveform Audio