{
  "openapi": "3.1.0",
  "info": {
    "title": "Voice Creator Pro Cloud API",
    "version": "1.0.0",
    "description": "Generate speech, clone and design voices, change voices, transcribe audio, and make avatar videos, dubs and cuts.\n\n## Quickstart\n\nCreate a key in Settings > API at [app.voicecreator.pro](https://app.voicecreator.pro). The API needs a Starter or Premium plan.\n\n```bash\ncurl -X POST https://api.vcp.name/v1/speech \\\n  -H \"Authorization: Bearer $VCP_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\": \"Hello from the API.\", \"voice\": \"af_alloy\"}'\n\ncurl \"https://api.vcp.name/v1/jobs/JOB_ID?wait=60\" \\\n  -H \"Authorization: Bearer $VCP_API_KEY\"\n```\n\nWhen the job succeeds, `result.audio_url` links to the WAV. `GET /v1/voices` lists voice ids.\n\n## Authentication\n\nSend your key as a bearer token: `Authorization: Bearer vcp_live_...`. Keep it secret.\n\n## Jobs\n\nEndpoints that generate media return `202` with a job. `GET /v1/jobs/{id}?wait=60` returns when the job finishes, or after at most 60 seconds. Call it again while the status is queued or running, or use webhooks. Results are kept for 24 hours.\n\n## Files\n\nSend audio as `audio_file_id` or `audio_url`, photos as `photo_file_id` or `photo_url`, and videos as `video_file_id`. To upload, call `POST /v1/uploads`, PUT the file to `upload_url` with the same Content-Type within 2 hours, then pass `file_id`. Uploads are kept for 24 hours.\n\n| Type | Formats | Upload | Link |\n| --- | --- | --- | --- |\n| Audio | WAV, FLAC, Ogg/Opus, MP3 | 200 MB | 25 MB |\n| Photo | JPEG, PNG, WEBP | 20 MB | 20 MB |\n| Video | MP4, MOV, MKV, WEBM | 2 GB | Not supported |\n\nAvatar audio can be up to 20 seconds.\n\n## Errors\n\nErrors return an HTTP status and a body with a `code`, a `message` and, when one field is at fault, a `param`.\n\n```json\n{ \"error\": { \"code\": \"invalid_request\", \"message\": \"text is required.\", \"param\": \"text\" } }\n```\n\nRetry `429`, `500` and `503` with exponential backoff, waiting at least `Retry-After` when it is set. Send an `Idempotency-Key` so a retried POST cannot start a second job. Other errors fail again until the request changes.\n\nEvery response has a `Request-Id` header. Include it when you contact support.\n\n| Status | Code | Meaning |\n| --- | --- | --- |\n| 400 | `invalid_request` | A parameter is missing or invalid. `param` names it. |\n| 400 | `invalid_json` | The body is not JSON. |\n| 400 | `model_not_supported` | The model cannot do this. |\n| 400 | `url_fetch_failed` | The audio or photo link could not be downloaded. |\n| 401 | `unauthorized` | The API key is missing, invalid or revoked. |\n| 402 | `out_of_tokens` | The account is out of tokens for this period. |\n| 403 | `paid_plan_required` | The API needs a Starter or Premium plan. |\n| 403 | `preset_read_only` | Preset voices cannot be renamed or deleted. |\n| 404 | `not_found` | No such resource. |\n| 404 | `voice_not_found` | No such voice. |\n| 404 | `file_not_found` | No such upload. Uploads expire after 24 hours. |\n| 404 | `speech_job_not_found` | No such speech job, or its audio expired. |\n| 405 | `method_not_allowed` | The path does not support this method. |\n| 409 | `idempotency_conflict` | The Idempotency-Key was used with a different body. |\n| 409 | `job_not_ready` | The job has not succeeded yet. |\n| 409 | `design_expired` | The voice design is older than 24 hours. |\n| 409 | `voice_unavailable` | The voice has no reference audio. |\n| 409 | `voice_save_failed` | The voice could not be saved. |\n| 413 | `too_large` | The file or text is too large. |\n| 413 | `storage_full` | The account storage is full. |\n| 422 | `photo_refused` | The photo cannot be used. |\n| 429 | `rate_limited` | Too many requests for this key. |\n| 429 | `concurrency_limit` | Too many jobs in progress. |\n| 500 | `internal_error` | Something went wrong on our side. |\n| 503 | `unavailable` | Temporarily unavailable. |\n\nA failed job has status `failed` and an `error` with one of these codes:\n\n| Code | Meaning |\n| --- | --- |\n| `out_of_tokens` | The account ran out of tokens. |\n| `no_speech` | No speech was found, or none was produced. |\n| `no_face` | No face was found in the photo. |\n| `many_faces` | The photo shows more than one face. |\n| `too_long` | The video is longer than 30 minutes for a dub or 3 hours for a cut. |\n| `unsupported_language` | The model cannot speak the target language. |\n| `bad_video` | The video has no audio track or cannot be read. |\n| `generation_failed` | The job failed. Try again. |\n\n## Idempotency\n\nPOST requests that start a job accept an `Idempotency-Key` header. Retrying with the same key and body returns the original job. The same key with a different body returns `409 idempotency_conflict`. Keys are kept for 90 days.\n\n## Rate limits\n\n| Limit | Starter | Premium |\n| --- | --- | --- |\n| Requests per minute, per key | 60 | 60 |\n| Jobs in progress | 3 | 10 |\n\nOver a limit, requests get `429` with a `Retry-After` header. Responses to a valid key have a `RateLimit-Policy` header.\n\n## Webhooks\n\nAdd up to 5 https endpoints in Settings > API. When a job made with an API key finishes, every enabled endpoint gets a POST with `job.succeeded`, `job.failed` or `job.cancelled`. `data` is the job.\n\nRequests are signed with HMAC-SHA256 in the `webhook-id`, `webhook-timestamp` and `webhook-signature` headers of [Standard Webhooks](https://www.standardwebhooks.com). Verify them with your `whsec_` secret and the raw request body:\n\n```js\nimport { Webhook } from 'standardwebhooks'\n\nconst event = new Webhook(process.env.VCP_WEBHOOK_SECRET).verify(rawBody, headers)\n```\n\n```python\nimport os\nfrom standardwebhooks.webhooks import Webhook\n\nevent = Webhook(os.environ[\"VCP_WEBHOOK_SECRET\"]).verify(raw_body, headers)\n```\n\n`verify` fails when the signature is wrong or the timestamp is more than 5 minutes off.\n\nRespond with a 2xx within 10 seconds. Redirects are not followed. Failed deliveries are retried after 1 minute, 5 minutes, 30 minutes, 2 hours, 8 hours and 12 hours, up to 7 attempts over about 23 hours. An endpoint that fails for 3 days is turned off. Use `webhook-id` to skip duplicates. Events can arrive out of order.\n\n## Usage\n\nJobs use tokens from your plan. `tokens_charged` on the job shows the cost. API requests stay out of History. List them in Settings > API or with `GET /v1/requests`."
  },
  "servers": [
    {
      "url": "https://api.vcp.name"
    }
  ],
  "tags": [
    {
      "name": "Speech"
    },
    {
      "name": "Voices"
    },
    {
      "name": "Transcriptions"
    },
    {
      "name": "Voice changer"
    },
    {
      "name": "Avatar videos"
    },
    {
      "name": "Dubs"
    },
    {
      "name": "Cuts"
    },
    {
      "name": "Jobs"
    },
    {
      "name": "Uploads"
    },
    {
      "name": "Account"
    }
  ],
  "security": [
    {
      "bearer": []
    }
  ],
  "paths": {
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List models",
        "description": "Lists the models you can generate with, with their languages and preset voices.",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                },
                "example": {
                  "models": [
                    {
                      "id": "qwen3-tts",
                      "name": "Qwen3",
                      "clone": true,
                      "design": true,
                      "design_takes_text": true,
                      "languages": [
                        "English",
                        "Spanish",
                        "French"
                      ],
                      "presets": [
                        {
                          "id": "Ryan",
                          "name": "Ryan",
                          "description": "",
                          "language": "English"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Get usage",
        "description": "Returns your plan and the tokens used this period.",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                },
                "example": {
                  "tier": "premium",
                  "tokens_used": 188586,
                  "tokens_limit": 1500000,
                  "period_start": "2026-10-01T00:00:00.000Z",
                  "period_end": "2026-11-01T00:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/requests": {
      "get": {
        "operationId": "listRequests",
        "summary": "List requests",
        "description": "Lists your API requests, newest first. Pass `next_before` as `before` to get the next page, until it is null. A page can be empty while `next_before` is set, or hold more than `limit` requests made at the same moment.",
        "tags": [
          "Account"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "description": "Requests per page."
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Only requests made before this time."
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/JobType"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/JobStatus"
            }
          },
          {
            "name": "key_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Only requests made with this API key."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestLog"
                },
                "example": {
                  "requests": [
                    {
                      "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                      "type": "speech",
                      "status": "succeeded",
                      "error": null,
                      "tokens_charged": 42,
                      "api_key_id": "5f0c2a8e-3b1d-4c7e-9a62-1d8f4e7b2c90",
                      "summary": {
                        "text": "Hello from the API.",
                        "voice": "Alloy",
                        "model": "kokoro"
                      },
                      "created_at": "2026-10-30T00:10:42Z",
                      "finished_at": "2026-10-30T00:18:01Z"
                    }
                  ],
                  "next_before": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/avatar-videos": {
      "post": {
        "operationId": "createAvatarVideo",
        "summary": "Make an avatar video",
        "description": "Makes a video of the person in a photo speaking the audio. Send the audio as `speech_job_id` from POST /v1/speech, or as a WAV of up to 20 seconds. The photo must show one face. Returns a job whose result is an `AvatarVideoResult`.",
        "tags": [
          "Avatar videos"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "description": "Optional. Up to 255 characters, scoped to your account and kept for 90 days. Sending the same key with the same body again returns the original job. The same key with a different body is rejected with 409."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AvatarVideoBody"
              },
              "example": {
                "photo_file_id": "8383fc02-625a-4b71-a226-cbb2d19aaf17",
                "speech_job_id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                "consent": true
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted. Returns the job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "avatar_video",
                  "status": "queued",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": "857fcb81-9073-4f26-97c7-a388979fcdca",
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of tokens for this period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "422": {
            "description": "The photo cannot be used.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or this account already has too many jobs in progress. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/cuts": {
      "post": {
        "operationId": "createCut",
        "summary": "Cut a video",
        "description": "Cuts filler words, retakes and long pauses out of a video of up to 3 hours. Returns a job whose result is a `CutResult`. The job stays `running` until the cut video is ready.\n\nEstimated cost: 7000 tokens plus 20 per second of video, plus 4 per second of the cut video.",
        "tags": [
          "Cuts"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "description": "Optional. Up to 255 characters, scoped to your account and kept for 90 days. Sending the same key with the same body again returns the original job. The same key with a different body is rejected with 409."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CutBody"
              },
              "example": {
                "video_file_id": "8383fc02-625a-4b71-a226-cbb2d19aaf17"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted. Returns the job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "cut",
                  "status": "queued",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": "857fcb81-9073-4f26-97c7-a388979fcdca",
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of tokens for this period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or this account already has too many jobs in progress. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/voices/design": {
      "post": {
        "operationId": "designVoice",
        "summary": "Design a voice",
        "description": "Designs a voice from a description and speaks a sample. Returns a job whose result is an `AudioResult`. Save the voice with POST /v1/voices/design/{id}/save within 24 hours.",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "description": "Optional. Up to 255 characters, scoped to your account and kept for 90 days. Sending the same key with the same body again returns the original job. The same key with a different body is rejected with 409."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoiceDesignBody"
              },
              "example": {
                "description": "A calm, low narrator voice.",
                "text": "Welcome back to the show."
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted. Returns the job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "voice_design",
                  "status": "queued",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": null,
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of tokens for this period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or this account already has too many jobs in progress. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/voices/design/{id}/save": {
      "post": {
        "operationId": "saveDesignedVoice",
        "summary": "Save a designed voice",
        "description": "Saves the voice from a succeeded design job. Returns `409 design_expired` after 24 hours.",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoiceNameBody"
              },
              "example": {
                "name": "Narrator"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Voice"
                },
                "example": {
                  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                  "name": "Narrator",
                  "type": "design",
                  "model": null,
                  "duration_seconds": null,
                  "created_at": "2026-10-30T00:10:42Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/dubs": {
      "post": {
        "operationId": "createDub",
        "summary": "Dub a video",
        "description": "Dubs a video of up to 30 minutes into another language. Each speaker gets a voice cloned from their own lines unless `clone_voices` is false. Returns a job whose result is a `DubResult`.\n\nEstimated cost: 225 tokens per second of video, plus lip sync.",
        "tags": [
          "Dubs"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "description": "Optional. Up to 255 characters, scoped to your account and kept for 90 days. Sending the same key with the same body again returns the original job. The same key with a different body is rejected with 409."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DubBody"
              },
              "example": {
                "video_file_id": "8383fc02-625a-4b71-a226-cbb2d19aaf17",
                "target_language": "es"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted. Returns the job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "dub",
                  "status": "queued",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": "857fcb81-9073-4f26-97c7-a388979fcdca",
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of tokens for this period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or this account already has too many jobs in progress. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/dubs/{id}/subtitles": {
      "get": {
        "operationId": "getDubSubtitles",
        "summary": "Get the subtitles of a dub",
        "description": "Returns the lines of a dub job as SRT, VTT or JSON.",
        "tags": [
          "Dubs"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "srt",
                "vtt",
                "json"
              ],
              "default": "srt",
              "description": "srt for SubRip, vtt for WebVTT, or json for each line with its speaker and the original text."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/x-subrip": {
                "schema": {
                  "type": "string",
                  "description": "SubRip subtitles."
                }
              },
              "text/vtt": {
                "schema": {
                  "type": "string",
                  "description": "WebVTT subtitles."
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubtitleList"
                },
                "example": [
                  {
                    "start": 0.4,
                    "end": 2.6,
                    "text": "Bienvenidos de nuevo.",
                    "speaker": "SPEAKER_00",
                    "source_text": "Welcome back."
                  }
                ]
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "summary": "Get a job",
        "description": "Returns a job. With `wait`, holds the request until the job finishes or `wait` seconds pass.",
        "tags": [
          "Jobs"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "minimum": 0,
              "maximum": 60,
              "description": "Seconds to wait for the job to finish, up to 60."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "speech",
                  "status": "succeeded",
                  "progress": null,
                  "result": {
                    "audio_url": "https://files.example.com/speech.wav",
                    "download_url": "https://files.example.com/speech.wav?download=speech.wav",
                    "expires_at": "2026-10-31T00:10:42Z"
                  },
                  "error": null,
                  "tokens_charged": 42,
                  "resource_id": null,
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": "2026-10-30T00:18:01Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}/cancel": {
      "post": {
        "operationId": "cancelJob",
        "summary": "Cancel a job",
        "description": "Cancels a queued or running job. A finished job is returned unchanged.",
        "tags": [
          "Jobs"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "dub",
                  "status": "cancelled",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": "857fcb81-9073-4f26-97c7-a388979fcdca",
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": "2026-10-30T00:18:01Z"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/speech": {
      "post": {
        "operationId": "createSpeech",
        "summary": "Generate speech",
        "description": "Speaks text in a saved or preset voice. Returns a job whose result is an `AudioResult`.",
        "tags": [
          "Speech"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "description": "Optional. Up to 255 characters, scoped to your account and kept for 90 days. Sending the same key with the same body again returns the original job. The same key with a different body is rejected with 409."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpeechBody"
              },
              "example": {
                "text": "Hello from the API.",
                "voice": "af_alloy"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted. Returns the job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "speech",
                  "status": "queued",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": null,
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of tokens for this period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or this account already has too many jobs in progress. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/transcriptions": {
      "post": {
        "operationId": "createTranscription",
        "summary": "Transcribe audio",
        "description": "Transcribes audio. Returns a job whose result is a `TranscriptionResult`.",
        "tags": [
          "Transcriptions"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "description": "Optional. Up to 255 characters, scoped to your account and kept for 90 days. Sending the same key with the same body again returns the original job. The same key with a different body is rejected with 409."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TranscriptionBody"
              },
              "example": {
                "audio_url": "https://example.com/interview.mp3"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted. Returns the job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "transcription",
                  "status": "queued",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": null,
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of tokens for this period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or this account already has too many jobs in progress. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/uploads": {
      "post": {
        "operationId": "createUpload",
        "summary": "Upload a file",
        "description": "Creates an upload link. PUT the file to `upload_url` with the same Content-Type within 2 hours, then pass `file_id` to another endpoint.",
        "tags": [
          "Uploads"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadBody"
              },
              "example": {
                "content_type": "video/mp4",
                "size": 284023112
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Upload"
                },
                "example": {
                  "file_id": "8383fc02-625a-4b71-a226-cbb2d19aaf17",
                  "upload_url": "https://files.example.com/upload/8383fc02-625a-4b71-a226-cbb2d19aaf17?token=abc",
                  "expires_at": "2026-10-31T00:10:42Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/voice-changer": {
      "post": {
        "operationId": "createVoiceChange",
        "summary": "Change a voice",
        "description": "Makes speech sound like one of your saved voices. The audio can be up to 60 minutes long. Returns a job whose result is an `AudioResult`.",
        "tags": [
          "Voice changer"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "description": "Optional. Up to 255 characters, scoped to your account and kept for 90 days. Sending the same key with the same body again returns the original job. The same key with a different body is rejected with 409."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoiceChangeBody"
              },
              "example": {
                "audio_file_id": "8383fc02-625a-4b71-a226-cbb2d19aaf17",
                "voice": "Narrator"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted. Returns the job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "voice_change",
                  "status": "queued",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": null,
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of tokens for this period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or this account already has too many jobs in progress. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/voices": {
      "post": {
        "operationId": "createVoice",
        "summary": "Clone a voice",
        "description": "Clones a voice from a WAV clip of 5 to 30 seconds. Returns a job whose result is a `VoiceCloneResult`, and `resource_id` is the new voice. A clip with no speech fails with `no_speech` but the voice is saved.",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255,
              "description": "Optional. Up to 255 characters, scoped to your account and kept for 90 days. Sending the same key with the same body again returns the original job. The same key with a different body is rejected with 409."
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoiceCloneBody"
              },
              "example": {
                "name": "Narrator",
                "audio_file_id": "8383fc02-625a-4b71-a226-cbb2d19aaf17"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted. Returns the job.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
                  "type": "voice_clone",
                  "status": "queued",
                  "progress": null,
                  "result": null,
                  "error": null,
                  "tokens_charged": null,
                  "resource_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                  "created_at": "2026-10-30T00:10:42Z",
                  "finished_at": null
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of tokens for this period.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "409": {
            "description": "Conflicts with the current state, or an Idempotency-Key was reused with a different body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "413": {
            "description": "The request is too large.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or this account already has too many jobs in progress. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listVoices",
        "summary": "List voices",
        "description": "Lists your saved voices, newest first, then the preset voices.",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "saved",
                "preset"
              ],
              "description": "Only saved voices or only presets."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VoiceList"
                },
                "example": {
                  "voices": [
                    {
                      "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "name": "Narrator",
                      "type": "clone",
                      "model": null,
                      "duration_seconds": 12.4,
                      "created_at": "2026-10-30T00:10:42Z"
                    },
                    {
                      "id": "af_alloy",
                      "name": "Alloy",
                      "type": "preset",
                      "model": "kokoro",
                      "duration_seconds": null,
                      "created_at": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    },
    "/v1/voices/{id}": {
      "get": {
        "operationId": "getVoice",
        "summary": "Get a voice",
        "description": "Returns a saved or preset voice.",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Voice"
                },
                "example": {
                  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                  "name": "Narrator",
                  "type": "clone",
                  "model": null,
                  "duration_seconds": 12.4,
                  "created_at": "2026-10-30T00:10:42Z"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "renameVoice",
        "summary": "Rename a voice",
        "description": "Renames a saved voice.",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VoiceNameBody"
              },
              "example": {
                "name": "Narrator"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Voice"
                },
                "example": {
                  "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                  "name": "Narrator",
                  "type": "clone",
                  "model": null,
                  "duration_seconds": 12.4,
                  "created_at": "2026-10-30T00:10:42Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is invalid. The message names the field.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteVoice",
        "summary": "Delete a voice",
        "description": "Deletes a saved voice.",
        "tags": [
          "Voices"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Done. No body."
          },
          "401": {
            "description": "The API key is missing, invalid or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "403": {
            "description": "The account needs a paid plan, or the action is not allowed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "404": {
            "description": "Not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily unavailable. Retry after the Retry-After header.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "job": {
      "post": {
        "operationId": "jobWebhook",
        "summary": "Job finished",
        "description": "Sent to every enabled endpoint when a job made with an API key succeeds, fails or is cancelled. Answer with a 2xx status within 10 seconds.",
        "security": [],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The delivery id. It stays the same on every attempt, so use it to skip events you already handled."
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "When this attempt was sent, in Unix seconds."
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "v1, a comma, then the base64 HMAC-SHA256 of webhook-id, webhook-timestamp and the body joined with dots. The key is the part of your secret after whsec_, decoded from base64."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Any 2xx status within 10 seconds marks the event delivered. Anything else, including a redirect, is sent again later."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "An API key from Settings, starting vcp_live_."
      }
    },
    "schemas": {
      "ErrorBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        },
        "examples": [
          {
            "error": {
              "code": "invalid_request",
              "message": "text is required.",
              "param": "text"
            }
          }
        ]
      },
      "ErrorDetail": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "A code from the error tables."
          },
          "message": {
            "type": "string",
            "description": "What went wrong."
          },
          "param": {
            "type": "string",
            "description": "The request field at fault, when there is one."
          }
        }
      },
      "JobType": {
        "type": "string",
        "enum": [
          "speech",
          "voice_design",
          "voice_clone",
          "voice_change",
          "transcription",
          "dub",
          "avatar_video",
          "cut"
        ]
      },
      "JobStatus": {
        "type": "string",
        "enum": [
          "queued",
          "running",
          "succeeded",
          "failed",
          "cancelled"
        ]
      },
      "Job": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "type",
          "status",
          "progress",
          "result",
          "error",
          "tokens_charged",
          "resource_id",
          "created_at",
          "finished_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Job id."
          },
          "type": {
            "$ref": "#/components/schemas/JobType"
          },
          "status": {
            "$ref": "#/components/schemas/JobStatus"
          },
          "progress": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "From 0 to 1 while an avatar video renders, a dub runs or a video is cut, otherwise null."
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AudioResult"
              },
              {
                "$ref": "#/components/schemas/TranscriptionResult"
              },
              {
                "$ref": "#/components/schemas/VoiceCloneResult"
              },
              {
                "$ref": "#/components/schemas/AvatarVideoResult"
              },
              {
                "$ref": "#/components/schemas/DubResult"
              },
              {
                "$ref": "#/components/schemas/CutResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The result of a succeeded job, or null. Speech, voice designs and the voice changer give AudioResult, kept for 24 hours after the job finishes, then this is null. Transcriptions give TranscriptionResult. Voice clones give VoiceCloneResult. Avatar videos give AvatarVideoResult, dubs give DubResult and cuts give CutResult, all kept for 24 hours after the job was created."
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ErrorDetail"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the job failed, or null."
          },
          "tokens_charged": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Tokens billed, or null until billing has run."
          },
          "resource_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The voice id for voice clones, the project id for dubs and cuts, and the video id for avatar videos."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the job was created."
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the job finished, or null while it runs."
          }
        }
      },
      "AudioResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "audio_url",
          "download_url",
          "expires_at"
        ],
        "properties": {
          "audio_url": {
            "type": "string",
            "format": "uri",
            "description": "WAV audio link for playback."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "description": "The same audio, served as a download."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When both links stop working, 24 hours after the job finished."
          }
        },
        "description": "Links to the audio. The audio is kept for 24 hours after the job finishes.",
        "examples": [
          {
            "audio_url": "https://files.example.com/speech.wav",
            "download_url": "https://files.example.com/speech.wav?download=speech.wav",
            "expires_at": "2026-10-31T00:10:42Z"
          }
        ]
      },
      "TranscriptionResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "text",
          "language",
          "words"
        ],
        "properties": {
          "text": {
            "type": "string",
            "description": "The full transcript."
          },
          "language": {
            "type": [
              "string",
              "null"
            ],
            "description": "The spoken language, or null if unknown."
          },
          "words": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Word"
                }
              },
              {
                "type": "null"
              }
            ],
            "description": "Each word with its timing, or null without timestamps."
          }
        },
        "description": "The transcript of the audio.",
        "examples": [
          {
            "text": "Welcome back to the show.",
            "language": "English",
            "words": [
              {
                "text": "Welcome",
                "start": 0.32,
                "end": 0.71,
                "speaker": "SPEAKER_00"
              },
              {
                "text": "back",
                "start": 0.71,
                "end": 0.94,
                "speaker": "SPEAKER_00"
              }
            ]
          }
        ]
      },
      "VoiceCloneResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "voice",
          "transcript"
        ],
        "properties": {
          "voice": {
            "$ref": "#/components/schemas/Voice"
          },
          "transcript": {
            "type": [
              "string",
              "null"
            ],
            "description": "What the clip says, or null if it has no transcript."
          }
        },
        "description": "The saved voice.",
        "examples": [
          {
            "voice": {
              "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
              "name": "Narrator",
              "type": "clone",
              "model": null,
              "duration_seconds": 12.4,
              "created_at": "2026-10-30T00:10:42Z"
            },
            "transcript": "Welcome back to the show."
          }
        ]
      },
      "AvatarVideoResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "video_url",
          "download_url",
          "thumbnail_url",
          "duration_s",
          "width",
          "height",
          "expires_at"
        ],
        "properties": {
          "video_url": {
            "type": "string",
            "format": "uri",
            "description": "MP4 video link for playback."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "description": "The same video, served as a download."
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "A still image of the video, or null if there is none."
          },
          "duration_s": {
            "type": "number",
            "minimum": 0,
            "description": "The video length in seconds."
          },
          "width": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "The video width in pixels, or null if unknown."
          },
          "height": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "The video height in pixels, or null if unknown."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the links stop working and the video is deleted, 24 hours after the job was created."
          }
        },
        "description": "Links to the video. The video is kept for 24 hours after the job was created.",
        "examples": [
          {
            "video_url": "https://files.example.com/avatar.mp4",
            "download_url": "https://files.example.com/avatar.mp4?download=avatar.mp4",
            "thumbnail_url": "https://files.example.com/avatar.jpg",
            "duration_s": 8.2,
            "width": 1280,
            "height": 720,
            "expires_at": "2026-10-31T00:10:42Z"
          }
        ]
      },
      "DubResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "video_url",
          "download_url",
          "audio_url",
          "background_url",
          "subtitles_url",
          "duration_s",
          "source_language",
          "target_language",
          "speakers",
          "lipsynced",
          "expires_at"
        ],
        "properties": {
          "video_url": {
            "type": "string",
            "format": "uri",
            "description": "MP4 video link for playback. The lip-synced video when lip sync ran, otherwise the dubbed video."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "description": "The same video, served as a download."
          },
          "audio_url": {
            "type": "string",
            "format": "uri",
            "description": "The new voices on their own, as a WAV file."
          },
          "background_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "The music and sound effects without the voices, as a WAV file, or null when keep_background was false."
          },
          "subtitles_url": {
            "type": "string",
            "format": "uri",
            "description": "GET /v1/dubs/{id}/subtitles for this job. Send your API key with it."
          },
          "duration_s": {
            "type": "number",
            "minimum": 0,
            "description": "The video length in seconds."
          },
          "source_language": {
            "type": [
              "string",
              "null"
            ],
            "description": "The spoken language of the original video, or null if unknown."
          },
          "target_language": {
            "type": "string",
            "description": "The language the video was dubbed into."
          },
          "speakers": {
            "type": "integer",
            "minimum": 0,
            "description": "How many speakers were found."
          },
          "lipsynced": {
            "type": "boolean",
            "description": "True when the lips were matched to the new voices."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the links stop working and the dub is deleted, 24 hours after the job was created."
          }
        },
        "description": "Links to the dubbed video and its parts. The dub is kept for 24 hours after the job was created.",
        "examples": [
          {
            "video_url": "https://files.example.com/dub.mp4",
            "download_url": "https://files.example.com/dub.mp4?download=dub.mp4",
            "audio_url": "https://files.example.com/dub-voices.wav",
            "background_url": "https://files.example.com/dub-background.wav",
            "subtitles_url": "https://api.example.com/v1/dubs/04bd0571-e2c8-4d5b-a3cc-e56f85773abf/subtitles",
            "duration_s": 94.5,
            "source_language": "English",
            "target_language": "es",
            "speakers": 2,
            "lipsynced": false,
            "expires_at": "2026-10-31T00:10:42Z"
          }
        ]
      },
      "CutResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "video_url",
          "download_url",
          "duration_s",
          "source_duration_s",
          "width",
          "height",
          "removed",
          "language",
          "incomplete",
          "expires_at"
        ],
        "properties": {
          "video_url": {
            "type": "string",
            "format": "uri",
            "description": "MP4 video link for playback."
          },
          "download_url": {
            "type": "string",
            "format": "uri",
            "description": "The same video, served as a download."
          },
          "duration_s": {
            "type": "number",
            "minimum": 0,
            "description": "The cut video length in seconds."
          },
          "source_duration_s": {
            "type": "number",
            "minimum": 0,
            "description": "The uploaded video length in seconds."
          },
          "width": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "The video width in pixels, or null if unknown."
          },
          "height": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "description": "The video height in pixels, or null if unknown."
          },
          "removed": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "start",
                "end",
                "reasons"
              ],
              "properties": {
                "start": {
                  "type": "number",
                  "minimum": 0,
                  "description": "Seconds from the start of the uploaded video."
                },
                "end": {
                  "type": "number",
                  "minimum": 0,
                  "description": "Seconds from the start of the uploaded video."
                },
                "reasons": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "enum": [
                      "filler",
                      "retake",
                      "silence"
                    ]
                  },
                  "description": "Why the part was taken out. Lists silence only when no filler or retake was found in the part."
                }
              }
            },
            "description": "Each part taken out of the uploaded video, in order, with why it was taken out. Empty when nothing needed cutting."
          },
          "language": {
            "type": [
              "string",
              "null"
            ],
            "description": "The spoken language, or null if unknown."
          },
          "incomplete": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "fillers",
                "retakes",
                "silences"
              ]
            },
            "description": "Which of fillers, retakes or silences could not check the whole video. Empty when every step checked it all."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the links stop working and the cut is deleted, 24 hours after the job was created."
          }
        },
        "description": "Links to the cut video and what was taken out. The cut is kept for 24 hours after the job was created.",
        "examples": [
          {
            "video_url": "https://files.example.com/cut.mp4",
            "download_url": "https://files.example.com/cut.mp4?download=cut.mp4",
            "duration_s": 281.344,
            "source_duration_s": 485.87,
            "width": 1080,
            "height": 1920,
            "removed": [
              {
                "start": 0,
                "end": 107.62,
                "reasons": [
                  "retake"
                ]
              },
              {
                "start": 120.786,
                "end": 121.106,
                "reasons": [
                  "filler"
                ]
              },
              {
                "start": 129.3,
                "end": 129.44,
                "reasons": [
                  "silence"
                ]
              }
            ],
            "language": "English",
            "incomplete": [],
            "expires_at": "2026-10-31T00:10:42Z"
          }
        ]
      },
      "SubtitleLine": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "start",
          "end",
          "text",
          "speaker",
          "source_text"
        ],
        "properties": {
          "start": {
            "type": "number",
            "minimum": 0,
            "description": "Seconds from the start of the video."
          },
          "end": {
            "type": "number",
            "minimum": 0,
            "description": "Seconds from the start of the video."
          },
          "text": {
            "type": "string",
            "description": "The dubbed line."
          },
          "speaker": {
            "type": [
              "string",
              "null"
            ],
            "description": "Who says the line, or null if unknown."
          },
          "source_text": {
            "type": "string",
            "description": "What was said in the original video."
          }
        }
      },
      "SubtitleList": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/SubtitleLine"
        },
        "description": "Each subtitle line in order."
      },
      "Word": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "text",
          "start",
          "end",
          "speaker"
        ],
        "properties": {
          "text": {
            "type": "string"
          },
          "start": {
            "type": "number",
            "minimum": 0,
            "description": "Seconds from the start of the audio."
          },
          "end": {
            "type": "number",
            "minimum": 0,
            "description": "Seconds from the start of the audio."
          },
          "speaker": {
            "type": "string",
            "description": "Who said the word, as SPEAKER_00, SPEAKER_01 and so on."
          }
        }
      },
      "Voice": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "type",
          "model",
          "duration_seconds",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "A uuid for saved voices, or the preset id."
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "clone",
              "design",
              "preset"
            ]
          },
          "model": {
            "type": [
              "string",
              "null"
            ],
            "description": "The model a preset belongs to, or null for saved voices."
          },
          "duration_seconds": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "description": "Length of the reference clip, or null."
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the voice was saved, or null for presets."
          }
        }
      },
      "VoiceList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "voices"
        ],
        "properties": {
          "voices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Voice"
            }
          }
        }
      },
      "Model": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "clone",
          "design",
          "design_takes_text",
          "languages",
          "presets"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Pass as model."
          },
          "name": {
            "type": "string"
          },
          "clone": {
            "type": "boolean",
            "description": "Speaks in saved voices."
          },
          "design": {
            "type": "boolean",
            "description": "Designs voices from a description."
          },
          "design_takes_text": {
            "type": "boolean",
            "description": "Voice design speaks the given text."
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Languages to pass as language."
          },
          "presets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Preset"
            },
            "description": "Preset voices of this model."
          }
        }
      },
      "Preset": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "description",
          "language"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Pass as voice."
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "language": {
            "type": [
              "string",
              "null"
            ],
            "description": "The language the preset speaks, or null."
          }
        }
      },
      "ModelList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "models"
        ],
        "properties": {
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Model"
            }
          }
        }
      },
      "Usage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "tier",
          "tokens_used",
          "tokens_limit",
          "period_start",
          "period_end"
        ],
        "properties": {
          "tier": {
            "type": "string",
            "enum": [
              "free",
              "starter",
              "premium"
            ]
          },
          "tokens_used": {
            "type": "integer",
            "minimum": 0,
            "description": "Tokens used this period."
          },
          "tokens_limit": {
            "type": "integer",
            "minimum": 0,
            "description": "Tokens included in the plan each period."
          },
          "period_start": {
            "type": "string",
            "format": "date-time",
            "description": "When this token period started."
          },
          "period_end": {
            "type": "string",
            "format": "date-time",
            "description": "When this token period ends and the next one starts."
          }
        }
      },
      "RequestSummary": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "text": {
            "type": "string"
          },
          "voice": {
            "type": "string"
          },
          "model": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        }
      },
      "RequestLogEntry": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "type",
          "status",
          "error",
          "tokens_charged",
          "api_key_id",
          "summary",
          "created_at",
          "finished_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Job id."
          },
          "type": {
            "$ref": "#/components/schemas/JobType"
          },
          "status": {
            "$ref": "#/components/schemas/JobStatus"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ErrorDetail"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the job failed, or null."
          },
          "tokens_charged": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "Tokens billed, or null until billing has run."
          },
          "api_key_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The key that made the request, or null if the key was deleted."
          },
          "summary": {
            "$ref": "#/components/schemas/RequestSummary"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the job was created."
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the job finished, or null while it runs."
          }
        }
      },
      "RequestLog": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "requests",
          "next_before"
        ],
        "properties": {
          "requests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RequestLogEntry"
            }
          },
          "next_before": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Pass as before to get the next page, or null on the last page."
          }
        }
      },
      "SpeechBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "text",
          "voice"
        ],
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "description": "The text to speak."
          },
          "voice": {
            "type": "string",
            "minLength": 1,
            "description": "A saved voice id, a saved voice name or a preset id."
          },
          "model": {
            "type": "string",
            "description": "A model id from GET /v1/models."
          },
          "language": {
            "type": "string",
            "description": "A language from the model, such as English."
          }
        }
      },
      "VoiceDesignBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "description"
        ],
        "properties": {
          "description": {
            "type": "string",
            "minLength": 1,
            "description": "What the voice sounds like."
          },
          "text": {
            "type": "string",
            "description": "What the sample says."
          },
          "model": {
            "type": "string",
            "description": "A model id from GET /v1/models."
          },
          "language": {
            "type": "string",
            "description": "A language from the model, such as English."
          }
        }
      },
      "TranscriptionBody": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "audio_file_id": {
            "type": "string",
            "description": "A file_id from POST /v1/uploads. Send this or audio_url."
          },
          "audio_url": {
            "type": "string",
            "format": "uri",
            "description": "An https link to the audio, up to 25 MB. Send this or audio_file_id."
          },
          "language": {
            "type": "string",
            "description": "The spoken language, such as English. Leave it out to detect it."
          },
          "timestamps": {
            "type": "boolean",
            "default": true,
            "description": "Return each word with its timing and speaker."
          },
          "speakers": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "description": "How many people speak. Leave it out to detect it. Only used when timestamps is true."
          },
          "model": {
            "type": "string",
            "enum": [
              "standard",
              "higher_quality",
              "parakeet_v3",
              "orukeet"
            ],
            "default": "higher_quality",
            "description": "The speech recognition model."
          }
        }
      },
      "VoiceChangeBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "voice"
        ],
        "properties": {
          "audio_file_id": {
            "type": "string",
            "description": "A file_id from POST /v1/uploads. Send this or audio_url."
          },
          "audio_url": {
            "type": "string",
            "format": "uri",
            "description": "An https link to the audio, up to 25 MB. Send this or audio_file_id."
          },
          "voice": {
            "type": "string",
            "minLength": 1,
            "description": "A saved voice id or name. Presets cannot be used."
          }
        }
      },
      "VoiceCloneBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "The voice name."
          },
          "audio_file_id": {
            "type": "string",
            "description": "A file_id from POST /v1/uploads. Send this or audio_url."
          },
          "audio_url": {
            "type": "string",
            "format": "uri",
            "description": "An https link to the audio, up to 25 MB. Send this or audio_file_id."
          },
          "transcript": {
            "type": "string",
            "description": "What the clip says. Leave it out to transcribe the clip.",
            "maxLength": 4000
          }
        }
      },
      "AvatarVideoBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "consent"
        ],
        "properties": {
          "photo_file_id": {
            "type": "string",
            "description": "A file_id from POST /v1/uploads of a JPEG, PNG or WEBP photo. Send this or photo_url."
          },
          "photo_url": {
            "type": "string",
            "format": "uri",
            "description": "An https link to the photo, up to 20 MB. Send this or photo_file_id."
          },
          "speech_job_id": {
            "type": "string",
            "description": "The id of a succeeded POST /v1/speech job from the last 24 hours. Send this, audio_file_id or audio_url."
          },
          "audio_file_id": {
            "type": "string",
            "description": "A file_id from POST /v1/uploads of a WAV file up to 10 MB. Send this, speech_job_id or audio_url."
          },
          "audio_url": {
            "type": "string",
            "format": "uri",
            "description": "An https link to a WAV file, up to 10 MB. Send this, speech_job_id or audio_file_id."
          },
          "consent": {
            "type": "boolean",
            "const": true,
            "description": "Must be true. Confirms you have the right to use the face in the photo."
          },
          "resolution": {
            "type": "string",
            "enum": [
              "480p",
              "720p",
              "1080p",
              "1440p"
            ],
            "default": "720p",
            "description": "The output resolution."
          },
          "fps": {
            "type": "integer",
            "enum": [
              24,
              25,
              48,
              50
            ],
            "default": 24,
            "description": "Frames per second."
          },
          "engine": {
            "type": "string",
            "enum": [
              "ltx-2.3",
              "ltx-2.5"
            ],
            "default": "ltx-2.5",
            "description": "The video model."
          }
        }
      },
      "DubBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "video_file_id",
          "target_language"
        ],
        "properties": {
          "video_file_id": {
            "type": "string",
            "minLength": 1,
            "description": "A file_id from POST /v1/uploads of an MP4, MOV, MKV or WEBM video up to 2 GB and 30 minutes long."
          },
          "target_language": {
            "type": "string",
            "enum": [
              "es",
              "fr",
              "de",
              "ja",
              "ko",
              "zh",
              "zh-Hant",
              "pt",
              "ru",
              "it",
              "ar",
              "hi",
              "th",
              "vi",
              "id",
              "tr",
              "pl",
              "nl",
              "uk",
              "cs",
              "en",
              "Spanish",
              "French",
              "German",
              "Japanese",
              "Korean",
              "Chinese",
              "Traditional Chinese",
              "Portuguese",
              "Russian",
              "Italian",
              "Arabic",
              "Hindi",
              "Thai",
              "Vietnamese",
              "Indonesian",
              "Turkish",
              "Polish",
              "Dutch",
              "Ukrainian",
              "Czech",
              "English",
              "Standard Arabic"
            ],
            "description": "The language to dub into."
          },
          "source_language": {
            "type": "string",
            "default": "auto",
            "description": "The spoken language of the video, such as English. Leave it out to detect it."
          },
          "keep_background": {
            "type": "boolean",
            "default": true,
            "description": "Keep the music and sound effects under the new voices."
          },
          "clone_voices": {
            "type": "boolean",
            "default": true,
            "description": "Give each speaker a voice cloned from their own lines."
          },
          "voice": {
            "type": "string",
            "description": "A saved voice id, a saved voice name or a preset id. Used for speakers that are not cloned, and for every speaker when clone_voices is false. Required when clone_voices is false."
          },
          "model": {
            "type": "string",
            "description": "A model id from GET /v1/models. A preset voice uses its own model."
          },
          "speakers": {
            "type": "integer",
            "minimum": 1,
            "maximum": 6,
            "description": "How many people speak. Leave it out to detect it."
          },
          "lipsync": {
            "type": "boolean",
            "default": false,
            "description": "Match the lips to the new voices. Only for videos up to 60 seconds. A longer video is dubbed without it and lipsynced is false."
          }
        }
      },
      "CutBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "video_file_id"
        ],
        "properties": {
          "video_file_id": {
            "type": "string",
            "minLength": 1,
            "description": "A file_id from POST /v1/uploads of an MP4, MOV, MKV or WEBM video up to 2 GB and 3 hours long."
          },
          "fillers": {
            "type": "boolean",
            "default": true,
            "description": "Cut filler words such as um and uh."
          },
          "retakes": {
            "type": "boolean",
            "default": true,
            "description": "Cut lines that were said more than once, keeping one take."
          },
          "silences": {
            "type": "boolean",
            "default": true,
            "description": "Shorten long pauses."
          },
          "pace": {
            "type": "string",
            "enum": [
              "natural",
              "tight"
            ],
            "default": "natural",
            "description": "tight leaves shorter pauses than natural."
          }
        }
      },
      "VoiceNameBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "The voice name."
          }
        }
      },
      "UploadBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "content_type",
          "size"
        ],
        "properties": {
          "content_type": {
            "type": "string",
            "enum": [
              "audio/wav",
              "audio/x-wav",
              "audio/wave",
              "audio/vnd.wave",
              "audio/flac",
              "audio/x-flac",
              "audio/ogg",
              "audio/opus",
              "audio/mpeg",
              "image/jpeg",
              "image/png",
              "image/webp",
              "video/mp4",
              "video/quicktime",
              "video/x-matroska",
              "video/webm"
            ],
            "description": "The file format. Send the same Content-Type when you upload the file."
          },
          "size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483648,
            "description": "The file size in bytes. Audio can be up to 209715200 bytes, a photo up to 20971520 bytes and a video up to 2147483648 bytes."
          }
        }
      },
      "Upload": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "file_id",
          "upload_url",
          "expires_at"
        ],
        "properties": {
          "file_id": {
            "type": "string",
            "description": "Pass as audio_file_id, photo_file_id or video_file_id. The file is kept for 24 hours."
          },
          "upload_url": {
            "type": "string",
            "format": "uri",
            "description": "PUT the file here."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "When upload_url stops working, 2 hours from now."
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "timestamp",
          "api_key_id",
          "data"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "job.succeeded",
              "job.failed",
              "job.cancelled",
              "webhook.test"
            ],
            "description": "What happened. webhook.test comes from Send test in Settings > API."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "When this attempt was sent."
          },
          "api_key_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "The key that made the request, or null for webhook.test."
          },
          "data": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Job"
              },
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "endpoint_id"
                ],
                "properties": {
                  "endpoint_id": {
                    "type": "string",
                    "description": "The endpoint the test was sent to."
                  }
                }
              }
            ],
            "description": "The job, the same as GET /v1/jobs/{id} returns it. For webhook.test, the endpoint id."
          }
        },
        "description": "The JSON body of every webhook request.",
        "examples": [
          {
            "type": "job.succeeded",
            "timestamp": "2026-10-30T00:18:01Z",
            "api_key_id": "5f0c2a8e-3b1d-4c7e-9a62-1d8f4e7b2c90",
            "data": {
              "id": "04bd0571-e2c8-4d5b-a3cc-e56f85773abf",
              "type": "cut",
              "status": "succeeded",
              "progress": null,
              "result": {
                "video_url": "https://files.example.com/cut.mp4",
                "download_url": "https://files.example.com/cut.mp4?download=cut.mp4",
                "duration_s": 281.344,
                "source_duration_s": 485.87,
                "width": 1080,
                "height": 1920,
                "removed": [
                  {
                    "start": 0,
                    "end": 107.62,
                    "reasons": [
                      "retake"
                    ]
                  },
                  {
                    "start": 120.786,
                    "end": 121.106,
                    "reasons": [
                      "filler"
                    ]
                  },
                  {
                    "start": 129.3,
                    "end": 129.44,
                    "reasons": [
                      "silence"
                    ]
                  }
                ],
                "language": "English",
                "incomplete": [],
                "expires_at": "2026-10-31T00:10:42Z"
              },
              "error": null,
              "tokens_charged": 16311,
              "resource_id": "857fcb81-9073-4f26-97c7-a388979fcdca",
              "created_at": "2026-10-30T00:10:42Z",
              "finished_at": "2026-10-30T00:18:01Z"
            }
          }
        ]
      }
    }
  }
}
