> 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. # Error Handling > Complete guide to sync. labs API error codes and troubleshooting. Input validation, batch processing, and system error resolution. ## Retrying generation creation For `POST /v2/generate`, send an [Idempotency-Key](/api-reference/guides/idempotency) on the **first** attempt and reuse it with the same payload on every retry. The guide covers replay responses, payload conflicts, retention, and all `IDEMPOTENCY_*` errors. A lost response or `IDEMPOTENCY_OUTCOME_UNKNOWN` does not authorize a fresh key or an unkeyed retry. An unknown response may include `generationId`; poll it when available. Without a key, a create timeout or transport failure can leave acceptance uncertain. Confirm the outcome before submitting again. General backoff advice below does not make an unkeyed create safe to repeat. ## HTTP Status Codes When calling the Sync Labs API, you may encounter the following HTTP status codes. These are returned at the HTTP level before any generation-specific error codes. | Status Code | Name | Common Cause | Resolution | | :---------: | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 401 | Unauthorized | Invalid or missing API key. The `SYNC_API_KEY` environment variable is not set or the key has been revoked. | Create a new key from the [Dashboard](https://sync.so/settings/api-keys). Verify the key is included in the `x-api-key` header. | | 402 | Payment Required | The account cannot start another generation because of billing or plan state. Common causes include exhausted free-tier generations, no active paid plan for paid-only usage, an unpaid usage invoice, or a plan limit being exceeded. | Check your plan and invoices on the [Billing page](https://sync.so/billing). Free accounts allow 3 generations/month, max 20s each, with at most 1 sync-3 generation at 15s max. Upgrade your plan, resolve any unpaid invoice, or wait for the next billing cycle. | | 413 | Payload Too Large | A file uploaded directly to `POST /v2/generate` exceeds the 5 GiB per-file limit. The body carries `errorCode: generation_input_validation_failed`. No generation is created and no credits are held. | Use a smaller file, or pass the file by public URL. Files within 5 GiB must also fit your plan's file size limit. | | 429 | Too Many Requests | Rate limit exceeded — see [Rate Limits](/api-reference/guides/rate-limits) page for per-endpoint limits. | Implement exponential backoff. See the [Rate Limits](/api-reference/guides/rate-limits) page for details. | | 500 | Internal Server Error | Server-side error during processing. | Retry after a brief delay. The body carries `errorCode: internal_error` and a `requestId` — include the `requestId` when contacting support so we can locate the failing request directly. If persistent, check [status.sync.so](https://status.sync.so) for service status. | | 503 | Service Unavailable | Service temporarily down for maintenance, high load, or a provider dependency outage. | Retry with exponential backoff, honoring the `Retry-After` header when present. Check [status.sync.so](https://status.sync.so) for ongoing incidents. | | 504 | Gateway Timeout | A sync. labs service or provider dependency timed out before it could complete the request. | Retry with exponential backoff. If the body includes a `requestId` and the timeout keeps happening, include it when contacting support. | ### HTML 403 or Cloudflare Access denied If a request to `api.sync.so` returns an HTML page identifying Cloudflare with HTTP 403, `Access denied`, or error 1010, treat it separately from the JSON API errors below. A Cloudflare block can occur before API validation, so it does not by itself establish that your API key, plan, or media is invalid. Stop repeated retries and contact [support@sync.so](mailto:support@sync.so) with the request method and endpoint, UTC timestamp, Cloudflare Ray ID, client/SDK version, and a redacted response or screenshot. For uploads, include the content type and file sizes. Do not send API keys, authorization headers, or signed media URLs. Support needs the specific response to investigate; do not assume that every 403 has the same cause. A 403 from a presigned storage upload URL is a different case: check the [Asset Uploads troubleshooting guide](/developer-guides/asset-uploads) for content-type and URL-expiry checks. ## Machine-Readable Error Codes Every failed generation carries a stable, machine-readable `errorCode` alongside the human-readable `error` message. The `errorCode` appears on both the [Get Generation](/api-reference/api/generate-api/get) response (`GET /v2/generate/{id}`) and the [webhook payload](/api-reference/api/webhooks-payload-reference/webhooks) delivered when a job finishes. > **Note** > > Branch your error handling on `errorCode`, not on the `error` string. The `error` message is meant for humans and may be reworded over time; the `errorCode` is a stable identifier you can safely switch on in code. A failed generation looks like this: ```json { "id": "550e8400-e29b-41d4-a716-446655440000", "status": "FAILED", "error": "The provided audio exceeds the maximum allowed length.", "errorCode": "generation_audio_length_exceeded" } ``` Error responses on request endpoints (assets, voices, TTS, and submit-time generate rejections) carry the same machine-readable shape, with two optional extras: `field` names the request field that caused the failure (for example `voiceId` or `input[].assetId`), and `docsUrl` links to the relevant documentation page. Unhandled 500s include a `requestId` you can give to support, alongside `errorCode: internal_error`: ```json { "statusCode": 422, "errorCode": "voice_not_found", "message": "Voice with ID \"abc\" not found. Please verify the voice ID is correct.", "suggestion": "List valid voice ids via GET /v2/voices. Cloned voice ids are UUIDs scoped to the organization that created them.", "field": "voiceId" } ``` ### Look up any code with the error catalog `GET /v2/errors` returns the full catalog of error codes — generation codes plus the API request codes below — as an array of `{ code, message, suggestion }` objects. The endpoint is **unauthenticated** — no `x-api-key` header is required — so you can resolve any `errorCode` to its meaning and a suggested fix at runtime. ```bash curl https://api.sync.so/v2/errors ``` A typical entry looks like this: ```json { "code": "generation_audio_length_exceeded", "message": "The provided audio exceeds the maximum allowed length.", "suggestion": "Trim or split your audio so each generation is under 300 seconds (5 minutes)." } ``` ### Read and resolve an error code When a generation fails, read its `errorCode` and look it up in the catalog returned by `GET /v2/errors`. **`curl`** ```bash curl # 1. Fetch the failed generation curl https://api.sync.so/v2/generate/550e8400-e29b-41d4-a716-446655440000 \ -H "x-api-key: " # 2. Look up the returned errorCode in the catalog (no auth required) curl https://api.sync.so/v2/errors ``` **`Python`** ```python Python from sync import Sync sync = Sync() generation = sync.generations.get("550e8400-e29b-41d4-a716-446655440000") if generation.status == "FAILED": catalog = sync.errors.list() entry = next((e for e in catalog if e.code == generation.error_code), None) if entry: print(entry.message) print(entry.suggestion) ``` **`TypeScript`** ```typescript TypeScript import { SyncClient } from "@sync.so/sdk"; const sync = new SyncClient(); const generation = await sync.generations.get("550e8400-e29b-41d4-a716-446655440000"); if (generation.status === "FAILED") { const catalog = await sync.errors.list(); const entry = catalog.find((e) => e.code === generation.errorCode); if (entry) { console.log(entry.message); console.log(entry.suggestion); } } ``` ## Submit-Time Validation Errors Some requests are rejected **at submit time** — the API responds with an error on the request itself, before any render starts, instead of accepting the job and failing it later. These rejections return an HTTP status and a machine-readable `errorCode` in the response body, so you can correct the request and resubmit without wasting a generation. | Status | Error Code | Cause | Resolution | | :----: | :---------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------- | | 400 | `invalid_generation_id` | The id passed to `GET /v2/generate/{id}` is not a UUID. | Use the `id` returned by `POST /v2/generate`. | | 400 | `unsupported_generation_id_format` | The id passed to `GET /v2/generate/{id}` uses a `provider:id` format from another system. | Use the plain UUID returned by `POST /v2/generate`. | | 402 | `generation_plan_duration_exceeded` | The output duration exceeds your plan's per-generation limit. This is `sync_mode`-aware — `cut_off` clips the output to the shorter of the audio and video tracks before the limit is checked. | Upgrade your plan for a longer limit, use a `sync_mode` (such as `cut_off`) that shortens the output, or trim the longer input track. | | 404 | `generation_not_found` | The id passed to `GET /v2/generate/{id}` is a valid UUID but no generation matches it in your organization. | Check the id, and make sure you're using the same API key (organization) that created the generation. | | 409 | `generation_conflict` | The controller rejected a duplicate internal backend submission. Public creates accept an optional organization-scoped `Idempotency-Key`; a generation ID is still server-assigned. | Do not blindly retry an ambiguous network failure; confirm the submission outcome before retrying. | | 422 | `invalid_asset_id_format` | An `input[].assetId` is not a valid UUID. | Use the id returned by `POST /v2/assets`, or provide a `url` instead. | | 422 | `asset_not_found` | An `input[].assetId` doesn't resolve to an asset your key can access. | Use an asset id from your organization (`GET /v2/assets`); ids from other organizations are not visible. | | 422 | `generation_input_asset_type_mismatch` | An asset's actual type doesn't match the input slot it was supplied to (for example, an audio asset placed in a video slot). | Make sure each input's `type` matches the asset you're passing, and that the asset is the media kind that slot expects. | | 422 | `generation_input_too_many_visual` | The request contains more than one visual input — only a single video or image is allowed per generation. | Send exactly one video or image input. | | 422 | `generation_input_segments_invalid` | The `segments` array is invalid: segments overlap, a segment's `startTime` is greater than its `endTime`, or two segments reuse the same `refId`. | Review your [segments](/developer-guides/segments): keep them non-overlapping, ensure `startTime` \< `endTime`, and use a unique `refId` per segment. | | 422 | `generation_input_dub_audio_conflict` | The request supplies both `dubParams` and an explicit audio or text input. These are mutually exclusive. | Send one or the other: either `dubParams` (to dub) or an explicit audio/text input — not both. | | 422 | `cost_estimate_unavailable` | The billing calculation rejected the duration or frame rate for [Estimate Cost](/api-reference/api/generate-api/estimate-cost) (`POST /v2/generations/estimate`); no price or generation is returned. Request-field validation returns 400. | Supply a finite, positive `duration` in seconds and optional finite, positive `fps`. | | 429 | `concurrency_limit_reached` | You have too many generations in progress for your plan's concurrency limit. | Wait for in-flight generations to finish, or upgrade your plan for higher concurrency. See [Rate Limits](/api-reference/guides/rate-limits). | | 429 | `rate_limit_exceeded` | Your per-key request rate was exceeded (for example, on TTS, voice clone, or upload requests). | Slow your request rate and implement exponential backoff. See [Rate Limits](/api-reference/guides/rate-limits). | | 503 | `generation_media_probe_unavailable` / `generation_media_probe_timeout` | An input-media check was unavailable or timed out. | Retry with backoff; verify the media host is reachable. Include the request ID when contacting support. | | 503 | `controller_unavailable` / `controller_dependency_error` | The generation service (or one of its dependencies) is temporarily unavailable at submit time. | For a keyed create, retry with the same key and inputs, honoring `Retry-After`. For an unkeyed create, confirm acceptance before resubmitting. | | 503 | `generation_admission_paused` | New generation requests are temporarily paused for maintenance. The request is rejected before any work starts. Generations already accepted keep processing, and you can still check their status. | Retry after the `Retry-After` interval. For a keyed create, keep the same `Idempotency-Key` and inputs. | | 503 | `generation_admission_unavailable` | The API can't confirm that new generation requests are being accepted, so it rejects the request before any work starts. | Retry after the `Retry-After` interval. For a keyed create, keep the same `Idempotency-Key` and inputs. | | 504 | `controller_timeout` | The generation service took too long to accept the job. | For a keyed create, retry with the same key and inputs, honoring `Retry-After`. For an unkeyed create, confirm acceptance before resubmitting. | > **Warning** > > A submit-time error returns `errorCode` on the HTTP response. Validation failures can precede generation creation, but an uncertain submission may already have a generation. Poll `generationId` when provided and follow the [idempotency recovery guidance](/api-reference/guides/idempotency) before retrying. > **Note** > > Rate-limit and dependency errors (429/503/504) also mirror their retry guidance into headers: `Retry-After` (seconds), and for concurrency 429s, `X-Sync-Concurrency-Limit` and `X-Sync-Active-Generations`. ## API Request Error Codes Beyond generation failures, the assets, voices, TTS, and generation download endpoints return their own stable `errorCode` values on error responses. Where applicable the body also carries `field` (the request field at fault) and `docsUrl` (a link to the relevant docs page). All of these appear in the [error catalog](/api-reference/api/errors-api/list) (`GET /v2/errors`). ### Assets | Status | Error Code | Cause | Resolution | | :----: | :----------------------------- | :------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------- | | 422 | `project_not_found` | The `projectId` doesn't exist in your organization (wrong org, deleted, or mistyped). | Omit `projectId`, or use a project id that belongs to your organization. | | 404 | `asset_not_found` | No asset exists with that id in your organization. | Use an asset id returned by `POST /v2/assets` or `GET /v2/assets`. Asset ids from another organization are not visible. | | 403 | `asset_forbidden` | You can view this asset but lack permission to modify or delete it. | Only the asset owner or an organization admin/owner can modify it. | | 422 | `invalid_asset_id_format` | An `assetId` (including `input[].assetId` on generate) is not a valid UUID. | Use the id returned by `POST /v2/assets`, or provide a `url` instead. | | 422 | `uploaded_file_not_found` | No file bytes were found at the pre-signed upload URL. | `PUT` the file to the `uploadUrl` from `POST /v2/assets/upload` before registering the asset. | | 422 | `file_not_in_org_storage` | The URL you registered is not in your organization's sync. labs storage. | Upload via `POST /v2/assets/upload` first, then register the returned url. | | 422 | `file_size_exceeds_plan_limit` | The file exceeds your plan's maximum size. | Upload a smaller file or upgrade your plan. | ### Voices and TTS | Status | Error Code | Cause | Resolution | | :-------: | :------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 422 / 404 | `voice_not_found` | The `voiceId` doesn't resolve to a premade or cloned voice in your organization. Returned as 422 on `POST /v2/tts` and generation text inputs, 404 on `GET /v2/voices/{id}` and `DELETE /v2/voices/{id}`. | List valid ids via `GET /v2/voices`. Cloned voice ids are UUIDs scoped to the organization that created them. | | 400 / 422 | `voice_verification_required` | The selected voice needs ElevenLabs verification before it can be used for synthesis. Returned on `POST /v2/tts` and generation text inputs — normally 422 from the pre-synthesis check, or 400 when that check was unavailable and the voice is rejected during synthesis. | If the voice is from your own connected ElevenLabs account, complete verification in ElevenLabs (linked under Settings > Integrations). Otherwise, choose another voice, or contact Sync support for a Sync-managed voice. | | 400 / 422 | `voice_blocked` | ElevenLabs has blocked the selected voice. Returned on `POST /v2/tts` and generation text inputs — normally 422 from the pre-synthesis check, or 400 when that check was unavailable and the voice is rejected during synthesis. | Choose another voice — a blocked voice can't be used for synthesis. If it's from your own connected ElevenLabs account (Settings > Integrations), contact ElevenLabs. Otherwise, for a Sync-managed voice, contact Sync support. | | 400 | `voice_access_denied` | ElevenLabs denied access to the selected voice — a generic access denial, not specifically a verification or block state. Surfaces only during synthesis on `POST /v2/tts` and generation text inputs. | Choose another voice. If the voice is from your own connected ElevenLabs account (Settings > Integrations), check its access settings in ElevenLabs; otherwise, for a Sync-managed voice, contact Sync support. | | 422 | `voice_sample_not_accessible` | The clone sample asset was not found or is not accessible. | Use an audio or video asset id from your organization. | | 422 | `voice_sample_type_unsupported` | The clone sample asset is not audio or video. | Clone from an AUDIO or VIDEO asset. | | 422 | `voice_sample_upload_required` | The clone sample url is not hosted in sync. labs storage. | Upload via `POST /v2/assets/upload` first, then clone from the returned `assetId` or url. | | 422 | `voice_sample_extraction_failed` | No audio track could be extracted from the video sample. | Check the video has an audio track and is a supported format. | | 400 | `voice_sample_too_short` | The sample is too short to clone from. | Use a longer sample with clear speech (ideally 30+ seconds). | | 400 | `voice_sample_invalid` | The sample could not be processed. | Use a valid audio file with clear speech. | | 403 | `voice_clone_limit_reached` | Your plan's voice clone slots are all in use. | Delete a voice via `DELETE /v2/voices/{id}` or upgrade your plan. | | 429 | `voice_clone_busy` | Another shared voice clone is reserving provider capacity. | Honor `Retry-After` and retry after the indicated delay. | | 413 | `voice_sample_source_too_large` | The video source exceeds the 1 GiB clone-preparation limit. | Trim the video or use a smaller source. | | 409 | `voice_name_conflict` | You already have a voice with this name. | Choose a different name, or delete the existing voice via `DELETE /v2/voices/{id}` first. | | 400 | `elevenlabs_api_key_invalid` | Your connected (bring-your-own) ElevenLabs API key is invalid or revoked. | Reconnect a valid key in Settings > Integrations, or remove it to fall back to the shared voices. | | 402 | `elevenlabs_quota_exceeded` | Your own ElevenLabs account's quota is exhausted. | Check your ElevenLabs subscription, or wait for its quota to reset. | | 503 / 504 | `elevenlabs_service_unavailable` | The ElevenLabs voice service is temporarily unavailable. Returned as 504 for provider timeouts, and 503 for other provider outages on `POST /v2/tts` and unkeyed generation `text` inputs. Keyed uncertain outcomes use `IDEMPOTENCY_OUTCOME_UNKNOWN`. | Retry the request with backoff. If it keeps failing, contact support with the request id. | ### Downloads `GET /v2/generations/{id}/download` returns a URL for downloading a completed generation's output. Missing, deleted, or out-of-organization generations return `generation_not_found` (404), as covered above. A missing, invalid, or revoked API key returns 401, and a non-UUID id returns 400. The download-specific codes are: | Status | Error Code | Cause | Resolution | | :----: | :-------------------------------- | :------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------ | | 409 | `generation_not_ready` | The generation is still pending or processing, so its output is not ready to download. | Poll `GET /v2/generate/{id}` until it reports `COMPLETED`, then request the download URL again. | | 422 | `generation_not_downloadable` | The generation failed or was rejected, so it has no output to download. | Inspect the generation's status and error with `GET /v2/generate/{id}`; fix the input and resubmit if needed. | | 404 | `generation_output_unavailable` | The generation has no eligible output reference, or the stored output file is missing. | This endpoint does not recreate outputs. Contact support if a completed generation is missing its output. | | 503 | `generation_download_unavailable` | The output could not be checked in storage, or a download URL could not be signed. | Retry with exponential backoff. If it keeps failing, contact support with the request id. | ## What do Sync Labs API error codes mean? Here's a comprehensive list of Sync Labs lip sync API error codes you may encounter, grouped by category and ordered from most common to least common. ### Input Validation Errors #### `generation_unsupported_model` **Message:** "The requested model is not supported for this operation." **Description:** This error is thrown when you attempt to use a model that is not compatible with the current operation or API endpoint. **Resolution:** 1. Check the [model documentation](/models/lipsync) to see which models are supported for this specific API call. 2. Update your request to use a supported model. 3. If you believe this is an error, please contact our support team with details of your use case. #### `generation_media_metadata_missing` **Message:** "Required media metadata is missing from the request." **Description:** This error occurs when the media file lacks essential metadata for processing. The required metadata fields include: * `duration`: The length of the media in seconds (for both audio and video) * `frame_rate`: The number of frames per second (for video content only) **Resolution:** 1. Ensure that your media file includes the required metadata embedded within it: * For audio files: Verify that the `duration` metadata is present. * For video files: Check that both `duration` and `frame_rate` metadata are included. 2. Use media editing tools to add or update the necessary metadata to your file. 3. Verify that the metadata is correctly embedded and readable before submitting the media for processing. 4. For persistent issues, contact our support team for guidance on proper media preparation and metadata requirements. #### `generation_audio_length_exceeded` **Message:** "The provided audio exceeds the maximum allowed length." **Description:** This error is thrown when the audio file submitted for processing is longer than the maximum permitted duration of 300 seconds (5 minutes). **Resolution:** 1. Trim or split your audio file to meet the length requirements. 2. If you need to process longer audio files, consider batching your requests into smaller chunks or contact support for alternative solutions. #### `generation_text_length_exceeded` **Message:** "Text must be less than 5000 characters in one generation." **Description:** This error occurs when the text provided for text-to-speech (TTS) generation exceeds the maximum allowed length of 5,000 characters. **Resolution:** 1. Reduce the length of your text input to 5,000 characters or fewer. 2. Consider breaking longer text into multiple smaller requests. 3. Remove unnecessary content or use more concise language to fit within the limit. #### `generation_audio_missing` **Message:** "No audio file was provided in the request." **Description:** This error occurs when an audio file is expected but not included in the API request. **Resolution:** 1. Ensure that you're including the audio file in your request payload. 2. Verify that the audio file is properly encoded and formatted as per the API requirements. 3. For persistent issues, contact our support team for guidance on proper audio file preparation and submission. #### `generation_video_missing` **Message:** "No video file was provided in the request." **Description:** This error occurs when a video file is expected but not included in the API request. **Resolution:** 1. Make sure you're including the video file in your request payload. 2. Verify that the video file is properly encoded and formatted according to the API specifications. 3. For persistent issues, contact our support team for guidance on proper video file preparation and submission. #### `generation_input_validation_failed` **Message:** "Failed to validate input: \[specific error details or 'unknown validation failure']" **Description:** This error occurs when the provided input data does not meet the required validation criteria for processing. The error message includes specific details about what validation failed, which can help identify issues with file formats, metadata, or other input parameters that don't conform to expected specifications. If specific details aren't available, the message will indicate "unknown validation failure." **Resolution:** 1. Review your input data to ensure it meets all API requirements and specifications. 2. Check that all required fields are present and properly formatted. 3. Verify that file formats, sizes, and other parameters are within acceptable limits. 4. If the issue persists, contact our support team with details about your input data for further assistance. #### `generation_input_audio_invalid` **Message:** "The provided audio file has invalid metadata." **Description:** This error occurs when the audio file contains metadata that cannot be properly parsed or validated. Unlike `generation_media_metadata_missing` (which indicates missing metadata), this error means metadata is present but malformed, corrupted, or contains invalid values. Typical causes are corrupted audio files, damaged headers, or files from tools that produce non-standard metadata. **Resolution:** 1. Re-encode your audio file using a standard tool like FFmpeg to ensure proper metadata formatting: ```bash ffmpeg -i input.wav -c:a pcm_s16le output.wav ``` 2. Verify that your audio file opens and plays correctly in a media player. 3. Check that the audio file has not been corrupted during download or transfer. 4. If the issue persists, try converting your audio to a different supported format (WAV, MP3, OGG, FLAC) and re-submit. #### `generation_input_face_selection_invalid` **Message:** "We could not use the selected speaker face for this video. Please select the face again or try auto-detect." **Description:** This error occurs when the manually selected speaker face cannot be used for the generation. The selected face may not be detected in the video, the supplied face coordinates may fall outside the video frame, or the active-speaker selection may be invalid. **Resolution:** 1. Re-run face detection and select the speaker again, making sure the face is clearly visible in the chosen frame. 2. Verify that any manually supplied coordinates or bounding boxes fall within the video's dimensions. 3. Alternatively, turn off manual speaker selection to let the system auto-detect the active speaker, then resubmit. ### Batch API Errors #### `batch_concurrency_limit_reached` **Message:** "Batch concurrency limit reached. You have X active batches and your plan allows Y. Please wait for existing batches to complete or upgrade your plan for higher limits." **Description:** This error occurs when you attempt to create a new batch while already at your plan's batch concurrency limit. **Resolution:** 1. Wait for one or more of your active batches to complete before submitting new ones. 2. Check your active batches using the List Batches endpoint to monitor their progress. 3. Consider upgrading to a higher plan if you need more concurrent batch processing capacity. #### `batch_plan_required` **Message:** "This endpoint is only available for scale and enterprise plans. Please upgrade your plan." **Description:** The Batch API is only available for Scale plan subscribers and above. **Resolution:** 1. Upgrade your subscription to Scale plan or higher to access batch processing features. 2. Contact our sales team to discuss plan options that meet your batch processing needs. #### `batch_file_too_large` **Message:** "File size exceeds the maximum limit of 5MB." **Description:** The uploaded batch file exceeds the 5MB size limit. **Resolution:** 1. Reduce the size of your batch file by splitting it into smaller batches. 2. Remove unnecessary data or optimize your JSON formatting to reduce file size. 3. Consider processing your data in multiple smaller batches instead of one large batch. #### `batch_too_many_requests` **Message:** "Number of records exceeds the maximum limit of 1,000." **Description:** Your batch file contains more than the maximum allowed 1,000 generation requests. **Resolution:** 1. Split your batch into multiple smaller batches, each containing 1,000 or fewer requests. 2. Process your data in chunks to stay within the limit. #### `batch_insufficient_records` **Message:** "Input file must contain at least 20 records. Found X record(s)." **Description:** Your batch file contains fewer than the minimum required 20 generation requests. **Resolution:** 1. Add more generation requests to your batch file to meet the minimum requirement of 20 records. 2. Consider combining multiple smaller batches into a single batch that meets the minimum threshold. 3. If you have fewer than 20 requests to process, use the individual [Generate API](/api-reference/api/generate-api/create) instead of batch processing. #### `batch_invalid_jsonl` **Message:** "Invalid JSON at line X: \[specific error message]" **Description:** The batch file contains invalid JSON formatting on a specific line. **Resolution:** 1. Validate your JSON Lines (.jsonl) file format - each line must be valid JSON. 2. Check the specific line mentioned in the error message for syntax errors. 3. Ensure there are no trailing commas, missing quotes, or other JSON formatting issues. 4. Use a JSON validator to check each line of your file. #### `batch_duplicate_request_id` **Message:** "Duplicate request\_id found at line X: \[request\_id]" **Description:** The batch file contains duplicate `request_id` values, which must be unique within each batch. **Resolution:** 1. Ensure all `request_id` values in your batch file are unique. 2. Review your batch generation logic to prevent duplicate IDs. 3. Consider using UUIDs or timestamps to ensure uniqueness. #### `batch_invalid_endpoint` **Message:** "Invalid endpoint specified. Only '/v2/generate' is supported." **Description:** The batch file contains requests for unsupported endpoints. **Resolution:** 1. Ensure all requests in your batch file use `"endpoint": "/v2/generate"`. 2. Currently, only the generate endpoint is supported for batch processing. ### System and Processing Errors #### `generation_timeout` **Message:** "The generation process exceeded the maximum allowed time." **Description:** This is an internal error that occurs when our system is under high load, causing the requested operation to take longer than the allotted time to complete. **Resolution:** 1. Retry your request after a short delay, as the high load may be temporary. 2. If possible, try submitting your request during off-peak hours. 3. Consider breaking down large requests into smaller, more manageable chunks. 4. If the issue persists, contact our support team to report the problem and discuss potential solutions. #### `generation_pipeline_failed` **Message:** "An error occurred in the generation pipeline." **Description:** This error indicates a failure in one of the internal processing steps of the generation pipeline. **Resolution:** 1. Review your input data to ensure it meets all the required specifications. 2. Try resubmitting the request, as some pipeline errors may be temporary. 3. If the problem continues, reach out to our support team with details about your request and the specific error message for further investigation. #### `generation_database_error` **Message:** "An error occurred while accessing the database." **Description:** This error indicates a problem with database operations during the generation process. **Resolution:** 1. Verify that your request doesn't contain any invalid or conflicting data that might cause database issues. 2. Try your request again after a short wait, as database errors can sometimes be temporary. 3. If the problem continues, report the issue to our support team, providing details about your request and any specific error messages you received. #### `generation_internal_auth` **Message:** "Authentication failed for internal generation service." **Description:** This error occurs when there's an issue with our internal authentication process. If you get this error, contact our support team so we can get it fixed. #### `generation_unhandled_error` **Message:** "An unexpected error occurred during the generation process." **Description:** This is a catch-all error for unforeseen issues that aren't covered by more specific error codes. **Resolution:** 1. Check all aspects of your request for any potential issues or inconsistencies. 2. Try the request again, as some unhandled errors may be due to temporary system glitches. 3. If the error persists, contact our support team with a detailed description of your request and the steps to reproduce the error. #### `generation_infra_storage_error` **Message:** "An error occurred while accessing the storage on infra layer." **Description:** This error indicates a problem with accessing or managing storage resources during the generation process. This can occur due to temporary storage service issues or connectivity problems. **Resolution:** 1. Retry your request after a short delay, as storage errors are often temporary. 2. Ensure your input files are accessible and not corrupted. 3. If the problem persists, contact our support team as this may indicate a broader infrastructure issue. #### `generation_infra_resource_exhausted` **Message:** "The infra resources are exhausted." **Description:** This error occurs when the infrastructure resources required for processing your request are temporarily unavailable or at capacity. **Resolution:** 1. Wait a few minutes and retry your request, as resource availability fluctuates. 2. Consider submitting your request during off-peak hours when resources are more readily available. 3. If you frequently encounter this error, contact our support team to discuss your usage patterns and potential solutions. #### `generation_infra_service_unavailable` **Message:** "The infra service is unavailable." **Description:** This error indicates that one or more infrastructure services required for processing are temporarily unavailable. This can be due to maintenance, connectivity issues, or service outages. **Resolution:** 1. Check our status page for any ongoing service issues or maintenance windows. 2. Retry your request after a short delay, as service availability issues are typically temporary. 3. If the service remains unavailable for an extended period, contact our support team for updates and assistance. ## General Troubleshooting Tips 1. **Check your API key:** Ensure you're using the correct API key and that it is not revoked. 2. **Verify request format:** Double-check that your API request is properly formatted and includes all required parameters. 3. **Review rate limits:** Make sure you haven't exceeded your API rate limits. 4. **Check service status:** Visit our status page to see if there are any ongoing service issues. 5. **Consult the documentation:** Our API documentation may have been updated with new information or changes. ### Finding Generation IDs from Studio If you need to find a generation ID for troubleshooting purposes, you can easily locate it through the Studio interface. Both Studio Pro and Studio Lite modes follow the same basic process: **For Studio Pro Mode:** First click on the "History" button in the Studio interface, then follow the steps below. **For Studio Lite Mode:** Go directly to the steps below. 1. **Locate Your Generation:** Find the generation thumbnail you need the ID for 2. **Access the Menu:** Hover over the generation thumbnail and click the three dots menu that appears 3. **Copy the Job ID:** Select "copy job id" from the dropdown menu ![Screenshot showing how to copy job ID from Studio three dots menu](https://promptless-customer-doc-assets.s3.amazonaws.com/docs-images/org_2xKQTVCdcBTIHBg7NRIhpl2O3os/c973e905-e645-4c89-936d-2f18a73957f2-studio-lite-generation-id-menu.png) **For Agent Mode:** In Agent Mode, you can find generation IDs in two ways: 1. **Sessions Sidebar:** Click the dropdown menu (three dots) next to any session entry in the sidebar and select "Copy Job ID" 2. **Error Card:** When a generation fails, click the "Copy Job ID" button directly on the error notification card This generation ID can then be used when contacting support or when making API calls to retrieve specific generation details. If you're still experiencing issues after trying these steps, check the [Troubleshooting](/product/troubleshooting) page for common problems and solutions, or reach out to our support team for assistance. ## Frequently Asked Questions #### What does error 400 mean? A 400 error means your request has invalid input. Common causes include a malformed URL, unsupported media format, missing required fields, or audio exceeding the 300-second limit. Check the specific error code in the response body for details on what to fix. #### Why is my generation stuck in PENDING? A generation in PENDING status is waiting for processing resources. During periods of high demand, jobs may queue briefly before starting. If a generation stays in PENDING for an extended time, poll its existing ID or contact support. Do not create a replacement just because it is still pending. #### How do I retry failed generations? After a confirmed terminal failure, you can intentionally submit a replacement generation with a new key. Reusing the original key returns the original failed generation. For a timeout or unknown submission outcome, keep the original key and inputs; do not start a replacement. See [Idempotent Requests](/api-reference/guides/idempotency). For generation creation retries, follow [Idempotent Requests](/api-reference/guides/idempotency). Send a key on the first attempt and preserve it and the payload. Never bypass an unknown outcome with a new key; unkeyed timeouts require outcome confirmation before resubmission. ## Error Code Reference Failed generations carry a machine-readable `errorCode` (alongside the human `error` message) on both `GET /v2/generate/{id}` and the webhook payload. Branch on `errorCode`, not on the `error` string. `GET /v2/errors` is unauthenticated and returns the full catalog (generation + API request codes) as `{ code, message, suggestion }` objects. Error responses on request endpoints may also carry `field` (the request field at fault) and `docsUrl`; unhandled 500s carry `errorCode: internal_error` plus a `requestId` for support. ### HTTP Status Codes | Status Code | Name | Common Cause | Resolution | | :---------: | :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- | | 401 | Unauthorized | Invalid or missing API key | Create a new key at [https://sync.so/settings/api-keys](https://sync.so/settings/api-keys); include in `x-api-key` header | | 402 | Payment Required | Billing or plan state blocks another generation: exhausted free-tier generations, no active paid plan for paid-only usage, unpaid usage invoice, or plan limit exceeded | Check plan and invoices on Billing page; free tier: 3 generations/month, max 20s each, with at most 1 sync-3 generation at 15s max | | 413 | Payload Too Large | Direct upload to `POST /v2/generate` exceeds 5 GiB per file (`errorCode: generation_input_validation_failed`) | Use a smaller file or a public URL | | 429 | Too Many Requests | Rate limit exceeded — see Rate Limits page for per-endpoint limits | Implement exponential backoff; see Rate Limits page | | 500 | Internal Server Error | Server-side processing error | Retry after a brief delay; check [https://status.sync.so](https://status.sync.so) | | 503 | Service Unavailable | Service temporarily down or provider dependency unavailable | Retry with exponential backoff; check [https://status.sync.so](https://status.sync.so) | | 504 | Gateway Timeout | Service or provider dependency timed out | Retry with exponential backoff; include `requestId` when contacting support if it persists | ### Submit-Time Validation Errors Returned at request time (before any render starts), with an HTTP status and `errorCode` on the error response — there is no generation to poll. | Status | Error Code | Cause | Resolution | | :----: | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | 400 | `invalid_generation_id` | `GET /v2/generate/{id}` id is not a UUID | Use the `id` returned by `POST /v2/generate` | | 400 | `unsupported_generation_id_format` | `provider:id`-style id from another system | Use the plain UUID returned by `POST /v2/generate` | | 402 | `generation_plan_duration_exceeded` | Output duration exceeds plan limit (`sync_mode`-aware; `cut_off` clips to the shorter track) | Upgrade plan, use a shortening `sync_mode`, or trim the longer track | | 404 | `generation_not_found` | Valid UUID but no matching generation in your organization | Check the id and that you're using the creating organization's key | | 409 | `generation_conflict` | Duplicate internal backend submission; public creates support an optional `Idempotency-Key` | Do not blindly retry an ambiguous network failure; confirm the submission outcome first | | 422 | `invalid_asset_id_format` | `input[].assetId` is not a valid UUID | Use the id from `POST /v2/assets`, or provide a `url` | | 422 | `asset_not_found` | `input[].assetId` doesn't resolve to an accessible asset | Use an asset id from your organization | | 422 | `generation_input_asset_type_mismatch` | An asset's type doesn't match its input slot | Match each input's `type` to the asset supplied | | 422 | `generation_input_too_many_visual` | More than one video/image input | Send exactly one visual input | | 422 | `generation_input_segments_invalid` | Overlapping segments, `startTime` > `endTime`, or duplicate `refId`s | Keep segments non-overlapping with valid times and unique `refId`s | | 422 | `generation_input_dub_audio_conflict` | Both `dubParams` and an explicit audio/text input supplied | Send one or the other, not both | | 422 | `cost_estimate_unavailable` | The billing calculation rejected the duration or frame rate for [Estimate Cost](/api-reference/api/generate-api/estimate-cost) (`POST /v2/generations/estimate`); no price or generation is returned. Request-field validation returns 400. | Supply a finite, positive `duration` in seconds and optional finite, positive `fps`. | | 429 | `concurrency_limit_reached` | Too many generations in progress for the plan | Wait for in-flight jobs to finish or upgrade plan; headers `Retry-After`, `X-Sync-Concurrency-Limit`, `X-Sync-Active-Generations` | | 429 | `rate_limit_exceeded` | Per-key request rate exceeded (TTS, voice clone, uploads) | Slow request rate; use exponential backoff | | 503 | `generation_media_probe_unavailable` / `generation_media_probe_timeout` | An input-media check was unavailable or timed out. | Retry with backoff; verify the media host is reachable. Include the request ID when contacting support. | | 503 | `controller_unavailable` / `controller_dependency_error` | Generation service or dependency unavailable at submit | Retry with backoff, honor `Retry-After` | | 503 | `generation_admission_paused` / `generation_admission_unavailable` | New generation requests paused for maintenance, or acceptance can't be confirmed; no work starts | Retry after `Retry-After`; keep the same `Idempotency-Key` and inputs | | 504 | `controller_timeout` | Generation service took too long to accept the job | Follow keyed recovery; confirm an unkeyed outcome before resubmitting | Unexpected 500s carry `errorCode: internal_error` plus a `requestId` — include the `requestId` in support requests. ### API Request Error Codes (assets, voices, TTS) Coded error bodies on the assets/voices/TTS endpoints: `{ statusCode, errorCode, message, suggestion, field?, docsUrl? }`. All codes appear in `GET /v2/errors`. | Status | Error Code | Cause | Resolution | | :-----: | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 422 | `project_not_found` | `projectId` on `POST /v2/assets` isn't a project in your organization | Omit `projectId` or use one of your organization's project ids | | 404 | `asset_not_found` | Asset id doesn't resolve to anything your key can see | Use an id from `POST /v2/assets` / `GET /v2/assets` in the same organization | | 403 | `asset_forbidden` | Asset is visible but only its owner or an org admin/owner can modify it | Ask the owner or use an admin/owner session | | 422 | `invalid_asset_id_format` | `assetId` is not a valid UUID | Use the id from `POST /v2/assets`, or a `url` | | 422 | `uploaded_file_not_found` | Asset registered before the file was PUT to the `uploadUrl` | PUT the bytes to `uploadUrl` from `POST /v2/assets/upload` first | | 422 | `file_not_in_org_storage` | `url` points at storage outside your organization | Upload via `POST /v2/assets/upload`, register the returned `url` | | 422 | `file_size_exceeds_plan_limit` | File larger than the plan's per-file limit | Upload a smaller file or upgrade | | 422/404 | `voice_not_found` | `voiceId` is neither a built-in provider voice nor your organization's clone. Returned as 422 on TTS/generate text inputs and 404 on GET/DELETE `/v2/voices/{id}`. | List valid ids via `GET /v2/voices` | | 400/422 | `voice_verification_required` | Selected voice needs ElevenLabs verification before synthesis; on TTS/generate text inputs. Normally 422 from the pre-synthesis check, 400 when that check was unavailable and the voice is rejected during synthesis | If it's from your own connected ElevenLabs account, verify it in ElevenLabs (linked in Settings > Integrations); otherwise choose another voice, or contact Sync support for a Sync-managed voice | | 400/422 | `voice_blocked` | ElevenLabs has blocked the selected voice; on TTS/generate text inputs. Normally 422 from the pre-synthesis check, 400 when that check was unavailable and the voice is rejected during synthesis | Choose another voice — a blocked voice can't be used for synthesis. If it's from your own connected ElevenLabs account (Settings > Integrations), contact ElevenLabs. Otherwise, for a Sync-managed voice, contact Sync support | | 400 | `voice_access_denied` | ElevenLabs denied access to the selected voice — generic denial, not a verification or block state. Surfaces only during synthesis on TTS/generate text inputs | Choose another voice. If it's from your own connected ElevenLabs account (Settings > Integrations), check its access settings in ElevenLabs; otherwise, for a Sync-managed voice, contact Sync support | | 422 | `voice_sample_not_accessible` | Clone sample `assetId` not found/accessible | Use an audio/video asset from your organization | | 422 | `voice_sample_type_unsupported` | Sample asset is not audio or video | Clone from an AUDIO or VIDEO asset | | 422 | `voice_sample_upload_required` | Sample source hosted outside sync. labs storage | Upload via `POST /v2/assets/upload` first | | 422 | `voice_sample_extraction_failed` | No audio track extractable from the video sample | Check the video has an audio track | | 400 | `voice_sample_too_short` | Sample too short for cloning | Use 30s–2min of clear single-speaker speech | | 400 | `voice_sample_invalid` | Sample couldn't be processed by the provider | Use a valid audio file with clear speech | | 403 | `voice_clone_limit_reached` | Plan's clone slots all in use | `DELETE /v2/voices/{id}` or upgrade | | 429 | `voice_clone_busy` | Another shared voice clone is reserving provider capacity. | Honor `Retry-After` and retry after the indicated delay. | | 413 | `voice_sample_source_too_large` | The video source exceeds the 1 GiB clone-preparation limit. | Trim the video or use a smaller source. | | 409 | `voice_name_conflict` | Organization already has a voice with this name | Pick a different name or delete the existing voice | | 400 | `elevenlabs_api_key_invalid` | Connected (BYO) ElevenLabs key invalid or revoked | Reconnect in Settings > Integrations or remove it | | 402 | `elevenlabs_quota_exceeded` | Own ElevenLabs account quota exhausted | Check the ElevenLabs subscription or wait for reset | | 503/504 | `elevenlabs_service_unavailable` | ElevenLabs voice service unavailable; 504 for provider timeouts, 503 for other provider outages on TTS/unkeyed generate text inputs; keyed uncertainty uses IDEMPOTENCY\_OUTCOME\_UNKNOWN | Retry with backoff; contact support with request id if it persists | ### Download Errors (`GET /v2/generations/{id}/download`) Also returns `generation_not_found` (404) for missing/deleted/foreign ids, 401 for a missing/invalid/revoked key, and 400 for a non-UUID id. | Status | Error Code | Cause | Resolution | | :----: | --------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------- | | 409 | `generation_not_ready` | Generation still pending or processing | Poll `GET /v2/generate/{id}` until `COMPLETED`, then re-request the URL | | 422 | `generation_not_downloadable` | Generation failed or was rejected | Inspect status and error via `GET /v2/generate/{id}` | | 404 | `generation_output_unavailable` | No eligible output reference, or the stored file is missing | Not recreatable here; contact support | | 503 | `generation_download_unavailable` | Storage check or URL signing failed | Retry with backoff; contact support with request id if it persists | ### Long-Poll (`wait=true`) on GET /v2/generate/\{id} `GET /v2/generate/{id}?wait=true` holds the request open until the generation is terminal or the timeout elapses (`timeout` param: default 5s, max 10s; values outside 1-10 are rejected with 400). On timeout the current state returns with HTTP 200 — check `status` and retry. wait=true responses carry `X-Sync-Wait-Mode: long_poll`, `X-Sync-Wait-Timeout-Seconds`, and `Retry-After: 2` headers. Use webhooks for long jobs. ### Input Validation Errors | Error Code | Message | Resolution | | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | `generation_unsupported_model` | The requested model is not supported for this operation | Use a supported model from the current model list: sync-3, lipsync-2, lipsync-2-pro, lipsync-1.9.0-beta, or react-1 | | `generation_media_metadata_missing` | Required media metadata is missing | Ensure audio has `duration` metadata; video has `duration` and `frame_rate` metadata | | `generation_audio_length_exceeded` | Audio exceeds maximum allowed length | Trim audio to under 300 seconds (5 minutes) | | `generation_text_length_exceeded` | Text must be less than 5000 characters | Reduce TTS text input to under 5,000 characters | | `generation_audio_missing` | No audio file was provided | Include an audio file in the request payload | | `generation_video_missing` | No video file was provided | Include a video file in the request payload | | `generation_input_validation_failed` | Input data failed validation | Check file formats, metadata, and required parameters | | `generation_input_audio_invalid` | Audio file has invalid metadata | Re-encode audio with FFmpeg; verify file is not corrupted | | `generation_input_face_selection_invalid` | The manually selected speaker face could not be used (face not detected, coordinates out of frame, or invalid active-speaker selection) | Re-run face detection and pick the speaker again, or turn off manual speaker selection to auto-detect, then resubmit | ### Batch API Errors | Error Code | Message | Resolution | | --------------------------------- | --------------------------------------------- | ------------------------------------------------------- | | `batch_concurrency_limit_reached` | Batch concurrency limit reached | Wait for active batches to complete or upgrade plan | | `batch_plan_required` | Only available for scale and enterprise plans | Upgrade to Scale plan or higher | | `batch_file_too_large` | File size exceeds 5MB limit | Split into smaller batch files | | `batch_too_many_requests` | Exceeds maximum 500 records | Split batch into files of 500 or fewer requests | | `batch_insufficient_records` | Must contain at least 20 records | Add more records or use individual Generate API instead | | `batch_invalid_jsonl` | Invalid JSON at specific line | Fix JSON syntax on the indicated line | | `batch_duplicate_request_id` | Duplicate request\_id found | Ensure all request\_id values are unique | | `batch_invalid_endpoint` | Invalid endpoint specified | Use `"endpoint": "/v2/generate"` only | ### System and Processing Errors | Error Code | Message | Resolution | | -------------------------------------- | ----------------------------------- | -------------------------------------------------- | | `generation_timeout` | Generation exceeded maximum time | Retry after a delay; system may be under high load | | `generation_pipeline_failed` | Error in generation pipeline | Verify input specs and retry | | `generation_database_error` | Database access error | Retry after a short wait | | `generation_internal_auth` | Internal authentication failed | Contact support | | `generation_unhandled_error` | Unexpected error occurred | Retry; contact support if persistent | | `generation_infra_storage_error` | Storage access error on infra layer | Retry after a delay | | `generation_infra_resource_exhausted` | Infra resources exhausted | Wait and retry; try off-peak hours | | `generation_infra_service_unavailable` | Infra service unavailable | Check status page; retry after a delay | > Complete guide to sync. labs API error codes and troubleshooting. Input validation, batch processing, and system error resolution.