Skip to main content
Most CAMB.AI APIs use an asynchronous task pattern that allows your application to submit requests and continue working while processing happens in the background. This guide explains how tasks and runs work.

The Task Lifecycle

1

Submit a Request

Send your data (text, audio, video) to a creation endpoint. The API immediately returns a task_id.
2

Poll for Status

Use the task_id to check progress. The task moves through states: PENDING β†’ SUCCESS (or ERROR).
3

Get the Result

Once the status is SUCCESS, you receive a run_id. Use this to download your result.

Task vs Run

ConceptDescriptionID
TaskA job submitted for processingtask_id
RunThe completed result of a taskrun_id
A task represents your request being processed. Once complete, the result becomes a run that you can download or reference.

Task Status Types

StatusMeaningAction
PENDINGProcessing in progressContinue polling
SUCCESSCompleted successfullyRetrieve result using run_id
ERRORProcessing failedCheck error message, retry
TIMEOUTProcessing exceeded time limitBreak into smaller requests
PAYMENT_REQUIREDInsufficient creditsAdd credits to account

Example: Complete Workflow

Here’s a complete example showing the task pattern for text-to-speech:
import requests
import time

API_KEY = "your-api-key"
BASE_URL = "https://client.camb.ai/apis"

headers = {
    "x-api-key": API_KEY,
    "Content-Type": "application/json"
}

# Step 1: Submit the task
response = requests.post(
    f"{BASE_URL}/tts",
    headers=headers,
    json={
        "text": "Hello, this is a test of the task system.",
        "voice_id": 147320,
        "language": 1
    }
)
task_id = response.json()["task_id"]
print(f"Task submitted: {task_id}")

# Step 2: Poll for completion
while True:
    status_response = requests.get(
        f"{BASE_URL}/tts/{task_id}",
        headers=headers
    )
    status_data = status_response.json()
    status = status_data["status"]

    print(f"Status: {status}")

    if status == "SUCCESS":
        run_id = status_data["run_id"]
        break
    elif status in ["ERROR", "TIMEOUT", "PAYMENT_REQUIRED"]:
        print(f"Task failed: {status}")
        exit(1)

    time.sleep(2)  # Wait before polling again

# Step 3: Download the result
result_response = requests.get(
    f"{BASE_URL}/tts-result/{run_id}",
    headers=headers,
    stream=True
)

with open("output.wav", "wb") as f:
    for chunk in result_response.iter_content(chunk_size=1024):
        if chunk:
            f.write(chunk)

print(f"Audio saved! Run ID: {run_id}")

Polling Best Practices

Start with 2-5 second intervals. Shorter tasks (TTS) complete faster than longer ones (dubbing).
For longer tasks, increase the polling interval over time to reduce API calls.
Don’t poll forever. Set a maximum wait time and handle timeouts gracefully.
Always handle ERROR, TIMEOUT, and PAYMENT_REQUIRED statuses in your code.

Bulk Operations

For processing multiple items, use the bulk fetch endpoints:
# Fetch multiple results at once
response = requests.post(
    f"{BASE_URL}/fetch-tts-results",
    headers=headers,
    json={
        "run_ids": [123, 456, 789]
    }
)
results = response.json()

APIs Using This Pattern

Most CAMB.AI APIs follow the task pattern:
APICreateStatusResult
Text-to-SpeechPOST /ttsGET /tts/{task_id}GET /tts-result/{run_id}
TranslationPOST /translationGET /translation/{task_id}GET /translation-result/{run_id}
TranscriptionPOST /transcriptionGET /transcription/{task_id}GET /transcription-result/{run_id}
DubbingPOST /end-to-end-dubbingGET /end-to-end-dubbing/{task_id}GET /dubbed-run-info/{run_id}
StoriesPOST /create-storyGET /story/{task_id}GET /story-run/{run_id}

Streaming Alternative

For real-time applications, some APIs offer streaming endpoints that return data immediately without the task pattern:
  • POST /tts-stream - Streaming text-to-speech
  • POST /translation-stream - Streaming translation
Use streaming when you need immediate response and can process audio chunks as they arrive.

Next Steps