> ## 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.

# Translate Recording

> Add one or more target translation languages to a recording that already exists, without recreating the project. Use this instead of `POST /v1/projects` whenever the project already exists — for example the caller forgot a language at creation time, the user asks for another language later, or the caller only learns which language is needed after seeing the transcript.

## Precondition: source transcription must be complete

Translation reads the recording's transcript, so it can only run after transcription has finished. This is **not enforced synchronously** by this endpoint — a call made too early is accepted and queued, but produces no usable result. Before calling this endpoint, check `GET /v1/recordings/{recordingId}/status?language={sourceLanguage}` and confirm `transcription` is `true` (or poll `GET /v1/recordings/{recordingId}/status?summary=true` until `status` is `COMPLETED`).

## Re-requesting a language

A language already in the recording's translation languages is not skipped — it is retranslated (logged as a retranslation rather than an initial translation). Only include a language in `languages` if you actually want it (re-)translated; use `ignoredLanguages` to record a language as intentionally not translated without omitting it from tracking.

## Language support

`languages` accepts any BCP-47-style code Phrase Studio has translation support for — effectively all locales except the literal `auto` placeholder. Do not pass the recording's own source language: the Studio UI excludes it from the language picker, but this endpoint does **not** reject it — it is accepted and produces a same-language "translation". An unsupported code is rejected with `400`.

## After translation completes

Call `POST /v1/projects/{projectId}/recordings/{recordingId}/dubbing` to dub any of the resulting languages — dubbing requires the language to be translated first.



## OpenAPI

````yaml /openapi/phrase-studio.json post /v1/projects/{projectId}/recordings/{recordingId}/translate
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}/translate:
    post:
      tags:
        - Recordings
      summary: Translate Recording
      description: >-
        Add one or more target translation languages to a recording that already
        exists, without recreating the project. Use this instead of `POST
        /v1/projects` whenever the project already exists — for example the
        caller forgot a language at creation time, the user asks for another
        language later, or the caller only learns which language is needed after
        seeing the transcript.


        ## Precondition: source transcription must be complete


        Translation reads the recording's transcript, so it can only run after
        transcription has finished. This is **not enforced synchronously** by
        this endpoint — a call made too early is accepted and queued, but
        produces no usable result. Before calling this endpoint, check `GET
        /v1/recordings/{recordingId}/status?language={sourceLanguage}` and
        confirm `transcription` is `true` (or poll `GET
        /v1/recordings/{recordingId}/status?summary=true` until `status` is
        `COMPLETED`).


        ## Re-requesting a language


        A language already in the recording's translation languages is not
        skipped — it is retranslated (logged as a retranslation rather than an
        initial translation). Only include a language in `languages` if you
        actually want it (re-)translated; use `ignoredLanguages` to record a
        language as intentionally not translated without omitting it from
        tracking.


        ## Language support


        `languages` accepts any BCP-47-style code Phrase Studio has translation
        support for — effectively all locales except the literal `auto`
        placeholder. Do not pass the recording's own source language: the Studio
        UI excludes it from the language picker, but this endpoint does **not**
        reject it — it is accepted and produces a same-language "translation".
        An unsupported code is rejected with `400`.


        ## After translation completes


        Call `POST /v1/projects/{projectId}/recordings/{recordingId}/dubbing` to
        dub any of the resulting languages — dubbing requires the language to be
        translated first.
      operationId: translateRecording
      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/TranslateRecordingRequest'
            examples:
              add_translation_language:
                summary: Add Czech as a translation target language
                value:
                  languages:
                    - cs
      responses:
        '200':
          description: Translation 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'
        '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:
    TranslateRecordingRequest:
      type: object
      required:
        - languages
      properties:
        languages:
          type: array
          items:
            type: string
          description: >-
            Target languages to (re-)translate. A language already present on
            the recording is retranslated, not skipped — only list a language
            here if you want it (re-)run. Any BCP-47-style code with translation
            support is accepted except the literal `auto` placeholder. Do not
            pass the recording's source language — the Studio UI excludes it
            from the picker, but this field does not reject it.
        ignoredLanguages:
          type: array
          items:
            type: string
          default: []
          description: >-
            Subset of `languages` to record as intentionally not translated
            (tracked on the recording so it shows as deliberately skipped, not
            pending or failed) instead of actually running translation for it
        tmsProjectTemplateUid:
          type: string
          description: >-
            TMS project template to use if translation is routed through a
            connected TMS
        subtitleProfiles:
          type: object
          additionalProperties:
            type: string
          description: >-
            Subtitle profile id per language code. List available ids with GET
            /v1/subtitle-profiles.
        styleGuides:
          type: object
          additionalProperties:
            type: string
          description: >-
            Style guide id per language code. Style guides belong to a separate
            Phrase system (Frame), not Phrase Studio itself — no external Studio
            API lists them.
        termBases:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: >-
            Term base ids per language code. Term bases belong to a connected
            TMS, not Phrase Studio itself — no external Studio API lists them.
    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

````