openapi: 3.0.3 info: title: Sync Labs API description: >- The Sync Labs API provides studio-grade AI lip-sync and visual dubbing capabilities. Generate perfectly synchronized lip movements for any video and audio input using state-of-the-art models. Supports single generation, batch processing, asset management, and webhook notifications. Used for video localization, content dubbing, personalized video, and educational content translation. version: 'v2' contact: name: Sync Labs Support email: hello@sync.so url: https://sync.so license: name: Commercial url: https://sync.so/terms servers: - url: https://api.sync.so/v2 description: Sync Labs API v2 security: - ApiKeyAuth: [] tags: - name: Generate description: Lip-sync video generation operations - name: Batch description: Batch processing multiple videos - name: Assets description: Uploaded asset management - name: Models description: Available AI model listing - name: Webhooks description: Webhook notification management paths: /generate: post: summary: Create Lip-Sync Generation description: >- Submit a video and audio input to generate a lip-synced output video. The operation is asynchronous — poll the GET endpoint or use webhooks for completion notification. Rate limited to 60 requests/min. operationId: createGeneration tags: - Generate requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GenerationRequest' responses: '201': description: Generation job created successfully content: application/json: schema: $ref: '#/components/schemas/GenerationResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/RateLimitExceeded' '500': $ref: '#/components/responses/InternalError' get: summary: List Generations description: List all generation jobs for the authenticated account operationId: listGenerations tags: - Generate parameters: - name: limit in: query schema: type: integer default: 20 maximum: 100 description: Maximum number of results to return - name: offset in: query schema: type: integer default: 0 description: Pagination offset - name: status in: query schema: type: string enum: [pending, processing, completed, failed] description: Filter by status responses: '200': description: List of generation jobs content: application/json: schema: type: object properties: generations: type: array items: $ref: '#/components/schemas/GenerationResponse' total: type: integer has_more: type: boolean '401': $ref: '#/components/responses/Unauthorized' /generate/{id}: get: summary: Get Generation Status description: Retrieve the status and result of a specific generation job operationId: getGeneration tags: - Generate parameters: - name: id in: path required: true schema: type: string description: Generation job ID responses: '200': description: Generation job details content: application/json: schema: $ref: '#/components/schemas/GenerationResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /generate/estimate-cost: get: summary: Estimate Generation Cost description: Calculate the estimated cost before submitting a generation operationId: estimateGenerationCost tags: - Generate parameters: - name: model in: query required: true schema: $ref: '#/components/schemas/ModelId' description: AI model to use - name: duration in: query required: true schema: type: number format: float description: Video duration in seconds responses: '200': description: Cost estimate content: application/json: schema: type: object properties: estimated_cost: type: number format: float description: Estimated cost in USD model: type: string duration_seconds: type: number cost_per_second: type: number '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /batch: post: summary: Create Batch Generation description: Submit multiple generation jobs in a single batch (up to 500 on Scale+ plans) operationId: createBatch tags: - Batch requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BatchRequest' responses: '201': description: Batch created content: application/json: schema: $ref: '#/components/schemas/BatchResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' get: summary: List Batches description: List all batch jobs for the authenticated account operationId: listBatches tags: - Batch parameters: - name: limit in: query schema: type: integer default: 20 - name: offset in: query schema: type: integer default: 0 responses: '200': description: List of batches content: application/json: schema: type: object properties: batches: type: array items: $ref: '#/components/schemas/BatchResponse' '401': $ref: '#/components/responses/Unauthorized' /batch/{id}: get: summary: Get Batch Status description: Retrieve the status and results of a batch job operationId: getBatch tags: - Batch parameters: - name: id in: path required: true schema: type: string description: Batch job ID responses: '200': description: Batch details content: application/json: schema: $ref: '#/components/schemas/BatchResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /assets: get: summary: List Assets description: List all uploaded assets for the authenticated account operationId: listAssets tags: - Assets parameters: - name: limit in: query schema: type: integer default: 20 - name: offset in: query schema: type: integer default: 0 - name: type in: query schema: type: string enum: [video, audio] description: Filter by asset type responses: '200': description: List of assets content: application/json: schema: type: object properties: assets: type: array items: $ref: '#/components/schemas/Asset' total: type: integer '401': $ref: '#/components/responses/Unauthorized' /assets/{id}: get: summary: Get Asset description: Retrieve details about a specific uploaded asset operationId: getAsset tags: - Assets parameters: - name: id in: path required: true schema: type: string description: Asset ID responses: '200': description: Asset details content: application/json: schema: $ref: '#/components/schemas/Asset' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /models: get: summary: List Available Models description: Retrieve the list of available AI lip-sync models and their capabilities operationId: listModels tags: - Models responses: '200': description: List of available models content: application/json: schema: type: object properties: models: type: array items: $ref: '#/components/schemas/Model' '401': $ref: '#/components/responses/Unauthorized' components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: x-api-key description: API key from https://sync.so/settings/api-keys responses: BadRequest: description: Bad request - invalid parameters content: application/json: schema: $ref: '#/components/schemas/Error' Unauthorized: description: Unauthorized - missing or invalid API key content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: Resource not found content: application/json: schema: $ref: '#/components/schemas/Error' RateLimitExceeded: description: Rate limit exceeded (60 req/min on POST /v2/generate) content: application/json: schema: $ref: '#/components/schemas/Error' InternalError: description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' schemas: ModelId: type: string enum: - sync-3 - lipsync-2-pro - lipsync-2 - lipsync-1.9 - react-1 description: AI model identifier GenerationRequest: type: object required: - video_url - audio_url - model properties: video_url: type: string format: uri description: URL to the source video (MP4 or common video formats) audio_url: type: string format: uri description: URL to the source audio (WAV or MP3) video_asset_id: type: string description: Alternatively, provide an uploaded video asset ID audio_asset_id: type: string description: Alternatively, provide an uploaded audio asset ID model: $ref: '#/components/schemas/ModelId' webhook_url: type: string format: uri description: URL to receive webhook notification on completion synergize: type: boolean description: Enable multi-speaker detection and selection max_face_resolution: type: integer description: Maximum face resolution cap in pixels output_format: type: string enum: [mp4, webm] default: mp4 description: Output video format GenerationResponse: type: object properties: id: type: string description: Unique generation job ID status: type: string enum: [pending, processing, completed, failed] description: Current job status created_at: type: string format: date-time description: Job creation timestamp completed_at: type: string format: date-time nullable: true description: Job completion timestamp video_url: type: string format: uri nullable: true description: URL to the output video (available when completed) model: $ref: '#/components/schemas/ModelId' error: type: string nullable: true description: Error message if status is failed duration_seconds: type: number format: float description: Duration of the generated video in seconds cost: type: number format: float nullable: true description: Actual cost of the generation in USD BatchRequest: type: object required: - generations properties: generations: type: array maxItems: 500 items: $ref: '#/components/schemas/GenerationRequest' description: List of generation requests (up to 500 on Scale+ plans) webhook_url: type: string format: uri description: URL to receive batch completion notification BatchResponse: type: object properties: id: type: string description: Unique batch ID status: type: string enum: [pending, processing, completed, partially_failed, failed] created_at: type: string format: date-time completed_at: type: string format: date-time nullable: true total: type: integer description: Total number of generations in the batch completed: type: integer description: Number of completed generations failed: type: integer description: Number of failed generations generations: type: array items: $ref: '#/components/schemas/GenerationResponse' Asset: type: object properties: id: type: string description: Unique asset ID type: type: string enum: [video, audio] description: Asset media type filename: type: string description: Original filename size_bytes: type: integer description: File size in bytes duration_seconds: type: number format: float description: Media duration in seconds created_at: type: string format: date-time url: type: string format: uri description: Direct download URL Model: type: object properties: id: $ref: '#/components/schemas/ModelId' name: type: string description: Human-readable model name description: type: string description: Model capabilities and use cases max_resolution: type: string description: Maximum face resolution supported max_duration_seconds: type: integer description: Maximum video duration in seconds cost_per_second: type: number format: float description: Cost per second of generated video in USD supports_batch: type: boolean description: Whether the model supports batch processing Error: type: object properties: error: type: string description: Error type message: type: string description: Human-readable error description request_id: type: string description: Request ID for support reference