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 HubSpot contacts have custom properties — persona field, buying committee role, company size tier. Before launching a campaign, you want synthetic feedback from each segment: Will the messaging resonate with economic buyers differently than end users? You extract segments, map each to a Mavera persona, then run a Focus Group with segment-specific questions.

Architecture

Code

import os, requests, time

HS = os.environ["HUBSPOT_ACCESS_TOKEN"]
MV = os.environ["MAVERA_API_KEY"]
HB = "https://api.hubapi.com/crm/v3"
MB = "https://app.mavera.io/api/v1"
MH = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

SEGMENTS = [
    {"prop": "hs_persona", "val": "persona_economic_buyer", "label": "Economic Buyer"},
    {"prop": "hs_persona", "val": "persona_end_user", "label": "End User"},
    {"prop": "hs_persona", "val": "persona_champion", "label": "Internal Champion"},
    {"prop": "hs_persona", "val": "persona_technical", "label": "Technical Evaluator"},
]

# 1. Create personas from HubSpot segments
persona_ids = []
for seg in SEGMENTS:
    r = requests.post(f"{HB}/objects/contacts/search",
        headers={"Authorization": f"Bearer {HS}"},
        json={"filterGroups": [{"filters": [
            {"propertyName": seg["prop"], "operator": "EQ", "value": seg["val"]}
        ]}], "properties": ["jobtitle", "industry"], "limit": 30})
    if r.status_code == 429: time.sleep(1); continue
    r.raise_for_status()
    contacts = r.json().get("results", [])
    if not contacts: continue

    titles = list({c["properties"].get("jobtitle","") for c in contacts if c["properties"].get("jobtitle")})[:5]
    p = requests.post(f"{MB}/personas", headers=MH, json={
        "name": f"HubSpot: {seg['label']}",
        "description": f"{seg['label']} segment. Titles: {', '.join(titles)}. N={len(contacts)}.",
        "demographic": {"job_titles": titles},
    }).json()
    persona_ids.append({"id": p["id"], "label": seg["label"]})
    time.sleep(0.3)

# 2. Run Focus Group
CAMPAIGN = '''We're launching an AI analytics platform that cuts reporting time by 60%.
Early access: $499/mo for teams up to 50. "Stop building dashboards. Start making decisions."'''

fg = requests.post(f"{MB}/focus-groups", headers=MH, json={
    "name": "Q3 Campaign Pre-Launch",
    "persona_ids": [p["id"] for p in persona_ids],
    "questions": [
        "How does this value proposition resonate with you?",
        "Is $499/mo reasonable for this type of tool?",
        "What objections would you raise to your team?",
        "How would you describe this to a colleague in one sentence?",
    ],
    "context": CAMPAIGN,
    "responses_per_persona": 3,
}).json()

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

for resp in data.get("responses", []):
    label = next((p["label"] for p in persona_ids if p["id"] == resp.get("persona_id")), "?")
    print(f"[{label}] {resp.get('question','')[:60]}")
    print(f"  → {resp.get('answer','')[:200]}\n")

Example Output

[Economic Buyer] Is $499/mo reasonable?
  → Under $10/user/month — competitive. I'd want an ROI calculator first.

[End User] How does this resonate?
  → "Stop building dashboards" hits home. 3 hours/week on reports nobody reads.

[Technical Evaluator] What objections?
  → Data security and integration depth. SOC 2 non-negotiable.

Error Handling

If hs_persona doesn’t exist, Search returns 400. List properties with GET /crm/v3/properties/contacts.
Large groups (4+ personas × 4 questions) may take 60–90s. The loop allows ~100s. Increase attempts for larger configs.

HubSpot Integration

Focus Groups API