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

# Python SDK

> Install and use the Python SDK with sync and async clients for Python 3.9+

The official Python SDK for Camb.ai provides convenient access to text-to-speech, dubbing, translation, transcription, audio separation, voice cloning, and audio generation. It ships synchronous and asynchronous clients with streaming audio helpers and typed language enums.

## Installation

```bash theme={null}
pip install camb-sdk
```

Requires Python 3.9 or later.

***

## Authentication

Get your API key from [Camb.ai Studio](https://studio.camb.ai) and set it as an environment variable. The client reads it via `os.getenv("CAMB_API_KEY")` so your key never has to appear in source code.

The SDK ships two clients. Use `CambAI` for scripts, data pipelines, and anything thread-managed. Use `AsyncCambAI` for web servers (FastAPI, Sanic) and high-concurrency applications where blocking would hurt throughput.

```python theme={null}
import os
from camb.client import CambAI, AsyncCambAI

# Synchronous — for scripts and data pipelines
client = CambAI(api_key=os.getenv("CAMB_API_KEY"))

# Asynchronous — for web servers and high-concurrency applications
async_client = AsyncCambAI(api_key=os.getenv("CAMB_API_KEY"))
```

***

## Quick Start

The quickest way to get started is streaming TTS audio directly to a file. `tts()` returns a byte iterator that `save_stream_to_file` writes in one call:

```python theme={null}
import os
from camb.client import CambAI, save_stream_to_file

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

stream = client.text_to_speech.tts(
    text="Hello from Camb.ai.",
    language="en-us",
    voice_id=147320,
    speech_model="mars-flash",
)
save_stream_to_file(stream, "output.wav")
```

For async applications, use `AsyncCambAI` and `save_async_stream_to_file`. The interface is identical to the sync client:

```python theme={null}
import asyncio
import os
from camb.client import AsyncCambAI, save_async_stream_to_file

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

async def main():
    stream = client.text_to_speech.tts(
        text="Hello from Camb.ai.",
        language="en-us",
        voice_id=147320,
        speech_model="mars-flash",
    )
    await save_async_stream_to_file(stream, "output.wav")

asyncio.run(main())
```

***

## Models

Camb.ai offers MARS models tuned for different quality and latency requirements. Pass the model name as `speech_model` in any TTS call. If you omit it, the API uses a default model.

| Model                 | Sample Rate | Best For                                                                     |
| --------------------- | ----------- | ---------------------------------------------------------------------------- |
| `mars-8.1-flash-beta` | 48 kHz      | Faster MARS 8.1 generation; same quality improvements as `mars-8.1-pro-beta` |
| `mars-8.1-pro-beta`   | 48 kHz      | Improved pronunciation, expressiveness, and prosody over `mars-pro`          |
| `mars-flash`          | 22.05 kHz   | Low-latency real-time applications and conversational AI                     |
| `mars-pro`            | 48 kHz      | High-fidelity audio production and long-form content                         |
| `mars-instruct`       | 22.05 kHz   | Fine-grained tone and style control via text instructions                    |

<Tabs>
  <Tab title="MARS Flash">
    ```python theme={null}
    stream = client.text_to_speech.tts(
        text="Hey, I can respond much faster.",
        language="en-us",
        voice_id=147320,
        speech_model="mars-flash",
    )
    ```

    **Best for:** Voice agents, real-time applications

    **Sample rate:** 22.05 kHz
  </Tab>

  <Tab title="MARS Pro">
    ```python theme={null}
    stream = client.text_to_speech.tts(
        text="High-fidelity audio for production use.",
        language="en-us",
        voice_id=147320,
        speech_model="mars-pro",
    )
    ```

    **Best for:** Audio production, dubbing, long-form content

    **Sample rate:** 48 kHz
  </Tab>

  <Tab title="MARS Instruct">
    ```python theme={null}
    stream = client.text_to_speech.tts(
        text="[warm, friendly] Great to meet you!",
        language="en-us",
        voice_id=147320,
        speech_model="mars-instruct",
        user_instructions="Speak warmly and with enthusiasm.",
    )
    ```

    **Best for:** Fine-grained control over tone and delivery

    **Sample rate:** 22.05 kHz
  </Tab>
</Tabs>

***

## Voices

### List Voices

Call `list_voices()` to retrieve all voices available on your account, including pre-built library voices and any custom voices you have created. The `id` field is what you pass as `voice_id` in TTS calls.

```python theme={null}
import os
from camb.client import CambAI

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

voices = client.voice_cloning.list_voices()
for voice in voices:
    print(f"ID: {voice['id']}  Name: {voice['voice_name']}  Gender: {voice['gender']}")
```

### Create a Custom Voice

To clone a voice, upload a short reference audio sample alongside a name and gender. Setting `enhance_audio=True` applies preprocessing that improves cloning quality on recordings with background noise.

```python theme={null}
import os
from camb.client import CambAI

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

with open("reference.wav", "rb") as f:
    result = client.voice_cloning.create_custom_voice(
        voice_name="My Custom Voice",
        gender="female",
        file=f,
        description="Warm and conversational.",
        enhance_audio=True,
    )

print(f"Voice created: {result}")
```

***

## Language Support

Camb.ai supports up to 158 languages depending on the MARS model — see [Language Support](/language-support) for the full per-model locale list. You can pass locale strings directly, but using the `Languages` enum is recommended because it provides autocomplete in your editor and prevents typos in language codes.

```python theme={null}
from camb.types.language_enums import Languages

print(Languages.EN_US)   # en-us
print(Languages.HI_IN)   # hi-in
print(Languages.FR_FR)   # fr-fr
print(Languages.DE_DE)   # de-de
print(Languages.JA_JP)   # ja-jp
```

To fetch the full list of supported languages at runtime, use the `languages` sub-client. Source languages are what you can transcribe or translate from; target languages are what you can translate or dub into.

```python theme={null}
import os
from camb.client import CambAI

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

source_languages = client.languages.get_source_languages()
target_languages = client.languages.get_target_languages()

for lang in source_languages:
    print(lang)
```

Languages supported per model are listed at [MARS Models](/models).

***

## Dubbing

The dubbing pipeline takes a publicly accessible video URL, translates the audio track into your target language, and synthesizes speech using a clone of the original speaker's voice. Dubbing is asynchronous: you submit the job, poll for completion, and then fetch the result.

```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"))

response = client.dub.create_dub(
    video_url="https://example.com/video.mp4",
    source_language=Languages.EN_US,
    target_language=Languages.HI_IN,
)

while True:
    status = client.dub.get_dubbing_status(task_id=response.task_id)
    if status.status == "SUCCESS":
        result = client.dub.get_dubbed_run_info(status.run_id)
        print(f"Video: {result.video_url}")
        print(f"Audio: {result.audio_url}")
        break
    time.sleep(5)
```

To dub into multiple languages in a single job, replace `target_language` with the `target_languages` list:

```python theme={null}
response = client.dub.create_dub(
    video_url="https://example.com/video.mp4",
    source_language=Languages.EN_US,
    target_languages=[Languages.HI_IN, Languages.FR_FR, Languages.DE_DE],
)
```

### Get Transcript

Once a dubbing job completes, you can retrieve the full transcript for any target language using the `run_id` returned by `get_dubbing_status`.

```python theme={null}
transcript = client.dub.get_dubbed_run_transcript(
    run_id=status.run_id,
    language=Languages.HI_IN,
)
print(transcript)
```

***

## Translation

The translation API accepts a list of text strings and returns them translated into the target language in the same order. Like dubbing, translation is asynchronous. You submit a job and poll until the status reaches `SUCCESS`.

```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"))

response = client.translation.create_translation(
    texts=["Hello, how are you?", "Welcome to Camb.ai."],
    source_language=Languages.EN_US,
    target_language=Languages.FR_FR,
)

while True:
    status = client.translation.get_translation_task_status(task_id=response["task_id"])
    if status.status == "SUCCESS":
        result = client.translation.get_translation_result(run_id=status.run_id)
        for text in result.texts:
            print(text)
        break
    time.sleep(2)
```

<Note>
  `create_translation` accepts a list of strings under `texts`. All strings are translated in a single job and returned in order.
</Note>

***

## Transcription

Submit an audio or video file for transcription and retrieve the result once processing completes. You can pass a remote URL via `media_url` or upload a local file via `media_file`. The result supports optional word-level timestamps.

```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"))

response = client.transcription.create_transcription(
    language=Languages.EN_US,
    media_url="https://example.com/audio.mp3",
)

while True:
    status = client.transcription.get_transcription_task_status(task_id=response.task_id)
    if status.status == "SUCCESS":
        result = client.transcription.get_transcription_result(
            run_id=status.run_id,
            word_level_timestamps=True,
        )
        print(result)
        break
    time.sleep(3)
```

To transcribe a local file rather than a URL, open it in binary mode and pass it via `media_file`:

```python theme={null}
with open("audio.mp3", "rb") as f:
    response = client.transcription.create_transcription(
        language=Languages.EN_US,
        media_file=f,
    )
```

***

## Audio Separation

Audio separation splits a mixed audio track into its vocal and background components. After the job completes, the result contains separate download URLs for each stem so you can use them independently.

```python theme={null}
import os
import time
from camb.client import CambAI

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

with open("track.mp3", "rb") as f:
    response = client.audio_separation.create_audio_separation(media_file=f)

while True:
    status = client.audio_separation.get_audio_separation_status(task_id=response.task_id)
    if status.status == "SUCCESS":
        result = client.audio_separation.get_audio_separation_run_info(run_id=status.run_id)
        print(result)
        break
    time.sleep(3)
```

***

## Text-to-Voice

Text-to-Voice creates a brand-new synthetic voice from a written description of the desired vocal characteristics. The API generates several audio samples so you can audition variations before deciding which voice ID to use in production.

```python theme={null}
import os
import time
from camb.client import CambAI

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

response = client.text_to_voice.create_text_to_voice(
    text="A confident narrator introducing a documentary.",
    voice_description="Deep, measured baritone with a slight gravel. Calm and authoritative.",
)

while True:
    status = client.text_to_voice.get_text_to_voice_status(task_id=response.task_id)
    if status.status == "SUCCESS":
        result = client.text_to_voice.get_text_to_voice_result(run_id=status.run_id)
        print(result)
        break
    time.sleep(3)
```

<Note>
  The result contains multiple sample audio URLs. Preview them and use the `voice_id` of your preferred sample with `client.text_to_speech.tts`.
</Note>

***

## Text-to-Audio

Text-to-Audio generates sound effects or ambient soundscapes from a descriptive text prompt. The job is asynchronous, and the result is a streamable audio file you can save with `save_stream_to_file` once processing completes.

```python theme={null}
import os
import time
from camb.client import CambAI, save_stream_to_file

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

response = client.text_to_audio.create_text_to_audio(
    prompt="Heavy rain on a tin roof at night with distant thunder.",
    duration=15,
    audio_type="sound",
)

while True:
    status = client.text_to_audio.get_text_to_audio_status(task_id=response.task_id)
    if status.status == "SUCCESS":
        stream = client.text_to_audio.get_text_to_audio_result(run_id=status.run_id)
        save_stream_to_file(stream, "soundscape.mp3")
        print("Saved to soundscape.mp3")
        break
    time.sleep(3)
```

***

## Stories

The Stories API takes a document file, structures its content into a narrative, and returns a fully narrated audio output. You can provide a custom narrator voice ID; if omitted, the API selects a default voice appropriate for the source language.

```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"))

with open("story.pdf", "rb") as f:
    response = client.story.create_story(
        file=f,
        source_language=Languages.EN_US,
        title="My Story",
    )

while True:
    status = client.story.get_story_status(task_id=response.task_id)
    if status.status == "SUCCESS":
        result = client.story.get_story_run_info(run_id=status.run_id)
        print(result)
        break
    time.sleep(5)
```

***

## Translated TTS

Translated TTS combines translation and speech synthesis into a single asynchronous job. The text is translated into the target language and then spoken using the voice you specify, without needing to run translation and TTS as separate steps.

```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"))

response = client.translated_tts.create_translated_tts(
    text="Good morning, welcome to our service.",
    voice_id=147320,
    source_language=Languages.EN_US,
    target_language=Languages.HI_IN,
)

while True:
    status = client.translated_tts.get_translated_tts_task_status(task_id=response.task_id)
    if status.status == "SUCCESS":
        print(status)
        break
    time.sleep(3)
```

***

## Dictionaries

Dictionaries contain custom term mappings that the API applies automatically when running dubbing or translation jobs. They are particularly useful for brand names, product terminology, and proper nouns that need consistent handling across languages.

### List Dictionaries

Call `get_dictionaries()` to retrieve all dictionaries on your account along with their metadata:

```python theme={null}
import os
from camb.client import CambAI

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

dictionaries = client.dictionaries.get_dictionaries()
for d in dictionaries:
    print(f"{d.id}: {d.name}")
```

### Create from File

Upload a CSV file to create a new dictionary. The file should contain source and target term pairs in a format the API expects:

```python theme={null}
with open("terms.csv", "rb") as f:
    client.dictionaries.create_dictionary_from_file(
        dictionary_file=f,
        dictionary_name="Product Terms",
        dictionary_description="Brand-specific terminology for our product line.",
    )
```

### Manage Terms

Use `add_term_to_dictionary` to insert individual term translations and `delete_dictionary_term` to remove them by ID. Each term takes a `source`, a `target`, and the language the target is in:

```python theme={null}
from camb.types import TermTranslationInput

# Add a term
client.dictionaries.add_term_to_dictionary(
    dictionary_id="dict_123",
    translations=[
        TermTranslationInput(source="Camb.ai", target="कैम्ब.एआई", language="hi-in")
    ],
)

# Delete a term
client.dictionaries.delete_dictionary_term(
    dictionary_id="dict_123",
    term_id="term_456",
)

# Delete the dictionary
client.dictionaries.delete_dictionary(dictionary_id="dict_123")
```

***

## Custom Provider

If you are running MARS on your own infrastructure through Baseten, you can initialize the client with a provider configuration instead of a Camb.ai API key. See [Custom Cloud Providers](/custom-cloud-providers) for deployment instructions.

### Baseten

Deploy the MARS model to your Baseten account, then point the client at your deployment URL. Baseten calls require a base64-encoded reference audio sample to be passed with every request:

```python theme={null}
import base64
import os
from camb.client import CambAI, save_stream_to_file

client = CambAI(
    tts_provider="baseten",
    provider_params={
        "api_key": os.getenv("BASETEN_API_KEY"),
        "mars_pro_url": "https://model-xxxxxx.api.baseten.co/environments/production/predict",
    },
)

with open("reference.wav", "rb") as f:
    reference_audio = base64.b64encode(f.read()).decode("utf-8")

stream = client.text_to_speech.tts(
    text="Hello from a self-hosted MARS deployment.",
    language="en-us",
    speech_model="mars-pro",
    request_options={
        "additional_body_parameters": {
            "reference_audio": reference_audio,
            "reference_language": "en-us",
        },
        "timeout_in_seconds": 300,
    },
)
save_stream_to_file(stream, "output.mp3")
```

<Note>
  Baseten deployments require `reference_audio` (base64-encoded WAV) and `reference_language` in `additional_body_parameters`.
</Note>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Voice Agents" icon="https://mintcdn.com/cambai/2LvnefIkletroPxv/images/pipecat-orange.svg?fit=max&auto=format&n=2LvnefIkletroPxv&q=85&s=40cf8e001b8cadc8a4c3c557dea603d5" href="/integrations/pipecat" width="24" height="24" data-path="images/pipecat-orange.svg">
    Build real-time voice agents with Pipecat
  </Card>

  <Card title="LiveKit Integration" icon="https://mintcdn.com/cambai/2LvnefIkletroPxv/images/livekit-orange.svg?fit=max&auto=format&n=2LvnefIkletroPxv&q=85&s=c750fcee9b1de69e3c1d0d6ec7eb6b3f" href="/integrations/livekit" width="24" height="24" data-path="images/livekit-orange.svg">
    Create voice agents with LiveKit
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/endpoint/create-tts-stream">
    Explore the full TTS API
  </Card>

  <Card title="Voice Library" icon="speech" href="/api-reference/endpoint/list-voices">
    Browse available voices
  </Card>
</CardGroup>

***

## Resources

* [GitHub: camb-ai/cambai-python-sdk](https://github.com/camb-ai/cambai-python-sdk)
* [SDK Examples](https://github.com/camb-ai/cambai-python-sdk/tree/main/examples)
* [API Reference](/api-reference/endpoint/create-tts-stream)
