> ## Documentation Index
> Fetch the complete documentation index at: https://developers.phrase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dub Recording

> Add one or more target dubbing languages to a recording that already exists, without recreating the project. Use this instead of `POST /v1/projects` whenever the project already exists.

## Precondition: the language must already be translated

Dubbing is generated from that language's translated subtitles, so a language can only be dubbed after it has been translated (see `POST /v1/projects/{projectId}/recordings/{recordingId}/translate`). This is **not enforced with a clear error** — requesting dubbing for a language with no completed translation is accepted, the language is recorded against the recording, but no dubbing output is produced. Before calling this endpoint, check `GET /v1/recordings/{recordingId}/status?language={code}` and confirm `translation` is `true` for every language you pass.

## Language support depends on the project's TTS provider

Each Studio project uses one text-to-speech provider, configured in project preferences (falls back to the account default). The set of dubbable languages is different for each provider — always check which provider the project uses before picking languages. Requesting a language unsupported by the project's current provider fails fast with `400` and a message naming the unsupported languages and the provider (see `language_not_supported_by_provider` below) — no dubbing subtitle file or task is created for it.

- **ElevenLabs v2** — 30 languages, base language only (no distinct regional voices; a region-specific code like `en-GB` is accepted only by falling back to its base `en`): `ar, bg, cs, da, de, el, en, es, fi, fil, fr, hi, hr, id, it, ja, ko, ms, nl, pl, pt, ro, ru, sk, sv, ta, tl, tr, uk, zh`
- **ElevenLabs v3** — 77 languages, base language only (same fallback caveat as v2): `af, ar, as, az, be, bg, bn, bs, ca, ceb, cs, cy, da, de, el, en, es, et, fa, fi, fil, fr, ga, gl, gu, ha, he, hi, hr, hu, hy, id, is, it, ja, jw, ka, kk, kn, ko, ky, lb, ln, lt, lv, mk, ml, mr, ms, ne, nl, nn, no, ny, pa, pl, prs, ps, pt, ro, ru, sd, sk, sl, so, sr, sv, sw, ta, te, th, tl, tr, uk, ur, vi, zh`
- **Azure TTS** — the only provider with real, distinct regional voices: 155 specific locales (not fallback-inherited) covering 85 languages: `af-ZA, am-ET, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, ar-JO, ar-KW, ar-LB, ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SY, ar-TN, ar-YE, as-IN, az-AZ, bg-BG, bn-BD, bn-IN, bs-BA, ca-ES, cs-CZ, cy-GB, da-DK, de-AT, de-CH, de-DE, el-GR, en-AU, en-CA, en-GB, en-HK, en-IE, en-IN, en-KE, en-NG, en-NZ, en-PH, en-SG, en-TZ, en-US, en-ZA, es-AR, es-BO, es-CL, es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, es-GQ, es-GT, es-HN, es-MX, es-NI, es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et-EE, eu-ES, fa-IR, fi-FI, fil-PH, fr-BE, fr-CA, fr-CH, fr-FR, ga-IE, gl-ES, gu-IN, he-IL, hi-IN, hr-HR, hu-HU, hy-AM, id-ID, is-IS, it-CH, it-IT, iu-Cans-CA, iu-Latn-CA, ja-JP, jv-ID, ka-GE, kk-KZ, km-KH, kn-IN, ko-KR, lo-LA, lt-LT, lv-LV, mk-MK, ml-IN, mn-MN, mr-IN, ms-MY, mt-MT, my-MM, nb-NO, ne-NP, nl-BE, nl-NL, or-IN, pa-IN, pl-PL, ps-AF, pt-BR, pt-PT, ro-RO, ru-RU, si-LK, sk-SK, sl-SI, so-SO, sq-AL, sr-Latn-RS, sr-RS, su-ID, sv-SE, sw-KE, sw-TZ, ta-IN, ta-LK, ta-MY, ta-SG, te-IN, th-TH, tr-TR, uk-UA, ur-IN, ur-PK, uz-UZ, vi-VN, wuu-CN, yue-CN, zh-CN, zh-CN-guangxi, zh-CN-henan, zh-CN-liaoning, zh-CN-shaanxi, zh-CN-shandong, zh-CN-sichuan, zh-HK, zh-TW, zu-ZA`. A base code without a region (e.g. plain `zh`) is resolved to one of that language's locales above; pass the specific regional code when you need a particular one (e.g. `zh-TW` rather than `zh-CN`).

## Re-requesting a language

A language already in the recording's dubbing languages is not skipped — it is re-dubbed. `ignoredLanguages` is accepted on this request for shape-parity with the translate endpoint but has no effect on dubbing; every language listed in `languages` is processed.



## OpenAPI

````yaml /openapi/phrase-studio.json post /v1/projects/{projectId}/recordings/{recordingId}/dubbing
openapi: 3.0.3
info:
  title: Studio API
  description: >-
    API for creating projects and reading transcription, translation, and
    dubbing results.
  version: 1.0.0
servers:
  - url: https://api.studio.us.phrase.com
    description: Production US Environment
  - url: https://api.studio.eu.phrase.com
    description: Production EU Environment
security: []
tags:
  - name: Projects
    description: Manage transcription, translation, and dubbing projects
  - name: Recordings
    description: Access recording status and output data
  - name: Subtitle Profiles
    description: Manage subtitle formatting profiles
  - name: Pronunciations
    description: Manage custom pronunciation rules
  - name: Glossaries
    description: Manage translation glossaries
  - name: Insights
    description: Manage AI-powered insight prompts
  - name: Safe Communications
    description: Access safe communication evaluation templates
  - name: Subtitles
    description: Write subtitle segments for a recording
paths:
  /v1/projects/{projectId}/recordings/{recordingId}/dubbing:
    post:
      tags:
        - Recordings
      summary: Dub Recording
      description: >-
        Add one or more target dubbing languages to a recording that already
        exists, without recreating the project. Use this instead of `POST
        /v1/projects` whenever the project already exists.


        ## Precondition: the language must already be translated


        Dubbing is generated from that language's translated subtitles, so a
        language can only be dubbed after it has been translated (see `POST
        /v1/projects/{projectId}/recordings/{recordingId}/translate`). This is
        **not enforced with a clear error** — requesting dubbing for a language
        with no completed translation is accepted, the language is recorded
        against the recording, but no dubbing output is produced. Before calling
        this endpoint, check `GET
        /v1/recordings/{recordingId}/status?language={code}` and confirm
        `translation` is `true` for every language you pass.


        ## Language support depends on the project's TTS provider


        Each Studio project uses one text-to-speech provider, configured in
        project preferences (falls back to the account default). The set of
        dubbable languages is different for each provider — always check which
        provider the project uses before picking languages. Requesting a
        language unsupported by the project's current provider fails fast with
        `400` and a message naming the unsupported languages and the provider
        (see `language_not_supported_by_provider` below) — no dubbing subtitle
        file or task is created for it.


        - **ElevenLabs v2** — 30 languages, base language only (no distinct
        regional voices; a region-specific code like `en-GB` is accepted only by
        falling back to its base `en`): `ar, bg, cs, da, de, el, en, es, fi,
        fil, fr, hi, hr, id, it, ja, ko, ms, nl, pl, pt, ro, ru, sk, sv, ta, tl,
        tr, uk, zh`

        - **ElevenLabs v3** — 77 languages, base language only (same fallback
        caveat as v2): `af, ar, as, az, be, bg, bn, bs, ca, ceb, cs, cy, da, de,
        el, en, es, et, fa, fi, fil, fr, ga, gl, gu, ha, he, hi, hr, hu, hy, id,
        is, it, ja, jw, ka, kk, kn, ko, ky, lb, ln, lt, lv, mk, ml, mr, ms, ne,
        nl, nn, no, ny, pa, pl, prs, ps, pt, ro, ru, sd, sk, sl, so, sr, sv, sw,
        ta, te, th, tl, tr, uk, ur, vi, zh`

        - **Azure TTS** — the only provider with real, distinct regional voices:
        155 specific locales (not fallback-inherited) covering 85 languages:
        `af-ZA, am-ET, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, ar-JO, ar-KW, ar-LB,
        ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SY, ar-TN, ar-YE, as-IN, az-AZ,
        bg-BG, bn-BD, bn-IN, bs-BA, ca-ES, cs-CZ, cy-GB, da-DK, de-AT, de-CH,
        de-DE, el-GR, en-AU, en-CA, en-GB, en-HK, en-IE, en-IN, en-KE, en-NG,
        en-NZ, en-PH, en-SG, en-TZ, en-US, en-ZA, es-AR, es-BO, es-CL, es-CO,
        es-CR, es-CU, es-DO, es-EC, es-ES, es-GQ, es-GT, es-HN, es-MX, es-NI,
        es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et-EE, eu-ES,
        fa-IR, fi-FI, fil-PH, fr-BE, fr-CA, fr-CH, fr-FR, ga-IE, gl-ES, gu-IN,
        he-IL, hi-IN, hr-HR, hu-HU, hy-AM, id-ID, is-IS, it-CH, it-IT,
        iu-Cans-CA, iu-Latn-CA, ja-JP, jv-ID, ka-GE, kk-KZ, km-KH, kn-IN, ko-KR,
        lo-LA, lt-LT, lv-LV, mk-MK, ml-IN, mn-MN, mr-IN, ms-MY, mt-MT, my-MM,
        nb-NO, ne-NP, nl-BE, nl-NL, or-IN, pa-IN, pl-PL, ps-AF, pt-BR, pt-PT,
        ro-RO, ru-RU, si-LK, sk-SK, sl-SI, so-SO, sq-AL, sr-Latn-RS, sr-RS,
        su-ID, sv-SE, sw-KE, sw-TZ, ta-IN, ta-LK, ta-MY, ta-SG, te-IN, th-TH,
        tr-TR, uk-UA, ur-IN, ur-PK, uz-UZ, vi-VN, wuu-CN, yue-CN, zh-CN,
        zh-CN-guangxi, zh-CN-henan, zh-CN-liaoning, zh-CN-shaanxi,
        zh-CN-shandong, zh-CN-sichuan, zh-HK, zh-TW, zu-ZA`. A base code without
        a region (e.g. plain `zh`) is resolved to one of that language's locales
        above; pass the specific regional code when you need a particular one
        (e.g. `zh-TW` rather than `zh-CN`).


        ## Re-requesting a language


        A language already in the recording's dubbing languages is not skipped —
        it is re-dubbed. `ignoredLanguages` is accepted on this request for
        shape-parity with the translate endpoint but has no effect on dubbing;
        every language listed in `languages` is processed.
      operationId: dubRecording
      parameters:
        - name: projectId
          in: path
          required: true
          description: Project ID
          schema:
            type: string
            format: uuid
        - name: recordingId
          in: path
          required: true
          description: Recording ID
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddDubbingRequest'
            examples:
              add_dubbing_language:
                summary: Add Czech as a dubbing target language
                value:
                  languages:
                    - cs
      responses:
        '200':
          description: Dubbing started for the requested languages
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                bad_request:
                  summary: Bad Request
                  value:
                    success: false
                    statusCode: 400
                    message: Bad Request
                    timestamp: '2025-01-01T00:00:00.000Z'
                language_not_supported_by_provider:
                  summary: Language not supported by the project's TTS provider
                  value:
                    success: false
                    statusCode: 400
                    message: Dubbing is not supported for cs with ElevenLabs v2
                    timestamp: '2025-01-01T00:00:00.000Z'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                unauthorized:
                  summary: Unauthorized
                  value:
                    success: false
                    statusCode: 401
                    message: Unauthorized
                    timestamp: '2025-01-01T00:00:00.000Z'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                forbidden:
                  summary: Forbidden
                  value:
                    success: false
                    statusCode: 403
                    message: Access denied
                    timestamp: '2025-01-01T00:00:00.000Z'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                not_found:
                  summary: Not Found
                  value:
                    success: false
                    statusCode: 404
                    message: Project or recording not found
                    timestamp: '2025-01-01T00:00:00.000Z'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                internal_server_error:
                  summary: Internal server error
                  value:
                    success: false
                    statusCode: 500
                    message: Internal server error
                    timestamp: '2025-01-01T00:00:00.000Z'
      security:
        - apiKeyAuth: []
components:
  schemas:
    AddDubbingRequest:
      type: object
      required:
        - languages
      properties:
        languages:
          type: array
          items:
            type: string
          description: >-
            Target languages to (re-)dub. A language already present on the
            recording is re-dubbed, not skipped. Each language must already be
            translated on this recording (see POST .../translate) — this is not
            checked, so an untranslated language is silently accepted but
            produces no dubbing output. Each language must also be supported by
            the project's configured TTS provider, which IS checked — an
            unsupported language fails the whole request with 400.
        ignoredLanguages:
          type: array
          items:
            type: string
          description: >-
            Accepted for shape-parity with TranslateRecordingRequest; has no
            effect on dubbing
        pronunciations:
          type: object
          additionalProperties:
            type: string
          description: Pronunciation ruleset id per language code
    ErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        statusCode:
          type: integer
          example: 400
        message:
          type: string
          example: Bad Request
        timestamp:
          type: string
          format: date-time
          example: '2025-01-01T00:00:00.000Z'
      required:
        - success
        - statusCode
        - message
        - timestamp
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

````