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

Amplitude tracks revenue events with properties like plan type, ARPU, and segment. You pull revenue metrics, compute ARPU by user segment, and run a Mavera Focus Group asking synthetic personas to rate willingness to pay at specific price points using Slider and NPS question types. The result is pricing validation grounded in real revenue data and tested against persona reactions.

Architecture

Code

import os, requests, time, json

AMP_KEY = os.environ["AMPLITUDE_API_KEY"]
AMP_SECRET = os.environ["AMPLITUDE_SECRET_KEY"]
MV = os.environ["MAVERA_API_KEY"]
MB = "https://app.mavera.io/api/v1"
MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
amp_auth = (AMP_KEY, AMP_SECRET)

r = requests.get(
    "https://amplitude.com/api/2/revenue/day",
    auth=amp_auth,
    params={
        "start": "20260215",
        "end": "20260317",
        "m": "revenue",
    },
)
if r.status_code == 429:
    time.sleep(int(r.headers.get("Retry-After", 60)))
    r = requests.get(
        "https://amplitude.com/api/2/revenue/day",
        auth=amp_auth,
        params={"start": "20260215", "end": "20260317", "m": "revenue"},
    )
r.raise_for_status()
revenue_data = r.json()

series = revenue_data.get("data", {}).get("series", [])
xvals = revenue_data.get("data", {}).get("xValues", [])

total_revenue = 0
paying_users = 0
for seg in series:
    vals = seg.get("values", seg.get("value", []))
    if isinstance(vals, list):
        total_revenue += sum(v for v in vals if isinstance(v, (int, float)))

SEGMENTS = {
    "Starter": {"price": 29, "arpu": 29, "users_est": 1200},
    "Pro": {"price": 79, "arpu": 74, "users_est": 800},
    "Enterprise": {"price": 249, "arpu": 312, "users_est": 150},
}

segment_summary = "\n".join(
    f"- {name}: ${info['price']}/mo list, ${info['arpu']} actual ARPU, ~{info['users_est']} users"
    for name, info in SEGMENTS.items()
)

personas = []
for seg_name, info in SEGMENTS.items():
    persona = requests.post(f"{MB}/personas", headers=MH, json={
        "name": f"Amplitude Revenue: {seg_name}",
        "description": (
            f"{seg_name} plan subscriber. Paying ${info['arpu']}/mo (list ${info['price']}/mo). "
            f"Estimated {info['users_est']} users in this tier. "
            f"{'Price-sensitive individual or small team.' if info['price'] < 50 else 'Mid-market team with budget authority.' if info['price'] < 150 else 'Enterprise buyer with procurement process.'}"
        ),
        "psychographic": {
            "plan": seg_name.lower(),
            "arpu": info["arpu"],
            "price_sensitivity": "high" if info["price"] < 50 else "medium" if info["price"] < 150 else "low",
        },
    }).json()
    personas.append(persona)
    time.sleep(0.3)

PROPOSED_PRICES = {
    "Starter": {"current": 29, "proposed": 39},
    "Pro": {"current": 79, "proposed": 99},
    "Enterprise": {"current": 249, "proposed": 299},
}

price_context = "\n".join(
    f"- {name}: ${p['current']}/mo → ${p['proposed']}/mo ({(p['proposed']-p['current'])/p['current']:.0%} increase)"
    for name, p in PROPOSED_PRICES.items()
)

fg = requests.post(f"{MB}/focus-groups", headers=MH, json={
    "name": "Amplitude: Pricing Willingness-to-Pay Study",
    "persona_ids": [p["id"] for p in personas],
    "questions": [
        f"We're considering adjusting pricing:\n{price_context}\nRate your willingness to pay the new price on a scale of 1-10, where 1 = 'I would cancel immediately' and 10 = 'No hesitation, still great value'. Explain your rating.",
        "At what monthly price would this product become too expensive for you to justify? Give a specific dollar amount and explain the tipping point.",
        "If the price increased but included ONE new feature, what feature would make the increase worth it? Be specific about the capability and why it matters to you.",
        "On a scale of 0-10, how likely are you to recommend this product to a colleague at the CURRENT price? What about at the NEW price? (NPS format)",
        "If we offered annual billing at a 20% discount, would that change your reaction to the price increase? Why or why not?",
    ],
    "context": f"""Revenue analysis from Amplitude (last 30 days):

CURRENT SEGMENTS:
{segment_summary}

PROPOSED PRICE CHANGES:
{price_context}

Total estimated MRR: ${sum(s['arpu'] * s['users_est'] for s in SEGMENTS.values()):,}
Projected MRR at new prices (assuming 0% churn): ${sum(PROPOSED_PRICES[n]['proposed'] * SEGMENTS[n]['users_est'] for n in SEGMENTS):,}""",
    "responses_per_persona": 2,
}).json()

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

print(f"Focus Group: {data.get('id')}{data.get('status')}\n")
for resp in data.get("responses", []):
    print(f"[{resp.get('persona_id','?')}] {resp.get('question','')[:80]}")
    print(f"  → {resp.get('answer','')[:300]}\n")

Example Output

Focus Group: fg_amp_pricing_4m7b — completed

[Starter] Rate willingness to pay $39/mo (up from $29)
  → 4/10. That's a 34% increase with no new value. I chose this plan
    because it was under $30/mo — a threshold I can expense without
    approval. At $39, I need my manager's sign-off, which means a
    conversation I don't want to have. You'd lose me at $35.

[Pro] At what price does this become too expensive?
  → $120/mo is my ceiling. Right now at $79 I feel good about the
    value. At $99 I'd start comparing alternatives. At $120 I'd run
    a formal evaluation of competitors. The gap between "easy renewal"
    and "procurement review" is about $100/mo for our team size.

[Enterprise] If price increased but included ONE new feature
  → SSO/SAML integration. We're paying $249/mo and still managing
    user access manually. Every enterprise tool we buy has SSO. If
    you added it at $299, that's a no-brainer — I'm already spending
    more than that on the workaround.

[Starter] NPS: Current vs. new price
  → Current price: 8/10 — I actively recommend it to freelancer
    friends. New price: 5/10 — I'd still use it but stop recommending
    it because cheaper alternatives exist. That 3-point NPS drop
    represents your entire word-of-mouth engine for small users.

[Pro] Annual billing at 20% discount
  → Yes, completely changes it. $99/mo × 12 = $1,188/yr. At 20%
    off that's $950/yr or ~$79/mo — exactly what I'm paying now.
    You get cash upfront, I get price stability. Win-win. But only
    if you lock the rate for at least 2 years.

Error Handling

The /api/2/revenue/day endpoint only returns data if you track revenue events via amplitude.revenue() or the Revenue API. If you only track subscriptions externally, import revenue data via the HTTP API or use a CDP integration.
The sample ARPU values are hardcoded for demonstration. In production, calculate ARPU from the Revenue API response by dividing total revenue by paying user count per segment.
Mavera Focus Groups support free-text responses. To simulate Slider and NPS question types, phrase questions with explicit scales (1-10, 0-10) and ask personas to provide both a numeric rating and explanation. Parse numeric values from the response text.
Personas may anchor to the current price in their responses. For more accurate willingness-to-pay data, run separate Focus Groups with different proposed prices (Van Westendorp method: too cheap, cheap, expensive, too expensive).

What’s Next

Amplitude Integration

Back to Amplitude integration overview

Persona Calibration

Calibrate personas from Amplitude composition data

Focus Groups API

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

Personas API

Full reference for POST /api/v1/personas