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.

Mavera Surfaces Used

SurfaceRole
Personas (POST /personas)Create customer personas from CRM data
Focus Groups (POST /focus-groups)Validate next year’s themes, priorities, and messaging with personas
Generate (POST /generate)Draft the annual plan sections from validated insights
Mave Agent (POST /mave/chat)Research market trends, competitive landscape, and industry benchmarks
Speak (POST /speak/conversations)Live voice conversations with personas for qualitative depth
Chat + response_formatStructure outputs and synthesize across stages
This is the capstone playbook — it chains every major Mavera surface into one end-to-end workflow. Each stage feeds the next, producing a data-backed annual marketing plan that would normally take weeks of agency work, internal workshops, and executive reviews.

What Value Does Mavera Add?

ValueHow
InsuranceEvery plan element is validated against personas before it reaches the board deck. No “gut feel” positioning or unvalidated assumptions.
Opening new doorsA complete annual plan — from CRM data to finished document — in a single day. Run multiple scenarios (aggressive vs conservative) in parallel.
Saving timeReplaces 4-6 weeks of agency research, internal workshops, cross-functional reviews, and document drafting with a single automated pipeline.

When to Use This

  • It’s Q4 and you need next year’s marketing plan with data-backed priorities.
  • You’re a new CMO establishing your first-year strategy and need to move fast.
  • You’re presenting to the board and need a plan that’s validated, not aspirational.
  • You want to compare multiple strategic scenarios (aggressive growth vs efficiency vs expansion).

What You Need

RequirementDetails
Mavera API keyStarts with mvra_live_. Get one at Developer Settings.
Workspace IDFrom your dashboard URL (ws_...).
CRM export or customer dataCustomer list with segment, ARR, tenure, and satisfaction data. CSV or JSON.
Current year metricsRevenue, pipeline, win rate, churn, CAC, LTV — for benchmarking.
Next year’s candidate themes3-5 strategic themes you’re considering (e.g. “Enterprise expansion”, “Product-led growth”, “International markets”).
Credits~500–1500 total. See Credits Estimate.
Python 3.8+ or Node.js 18+requests / openai for Python; native fetch for Node.
MAVERA_API_KEY=mvra_live_your_key_here
MAVERA_WORKSPACE_ID=ws_your_workspace_id
PLAN_YEAR=2027

The Pipeline

This is a 6-stage pipeline where each stage feeds the next:

The Flow

1

Analyze CRM data

Parse customer data to identify segments, satisfaction patterns, churn indicators, and growth opportunities. This creates the factual foundation for personas and planning.
2

Create personas from data

Build 5 personas that represent your actual customer base — not hypothetical ICPs, but data-informed profiles of your best, newest, at-risk, churned, and prospect segments.
3

Run Focus Groups on next year's themes

Present 3-5 candidate strategic themes to all personas. Use Ranking, Likert, and Open-Ended questions to validate which themes resonate and which fall flat.
4

Mave researches market context

Use Mave Agent to research market trends, competitive moves, and industry benchmarks that inform the plan. Combines with Focus Group data for grounded strategy.
5

Generate the annual plan

Feed validated themes, Focus Group data, and market research into Generate to draft each section of the annual plan. Structured output ensures consistency.
6

Speak validation conversations

Run live voice conversations with key personas to stress-test the plan. Ask probing questions, handle objections, and refine based on verbal feedback.

Code: Full Annual Planning Pipeline

Setup and Configuration

import os
import json
import time
import csv
import statistics
import requests
from openai import OpenAI

MAVERA_API_KEY = os.environ["MAVERA_API_KEY"]
WORKSPACE_ID = os.environ["MAVERA_WORKSPACE_ID"]
PLAN_YEAR = os.environ.get("PLAN_YEAR", "2027")
BASE = "https://app.mavera.io/api/v1"
HEADERS = {
    "Authorization": f"Bearer {MAVERA_API_KEY}",
    "Content-Type": "application/json",
}
mavera = OpenAI(api_key=MAVERA_API_KEY, base_url=BASE)

COMPANY = {
    "name": "Acme",
    "category": "AI-powered market research platform",
    "current_arr": "$4.2M",
    "growth_rate": "120% YoY",
    "team_size": 35,
    "key_metrics": {
        "customers": 280,
        "avg_contract": "$15K",
        "win_rate": "32%",
        "churn_rate": "8%",
        "cac": "$4,200",
        "ltv": "$42,000",
        "nps": 48,
    },
}

CANDIDATE_THEMES = [
    {
        "theme": "Enterprise Expansion",
        "description": (
            "Move upmarket: build enterprise features (SSO, SCIM, audit logs), "
            "hire enterprise AEs, target companies with 1000+ employees. "
            "Goal: 20 enterprise deals at $50K+ ACV."
        ),
    },
    {
        "theme": "Product-Led Growth",
        "description": (
            "Launch a self-serve tier with freemium entry. Invest in onboarding, "
            "in-app guides, and viral loops. Goal: 1000 self-serve accounts, "
            "15% conversion to paid."
        ),
    },
    {
        "theme": "Content & Thought Leadership",
        "description": (
            "Become the definitive voice in AI-powered market research. "
            "Weekly blog, monthly webinar, quarterly research report, conference presence. "
            "Goal: 3x organic traffic, 2x inbound pipeline."
        ),
    },
    {
        "theme": "Integration Ecosystem",
        "description": (
            "Build deep integrations with HubSpot, Salesforce, Slack, Notion. "
            "Launch a partner program. Goal: 10 integration partners, "
            "30% of customers using 2+ integrations."
        ),
    },
    {
        "theme": "International Markets",
        "description": (
            "Expand to EU and APAC. Localize product and content. "
            "Hire regional marketing leads. Goal: 15% of new ARR from international."
        ),
    },
]

Stage 1 — Analyze CRM Data

Parse customer data to identify segments and build persona-ready profiles.
SAMPLE_CRM_DATA = [
    {"name": "TechCorp", "segment": "enterprise", "arr": 85000, "tenure_months": 18, "nps": 9, "usage": "heavy", "features_used": ["focus_groups", "chat", "mave", "video"]},
    {"name": "StartupX", "segment": "startup", "arr": 5000, "tenure_months": 4, "nps": 7, "usage": "moderate", "features_used": ["chat", "mave"]},
    {"name": "AgencyPro", "segment": "agency", "arr": 24000, "tenure_months": 12, "nps": 8, "usage": "heavy", "features_used": ["focus_groups", "chat", "generate", "brand_voice"]},
    {"name": "MidMarket Inc", "segment": "mid_market", "arr": 36000, "tenure_months": 8, "nps": 6, "usage": "light", "features_used": ["chat"]},
    {"name": "ChurnedCo", "segment": "churned", "arr": 0, "tenure_months": 6, "nps": 3, "usage": "none", "features_used": []},
]


def analyze_crm_data(data: list[dict]) -> dict:
    """Analyze CRM data to identify segments and patterns."""
    segments = {}
    for customer in data:
        seg = customer["segment"]
        if seg not in segments:
            segments[seg] = {"customers": [], "total_arr": 0, "nps_scores": [], "tenures": []}
        segments[seg]["customers"].append(customer)
        segments[seg]["total_arr"] += customer["arr"]
        segments[seg]["nps_scores"].append(customer["nps"])
        segments[seg]["tenures"].append(customer["tenure_months"])

    analysis = {}
    for seg, data in segments.items():
        analysis[seg] = {
            "count": len(data["customers"]),
            "total_arr": data["total_arr"],
            "avg_arr": data["total_arr"] / len(data["customers"]) if data["customers"] else 0,
            "avg_nps": statistics.mean(data["nps_scores"]) if data["nps_scores"] else 0,
            "avg_tenure": statistics.mean(data["tenures"]) if data["tenures"] else 0,
            "top_features": _most_common_features(data["customers"]),
        }

    print(f"✓ Analyzed {sum(a['count'] for a in analysis.values())} customers across {len(analysis)} segments")
    for seg, info in analysis.items():
        print(f"  {seg}: {info['count']} customers, ${info['avg_arr']:.0f} avg ARR, NPS {info['avg_nps']:.1f}")

    return analysis


def _most_common_features(customers: list[dict]) -> list[str]:
    """Find most commonly used features across customers."""
    counts = {}
    for c in customers:
        for f in c.get("features_used", []):
            counts[f] = counts.get(f, 0) + 1
    return sorted(counts, key=counts.get, reverse=True)[:5]

Stage 2 — Create Personas from CRM Data

Build 5 personas that represent real customer segments, not hypothetical ICPs.
def generate_persona_descriptions(crm_analysis: dict) -> list[dict]:
    """Use Chat to generate rich persona descriptions from CRM segment data."""
    PERSONA_SCHEMA = {"type": "json_schema", "json_schema": {
        "name": "personas", "strict": True,
        "schema": {
            "type": "object",
            "properties": {
                "personas": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "name": {"type": "string"},
                            "segment": {"type": "string"},
                            "title": {"type": "string"},
                            "description": {"type": "string"},
                        },
                        "required": ["name", "segment", "title", "description"],
                    },
                },
            },
            "required": ["personas"],
        },
    }}

    prompt = (
        f"Based on this CRM analysis for {COMPANY['name']} ({COMPANY['category']}), "
        f"create 5 detailed personas — one per segment.\n\n"
        f"## CRM Analysis\n{json.dumps(crm_analysis, indent=2)}\n\n"
        f"## Company Context\n{json.dumps(COMPANY, indent=2)}\n\n"
        "For each persona, include:\n"
        "- Realistic name and title\n"
        "- Company size and budget context\n"
        "- How they use (or stopped using) the product\n"
        "- Their priorities for next year\n"
        "- What would make them increase/decrease their investment\n"
        "Make each description 3-5 sentences."
    )

    resp = mavera.responses.create(
        model="mavera-1",
        input=[{"role": "user", "content": prompt}],
        extra_body={"response_format": PERSONA_SCHEMA},
    )

    return json.loads(resp.output[0].content[0].text)["personas"]


def create_personas_from_descriptions(persona_descs: list[dict]) -> list[str]:
    """Create personas in Mavera from generated descriptions."""
    persona_ids = []

    for p in persona_descs:
        resp = requests.post(
            f"{BASE}/personas",
            headers=HEADERS,
            json={
                "name": p["name"],
                "description": f"[{p['segment']}] {p['title']}\n\n{p['description']}",
                "workspace_id": WORKSPACE_ID,
            },
        ).json()

        if "error" in resp:
            raise Exception(f"Failed: {p['name']}: {resp['error']['message']}")

        persona_ids.append(resp["id"])
        print(f"✓ Created: {p['name']} ({p['segment']}) — {resp['id']}")

    return persona_ids

Stage 3 — Focus Groups on Next Year’s Themes

def run_theme_focus_group(persona_ids: list[str]) -> dict:
    """Run a focus group validating candidate themes for next year."""
    themes_block = "\n".join(
        f"{i+1}. **{t['theme']}**: {t['description']}"
        for i, t in enumerate(CANDIDATE_THEMES)
    )

    payload = {
        "name": f"{PLAN_YEAR} Annual Planning — Theme Validation",
        "sample_size": 30,
        "persona_ids": persona_ids,
        "workspace_id": WORKSPACE_ID,
        "questions": [
            {
                "question": (
                    f"As a current or potential customer, rank these {PLAN_YEAR} strategic themes "
                    f"from most important to you (1st) to least (5th):\n\n{themes_block}"
                ),
                "type": "RANKING",
                "options": [t["theme"] for t in CANDIDATE_THEMES],
                "order": 1,
            },
            {
                "question": (
                    f"For the theme you ranked #1, rate how much it would increase "
                    f"your likelihood to invest more in {COMPANY['name']}. (1-10)"
                ),
                "type": "LIKERT",
                "scale": 10,
                "order": 2,
            },
            {
                "question": (
                    "Which theme would you be most disappointed if we did NOT pursue? "
                    "Why?"
                ),
                "type": "OPEN_ENDED",
                "order": 3,
            },
            {
                "question": (
                    f"Is there a strategic direction NOT listed above that you think "
                    f"{COMPANY['name']} should prioritize in {PLAN_YEAR}?"
                ),
                "type": "OPEN_ENDED",
                "order": 4,
            },
            {
                "question": (
                    f"Rate your overall confidence that {COMPANY['name']} is heading "
                    f"in the right direction. (0 = no confidence, 10 = very confident)"
                ),
                "type": "NPS",
                "order": 5,
            },
        ],
    }

    resp = requests.post(f"{BASE}/focus-groups", headers=HEADERS, json=payload).json()
    if "error" in resp:
        raise Exception(resp["error"]["message"])

    print(f"✓ Theme focus group launched: {resp['id']}")
    return resp


def poll_focus_group(fg_id: str, timeout_min: int = 15) -> dict:
    for _ in range(timeout_min * 6):
        resp = requests.get(f"{BASE}/focus-groups/{fg_id}", headers=HEADERS).json()
        if "error" in resp:
            raise Exception(resp["error"]["message"])
        if resp.get("status") == "COMPLETED":
            print("✓ Theme focus group completed")
            return resp
        if resp.get("status") == "FAILED":
            raise Exception("Focus group failed")
        time.sleep(10)
    raise TimeoutError("Focus group timed out")

Stage 4 — Mave Researches Market Context

def research_market_context() -> dict:
    """Use Mave to research market trends, competitive landscape, and benchmarks."""
    research_prompts = [
        {
            "label": "market_trends",
            "message": (
                f"Research the top trends in the {COMPANY['category']} market for {PLAN_YEAR}. "
                f"Focus on: technology shifts, buyer behavior changes, "
                f"emerging competitors, and market size projections. Cite sources."
            ),
        },
        {
            "label": "competitive_landscape",
            "message": (
                f"What are {COMPANY['name']}'s main competitors doing for {PLAN_YEAR}? "
                f"Any recent funding, product launches, acquisitions, or pivots? "
                f"How are they positioning for next year? Cite sources."
            ),
        },
        {
            "label": "industry_benchmarks",
            "message": (
                f"What are typical SaaS benchmarks for a company at {COMPANY['current_arr']} ARR "
                f"growing at {COMPANY['growth_rate']}? Include: ideal CAC:LTV ratio, "
                f"net revenue retention targets, magic number, and marketing spend as % of revenue. "
                f"Cite sources."
            ),
        },
    ]

    thread_id = None
    research = {}

    for prompt in research_prompts:
        payload = {"message": prompt["message"]}
        if thread_id:
            payload["thread_id"] = thread_id

        resp = requests.post(
            f"{BASE}/mave/chat",
            headers=HEADERS,
            json=payload,
            timeout=120,
        ).json()

        if "error" in resp:
            raise Exception(resp["error"]["message"])

        if not thread_id:
            thread_id = resp.get("thread_id")

        research[prompt["label"]] = {
            "content": resp.get("content", ""),
            "sources": resp.get("sources", []),
        }
        print(f"✓ Mave: {prompt['label']} ({len(resp.get('content', ''))} chars)")
        time.sleep(2)

    return {"thread_id": thread_id, "research": research}

Stage 5 — Generate the Annual Plan

PLAN_SECTIONS = [
    "executive_summary",
    "market_context",
    "strategic_themes",
    "target_segments",
    "channel_strategy",
    "budget_allocation",
    "okrs_and_kpis",
    "quarterly_roadmap",
    "risks_and_mitigations",
]


def generate_annual_plan(
    crm_analysis: dict, fg_results: dict, market_research: dict
) -> dict:
    """Generate each section of the annual plan using Generate API."""
    # Compile all inputs into context
    context = (
        f"# {PLAN_YEAR} Annual Marketing Plan Inputs\n\n"
        f"## Company\n{json.dumps(COMPANY, indent=2)}\n\n"
        f"## CRM Analysis\n{json.dumps(crm_analysis, indent=2)}\n\n"
        f"## Focus Group Results (Theme Validation)\n"
    )

    for result in fg_results.get("results", []):
        context += f"### {result.get('type')}: {result.get('question', '')[:80]}\n"
        if result.get("summary"):
            context += f"{result['summary']}\n"
        if result.get("ranking_distribution"):
            context += f"Rankings: {json.dumps(result['ranking_distribution'])}\n"
        if result.get("mean_score"):
            context += f"Mean: {result['mean_score']}\n"
        context += "\n"

    context += "## Market Research\n"
    for label, data in market_research["research"].items():
        context += f"### {label}\n{data['content'][:1000]}\n\n"

    plan_sections = {}

    for section in PLAN_SECTIONS:
        resp = requests.post(
            f"{BASE}/generate",
            headers=HEADERS,
            json={
                "prompt": (
                    f"Write the '{section.replace('_', ' ').title()}' section of the "
                    f"{PLAN_YEAR} annual marketing plan for {COMPANY['name']}.\n\n"
                    f"Use the data and insights below. Be specific — include numbers, "
                    f"timelines, and owners where appropriate. "
                    f"Write in a professional tone suitable for a board presentation.\n\n"
                    f"{context}"
                ),
                "workspace_id": WORKSPACE_ID,
                "max_tokens": 2000,
            },
        ).json()

        if "error" in resp:
            raise Exception(f"Generate failed for {section}: {resp['error']['message']}")

        plan_sections[section] = resp.get("content", resp.get("text", ""))
        print(f"✓ Generated: {section.replace('_', ' ').title()}")
        time.sleep(2)

    return plan_sections

Stage 6 — Speak Validation Conversations

Run live voice conversations with key personas to stress-test the plan.
SPEAK_QUESTIONS = [
    f"I'm going to share our top strategic theme for {PLAN_YEAR}. Tell me honestly — does this resonate with your needs?",
    "What's missing from this plan? What would make you more excited about our direction?",
    "If you had to bet, would this plan make you increase your investment with us, keep it the same, or decrease it?",
    "What's the one thing we could do next year that would make the biggest difference for you?",
]


def run_speak_conversations(persona_ids: list[str], plan_summary: str) -> list[dict]:
    """Run Speak conversations with each persona to validate the plan."""
    conversations = []

    for pid in persona_ids[:3]:  # Top 3 personas for voice validation
        resp = requests.post(
            f"{BASE}/speak/conversations",
            headers=HEADERS,
            json={
                "persona_id": pid,
                "workspace_id": WORKSPACE_ID,
                "context": (
                    f"You are reviewing the {PLAN_YEAR} annual marketing plan for {COMPANY['name']}. "
                    f"Here is the plan summary:\n\n{plan_summary}"
                ),
                "initial_message": SPEAK_QUESTIONS[0],
            },
        ).json()

        if "error" in resp:
            print(f"  Warning: Speak failed for persona {pid}: {resp['error']['message']}")
            continue

        conversation_id = resp.get("id")
        conversations.append({
            "persona_id": pid,
            "conversation_id": conversation_id,
            "initial_response": resp.get("response", ""),
        })
        print(f"✓ Speak conversation started: {conversation_id}")

        # Follow-up questions
        for question in SPEAK_QUESTIONS[1:]:
            time.sleep(3)
            follow_up = requests.post(
                f"{BASE}/speak/conversations/{conversation_id}/messages",
                headers=HEADERS,
                json={"message": question},
            ).json()

            if "error" not in follow_up:
                conversations[-1][f"response_{question[:30]}"] = follow_up.get("response", "")

        time.sleep(2)

    print(f"✓ Completed {len(conversations)} Speak conversations")
    return conversations

Running the Full Pipeline

def run_annual_planning():
    print("=" * 60)
    print(f"{PLAN_YEAR} ANNUAL PLANNING KICKOFF")
    print("=" * 60)

    # Stage 1: CRM Analysis
    print("\n--- Stage 1: CRM Data Analysis ---")
    crm_analysis = analyze_crm_data(SAMPLE_CRM_DATA)

    # Stage 2: Create Personas
    print("\n--- Stage 2: Creating Personas from CRM Data ---")
    persona_descs = generate_persona_descriptions(crm_analysis)
    persona_ids = create_personas_from_descriptions(persona_descs)

    # Stage 3: Theme Focus Group
    print("\n--- Stage 3: Theme Validation Focus Group ---")
    fg = run_theme_focus_group(persona_ids)
    fg_results = poll_focus_group(fg["id"])

    # Stage 4: Market Research
    print("\n--- Stage 4: Mave Market Research ---")
    market_research = research_market_context()

    # Stage 5: Generate Plan
    print("\n--- Stage 5: Generating Annual Plan ---")
    plan_sections = generate_annual_plan(crm_analysis, fg_results, market_research)

    # Compile plan document
    plan_doc = f"# {COMPANY['name']}{PLAN_YEAR} Annual Marketing Plan\n\n"
    for section, content in plan_sections.items():
        plan_doc += f"## {section.replace('_', ' ').title()}\n\n{content}\n\n---\n\n"

    with open(f"annual_plan_{PLAN_YEAR}.md", "w") as f:
        f.write(plan_doc)
    print(f"\n✓ Draft plan saved to annual_plan_{PLAN_YEAR}.md")

    # Stage 6: Speak Validation
    print("\n--- Stage 6: Speak Validation Conversations ---")
    plan_summary = plan_sections.get("executive_summary", plan_doc[:2000])
    speak_results = run_speak_conversations(persona_ids, plan_summary)

    # Save everything
    output = {
        "crm_analysis": crm_analysis,
        "personas": persona_descs,
        "persona_ids": persona_ids,
        "theme_validation": {
            "results": fg_results.get("results", []),
        },
        "market_research": {
            label: data["content"][:500]
            for label, data in market_research["research"].items()
        },
        "plan_sections": list(plan_sections.keys()),
        "speak_conversations": len(speak_results),
    }

    with open(f"planning_data_{PLAN_YEAR}.json", "w") as f:
        json.dump(output, f, indent=2)

    print(f"\n{'='*60}")
    print(f"{PLAN_YEAR} ANNUAL PLAN — COMPLETE")
    print(f"{'='*60}")
    print(f"  Plan document: annual_plan_{PLAN_YEAR}.md")
    print(f"  Supporting data: planning_data_{PLAN_YEAR}.json")
    print(f"  Personas created: {len(persona_ids)}")
    print(f"  Themes validated: {len(CANDIDATE_THEMES)}")
    print(f"  Plan sections: {len(plan_sections)}")
    print(f"  Speak conversations: {len(speak_results)}")

    return plan_sections


if __name__ == "__main__":
    run_annual_planning()

Example Output

The pipeline produces a full plan document. Here’s a sample executive summary section:
## Executive Summary

Acme's 2027 marketing plan is built on three validated strategic themes,
persona-validated by 5 customer segments representing 280 active accounts.

**Theme Priority (Focus Group Ranking, N=30):**
1. Integration Ecosystem (ranked #1 by 40% of respondents)
2. Product-Led Growth (ranked #1 by 27%)
3. Content & Thought Leadership (ranked #1 by 20%)

**Key Metrics Targets:**
- ARR: $4.2M → $9.5M (126% growth)
- Customers: 280 → 600
- Net Revenue Retention: 115% → 130%
- CAC Payback: 12 months → 9 months

**Budget Allocation:**
- Product-Led Growth: 35% ($1.2M)
- Integration Ecosystem: 25% ($875K)
- Content & Thought Leadership: 20% ($700K)
- Enterprise Expansion: 15% ($525K)
- International: 5% ($175K)

**Validated by:** 5 CRM-derived personas across enterprise, mid-market,
agency, startup, and churned segments. 3 Speak conversations confirmed
integration ecosystem as the top priority across all segments.

Variations

Run the pipeline 3 times with different theme priorities (aggressive, balanced, conservative):
scenarios = {
    "aggressive": {"budget_multiplier": 1.5, "growth_target": "150%"},
    "balanced": {"budget_multiplier": 1.0, "growth_target": "100%"},
    "conservative": {"budget_multiplier": 0.7, "growth_target": "60%"},
}
for name, params in scenarios.items():
    COMPANY["growth_target"] = params["growth_target"]
    plan = run_annual_planning()
Replace SAMPLE_CRM_DATA with a real CSV export:
def load_crm_csv(path: str) -> list[dict]:
    with open(path) as f:
        return list(csv.DictReader(f))

crm_data = load_crm_csv("crm_export.csv")
crm_analysis = analyze_crm_data(crm_data)
If you don’t need voice validation, skip Stage 6. The plan is still validated by Focus Groups and market research:
# Comment out Stage 6
# speak_results = run_speak_conversations(persona_ids, plan_summary)
After the company-level plan, generate department-specific versions:
departments = ["demand_gen", "product_marketing", "content", "brand"]
for dept in departments:
    resp = requests.post(f"{BASE}/generate", headers=HEADERS, json={
        "prompt": f"Extract the {dept} team's plan from the company plan: {plan_doc[:3000]}",
        "workspace_id": WORKSPACE_ID,
    })

Credits Estimate

StageTypical CostNotes
CRM analysis (local)0 creditsRuns locally
Generate persona descriptions (1 chat)5–15 credits
Create 5 personas0Persona creation is free
Focus Group (N=30, 5 questions)150–300 creditsTheme validation
Mave research (3 turns)30–90 creditsMarket context
Generate plan (9 sections)90–180 creditsOne Generate call per section
Speak conversations (3 personas)30–90 creditsOptional voice validation
Total (full pipeline)~305–675 credits
Total (without Speak)~275–585 credits
This is the most credit-intensive playbook. Run a quick version first (N=15 focus group, 3 plan sections, no Speak) to validate the pipeline before committing to the full run.

See Also

Market Entry Research

Deep market research for new opportunities

Positioning Workshop

Validate positioning as part of planning

Pricing Research

Test pricing alongside strategic planning

Brand Perception Audit

Measure brand health before planning

News-Triggered Research

Monitor market changes during plan execution

Focus Groups

Question types and configuration