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

Win/loss analysis usually happens after deals close — too late to course-correct. This job queries Opportunities at each stage (Negotiation, Closed Won, Closed Lost), extracts Contact Roles and notes, then runs a synthetic focus group with personas mapped to each stage. You get on-demand win/loss analysis instead of waiting for the quarterly retrospective.

Architecture

Code

import os, requests

SF   = os.environ["SALESFORCE_INSTANCE"]
SF_T = os.environ["SALESFORCE_ACCESS_TOKEN"]
MV_K = os.environ["MAVERA_API_KEY"]
SF_HEADERS = {"Authorization": f"Bearer {SF_T}"}
MV_HEADERS = {"Authorization": f"Bearer {MV_K}", "Content-Type": "application/json"}

STAGES = ["Negotiation", "Closed Won", "Closed Lost"]
persona_ids = []

for stage in STAGES:
    soql = (
        f"SELECT Id, Name, Amount, "
        f"(SELECT Contact.Name, Contact.Title, Role FROM OpportunityContactRoles) "
        f"FROM Opportunity WHERE StageName = '{stage}' LIMIT 20"
    )
    opps = requests.get(
        f"https://{SF}/services/data/v66.0/query",
        headers=SF_HEADERS, params={"q": soql},
    ).json()["records"]

    titles = []
    for opp in opps:
        roles = opp.get("OpportunityContactRoles", {})
        if roles and roles.get("records"):
            titles.extend(r["Contact"]["Title"] or "Stakeholder" for r in roles["records"])
    top_title = max(set(titles), key=titles.count) if titles else "Decision Maker"

    pr = requests.post(
        "https://app.mavera.io/api/v1/personas", headers=MV_HEADERS,
        json={
            "name": f"{stage} Buyer — {top_title}",
            "description": f"Buyers in '{stage}' stage. Common role: {top_title}. Based on {len(opps)} opps.",
        },
    )
    pr.raise_for_status()
    persona_ids.append(pr.json()["id"])

fg = requests.post(
    "https://app.mavera.io/api/v1/focus-groups", headers=MV_HEADERS,
    json={
        "persona_ids": persona_ids,
        "questions": [
            {"type": "nps", "text": "How likely are you to recommend our product to a peer?"},
            {"type": "open_ended", "text": "What nearly stopped you from buying?"},
            {"type": "open_ended", "text": "What was the single biggest factor in your decision?"},
            {"type": "open_ended", "text": "If you could change one thing about our sales process, what would it be?"},
        ],
    },
).json()

print(f"Focus Group ID: {fg['id']}")
for a in fg.get("responses", []):
    print(f"  [{a['persona_name']}] {a['question']}: {a['response']}")

Example Output

{
  "id": "fg_4kN8x",
  "responses": [
    {
      "persona_name": "Closed Lost Buyer — VP Engineering",
      "question": "What nearly stopped you from buying?",
      "response": "Your pricing model penalizes teams that scale. We hit 50 seats and the per-seat cost made no sense compared to a platform license."
    },
    {
      "persona_name": "Closed Won Buyer — Director of Product",
      "question": "What was the single biggest factor in your decision?",
      "response": "The POC was seamless — your SE built an integration in our sandbox within a day. Competitors needed two weeks."
    },
    {
      "persona_name": "Negotiation Buyer — CTO",
      "question": "How likely are you to recommend our product to a peer?",
      "response": "7 — I'd recommend it once I see the first quarterly ROI. Right now I believe the promise but need proof."
    }
  ]
}
Run this monthly to track sentiment drift across stages. Compare NPS scores over time to detect if your sales experience is improving or degrading.

Salesforce Overview

Back to all 8 Salesforce jobs

Account Intelligence Brief

Next: AI research briefs from Account data