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

You have a website and a product launch coming up. You need a blog post, a LinkedIn ad, an email sequence, social captions, a product description, and ad copy — all in the same voice. Normally you’d brief a writer, wait days, review for tone consistency, and iterate. This playbook creates a brand voice from your existing website pages, then fires every relevant Generate app against that voice. In one script run you get a full content library — every piece on-brand by construction.
Mavera-only. No external API, no CMS integration, no third-party auth. Just Brand Voice + Generate + the Mavera API.

Architecture


What You Need

RequirementDetails
Mavera API keyStarts with mvra_live_. Get one at Developer Settings.
Workspace IDFrom your dashboard URL (ws_...).
2–5 website URLsPublic pages that represent your brand voice (about page, blog, homepage).
Product briefTopic, audience, and key points for the content you want to generate.
Credits~200–400 total. See Credits Estimate.
Python 3.8+ or Node.js 18+requests for Python; native fetch for Node.
MAVERA_API_KEY=mvra_live_your_key_here
MAVERA_WORKSPACE_ID=ws_your_workspace_id

The Flow

1

Create brand voice from website URLs

POST /brand-voices with 2–5 public URLs. Mavera scrapes them and extracts tone, vocabulary, sentence style, and formality. Poll until status is READY.
2

Discover available generation apps

GET /generation-apps returns every template with its app_id and required input_data fields. Pick the apps that match your content plan.
3

Generate content for each app

Loop through your chosen apps. Every POST /generations call passes the same brand_voice_id, ensuring consistent voice across blog posts, emails, ads, and social content.
4

Collect and review

Each generation returns output (text) and usage.credits_used. Collect everything into a content library — ready for review, editing, and publishing.

Stage 1 — Create Brand Voice from URLs

import os
import time
import json
import requests

API_KEY = os.environ["MAVERA_API_KEY"]
WORKSPACE_ID = os.environ["MAVERA_WORKSPACE_ID"]
BASE = "https://app.mavera.io/api/v1"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

BRAND_URLS = [
    "https://yourbrand.com/about",
    "https://yourbrand.com/blog/why-we-exist",
    "https://yourbrand.com/blog/our-approach",
]

bv_resp = requests.post(
    f"{BASE}/brand-voices",
    headers=HEADERS,
    json={
        "label": "Launch Voice — Website",
        "usage_context": "Product launch content across blog, email, social, and ads",
        "urls": BRAND_URLS,
        "workspace_id": WORKSPACE_ID,
    },
)
bv_resp.raise_for_status()
brand_voice = bv_resp.json()
voice_id = brand_voice["id"]
print(f"Brand voice created: {voice_id} (status: {brand_voice['status']})")


def wait_for_voice(bv_id, max_wait=300):
    """Poll until brand voice is READY."""
    for _ in range(max_wait // 10):
        resp = requests.get(f"{BASE}/brand-voices/{bv_id}", headers=HEADERS)
        data = resp.json()
        if data.get("status") == "READY":
            return data
        time.sleep(10)
    raise TimeoutError(f"Brand voice {bv_id} not ready after {max_wait}s")


voice = wait_for_voice(voice_id)
print(f"Voice ready: {voice.get('voice_summary', '')[:120]}...")
print(f"Tone: {voice.get('tone_adjectives', [])}")

Stage 2 — Discover Generation Apps

apps_resp = requests.get(f"{BASE}/generation-apps", headers=HEADERS)
apps_resp.raise_for_status()
all_apps = apps_resp.json()["data"]

for app in all_apps:
    print(f"  {app['id']:35s}  {app.get('name', '')}")

CONTENT_PLAN = [
    {
        "app_id": "blog_post_generator",
        "title": "Launch Blog Post",
        "input_data": {
            "topic": "Introducing Our New Product Line",
            "target_audience": "Small business owners looking for workflow automation",
            "tone": "professional yet approachable",
            "length": "1200 words",
            "key_points": [
                "What the product does",
                "Three key features",
                "Customer pain points it solves",
                "Getting started steps",
            ],
        },
    },
    {
        "app_id": "linkedin_ad_generator",
        "title": "Launch LinkedIn Ad",
        "input_data": {
            "product": "Workflow Automation Suite",
            "target_audience": "Operations managers at 50-500 person companies",
            "value_proposition": "Cut manual processes by 60%",
            "cta": "Start free trial",
        },
    },
    {
        "app_id": "email_sequence_generator",
        "title": "Launch Email Nurture",
        "input_data": {
            "sequence_goal": "Convert free trial signups to paid customers",
            "emails_count": 5,
            "target_audience": "Trial users who signed up in the last 7 days",
            "key_points": [
                "Welcome and quick-start guide",
                "Feature highlight: automation builder",
                "Customer success story",
                "Pricing and upgrade benefits",
                "Last chance / trial ending",
            ],
        },
    },
    {
        "app_id": "social_post_generator",
        "title": "Launch Social Captions",
        "input_data": {
            "topic": "Product launch announcement",
            "platform": "Instagram",
            "tone": "exciting, conversational",
            "count": 5,
        },
    },
    {
        "app_id": "product_description",
        "title": "Product Page Copy",
        "input_data": {
            "product_name": "Workflow Automation Suite",
            "features": [
                "Drag-and-drop automation builder",
                "200+ integrations",
                "Real-time analytics dashboard",
            ],
            "target_audience": "Small business owners",
            "tone": "clear, benefit-focused",
        },
    },
    {
        "app_id": "ad_copy_generator",
        "title": "Launch Ad Copy Variants",
        "input_data": {
            "product": "Workflow Automation Suite",
            "audience": "SMB operations teams",
            "goal": "Drive demo signups",
            "variants": 3,
        },
    },
]

Stage 3 — Generate the Full Library

Every generation passes the same brand_voice_id. The voice rules constrain tone, vocabulary, and sentence style across all output — blog posts read like your website, emails read like your blog, ads read like your emails.
def generate_content(app_id, title, input_data, brand_voice_id):
    """Run one generation app with the shared brand voice."""
    resp = requests.post(
        f"{BASE}/generations",
        headers=HEADERS,
        json={
            "app_id": app_id,
            "title": title,
            "brand_voice_id": brand_voice_id,
            "input_data": input_data,
            "workspace_id": WORKSPACE_ID,
        },
    )
    resp.raise_for_status()
    gen = resp.json()

    if gen.get("status") in ("PENDING", "RUNNING"):
        gen = wait_for_generation(gen["id"])

    return gen


def wait_for_generation(gen_id, max_wait=300):
    """Poll until generation completes."""
    for _ in range(max_wait // 10):
        resp = requests.get(f"{BASE}/generations/{gen_id}", headers=HEADERS)
        data = resp.json()
        if data.get("status") == "COMPLETED":
            return data
        time.sleep(10)
    raise TimeoutError(f"Generation {gen_id} timed out")


library = []
total_credits = 0

for item in CONTENT_PLAN:
    print(f"Generating: {item['title']} ({item['app_id']})...")
    gen = generate_content(
        app_id=item["app_id"],
        title=item["title"],
        input_data=item["input_data"],
        brand_voice_id=voice_id,
    )
    credits = gen.get("usage", {}).get("credits_used", 0)
    total_credits += credits

    library.append({
        "title": item["title"],
        "app": item["app_id"],
        "output": gen.get("output", ""),
        "credits": credits,
    })
    print(f"  ✓ {credits} credits | {len(gen.get('output', ''))} chars")

print(f"\n{'='*50}")
print(f"Library complete: {len(library)} pieces | {total_credits} total credits")

Variations

Create separate brand voices for different audiences (e.g. enterprise vs SMB), then run the same content plan against each voice. Compare outputs side by side:
voices = {
    "enterprise": create_voice(["https://yourbrand.com/enterprise"]),
    "smb": create_voice(["https://yourbrand.com/small-business"]),
}
for segment, vid in voices.items():
    for item in CONTENT_PLAN:
        gen = generate_content(item["app_id"], f"{segment}{item['title']}", item["input_data"], vid)
Store the voice ID and re-run only new apps when new templates become available:
existing_apps = {p["app"] for p in manifest["pieces"]}
new_apps = [a for a in all_apps if a["id"] not in existing_apps]
for app in new_apps:
    gen = generate_content(app["id"], app["name"], default_input, voice_id)
    library.append(gen)
After generating the library, score each piece against the voice rules using Chat with response_format. Flag any pieces that drift:
from openai import OpenAI
mavera = OpenAI(api_key=API_KEY, base_url=BASE)

for piece in library:
    resp = mavera.responses.create(
        model="mavera-1",
        input=[
            {"role": "system", "content": f"Score brand voice consistency 1-10:\n{json.dumps(voice.get('tone_adjectives', []))}"},
            {"role": "user", "content": piece["output"][:2000]},
        ],
    )
    print(f"{piece['title']}: {resp.output[0].content[0].text}")
Each generation call is independent — use asyncio.gather (Python) or Promise.all (JS) to run all 6 apps concurrently instead of sequentially.

Credits Estimate

OperationTypical CostNotes
Brand voice creation50 creditsOne-time per voice profile
Blog post generation15–30 creditsDepends on length (500–1500 words)
LinkedIn ad generation10–20 creditsShort-form
Email sequence (5 emails)20–40 creditsMulti-part output
Social captions (5 posts)10–20 creditsShort-form batch
Product description10–25 creditsMedium-form
Ad copy variants (3)10–20 creditsShort-form batch
Total (voice + 6 apps)~125–205 credits
The brand voice is the most durable investment — create once, reuse across hundreds of generations. The 50-credit extraction pays for itself after 2–3 content runs.

What’s Next

Content Repurposing Pipeline

Turn one blog post into 5+ content formats

A/B Copy Production

Same brief, different voices — ready-to-test variants

Brand Voice Extraction & Audit

Score content consistency against extracted voice rules

Content Generation

Full API reference for generation apps

Brand Voice

Create and manage brand voice profiles

Credits & Budget

Usage tracking and cost estimation