Camb.ai Python SDK
The official Python SDK for interacting with Camb AI's powerful voice and audio generation APIs. Create expressive speech, unique voices, and rich soundscapes with just a few lines of Python.
✨ Features
- Dubbing: Dub your videos into multiple languages with voice cloning!
- Expressive Text-to-Speech: Convert text into natural-sounding speech using a wide range of pre-existing voices.
- Generative Voices: Create entirely new, unique voices from text prompts and descriptions.
- Soundscapes from Text: Generate ambient audio and sound effects from textual descriptions.
- Transcripts & Subtitles: Create async transcription/subtitle jobs and export TXT, SRT, or VTT results as raw data or files.
- Live Transcription: Stream microphone or file audio over a WebSocket and receive cumulative interim transcripts, word-level timing, and typed events.
- Access to voice cloning, translation, and more (refer to full API documentation).
📦 Installation
Install the SDK using pip, ensure Python 3.9+:
pip install camb-sdk
Or through
pip install git+https://github.com/Camb-ai/cambai-python-sdk
🔑 Authentication & Accessing Clients
To use the Camb AI SDK, you'll need an API key. You can authenticate it by:
from camb.client import CambAI, AsyncCambAI
# The SDK automatically reads the CAMB_API_KEY environment variable:
# export CAMB_API_KEY=your_key_here
# client = CambAI()
# Or pass the key explicitly:
# Synchronous Client
client = CambAI(api_key="YOUR_CAMB_API_KEY")
# Asynchronous Client
async_client = AsyncCambAI(api_key="YOUR_CAMB_API_KEY")
Client with Specific MARS Pro Provider (e.g. Vertex, Baseten)
Baseten
To deploy the model go to models from baseten example: https://app.baseten.co/deploy/mars8-flash and deploy then perform setup like below
client_baseten = CambAI(
tts_provider="baseten",
provider_params={
"api_key": "YOUR_BASETEN_API_KEY",
"mars_url": "YOUR_BASETEN_URL"
}
)
# Call TTS with Baseten
client_baseten.text_to_speech.tts(
text="Hello World and my dear friends",
language="en-us",
speech_model="mars-flash",
request_options={
"additional_body_parameters": {
"reference_audio": base64.b64encode(open("audio.wav", "rb").read()).decode('utf-8'), # also support public/signed urls
"reference_language": "en-us" # required
},
"timeout_in_seconds": 300
}
)
Vertex Support (In Progress)
client_with_provider = CambAI(
tts_provider="vertex",
provider_params={"project_id": "my-project", "location": "us-central1"}
)
🚀 Getting Started: Examples
NOTE: For more examples and full ready to run files refer to the examples/ directory.
1. Text-to-Speech (TTS)
Convert text into spoken audio using one of Camb AI's high-quality voices.
Supported Models & Sample Rates
| Model Name | Sample Rate | Description |
|---|---|---|
| mars-pro | 48kHz | High-fidelity, professional-grade speech synthesis. Ideal for long-form content and dubbing. |
| mars-8.1-pro-beta | 48kHz | Beta MARS Pro model. Try this model with the same source references, as it may perform much better for pronunciation, expressiveness with high-pitch references, overall prosody, accent control, and coverage. |
| mars-8.1-flash-beta | 48kHz | Beta MARS Pro model with faster speed. Try this model with the same source references, as it may perform much better for pronunciation, expressiveness with high-pitch references, overall prosody, accent control, and coverage. |
| mars-instruct | 22.05kHz | optimized for instruction-following and nuance control. |
| mars-flash | 22.05kHz | Low-latency model optimized for real-time applications and conversational AI. |
TTS request options
client.text_to_speech.tts(...) accepts the core request fields plus optional controls for model behavior and output format:
| Option | Description |
|---|---|
text |
Text to synthesize. For mars-instruct, you can include inline emotion or pacing tags. |
language |
BCP-47 locale such as en-us. |
voice_id |
Voice profile ID from client.voice_cloning.list_voices(). |
speech_model |
Model to use, such as mars-8.1-flash-beta, mars-pro, or mars-instruct. |
user_instructions |
Adds style, tone, pronunciation, or delivery guidance for the request. Available only with speech_model="mars-instruct". |
output_configuration |
Output settings such as audio format. |
voice_settings |
Voice behavior controls such as speaking rate, reference enhancement, or accent preservation. |
inference_options |
Advanced generation controls for supported models. |
enhance_named_entities_pronunciation |
Improves pronunciation for names and other named entities when supported. |
response = client.text_to_speech.tts(
text="[warm, friendly] Great to meet you!",
voice_id=147320,
language="en-us",
speech_model="mars-instruct",
user_instructions="Speak warmly and with enthusiasm.",
output_configuration=StreamTtsOutputConfiguration(format="wav"),
)
a) Get an Audio URL or Save to File
from camb.client import CambAI, save_stream_to_file
from camb.types.stream_tts_output_configuration import StreamTtsOutputConfiguration
# Initialize client (ensure API key is set)
client = CambAI(api_key="YOUR_CAMB_API_KEY")
response = client.text_to_speech.tts(
text="Hello from Camb AI! This is a test of our Text-to-Speech API.",
voice_id=20303, # Example voice ID, get from client.voice_cloning.list_voices()
language="en-us",
speech_model="mars-8.1-flash-beta", # options: mars-pro, mars-8.1-pro-beta, mars-flash, mars-instruct, auto
output_configuration=StreamTtsOutputConfiguration(
format="mp3"
)
)
save_stream_to_file(response, "tts_output.mp3")
print("Success! Audio saved to tts_output.mp3")
b) Async Text-to-Speech
You can also stream audio asynchronously using AsyncCambAI.
import asyncio
from camb.client import AsyncCambAI, save_async_stream_to_file
from camb.types.stream_tts_output_configuration import StreamTtsOutputConfiguration
async_client = AsyncCambAI(api_key="YOUR_CAMB_API_KEY")
async def main():
response = async_client.text_to_speech.tts(
text="Hello, this is a test of the text to audio streaming capabilities.",
language="en-us",
speech_model="mars-8.1-flash-beta", # options: mars-pro, mars-8.1-pro-beta, mars-flash, mars-instruct, auto
voice_id=147319,
output_configuration=StreamTtsOutputConfiguration(
format="mp3"
)
)
await save_async_stream_to_file(response, "text_to_audio_output.mp3")
print("Success! Audio saved to text_to_audio_output.mp3")
asyncio.run(main())
c) Using Mars Flash (Low Latency)
For applications requiring faster responses, make sure you're using mars-flash (22.05kHz).
response = client.text_to_speech.tts(
text="Hey! I can respond much faster.",
language="en-us",
speech_model="mars-flash",
voice_id=<id>,
output_configuration=StreamTtsOutputConfiguration(
format="wav"
)
)
d) List Available Voices
You can list available voices to find a voice_id that suits your needs:
voices = client.voice_cloning.list_voices()
print(f"Found {len(voices)} voices:")
for voice in voices[:5]: # Print first 5 as an example
print(f" - ID: {voice["id"]}, Name: {voice["voice_name"]}, Gender: {voice["gender"]}, Language: {voice["language"]}")
2. Text-to-Voice (Generative Voice)
Create completely new and unique voices from a textual description of the desired voice characteristics.
from camb.client import CambAI
# Initialize client
client = CambAI(api_key="YOUR_CAMB_API_KEY")
try:
print("Generating a new voice and speech...")
# Returns 3 sample URLs
result = client.text_to_voice.create_text_to_voice(
text="Crafting a truly unique and captivating voice that carries a subtle air of mystery, depth, and gentle warmth.",
voice_description="A smooth, rich baritone voice layered with a soft echo, ideal for immersive storytelling and emotional depth.",
)
print(result)
except Exception as e:
print(f"Exception when calling text_to_voice: {e}\n")
3. Text-to-Audio (Sound Generation)
Generate sound effects or ambient audio from a descriptive prompt.
from camb.client import save_stream_to_file
import time
response = client.text_to_audio.create_text_to_audio(
prompt="A gentle breeze rustling through autumn leaves in a quiet forest.",
duration=10,
audio_type="sound"
)
task_id = response.task_id
if task_id:
while True:
status = client.text_to_audio.get_text_to_audio_status(task_id=task_id)
if status.status == "SUCCESS":
result = client.text_to_audio.get_text_to_audio_result(status.run_id)
save_stream_to_file(result, "sound_effect.mp3")
print("Success! Sound effect saved to sound_effect.mp3")
break
time.sleep(2)
4. End-to-End Dubbing
Dub videos into different languages with voice cloning and translation capabilities. transcription_mode defaults to fast; pass "slow" when you want a more thorough transcription pass.
from camb.types.language_enums import Languages
result = client.dub.create_dub(
video_url="your_accessible_video_url",
source_language=Languages.EN_US, # English (Or Check client.languages.get_source_languages())
target_languages=[Languages.HI_IN], # list of Languages like [Languages.HI_IN, Languages.FR_FR] or if you want single language then can use target_language=Languages.HI_IN
transcription_mode="fast", # fast (default) or slow for a more thorough transcription pass
)
task_id = result.task_id
print(f"Dub Task created with ID: {task_id}")
while True:
status_response = client.dub.get_dubbing_status(task_id=task_id)
print(f"Current Status: {status_response.status}")
if status_response.status == "SUCCESS":
dubbed_run_info = client.dub.get_dubbed_run_info(status_response.run_id)
print(f"Dubbed Video URL: {dubbed_run_info.audio_url}")
print(f"Transcript: {dubbed_run_info.transcript}")
print(f"Video URL: {dubbed_run_info.video_url}")
break
time.sleep(5)
Use your own SRT transcript or translation
Pass SRT file contents in source_transcript and/or target_transcripts:
from pathlib import Path
from camb import DubSRTInput, DubTargetSRTInput
from camb.client import CambAI
from camb.types.language_enums import Languages
client = CambAI() # reads CAMB_API_KEY
result = client.dub.create_dub(
video_url="https://example.com/video.mp4",
source_language=Languages.EN_US,
target_languages=[Languages.ES_ES],
source_transcript=DubSRTInput(
content=Path("original.srt").read_text(encoding="utf-8"),
),
target_transcripts=[
DubTargetSRTInput(
language=Languages.ES_ES,
content=Path("spanish.srt").read_text(encoding="utf-8"),
)
],
)
print(result.task_id)
Plain dictionaries also work: source_transcript={"format": "srt", "content": srt_text}
and target_transcripts=[{"language": Languages.ES_ES, "format": "srt", "content": translated_srt}].
format defaults to "srt". Send the text itself, not a filename, URL, base64
string, or segment array. Translation languages accept locale tags or numeric IDs.
Both fields are optional. The same arguments work with AsyncCambAI.dub.create_dub
and the sync/async raw method dub.with_raw_response.end_to_end_dubbing.
Omitting the fields preserves the automatic dubbing flow.
The API parses SRT with the srt library, requires at least one parsed cue, and
enforces 2 MiB UTF-8 per script, 10 MiB combined, and at most 100 target scripts.
Translation languages must be unique and among the requested targets. Overlapping
and out-of-order cues are accepted; the SDK adds no cue-level checks. Server
validation failures raise camb.errors.UnprocessableEntityError with status 422
and the API's field details in exception.body.detail.
5. Live Transcription (Streaming WebSocket)
Stream audio over a single WebSocket and receive cumulative interim
transcripts, word-level timing, and typed events. The session exposes a
microphone helper, a file source for tests, and the same on(event)
dispatcher in both SDKs.
import asyncio
import os
from camb.client import CambAI
from camb.live_transcription import Microphone, ServerMessageType
async def main():
client = CambAI(api_key=os.environ["CAMB_API_KEY"])
session = await client.live_transcription.connect(
model="boli-v5",
language="en-us",
sample_rate=16000,
)
@session.on(ServerMessageType.RESULTS)
def _(msg):
# Cumulative transcript: replace the previous interim rather
# than concatenating successive Results events.
print(f"\r{msg.transcript}", end="", flush=True)
@session.on(ServerMessageType.CLOSED)
def _(info):
print(f"\nClosed: code={info.code} reason={info.reason!r}")
async with session:
mic = Microphone(sample_rate=16000, chunk_size=1600)
await session.stream_audio(mic)
asyncio.run(main())
Prefer streaming a file (no audio device dependency)? See
examples/live_transcription_file.py.
For the full event catalog (Ready, Results, Final, Error,
Closed), configuration options, and extensibility notes, see the
Live Transcription tutorial
and SDK guide.
6. Realtime Speech-to-Speech Translation (Streaming WebSocket)
Speak (or stream a file) in one language and receive the translation as live text and synthesized speech over a single WebSocket. Audio is PCM16 mono at 24 kHz in both directions.
import asyncio
import os
from camb.client import CambAI
from camb.live_transcription import Microphone
from camb.realtime import ServerEventType
async def main():
client = CambAI(api_key=os.environ["CAMB_API_KEY"])
session = await client.realtime.connect(
source_language="en-us",
target_language="de-de",
)
@session.on(ServerEventType.TEXT_DONE)
def _(event):
print(f"[translation] {event.text}")
@session.on(ServerEventType.AUDIO_DELTA)
def _(event):
... # event.data is raw PCM16 mono 24 kHz — play it through your speakers
async with session:
await session.wait_until_ready()
mic = Microphone(sample_rate=24000, chunk_size=2400)
await session.stream_audio(mic)
asyncio.run(main())
Sessions run in one of two modes, chosen with mode:
session = await client.realtime.connect(
source_language="en-us",
target_language="de-de",
mode="slow", # "fast" (default) or "slow"
)
"fast" accepts audio almost immediately and translates with the lowest latency, but supports
fewer languages. "slow" supports the full language list and translates more accurately, at the
cost of a 30s+ cold boot before the session is ready — wait_until_ready() covers that wait.
mode replaced a model argument that took engine codenames. Both are still accepted, so existing
code keeps working: model="iris" resolves to mode="fast", and "lilac"/"violet"/"orchid"
resolve to "slow", each with a DeprecationWarning. Note the default changed — it was "lilac",
whose language coverage matches today's "slow". If you never passed model and translate a pair
outside "fast"'s narrower set, pass mode="slow" explicitly.
By default the translation is synthesized with a built-in voice for the target
language. Pass voice_id to use one of your cloned voices instead (get the ID
from client.voice_cloning.list_voices()):
session = await client.realtime.connect(
source_language="en-us",
target_language="de-de",
voice_id=147320, # one of your cloned voices
)
For the most natural-sounding results, choose a voice whose reference language
matches target_language.
Runnable examples:
examples/realtime_translation_microphone.py
(mic in, translated speech out) and
examples/realtime_translation_file.py
(WAV in, translated WAV out — no audio device needed). For the full event
list and configuration, see the
Realtime Speech Translation tutorial
and the WebSocket API reference.
7. Transcription and Subtitles
Create transcription and subtitle jobs with formatting controls. You can pass
SubtitleFormattingOptions or a plain dict.
from camb.types.language_enums import Languages
from camb.types.subtitle_formatting_options import SubtitleFormattingOptions
transcription = client.transcription.create_transcription(
language=Languages.EN_US,
media_url="https://example.com/video.mp4",
formatting_options=SubtitleFormattingOptions(
max_segment_duration_in_seconds=6,
max_characters_in_segment=42,
),
)
print(f"Transcription task: {transcription.task_id}")
transcription_with_dict = client.transcription.create_transcription(
language=Languages.EN_US,
media_url="https://example.com/video.mp4",
formatting_options={"max_reading_speed_in_cps": 18},
)
Generate subtitles for one or more target languages, then poll, fetch, or export the result. Subtitle create requires a media URL (local file upload is not supported).
import time
from camb.types.language_enums import Languages
from camb.types.subtitle_formatting_options import SubtitleFormattingOptions
subtitle = client.subtitles.create_subtitle(
source_language=Languages.EN_US,
target_languages=[Languages.ES_ES, Languages.FR_FR],
media_url="https://example.com/video.mp4",
formatting_options=SubtitleFormattingOptions(
min_segment_duration_in_seconds=1,
max_characters_in_segment=42,
),
)
while True:
status = client.subtitles.get_subtitle_task_status(task_id=subtitle.task_id)
if status.status == "SUCCESS":
break
time.sleep(5)
result = client.subtitles.get_subtitle_result(status.run_id)
spanish_result = client.subtitles.get_subtitle_result_for_language(
status.run_id,
Languages.ES_ES,
)
srt_file = client.subtitles.get_subtitle_result_for_language(
status.run_id,
Languages.ES_ES,
format_type="srt",
data_type="file",
)
⚙️ Advanced Usage & Other Features
The Camb AI SDK offers a wide range of capabilities beyond these examples, including:
- Voice Cloning
- Translations
- Translated TTS
- Audio Dubbing
- Transcription (async file/URL jobs) and subtitles (media URL jobs) with TXT/SRT/VTT exports
- Live Transcription (streaming WebSocket — see Example 5 above)
- And more!
Please refer to examples for direct runnable examples and Official Camb AI API Documentation for a comprehensive list of features and advanced usage patterns.
📖 Examples
Check out the examples/ directory for complete, runnable examples:
async_tts_call.py- Async text-to-speech exampletext_to_audio.py- Sound generation exampleperform_dubbing.py- Video dubbing workflowtranscription.py- Select fast/slow mode, audio cleaning, music handling, and automatic language detectiontranscription_formatting.py- Async transcription with formatting options and TXT/SRT/VTT exportssubtitles.py- Subtitle job creation, polling, and language-specific TXT/SRT/VTT exportstranslation.py- Text translation workflowbaseten_provider_example.py- Using custom hosting providerslive_transcription_microphone.py- Stream microphone audio over the WebSocketlive_transcription_file.py- Stream a local audio file over the WebSocketrealtime_translation_microphone.py- Realtime speech translation from microphone inputrealtime_translation_file.py- Realtime speech translation from file input
License
This project is licensed under the MIT License - see the LICENSE file for details.
Transcription audio cleaning and automatic language detection
Transcription accepts run_audio_cleaning (default true). Set it to false for clean speech to skip source separation; media preparation still runs, including when requesting subtitle formatting. Pass language="auto" (Python) or language: "auto" (TypeScript) to use the existing auto-detection language. Dubbing, subtitles, translation, translated TTS, and project-setup language inputs also accept locale strings and "auto"; use a concrete target language when requesting translation. Numeric language IDs remain supported.
Choosing transcription mode and audio options
from camb.client import CambAI
client = CambAI() # Set CAMB_API_KEY in your environment.
job = client.transcription.create_transcription(
media_url="https://example.com/meeting.mp3",
language="auto", # Or a locale such as "en-us".
transcription_mode="fast", # Change to "slow" for the slower accuracy-oriented mode.
run_audio_cleaning=True, # False skips source separation for clean speech.
include_music_in_fg=True, # Only applies when audio cleaning is enabled.
formatting_options={ # Optional subtitle segmentation rules.
"max_segment_duration_in_seconds": 6,
"max_characters_in_segment": 42,
},
)
print(job.task_id)
fast is the default. slow takes longer and may improve accuracy. Both modes
include diarization. Disabling cleaning still extracts/decodes the media; it does
not disable diarization. For clean speech, set run_audio_cleaning=False.
Edit the URL and options directly in transcription.py, then run it to submit, poll, and print the result:
export CAMB_API_KEY="YOUR_API_KEY"
python examples/transcription.py
The script defaults to fast mode with audio cleaning and music inclusion disabled.
Add transcription_mode="slow" to choose slow mode. Each run creates one job.
Transcription API parity
The transcription client covers all four routes: POST /apis/transcribe,
GET /apis/transcribe/{task_id}, GET /apis/transcription-result/{run_id},
and POST /apis/transcription-results.
| Create input | Behavior |
|---|---|
language |
Required numeric ID, locale string, or "auto" |
media_file, media_url |
Upload or media URL; supply at least one media source |
file, audio_url |
Deprecated upload/URL aliases retained for compatibility |
project_name, project_description, folder_id |
Optional project metadata |
transcription_mode |
"fast" by default; also accepts "slow" |
run_audio_cleaning |
Defaults to true; false skips source separation |
include_music_in_fg |
Defaults to true; keeps music in foreground during separation; no effect when cleaning is false |
formatting_options |
Optional options object or JSON string, serialized as a multipart field |
Formatting supports all five API fields: max_segment_duration_in_seconds,
min_segment_duration_in_seconds, max_characters_in_segment,
max_reading_speed_in_cps, and min_gap_between_segments_in_frames.
Omitted rules use backend defaults; Python also accepts SubtitleFormattingOptions.
A single result requires a run ID. Omit both format_type and data_type for
structured segments (start, end, text, speaker). Request srt, vtt, or
txt with file or raw_data for an exported transcript. If only one export
option is specified, the other defaults to txt or file, respectively.
Bulk results send run_ids in JSON and return a mapping of run IDs to structured
transcripts.
Historical query arguments run_id on create/status/bulk and
word_level_timestamps on result retrieval are deprecated compatibility no-ops:
they remain callable but are not sent because the API does not support them.
This does not affect the required run ID in the single-result path.
Parity was audited against the client-microservice transcription router and its companion audio-cleaning PR (#4092). Wire tests cover normal/raw responses, all inputs, defaults and explicit false values, upload aliases, formatting serialization, status, structured/export results, and bulk requests.
Metadata
Release files for camb-sdk 1.6.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| camb_sdk-1.6.5.tar.gz | 124.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| camb_sdk-1.6.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 315.4 kB
Release files / camb_sdk-1.6.5.tar.gz
| Download URL | camb_sdk-1.6.5.tar.gz |
|---|---|
| Size | 124.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
31789940ed1545969581cc581e26fcc2bf0f01f8de9a3b9395a6fd939c668b5f
|
|
BLAKE2b-256 checksum How to use checksums |
fa2f32a973b07665733ea9c0aeee4d56becfb0551fe281af2a3de79f55db7340
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Release files / camb_sdk-1.6.5-py3-none-any.whl
| Download URL | camb_sdk-1.6.5-py3-none-any.whl |
|---|---|
| Size | 191.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2c5dc7694f6a0bf459aebffec00eed17b489cd44e2d7c581b921af3c6827e28a
|
|
BLAKE2b-256 checksum How to use checksums |
f0b6c50d0baaeaca8512acc0a35317fd2403cedc0afb01b33a06b39504a3c608
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|