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

Through LinkedIn’s Recruiter System Connect (RSC) or manual CSV exports from LinkedIn Recruiter, you have rich candidate profile data — titles, skills, industries, seniority levels, locations. Instead of building talent personas from intuition, you feed real candidate data into Mavera to create data-grounded personas, then test your employer value propositions against them. Flow: LinkedIn RSC export (CSV/JSON) → Parse profiles → Mavera POST /personas (per segment) → POST /focus-groups (test EVPs) → Validated employer value props

Architecture

Code

import os, json, csv, requests, time
from collections import defaultdict

MV = os.environ["MAVERA_API_KEY"]
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}

# 1. Load exported LinkedIn candidate data
# In production, this comes from RSC integration or Recruiter CSV export
SAMPLE_CANDIDATES = [
    {"title": "Staff Engineer", "skills": ["Python", "Kubernetes", "System Design"], "industry": "Technology", "seniority": "Senior", "location": "SF Bay Area"},
    {"title": "Engineering Manager", "skills": ["Team Leadership", "Agile", "Java"], "industry": "Technology", "seniority": "Manager", "location": "NYC"},
    {"title": "Senior Data Scientist", "skills": ["ML", "Python", "Statistics"], "industry": "Finance", "seniority": "Senior", "location": "Chicago"},
    {"title": "VP Engineering", "skills": ["Strategy", "Team Building", "Architecture"], "industry": "SaaS", "seniority": "Executive", "location": "Remote"},
    {"title": "Backend Developer", "skills": ["Node.js", "PostgreSQL", "AWS"], "industry": "E-commerce", "seniority": "Mid", "location": "Austin"},
    {"title": "ML Engineer", "skills": ["PyTorch", "MLOps", "Python"], "industry": "AI/ML", "seniority": "Senior", "location": "Seattle"},
    {"title": "Platform Engineer", "skills": ["Terraform", "Kubernetes", "Go"], "industry": "Fintech", "seniority": "Senior", "location": "London"},
]

# For CSV files from LinkedIn Recruiter export:
# with open("linkedin_export.csv") as f:
#     reader = csv.DictReader(f)
#     SAMPLE_CANDIDATES = [
#         {"title": row["Current Title"], "skills": row.get("Skills","").split(","),
#          "industry": row.get("Industry",""), "seniority": row.get("Seniority","")}
#         for row in reader
#     ]

# 2. Segment by seniority
segments = defaultdict(list)
for c in SAMPLE_CANDIDATES:
    segments[c["seniority"]].append(c)

# 3. Create personas per segment
persona_ids = []
for seniority, candidates in segments.items():
    if not candidates:
        continue
    titles = list({c["title"] for c in candidates})[:5]
    all_skills = [s for c in candidates for s in c.get("skills", [])]
    top_skills = sorted(set(all_skills), key=all_skills.count, reverse=True)[:5]
    industries = list({c["industry"] for c in candidates})[:3]
    locations = list({c.get("location", "N/A") for c in candidates})[:3]

    p = requests.post(f"{MV_BASE}/personas", headers=MV_H, json={
        "name": f"LI Talent: {seniority}",
        "description": (
            f"{seniority}-level talent. N={len(candidates)}. "
            f"Titles: {', '.join(titles)}. Skills: {', '.join(top_skills)}. "
            f"Industries: {', '.join(industries)}. Locations: {', '.join(locations)}."
        ),
        "demographic": {
            "job_titles": titles,
            "industries": industries,
            "locations": locations,
        },
        "psychographic": {
            "seniority": seniority,
            "skills": top_skills,
            "career_stage": seniority.lower(),
        },
    }).json()
    persona_ids.append({"id": p["id"], "seniority": seniority, "n": len(candidates)})
    print(f"Persona: {p['id']}{seniority} ({len(candidates)} profiles)")
    time.sleep(0.3)

# 4. Test employer value propositions
EVPS = {
    "mission": "We're on a mission to make AI accessible to every business, not just tech giants.",
    "growth": "Engineers here get promoted 2x faster than industry average. We invest in your career.",
    "tech": "Our stack is modern (Go, K8s, Postgres) and you'll ship to production on day one.",
    "culture": "Async-first, no meeting Wednesdays, unlimited PTO that people actually take (avg 28 days).",
}

evp_block = "\n".join(f"- **{k.title()}**: {v}" for k, v in EVPS.items())

fg = requests.post(f"{MV_BASE}/focus-groups", headers=MV_H, json={
    "name": "Employer Value Proposition Test",
    "persona_ids": [p["id"] for p in persona_ids],
    "questions": [
        {"type": "ranking", "text": f"Rank these EVPs by how compelling they are to YOU:\n{evp_block}"},
        "Which EVP would make you respond to a recruiter's InMail?",
        "Which EVP feels like empty marketing? Why?",
        "What's missing from these value props that you'd need to hear?",
        "Write a one-line EVP that would make YOU apply.",
    ],
    "context": f"Company: Series B AI startup, 120 employees, $40M raised.\n\nValue Propositions:\n{evp_block}",
    "responses_per_persona": 3,
}).json()

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

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

Example Output

{
  "evp_rankings_by_seniority": {
    "Senior": ["tech", "culture", "growth", "mission"],
    "Manager": ["growth", "culture", "mission", "tech"],
    "Executive": ["mission", "growth", "culture", "tech"],
    "Mid": ["growth", "tech", "culture", "mission"]
  },
  "key_findings": [
    {
      "seniority": "Senior",
      "insight": "Tech stack is #1. 'Go + K8s + Postgres is the exact stack I want to work in. Ship on day one — prove it with a GitHub repo.'"
    },
    {
      "seniority": "Executive",
      "insight": "Mission is #1 but needs proof. 'Every AI company says this. Show me 3 non-tech customers using your product.'"
    },
    {
      "seniority": "Mid",
      "insight": "Growth is #1. '2x faster promotions — how? Show me the rubric and the data. Otherwise it's just a recruiting line.'"
    }
  ],
  "custom_evps": [
    { "seniority": "Senior", "evp": "We need someone to redesign our payment pipeline from 800ms to 200ms. Interested?" },
    { "seniority": "Executive", "evp": "120 engineers, $40M raised, and the exec team still writes code on Fridays. Join us." }
  ]
}

Error Handling

LinkedIn Recruiter exports come as CSV or XLSX. Parse with csv (Python) or csv-parse (Node). Column names vary by export version — map them dynamically.
Never store or send candidate PII (names, emails, profile URLs) to Mavera. Aggregate to title/skill/industry level only. Comply with LinkedIn’s Terms of Service.
LinkedIn Recruiter exports may be capped at 1,000-2,500 profiles. For larger datasets, use RSC integration for programmatic access or run multiple exports by search criteria.