# Translation

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

Canonical: https://transcript1.com/docs/translation
Last updated: 2026-10-31

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.

```bash
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:

```bash
curl -X POST "https://api.transcript1.com/v1/transcriptions?wait=60" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -F file=@interview.m4a \
  -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:

```bash
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`:

```json
{
  "transcription_id": "tr_8fK2Lm0PqRsTuVwXyZaBcD",
  "language": "en",
  "status": "processing"
}
```

| Status | Meaning |
|---|---|
| `404` | The transcription was not found. |
| `409 transcript_not_ready` | The transcription is not `completed` yet. |
| `422` | The 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. 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`:

| `translation` | Result |
|---|---|
| `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. |
| `only` | The translated text replaces `text`. Timestamps and speakers stay the same. |
| `none` | The original transcript only. |

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

```json
{
  "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.

## Webhooks

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

| `type` | Sent when |
|---|---|
| `transcription.translation.completed` | The translation reached `completed`. |
| `transcription.translation.failed` | The translation reached `failed`. |

`data` is the transcription object plus `translation: { language, status, error }`. See [Webhooks](https://transcript1.com/docs/webhooks) for signatures and delivery rules.
