Translating Text and Subtitles

This guide translates text and WebVTT subtitles with the translation API. It runs on GPUs, supports 200 languages and costs $1 per million characters per target language. Only finished translations are charged.

Base URL: https://api.mamutecloud.com. Every call uses your organization API key in the Authorization header, without Bearer:

Authorization: mamute-...

Before you start

  • Create an API key (see Authentication) and store it as MAMUTECLOUD_API_KEY.
  • Translation is paid from your paid balance or with auto-recharge. The free signup credit does not apply. Check what is available with GET /v1/translations/balance.

1. Translate text

curl -X POST https://api.mamutecloud.com/v1/translations \
  -H "Authorization: $MAMUTECLOUD_API_KEY" \
  -H "content-type: application/json" \
  -d '{"text": "Olá, tudo bem? Hoje vamos falar de vendas.", "source": "pt", "targets": ["en", "es"]}'

The call waits up to about 20 seconds:

  • 200 with "status": "done": the translations are already in the response.
  • 202 with "status": "queued" or "processing": keep the id and read the result later (step 4), or use a webhook (step 5).

Add ?wait=false to always answer at once.

Line breaks are kept: each line comes back as one line, translated sentence by sentence. Up to 500,000 characters per request.

2. Translate subtitles

Send a WebVTT file as vtt. The result is WebVTT with the same cues and the same timings:

curl -X POST https://api.mamutecloud.com/v1/translations \
  -H "Authorization: $MAMUTECLOUD_API_KEY" \
  -H "content-type: application/json" \
  -d "$(jq -n --rawfile vtt class-01.vtt '{vtt: $vtt, source: "pt", targets: ["en"]}')"
  • Cues that split a sentence are translated together, and the translated text is spread back over them in proportion to the original, cutting between words.
  • Voice and style tags (<v Ana>, <i>) are not kept; translated cues are plain text.
  • Up to 1,000,000 characters of WebVTT per request.

3. Or translate a transcript you already made

Pass the id of a finished transcript from the transcription API. The source language comes from the transcript and the result is WebVTT:

curl -X POST https://api.mamutecloud.com/v1/translations \
  -H "Authorization: $MAMUTECLOUD_API_KEY" \
  -H "content-type: application/json" \
  -d '{"transcriptId": "6c0338e1-4d91-41ae-9735-e678d0df36a4", "targets": ["en", "es"]}'

The transcript must belong to your organization and still be available (7 days after it ended).

4. Read the result

curl https://api.mamutecloud.com/v1/translations/$TRANSLATION_ID \
  -H "Authorization: $MAMUTECLOUD_API_KEY"
{
  "data": {
    "id": "b1a50bd9-e409-4874-8882-f26f57a51fb7",
    "status": "done",
    "format": "text",
    "source": "pt",
    "targets": ["en", "es"],
    "characters": 102,
    "billedCharacters": 204,
    "translations": [
      { "language": "en", "format": "text", "content": "Hey, you all right? Today we're going to talk about sales.", "url": "https://..." },
      { "language": "es", "format": "text", "content": "¿Qué pasa? Hoy hablaremos de ventas.", "url": "https://..." }
    ],
    "expiresAt": "2026-10-21T19:16:24.023Z"
  }
}
  • content comes inline while all translations together are up to 4 MB; url is always there.
  • url is signed for 1 hour. Ask again for fresh links.
  • Results are deleted 7 days after the translation ends (expiresAt). Text is never used to train models.

5. Get notified with a webhook

Send webhookUrl when you create the translation. When it ends, MamuteCloud sends a POST to it:

{ "data": { "id": "b1a50bd9-...", "status": "done" } }

A delivery that fails is retried up to 7 more times over about 7 hours and 40 minutes. Each request carries the attempt number in the X-Mamute-Webhook-Attempt header. Fetch the full result with GET /v1/translations/{id} when it arrives.

Languages

Use ISO 639-1 codes such as pt, en or es (pt-BR is read as pt, zh-TW as Traditional Chinese), or any of the 202 FLORES-200 codes of the model, such as por_Latn. GET /v1/translations/languages lists every accepted code.

  • source is required for text and vtt.
  • Up to 10 targets per request, none equal to the source.

Quality is measured on a public test set, on Portuguese, English and Spanish among others. See Translation Quality for the numbers and the method.

Pricing and balance

Price$1 per million characters ($0.000001 per character)
Uniteach character of the source text, once per target language
Charged whenthe translation is done; failed translations cost nothing
Pays withpaid balance or auto-recharge (not the signup credit)

Characters are counted on the source: spaces count, and in WebVTT only the cue text counts, not timings or tags. billedCharacters is characters times the number of targets. An hour of speech has about 54,000 characters, so subtitling it into one language costs about $0.05.

Before the translation runs, its price is held from your balance. If the balance cannot cover it, the translation ends in error with a message starting with insufficient_balance: and nothing is charged. Without any paid balance or auto-recharge, POST /v1/translations answers 402.

curl https://api.mamutecloud.com/v1/translations/balance -H "Authorization: $MAMUTECLOUD_API_KEY"
# -> { "data": { "totalUsd": 27.98, "reservedUsd": 0.0002, "availableUsd": 27.9798, "autoRecharge": true } }

List and monitor

# Newest first; page with ?before=<nextBefore>
curl "https://api.mamutecloud.com/v1/translations?status=failed&limit=50" -H "Authorization: $MAMUTECLOUD_API_KEY"

# This month's characters, requests and spend, characters per day, and health
curl "https://api.mamutecloud.com/v1/translations/analytics?days=30" -H "Authorization: $MAMUTECLOUD_API_KEY"

Errors

StatusWhen
400invalid body: none or more than one of text/vtt/transcriptId, missing source, unknown language, a target equal to the source, more than 10 targets, input over the limit
401missing or invalid API key (remember: no Bearer before mamute-)
402no paid balance and no auto-recharge
404the translation (or the transcript) does not belong to your organization

Timing

A short text comes back in a few seconds, and an hour of subtitles in about 10 seconds per target language. When nobody has translated anything for an hour the GPUs are turned off, so the first request after a quiet period waits about 5 extra minutes while they start.

Known limits

  • No glossary. Names and terms that must not be translated cannot be pinned yet.
  • Japanese and Chinese are weaker than the European languages (see Translation Quality).

Full reference: Translation API.


Did this page help you?