Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mavera.io/llms.txt

Use this file to discover all available pages before exploring further.

Scenario

Clone a spokesperson’s voice using ElevenLabs’ voice cloning API, then generate audio versions of Mavera-generated content using that cloned voice — building a consistent audio identity across all content. Flow: ElevenLabs POST /voices/add → get voice_id → Mavera POST /generations → ElevenLabs POST /text-to-speech/{voice_id} → branded audio

Code

import os, requests, time
EL_KEY = os.environ["ELEVENLABS_API_KEY"]
EL_BASE = "https://api.elevenlabs.io/v1"
MV = os.environ["MAVERA_API_KEY"]
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
os.makedirs("branded_audio", exist_ok=True)
SAMPLE_FILES = ["voice_samples/intro.mp3", "voice_samples/pitch.mp3", "voice_samples/casual.mp3"]

# 1. Clone voice with multipart upload
files = [("files", (os.path.basename(f), open(f, "rb"), "audio/mpeg")) for f in SAMPLE_FILES]
clone = requests.post(f"{EL_BASE}/voices/add", headers={"xi-api-key": EL_KEY},
    data={"name": "Brand Spokesperson v1",
          "description": "Official brand voice from spokesperson recordings",
          "labels": '{"use_case": "marketing", "language": "en"}'},
    files=files).json()
for _, (_, fh, _) in zip(SAMPLE_FILES, files): fh.close()
voice_id = clone["voice_id"]
print(f"Voice cloned: {voice_id}")
time.sleep(2)

# 2. Generate content + convert to branded audio
SPECS = [
    {"prompt": "Write a 100-word product announcement for an AI analytics dashboard.", "label": "product-launch"},
    {"prompt": "Write a 60-second radio ad script for a B2B marketing platform.", "label": "radio-spot"},
    {"prompt": "Write a 30-second podcast pre-roll ad for a data intelligence tool.", "label": "podcast-preroll"},
]
for spec in SPECS:
    gen = requests.post(f"{MV_BASE}/generations", headers=MV_H,
        json={"prompt": spec["prompt"]}).json()
    text = gen.get("output") or gen.get("content") or ""
    print(f"[{spec['label']}] {len(text.split())} words")
    time.sleep(1)

    tts = requests.post(f"{EL_BASE}/text-to-speech/{voice_id}",
        headers={"xi-api-key": EL_KEY, "Content-Type": "application/json"},
        json={"text": text, "model_id": "eleven_multilingual_v2",
              "voice_settings": {"stability": 0.5, "similarity_boost": 0.8,
                                 "style": 0.3, "use_speaker_boost": True}})
    if tts.status_code == 200:
        path = f"branded_audio/{spec['label']}-cloned.mp3"
        with open(path, "wb") as f: f.write(tts.content)
        print(f"  → {path} ({len(tts.content) // 1024} KB)")
    time.sleep(2)

Example Output

Voice cloned: vId_a8f3c2d1e9b7
[product-launch] 104 words → product-launch-cloned.mp3 (142 KB)
[radio-spot] 87 words → radio-spot-cloned.mp3 (198 KB)
[podcast-preroll] 62 words → podcast-preroll-cloned.mp3 (89 KB)

Error Handling

Instant cloning accepts 1–25 samples. Provide at least 3 clean samples totaling 1–3 minutes with only the target speaker — no background music or multiple speakers.
Each plan has a monthly character quota (~500 chars per 100 words). A 401 with quota_exceeded means your allocation is exhausted — upgrade or wait for monthly reset.
If TTS returns 404 after cloning, the voice may still be processing. Wait 5–10 seconds and retry. Verify with GET /voices.