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

# Translation

> Translate text into another language with formality, gender, age, and domain customization using the Python or TypeScript SDK

## Overview

Translate an array of text segments from one language into another with fine-grained control over tone (`formality`), grammatical `gender`, audience `age`, and domain-specific terminology (`chosen_dictionaries`). Translation is ideal for localizing user content, documents, support replies, marketing copy, or any batch of strings that needs to read naturally in another language.

The translation pipeline is asynchronous: you submit a job with one or more texts, poll until it completes, then retrieve the translations in the same order as the inputs.

### Prerequisites

<Steps>
  <Step title="Create an account">
    Sign up at [CAMB.AI Studio](https://studio.camb.ai) if you haven't already.
  </Step>

  <Step title="Get your API key">
    Go to **Settings → API Keys** in Studio and copy your key. See [Authentication](/getting-started/authentication) for details.
  </Step>

  <Step title="Install the SDK">
    <CodeGroup>
      ```bash Python theme={null}
      pip install camb-sdk
      ```

      ```bash TypeScript theme={null}
      npm install @camb-ai/sdk
      ```
    </CodeGroup>

    Skip this step if you're using the [direct API](/tutorials/direct-api).
  </Step>

  <Step title="Set your API key to use in your code">
    ```bash theme={null}
    export CAMB_API_KEY="your_api_key_here"
    ```
  </Step>
</Steps>

***

## Code

<CodeGroup>
  ```python Python theme={null}
  import os
  import time
  from camb.client import CambAI
  from camb.types.language_enums import Languages

  client = CambAI(api_key=os.getenv("CAMB_API_KEY"))

  def translate_texts():
      source_texts = [
          "Thank you for your inquiry about our services.",
          "We would be happy to schedule a meeting next week.",
          "Please let us know what day works best for you.",
      ]

      # Step 1: Submit the translation job
      response = client.translation.create_translation(
          texts=source_texts,
          source_language=Languages.EN_US,   # English (US)
          target_language=Languages.ES_ES,   # Spanish (Spain)
          formality=1,          # Formal
          gender=1,             # Masculine grammatical forms when relevant
          age=30,
      )

      task_id = response.task_id
      print(f"Translation task created: {task_id}")

      # Step 2: Poll until complete
      while True:
          status = client.translation.get_translation_task_status(task_id=task_id)
          print(f"Status: {status.status}")

          if status.status == "SUCCESS":
              # Step 3: Retrieve the translated texts
              result = client.translation.get_translation_result(run_id=status.run_id)
              for src, dst in zip(source_texts, result.texts):
                  print(f"EN: {src}\nES: {dst}\n---")
              break
          elif status.status in ("ERROR", "TIMEOUT", "PAYMENT_REQUIRED"):
              print(f"Translation failed: {status.status}")
              break

          time.sleep(2)

  translate_texts()
  ```

  ```javascript TypeScript theme={null}
  import { CambClient, CambApi } from '@camb-ai/sdk';

  const client = new CambClient({
      apiKey: process.env.CAMB_API_KEY
  });

  async function translateTexts() {
      const sourceTexts = [
          'Thank you for your inquiry about our services.',
          'We would be happy to schedule a meeting next week.',
          'Please let us know what day works best for you.'
      ];

      // Step 1: Submit the translation job
      const response = await client.translation.createTranslation({
          texts: sourceTexts,
          source_language: CambApi.Languages.EN_US,  // English (US)
          target_language: CambApi.Languages.ES_ES,  // Spanish (Spain)
          formality: 1,         // Formal
          gender: 1,            // Masculine grammatical forms when relevant
          age: 30
      });

      const taskId = response.task_id;
      console.log(`Translation task created: ${taskId}`);

      // Step 2: Poll until complete
      while (true) {
          const status = await client.translation.getTranslationTaskStatus({
              task_id: taskId
          });

          console.log(`Status: ${status.status}`);

          if (status.status === 'SUCCESS') {
              // Step 3: Retrieve the translated texts
              const result = await client.translation.getTranslationResult({
                  run_id: status.run_id
              });

              sourceTexts.forEach((src, i) => {
                  console.log(`EN: ${src}\nES: ${result.texts[i]}\n---`);
              });
              break;
          } else if (['ERROR', 'TIMEOUT', 'PAYMENT_REQUIRED'].includes(status.status)) {
              console.error(`Translation failed: ${status.status}`);
              break;
          }

          await new Promise(resolve => setTimeout(resolve, 2000));
      }
  }

  translateTexts();
  ```
</CodeGroup>

***

## Customization options

### Formality

Adjust the formality level to fit the context. This affects pronoun choice (e.g. `tú` vs `usted` in Spanish, `du` vs `Sie` in German) and overall register.

| Value | Meaning  | Best for                                                      |
| ----- | -------- | ------------------------------------------------------------- |
| `1`   | Formal   | Business communications, official documents, customer support |
| `2`   | Informal | Casual chat, social posts, friendly marketing                 |

### Gender

In many target languages, adjectives, articles, and past participles agree with gender. Use the `gender` parameter to tell the engine which grammatical forms to prefer.

| Value | Meaning               |
| ----- | --------------------- |
| `0`   | Unspecified / neutral |
| `1`   | Masculine forms       |
| `2`   | Feminine forms        |
| `9`   | Other                 |

### Age

Pass an integer (e.g. `12`, `30`, `65`) to bias vocabulary and idioms toward an audience age range. Useful when translating content meant for kids or for very formal/elder audiences.

### Chosen dictionaries

Pass an array of dictionary IDs via `chosen_dictionaries` to apply specialized vocabulary (medical, legal, technical, etc.). Manage your dictionaries with the [Dictionaries API](/api-reference/endpoint/list-dictionaries).

***

## Parameters

### Required

| Parameter         | Type             | Description                                                                                                                                      |
| ----------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `texts`           | string\[]        | Array of text segments to translate. Each item is translated independently and returned in the same order.                                       |
| `source_language` | `Languages` enum | Source language (e.g. `Languages.EN_US`). The raw API also accepts locale-tag strings like `"en-us"`; numeric IDs still work but are deprecated. |
| `target_language` | `Languages` enum | Target language (e.g. `Languages.ES_ES`).                                                                                                        |

### Optional

| Parameter             | Type       | Description                                                      |
| --------------------- | ---------- | ---------------------------------------------------------------- |
| `formality`           | integer    | `1` for formal, `2` for informal                                 |
| `gender`              | integer    | Grammatical gender hint: `0`, `1`, `2`, or `9` (see table above) |
| `age`                 | integer    | Target audience age, used to adapt vocabulary                    |
| `chosen_dictionaries` | integer\[] | Dictionary IDs to apply specialized vocabulary                   |
| `project_name`        | string     | Label for the job in your dashboard                              |
| `project_description` | string     | Additional notes for the job                                     |
| `folder_id`           | integer    | Place the run inside a specific folder                           |

### Result shape

`get_translation_result` returns a `TranslationResult` with a single field:

| Field   | Type      | Description                                                                                              |
| ------- | --------- | -------------------------------------------------------------------------------------------------------- |
| `texts` | string\[] | Translated outputs, in the same order as the input `texts`. Pair index-by-index with the original array. |

***

## Languages

Translation requires both a `source_language` and a `target_language`. The Python and TypeScript SDKs expect the `Languages` enum:

| Language         | Enum              | Locale (raw API) |
| ---------------- | ----------------- | ---------------- |
| English (US)     | `Languages.EN_US` | `en-us`          |
| Spanish (Spain)  | `Languages.ES_ES` | `es-es`          |
| French (France)  | `Languages.FR_FR` | `fr-fr`          |
| German (Germany) | `Languages.DE_DE` | `de-de`          |
| Mandarin Chinese | `Languages.ZH_CN` | `zh-cn`          |
| Japanese (Japan) | `Languages.JA_JP` | `ja-jp`          |
| Arabic           | `Languages.AR_SA` | `ar-sa`          |

If you're calling the API directly (not via the SDK), pass the locale tag. Numeric language IDs still work but are deprecated.

<CardGroup cols={2}>
  <Card icon="languages" href="/api-reference/endpoint/get-source-languages" arrow={true} cta="Source languages">
    Full list of supported source languages.
  </Card>

  <Card icon="globe" href="/api-reference/endpoint/get-target-languages" arrow={true} cta="Target languages">
    Full list of supported target languages.
  </Card>
</CardGroup>

***

## Tips

* **Batch in one call:** Pass multiple strings in a single `texts` array instead of submitting one task per string — it is faster and uses fewer credits.
* **Preserve order:** `result.texts[i]` always corresponds to `texts[i]` from the input. Pair them with `zip` (Python) or index-by-index access (TypeScript).
* **Polling cadence:** Translation is usually quick; a 1-2 second polling interval works well. Cap the total wait time (for example, 5 minutes) so your code never hangs forever.
* **Pick the right register:** Setting `formality` and `gender` on customer-facing translations dramatically improves how natural the output reads in languages like Spanish, French, German, and Italian.
* **Domain accuracy:** For medical, legal, or technical content, define a dictionary first and pass its ID in `chosen_dictionaries` so jargon is translated consistently across runs.

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Create Translation API" icon="book" href="/api-reference/endpoint/create-translation">
    Full API reference for the translation endpoint.
  </Card>

  <Card title="Poll Translation Status" icon="clock" href="/api-reference/endpoint/poll-translation-result">
    Status polling endpoint reference.
  </Card>

  <Card title="Get Translation Result" icon="languages" href="/api-reference/endpoint/get-translation-run-result">
    Retrieve the translated texts for a completed run.
  </Card>

  <Card title="Fetch Multiple Runs" icon="layers" href="/api-reference/endpoint/fetch-translation-runs-results">
    Batch-fetch results for several translation run IDs in one call.
  </Card>
</CardGroup>
