DocsTranslation

Translation

Translate a transcript into another language while you transcribe or later, and read bilingual or translated-only text, SRT and VTT.

transcript1 transcribes the media first, then translates the transcript text into one language of your choice. Translation is aligned per segment and keeps the original timestamps and speakers. It is text translation only: there is no dubbing and no translated audio.

Translation is free. It uses 0 minutes and appears in your usage history as a free "Translation" entry. Transcription minutes apply as usual, and a failed translation never fails or refunds the transcript.

Translate while transcribing

Add translate_to to the request that creates the transcription. It is a two-letter lowercase ISO 639-1 code such as es or en. It works with a video link in the JSON body of POST /v1/transcriptions, a chunked upload reservation and a one-shot multipart upload.

curl -X POST "https://api.transcript1.com/v1/transcriptions?wait=60" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "translate_to": "es"}'

For a file upload, send translate_to as a form field:

curl -X POST "https://api.transcript1.com/v1/transcriptions?wait=60" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -F [email protected] \
  -F translate_to=en

The MCP transcribe tool takes translate_to as well. One target language per request.

Translate an existing transcript

Request a translation for a completed transcription:

curl -X POST "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD/translations" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"language": "en"}'

The API answers 202:

{
  "transcription_id": "tr_8fK2Lm0PqRsTuVwXyZaBcD",
  "language": "en",
  "status": "processing"
}
StatusMeaning
404The transcription was not found.
409 transcript_not_readyThe transcription is not completed yet.
422The language is not a valid two-letter code.

The call is idempotent. A translation that is processing or completed is returned as it is, and a failed one is retried. Request another language to add it: a transcription keeps one translation per language. The MCP tool translate_transcription takes id and language.

Read the translation

GET /v1/transcriptions/:id and the text, SRT and VTT downloads accept translation:

translationResult
both (default)JSON segments get a translation field. Text puts the translated line under the original. SRT and VTT cues have two lines: the original, then the translation.
onlyThe translated text replaces text. Timestamps and speakers stay the same.
noneThe original transcript only.

The response has a translation object, or null when no translation was requested:

{
  "translation": { "language": "es", "status": "completed" }
}

status is processing, completed or failed. A failed translation also has an error message. wait also waits for a requested translation; when the wait times out, the status is processing. The MCP get_transcription tool takes a translation parameter with the same values.

To show the original transcript before its translation is ready, add wait_for=transcript. The wait then returns as soon as the transcription itself is finished, even while the translation is still processing:

curl "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD?wait=60&wait_for=transcript" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY"

The JSON is completed with the full original transcript, segments have no translation yet, and translation (and its entry in translations) is { "language": "es", "status": "processing" }. Show the original, then call again with the default wait_for=translation to wait for the translated text. Text, SRT and VTT give no sign that a translation is pending, so use JSON. Any other wait_for value returns 422 invalid_request.

Choose a language

A transcription can hold several translations, one per language. translation_language (a two-letter code) picks the one to read on GET /v1/transcriptions/:id and in the format downloads. The list endpoint returns translations for each item. Without it, the translate_to language of the request is used, then the most recently created translation. A language that was never translated returns 404 translation_not_found, and a malformed code returns 422.

The transcription object lists every translation in translations, oldest first. translation describes the selected one:

{
  "translations": [
    { "language": "de", "status": "completed" },
    { "language": "fr", "status": "processing" }
  ]
}

The MCP get_transcription tool takes translation_language too. In the dashboard, the download menu lets you choose Original only, one language only, or Both (bilingual).

Same language, no translation

If the transcript is already in the language you ask for, transcript1 does not translate it. The translation is completed at once, it is free like every translation, and no "Translation" entry appears in your usage history. It is marked same_as_source: true in translation, in its entry of translations, in the 202 answer of POST /v1/transcriptions/:id/translations and in the webhook:

{
  "transcription_id": "tr_8fK2Lm0PqRsTuVwXyZaBcD",
  "language": "en",
  "status": "completed",
  "same_as_source": true
}
  • The transcript's language is its detected language, or the language you asked for when none was detected. With auto and no detected language, the transcript is translated as usual.
  • Regional variants count as one language: a transcript in en-US is already in en, and one in pt-BR is in pt. Scripts do not: zh-Hans and zh-Hant still count as different.
  • Reads return the original segments. In JSON, each segment's translation is its own text. Text, SRT and VTT show each line once, as with translation=none.
  • same_as_source is sent only when it is true.

Live translation

Live transcription translates while people speak. Add translate_to to POST /v1/live/sessions, or translateTo to t1.live.start. Every subtitle line carries its original and its translation. A line already in the target language is not translated: its translation is its own text, marked same_language: true, and a session whose language equals translate_to translates nothing. A live session has one target language, and translation is free.

A saved live session becomes a normal transcription. Its transcript is then translated again as a whole into the session's language, so the saved translation is processing for a short while after the session ends. If the transcript is already in that language, its translation is completed at once with same_as_source: true instead. Add more languages to it with the endpoint in Translate an existing transcript once it is completed. See Translate live for how lines and translations become final.

Webhooks

Two events report translation results, in addition to transcription.completed and transcription.failed, which are unchanged:

typeSent when
transcription.translation.completedThe translation reached completed.
transcription.translation.failedThe translation reached failed.

data is the transcription object plus translation: { language, status, error }. A translation into the transcript's own language sends transcription.translation.completed right away, with same_as_source: true in data.translation. See Webhooks for signatures and delivery rules.

Updated November 8, 2026