Concurrency & Rate Limiting
Rate Limiting
Request-rate limits count requests over a time window. These limits are separate from generation concurrency.
API Endpoints
Generation creation also enforces the plan’s concurrency limit described below. Inspect the error body instead of treating every 429 as the same limit.
When rate limited, the API returns a 429 response with a Retry-After header:
Concurrency
Concurrency refers to the number of generations that can be submitted/processed concurrently. Requests to create new generations will fail with a 429 error if the concurrency limit is exceeded. Batch records (approved organizations on Scale and above) do not count toward this limit; each active batch holds one slot of a separate batch limit.
A concurrency 429 looks like this:
The response also carries Retry-After, X-Sync-Concurrency-Limit and X-Sync-Active-Generations headers with the same values, so you can back off without parsing the body. Get Account returns your current limits.concurrency and activeJobs.generations.
To check your generations currently in PENDING/PROCESSING state, you can use the List Generations endpoint.
Concurrency limits are defined in the subscription plan. Usage-billed and credit-billing plans use the following defaults:
Your plan default is the minimum concurrency available to your account. Custom allowances can raise these limits, but never lower them. Read concurrencyLimit or the X-Sync-Concurrency-Limit header on a concurrency_limit_reached response for your effective limit.
Handling 429 Errors
When you exceed a rate limit or concurrency limit, the API returns a 429 Too Many Requests response. This applies to both per-minute rate limits and concurrent generation limits.
What to do when you hit a 429:
Tell them apart by errorCode:
- Rate limit (
rate_limit_exceeded): Wait and retry. Honor theRetry-Afterheader (orretryAfterSecondsandresetTimein the body); endpoint windows differ. - Concurrency limit (
concurrency_limit_reached): You already have the maximum number of generations in PENDING or PROCESSING state for your plan. WaitretryAfterSeconds(20) or for an existing generation to complete before submitting a new one, or upgrade your plan for higher limits.
Do not retry 429 responses immediately in a tight loop. This wastes requests and delays recovery. Use the retry strategy below instead.
Retry Strategies
Exponential backoff is the recommended approach for handling both rate limit and transient errors from the Sync Labs lip sync API. Each retry waits progressively longer, reducing pressure on the API and improving your success rate.
Python
TypeScript
Optimizing Concurrency
To get the most out of your plan’s concurrent generation slots:
- Monitor active jobs. Use the List Generations endpoint to check how many jobs are currently in PENDING or PROCESSING state before submitting new ones.
- Queue on your side. Maintain a local queue and only submit a new generation when a slot frees up. This avoids wasted 429 responses.
- Use webhooks. Configure a webhook to get notified when a generation completes, so you can immediately submit the next job without polling.
- Batch large runs. With organization approval on Scale and Enterprise plans, the Batch API queues 20 to 500 short generations per call outside your generation concurrency, with results over hours. For a few generations at once, send
POST /v2/generaterequests in parallel within your concurrency limit instead.
For API rate limiting best practices and general error handling, see the Error Handling guide.

