> For the documentation index, fetch https://sync.so/docs/llms.txt. Append .md to a page URL for Markdown. Documentation-search MCP: https://sync.so/docs/_mcp/server. # Batch Processing > Batch processing API for bulk AI lip sync generation. Process up to 500 videos in a single operation with webhooks and status tracking. The Sync Labs Batch API processes up to 500 lip sync generations in a single request using a JSONL file. This is ideal for bulk video processing workflows, such as personalized video campaigns, content localization, or any scenario requiring high-volume lip sync generation. ## What is the batch file format? Batch processing enables you to submit 20 to 500 generations without having to handle queueing or concurrency yourself, with a target turnaround time of 24 hours. Batch jobs bypass your normal generation concurrency limit, but the Batch API is only available on Scale and Enterprise plans. As of now, only generations with inputs up to 30 seconds are supported in batch processing. > **Note** > > Batch API is available for Scale and Enterprise users only ## Batch concurrency limits Batch jobs bypass your normal per-generation concurrency limit, but a separate limit caps how many batches you can run at once, based on your plan. If you submit a new batch while you are already at that limit, the API returns a `429 Too Many Requests` response. The 429 body is a JSON object describing the limit you hit: ```json { "statusCode": 429, "errorCode": "concurrency_limit_reached", "message": "Batch concurrency limit reached. Please wait for an existing batch to complete or upgrade your plan.", "activeBatches": 3, "concurrencyLimit": 3, "retryAfterSeconds": 20 } ``` The response also includes a `Retry-After` header (in seconds) and an `X-Sync-Concurrency-Limit` header. Rather than retrying immediately, wait `retryAfterSeconds` before submitting again, or wait for one of your in-flight batches to complete. ## How do I create a batch job? #### Prepare Your Input File Create a JSON Lines (.jsonl) file with your generation requests. Each line should contain a unique `request_id`, the `endpoint` (must be `"/v2/generate"`), and a `payload` with the standard generation request format (same as the [Generate API](/api-reference/api/generate-api/create)). The file must be in JSON Lines (.jsonl) format with a minimum of 20 records, maximum file size of 5MB, and up to 500 requests per batch. **`input.jsonl`** ```jsonl input.jsonl {"request_id": "request-1", "endpoint": "/v2/generate", "payload": {"model": "lipsync-2", "input": [{"type": "video", "url": "https://assets.sync.so/docs/example-video.mp4"}, {"type": "audio", "url": "https://assets.sync.so/docs/example-audio.wav"}]}} {"request_id": "request-2", "endpoint": "/v2/generate", "payload": {"model": "lipsync-2", "input": [{"type": "video", "url": "https://assets.sync.so/docs/example-video.mp4"}, {"type": "audio", "url": "https://assets.sync.so/docs/example-audio.wav"}]}} ``` #### Create a Batch ```python from sync import Sync sync = Sync() batch = sync.batch.create( input=open("input.jsonl", "rb") ) print(f"Batch created with ID: {batch.id}") ``` ```typescript import { SyncClient } from "@sync.so/sdk"; const client = new SyncClient(); const batch = await client.batch.create(fs.createReadStream("input.jsonl")); console.log('Batch created with ID:', batch.id) ``` **`curl`** ```bash curl curl -X POST https://api.sync.so/v2/batch \ -H "x-api-key: " \ -H "Content-Type: multipart/form-data" \ -F input=@ ``` **Optional parameters:** * `webhook_url`: Receive notifications when the batch completes * `dry_run`: Set to `true` to validate your input file without processing #### Check Batch Status Monitor your batch progress by polling the status: **`Check batch status`** ```python Check batch status batch = sync.batch.get(batch_id) print(f"Status: {batch.status}") print(f"Progress: {batch.metrics}") ``` ```typescript const batch = await client.batch.get(batch_id); console.log('Status:', batch.status); console.log('Progress:', batch.metrics); ``` ```bash curl https://api.sync.so/v2/batch/ \ -H "x-api-key: " ``` A batch can have one of the following status: 1. **`PENDING`**: Batch created, waiting to start processing 2. **`PROCESSING`**: Generations are being processed 3. **`COMPLETED`**: All generations finished (successfully or with failures) 4. **`FAILED`**: Batch processing failed entirely #### Check Batch Results When a batch completes, results are available as a JSON Lines file at the `outputUrl` of the get batch response. A `GET` to that URL returns a `302` redirect to a signed result file; clients that follow redirects automatically can read the JSONL response directly. Each line contains: **`output.jsonl`** ```jsonl output.jsonl {"request_id": "request-1", "endpoint": "/v2/generate", "payload": {...}, "status": "COMPLETED", "error": null, "response": {...}, "updated_at": "2024-01-15T10:35:00Z"} {"request_id": "request-2", "endpoint": "/v2/generate", "payload": {...}, "status": "FAILED", "error": {"code": "INVALID_INPUT", "message": "..."}, "response": null, "updated_at": "2024-01-15T10:35:00Z"} ``` The `response` field contains the same data as individual [Generate API](/api-reference/api/generate-api/create) responses. For a complete working example, see the [batch processing example](https://github.com/synchronicity-labs/sync-examples/tree/main/batch-processing/python) in our examples repository. ## Webhook Notifications When you provide a `webhook_url`, you'll receive POST notifications when your batch completes: **`webhook_payload.json`** ```json webhook_payload.json { "id": "batch_abc123", "createdAt": "2024-01-15T10:30:00Z", "status": "COMPLETED", "webhookUrl": "https://your-webhook-url.com/batch-webhook", "metrics": { "totalGenerations": 5, "successCount": 4, "failedCount": 1, "pendingCount": 0 }, "options": {}, "outputUrl": "https://api.sync.so/v2/batches/batch_abc123/result" } ``` > Process multiple lipsync generations efficiently