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://api.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.

HeaderValueDescription
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.
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.

StatusNameDescription
successSuccessThe request was successful.
createdCreatedThe request has been fulfilled and a new resource has been created.
in_progressIn ProgressThe request is being processed.
pendingPendingThe request is pending and awaiting processing.
invalid_requestInvalid RequestThe request is invalid.
failedFailedThe request failed to process.
unauthorizedUnauthorizedAuthentication is required and has failed.
forbiddenForbiddenYou do not have permission to access this resource.
not_foundNot FoundThe requested resource was not found.
internal_errorInternal Server ErrorAn 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
ParameterTypeRequiredDescription
assetsarrayRequired (JSON)Video asset with url or asset_id
videofileRequired (Form)Video file upload — .mp4 or .mov
video_asset_idintegerOptionalExisting video asset ID (alternative to upload)
options.scene_thresholdfloatOptionalScene split sensitivity
options.min_scene_lengthintegerOptionalMinimum frames between scene cuts
Request · JSON (Asset ID)
JSON
{
  "assets": [
    { "type": "video", "asset_id": 123 }
  ],
  "options": { "scene_threshold": 0.395, "min_scene_length": 3 }
}
Request · Multipart (Upload)
multipart/form-data
video=@/path/to/video.mp4
option={"scene_threshold": 0.395, "min_scene_length": 3}
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
ParameterTypeRequiredDescription
find_face_idstringRequiredFind-face ID from POST /find-face
Request
GET /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 scene_id + face_id pairs to build scene_faces in /generate.
Query Parameters
ParameterTypeRequiredDescription
find_face_idstringRequiredFind-face ID
🎞️ A single find-face request can return multiple scenes. Each scene has its own scene_id and its own list of faces. Pair scene_id with face_id to drive a specific face in /generate.
Per-Scene Fields
FieldTypeDescription
scene_idintegerIdentifier for the scene within this find-face request
start_frameintegerFirst frame of the scene
end_frameintegerLast frame of the scene
facesarrayFaces detected in the scene (empty if none)
Per-Face Fields (within a scene)
FieldTypeDescription
face_idintegerIdentifier for the face within the scene
keyframeintegerFrame index where the face is clearest
face_cropstring (url)Cropped thumbnail of the face for preview
face_coordinateobjectBounding box { x, y, w, h } in the keyframe
Success Response · 200
JSON
{
  "status": "success",
  "data": {
    "find_face_id": "ff_740006cb51da497fa1930dfe10520cc4",
    "video_asset_id": 123,
    "scenes": [
      {
        "scene_id": 1,
        "start_frame": 0,
        "end_frame": 156,
        "faces": [
          {
            "face_id": 0,
            "keyframe": 42,
            "face_crop": "https://cdn.syncmonster.ai/faces/ff_..._s1_f0.jpg",
            "face_coordinate": { "x": 320, "y": 110, "w": 180, "h": 180 }
          },
          {
            "face_id": 1,
            "keyframe": 51,
            "face_crop": "https://cdn.syncmonster.ai/faces/ff_..._s1_f1.jpg",
            "face_coordinate": { "x": 640, "y": 130, "w": 170, "h": 170 }
          }
        ]
      },
      {
        "scene_id": 2,
        "start_frame": 157,
        "end_frame": 320,
        "faces": [],
        "message": "No face in scene"
      },
      {
        "scene_id": 3,
        "start_frame": 321,
        "end_frame": 498,
        "faces": [
          {
            "face_id": 0,
            "keyframe": 360,
            "face_crop": "https://cdn.syncmonster.ai/faces/ff_..._s3_f0.jpg",
            "face_coordinate": { "x": 480, "y": 120, "w": 175, "h": 175 }
          }
        ]
      }
    ]
  }
}
Reading the Result · Three Cases per Scene
Multiple faces

The scene returns several faces, each with face_id, keyframe, face_crop, and face_coordinate. Pick which face_id(s) to drive in /generate.

No face

The faces array is empty and the scene carries "message": "No face in scene". That scene is passed through untouched.

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 faces as per the face_id chosen.

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. Drive specific faces with options.scene_faces.
Request Parameters
ParameterTypeRequiredDescription
find_face_idstringRequiredCompleted find-face request ID (the find_face_id from POST /find-face)
is_lipsyncbooleanRequiredEnable lip-sync
is_dramabooleanRequiredEnable drama. May be combined with lip-sync
modelstringRequired if is_lipsync=trueLip-sync model — e1 Pro (recommended), e2 Adaptive, e3 Legacy
assetsarrayRequired (JSON)Audio input with url or asset_id
audiofileRequired (Form)Audio upload — .mp3 or .wav
audio_asset_idintegerOptionalExisting audio asset ID
options.lipsync_intensityfloatOptional if is_lipsync=trueLip-sync strength: 0.5 to 3.5
drama.happyfloatOptional if is_drama=trueHappy intensity: 0 to 1
drama.sadfloatOptional if is_drama=trueSad intensity: 0 to 1
drama.excitedfloatOptional if is_drama=trueExcited intensity: 0 to 1
drama.angryfloatOptional if is_drama=trueAngry intensity: 0 to 1
options.scene_facesarrayOptionalPer-scene face selection (scene_id + face_ids). Omit for single-face scenes
ℹ️ Modes are independent. Set is_lipsync and is_drama in any combination. At least one must be true.
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": {
    "lipsync_intensity": 2.0,
    "scene_faces": [
      { "scene_id": 1, "face_ids": [0, 1] },
      { "scene_id": 3, "face_ids": [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": { "lipsync_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 }
}
Success Response · 201
JSON
{
  "status": "success",
  "message": "Job Created",
  "data": {
    "request_id": "a1b2c3d4e5f6g7h8",    // Use this to poll status
    "assets": [
      { "type": "video", "asset_id": 123 },
      { "type": "audio", "asset_id": 124 }
    ],
    "credit_details": { "lipsync_rate_per_sec": 1, "drama_rate_per_sec": 1 }
  }
}
💳 Lip-sync is 1 credit per second and drama is 1 credit per second of video. Running both together bills both rates.
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
ParameterTypeRangeDescription
modelstringe1 / e2 / e3Lip-sync model — e1 Pro, e2 Adaptive, e3 Legacy. Required when is_lipsync=true. e1 recommended
lipsync_intensityfloat0.5 – 3.5Sync 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.

ParameterTypeRangeDescription
drama.happyfloat0 – 1Happy intensity (inverse of sad)
drama.sadfloat0 – 1Sad intensity (inverse of happy)
drama.excitedfloat0 – 1Excited intensity
drama.angryfloat0 – 1Angry intensity
Per-Scene Face Selection · scene_faces

After Find Face returns the faces in each scene, choose which to drive. Each entry pairs a scene_id with one or more face_ids. Omit it for scenes with a single face.

JSON · options.scene_faces
"scene_faces": [
  { "scene_id": 1, "face_ids": [0, 1] },
  { "scene_id": 3, "face_ids": [0] }
]
GET
/get-status
Poll the current status of a generation job
200 OK
Query Parameters
ParameterTypeRequiredDescription
request_idstringRequiredThe job request ID returned from POST /generate
Request
GET /get-status?request_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
ParameterTypeRequiredDescription
request_idstringRequiredThe 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
ParameterTypeDefaultDescription
limitinteger10Records to return per page
page_nointeger0Page number for pagination
Request
GET /list-requests?limit=10&page_no=0
Success Response · 200
JSON
{
  "status": "success",
  "message": "Requests listed",
  "data": [
    {
      "request_id": "740006cb51da497fa1930dfe10520cc4",
      "status": "Success",
      "status_code": "success",
      "created_at": "2026-04-07T04:13:23",
      "completed_at": "2026-04-07T04:14:04"
    }
  ],
  "total_requests": 14,
  "end_of_records": false
}
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
ParameterTypeRequiredDescription
request_idstringRequiredFind-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
ParameterTypeRequiredDescription
asset_idintegerRequiredThe 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"
}

⚙️ 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

CodeNameDescription
ERR_003INTERNAL_SERVER_ERRORAn internal server error occurred
ERR_004NO_FACE_FOUNDNo face was detected in the provided video
ERR_006INSUFFICIENT_CREDITSNot enough credits to complete the request
ERR_007DATA_CORRUPTEDUploaded data is corrupted or invalid
ERR_008INVALID_FORMATUnsupported file type. Accepted: .mp4, .mov, .mp3, .wav
ERR_009LIMIT_EXCEEDSVideo duration exceeds the limit.

📁 Supported File Formats

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