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

Your product has 10 features, but only 3 are widely adopted. You pull feature usage metrics from Mixpanel, identify underused features with high retention correlation, then run a Focus Group asking “Are you aware of ?” (dichotomous yes/no + open-ended follow-up) and generate feature awareness campaigns for the gaps.

Architecture

Code

import os, requests, time, json

MP_SA = os.environ["MIXPANEL_SERVICE_ACCOUNT"]
MP_SECRET = os.environ["MIXPANEL_SECRET"]
MP_PROJECT = os.environ["MIXPANEL_PROJECT_ID"]
MV = os.environ["MAVERA_API_KEY"]
MB = "https://app.mavera.io/api/v1"
MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

FEATURES = {
    "Dashboard View": "Main dashboard with analytics overview",
    "Report Create": "Custom report builder",
    "Alert Set": "Automated alerts and notifications",
    "API Call": "Programmatic API access",
    "Export Data": "CSV/Excel data export",
    "Team Invite": "Add team members to workspace",
    "Integration Connect": "Connect third-party tools",
    "Template Use": "Pre-built report templates",
    "Scheduled Report": "Automated recurring reports",
    "Custom Widget": "Build custom dashboard widgets",
}

r = requests.post(
    "https://mixpanel.com/api/query/insights",
    auth=(MP_SA, MP_SECRET),
    json={
        "project_id": MP_PROJECT,
        "bookmark_id": None,
        "params": {
            "type": "unique",
            "events": [{"event": name} for name in FEATURES.keys()],
            "from_date": "2026-02-15",
            "to_date": "2026-03-17",
        },
    },
)
if r.status_code == 429:
    time.sleep(60)
r.raise_for_status()
insights = r.json()

total_users_r = requests.post(
    "https://mixpanel.com/api/query/insights",
    auth=(MP_SA, MP_SECRET),
    json={
        "project_id": MP_PROJECT,
        "params": {"type": "unique", "events": [{"event": "Login"}],
                   "from_date": "2026-02-15", "to_date": "2026-03-17"},
    },
)
total_users_data = total_users_r.json()
total_users = 5000

feature_adoption = []
series = insights.get("series", {})
for feature_name, desc in FEATURES.items():
    values = series.get(feature_name, {})
    unique_users = sum(values.values()) if isinstance(values, dict) else 0
    adoption_rate = unique_users / max(total_users, 1)
    feature_adoption.append({
        "feature": feature_name,
        "description": desc,
        "unique_users": unique_users,
        "adoption_rate": adoption_rate,
    })

feature_adoption.sort(key=lambda f: f["adoption_rate"])

underused = [f for f in feature_adoption if f["adoption_rate"] < 0.3]
well_adopted = [f for f in feature_adoption if f["adoption_rate"] >= 0.5]

adoption_table = "\n".join(
    f"- {f['feature']}: {f['unique_users']} users ({f['adoption_rate']:.0%} adoption) — {f['description']}"
    for f in feature_adoption
)

PERSONA_IDS = os.environ.get("FEATURE_PERSONA_IDS", "").split(",")
if not PERSONA_IDS[0]:
    for name, desc in [
        ("Active Free User", "Uses the product daily on a free plan. Hasn't upgraded because they don't know what they're missing."),
        ("New Pro User", "Recently upgraded. Using 2-3 features but hasn't explored the full platform."),
        ("Power User Champion", "Uses most features. Internal advocate. Wants to get more from the tool."),
    ]:
        p = requests.post(f"{MB}/personas", headers=MH, json={"name": name, "description": desc}).json()
        PERSONA_IDS.append(p["id"])
        time.sleep(0.3)

underused_list = ", ".join(f["feature"] for f in underused[:5])

fg = requests.post(f"{MB}/focus-groups", headers=MH, json={
    "name": "Feature Awareness & Adoption",
    "persona_ids": [pid for pid in PERSONA_IDS if pid],
    "questions": [
        f"Are you aware of these features: {underused_list}? For each, answer Yes or No, then explain why you do or don't use it.",
        "If you discovered a feature that could save you 2 hours per week, how would you want to learn about it? (in-app tooltip, email, video tutorial, peer recommendation, or other?)",
        f"Rank these underused features by how useful they WOULD be if you knew about them: {underused_list}. Explain your #1.",
        "What's the biggest gap in this product — a feature you wish existed?",
    ],
    "context": f"""Feature adoption data for our product (last 30 days):

{adoption_table}

Well-adopted (>50%): {', '.join(f['feature'] for f in well_adopted)}
Underused (<30%): {underused_list}

Total active users: ~{total_users}""",
    "responses_per_persona": 2,
}).json()

for _ in range(24):
    time.sleep(5)
    data = requests.get(f"{MB}/focus-groups/{fg['id']}", headers=MH).json()
    if data.get("status") == "completed":
        break

print("--- Focus Group Results ---\n")
for resp in data.get("responses", []):
    print(f"[{resp.get('persona_id','?')}] {resp.get('question','')[:70]}")
    print(f"  → {resp.get('answer','')[:250]}\n")

print("\n--- Generating Feature Campaigns ---\n")
for feature in underused[:3]:
    gen = requests.post(f"{MB}/generations", headers=MH, json={
        "prompt": (
            f"Create a feature awareness campaign for '{feature['feature']}' ({feature['description']}). "
            f"Current adoption: {feature['adoption_rate']:.0%} of users. "
            f"Generate:\n"
            f"1. In-app banner copy (max 20 words + CTA)\n"
            f"2. Email subject line + 50-word body\n"
            f"3. Tooltip text (max 15 words)\n"
            f"4. 30-second video script outline\n"
            f"Focus on the user benefit, not the feature name."
        ),
    }).json()

    print(f"Feature: {feature['feature']} ({feature['adoption_rate']:.0%} adoption)")
    print(gen.get("output", gen.get("content", ""))[:500])
    print()

Example Output

--- Focus Group Results ---

[Active Free User] Are you aware of: Alert Set, API Call, Custom Widget?
  → Alert Set: No — I didn't know I could get notified. I check the
    dashboard manually every morning. If I could get a Slack ping when
    a metric drops, that changes my workflow entirely.
    API Call: No — I'm not a developer.
    Custom Widget: No — what does it do?

[New Pro User] Rank by usefulness
  → #1: Scheduled Report. I build the same report every Monday. If I
    could automate it, I'd save 45 minutes/week and look more organized
    to my manager. That alone justifies the Pro upgrade.

--- Feature Campaigns ---

Scheduled Report (12% adoption)
1. Banner: "Stop rebuilding Monday's report. Automate it in 30 seconds." [Set Up →]
2. Email: Subject: "You rebuilt this report 4 times last month"
   Body: We noticed you create similar reports weekly. Scheduled Reports
   delivers them to your inbox automatically — same filters, same format,
   zero effort. Set it up in 30 seconds.
3. Tooltip: "Run this report automatically every week"
4. Video: Open on frustrated user rebuilding report → show 3-click
   setup → reveal report landing in inbox → "45 minutes back, every week."

Error Handling

The Insights API requires specific params structure with type (unique, general, average), events, and date range. Test queries in Mixpanel’s Insights UI first, then export the API call from the UI’s “API” button.
Features must correspond to tracked Mixpanel events. If your events are named differently (e.g. report.created instead of Report Create), update the FEATURES dict to match your event names exactly.
This job chains two Mavera calls — Focus Group then Generate. Budget 2–4 minutes total. The Focus Group must complete before generating campaigns, since the results inform messaging strategy.

What’s Next

Mixpanel Integration

Back to Mixpanel integration overview

Event-Based Persona Enrichment

Enrich personas with raw event patterns

Focus Groups API

Full reference for POST /api/v1/focus-groups

Generate API

Full reference for POST /api/v1/generations