Skip to main content

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.

Overview

Upload a .txt or .docx manuscript and produce narrated audio: full narration, an optional dialogue-only track, and optionally a time-coded transcript. Pick the narrator voice and source language, then run an asynchronous job and fetch URLs when it completes.

Prerequisites

1

Create an account

Sign up at CAMB.AI Studio if you haven’t already.
2

Get your API key

Go to Settings β†’ API Keys in Studio and copy your key. See Authentication for details.
3

Install the SDK

pip install camb-sdk
Skip this step if you’re using the direct API.
4

Set your API key to use in your code

export CAMB_API_KEY="your_api_key_here"

Code

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 narrate_story():
    # Replace with your story file (.txt or .docx)
    story_path = "story.txt"

    # Step 1: Submit the story job (multipart upload)
    response = client.story.create_story(
        file=open(story_path, "rb"),
        source_language=Languages.EN_US,
        title="My Story",
        description="Sample narrated story",
        narrator_voice_id=147320,
    )

    # Usually returns task_id for async processing (see Note below)
    task_id = getattr(response, "task_id", None)
    if not task_id:
        print("No task_id on response; if you received run_id directly, skip polling and call get_story_run_info.")
        return

    print(f"Story task created: {task_id}")

    # Step 2: Poll until complete
    max_attempts = 60
    attempt = 0
    while attempt < max_attempts:
        status = client.story.get_story_status(task_id=task_id)
        print(f"Status: {status.status}")

        if status.status == "SUCCESS":
            # Step 3: Full narration, dialogue track, optional transcript
            result = client.story.get_story_run_info(
                status.run_id,
                include_transcript=True,
            )
            print(f"Audio URL: {result.get('audio_url')}")
            print(f"Dialogue URL: {result.get('dialogue_url')}")
            transcript = result.get("transcript")
            if transcript:
                for row in transcript[:2]:
                    print(f"[{row.get('start')}-{row.get('end')}ms] {row.get('speaker')}: {row.get('text')}")
            break
        elif status.status == "ERROR":
            print(f"Story failed: {status.exception_reason}")
            break

        time.sleep(5)
        attempt += 1

narrate_story()
create_story / createStory may return either a task_id (poll as above) or, in some flows, a run_id immediately. If you already have run_id, call get_story_run_info / getStoryRunInfo without polling.

How it works

create_story / createStory (multipart: .txt or .docx)
        β”‚
        β–Ό
    task_id (typical)
        β”‚
        β–Ό
get_story_status / getStoryStatus  ← poll every ~5s
        β”‚
        β”œβ”€β”€ PENDING β†’ keep polling
        β”œβ”€β”€ ERROR   β†’ check exception_reason
        └── SUCCESS β†’ run_id available
                          β”‚
                          β–Ό
get_story_run_info / getStoryRunInfo (include_transcript optional)
                          β”‚
                          └── audio_url, dialogue_url, transcript

Parameters

Required

ParameterTypeDescription
filefile stream.txt or .docx content to narrate
source_languageLanguagesLanguage of the manuscript (enum / numeric ID)

Optional

ParameterTypeDescription
titlestringStory title
descriptionstringShort description
narrator_voice_idintegerVoice ID for the narrator (use list voices or pick one from Text to Speech)
folder_idintegerFolder for organizing the run
chosen_dictionariesinteger[]Custom pronunciation dictionaries
run_idintegerOptional tracing / linkage

Tips

  • Formats: Use .txt or .docx as described in the Create Story reference.
  • Languages: Use Get source languages to choose the correct language ID for source_language.
  • URLs: Download links from audio_url and dialogue_url expire after 24 hoursβ€”fetch and store files promptly.
  • Polling: Cap your loop (for example 60 attempts Γ— 5 seconds) and handle timeouts separately from ERROR status.

Next Steps

Create Story API

Multipart upload and story parameters.

Get Story Status

Poll with task_id.

Get Story Run Info

audio_url, dialogue_url, and optional transcript.

Text to Speech

Generate speech and explore voices for narrator_voice_id.