Skip to main content
Rep intelligence layers run across multiple analyses to surface patterns no single call can show. Three async jobs:
  • persona_assign — which of 5 sales archetypes does this rep most resemble?
  • methodology_assign — what primary + secondary methodology do they use?
  • synthesis — coaching summary with strengths, gaps, action plan, score trends
Each job is async (returns 202 + job_id), polls a single /intel-jobs/:job_id endpoint until complete, and writes a result that’s queryable via dedicated GET endpoints (/persona, /methodology, /synthesis/latest).

When to run each

JobCadenceWhen in the rep’s lifecycle
persona_assignOnce on onboarding, then quarterlyAfter 5+ analyses exist for the rep
methodology_assignOnce on onboarding, then quarterlyAfter 5+ analyses exist for the rep
synthesisWeekly or on-demandAnytime the rep has 3+ recent calls

The analysis_ids vs recording_urls decision

Both async jobs accept either an explicit list of analysis UUIDs or a list of recording URLs. Pick based on what you have:
  • analysis_ids — much faster (~15–30s). The analyses are already complete; the job only does the meta-step. Use this when the rep has historical analyses already.
  • recording_urls — slower (potentially several minutes). Each URL is run through the analysis pipeline first (with 30-day URL caching), then the meta-step runs. Use this for fresh onboarding when no analyses exist yet.
You can pass at most one — they’re mutually exclusive.

Example: assign a persona from existing analyses

curl -X POST \
  https://parlay-api-dev-o7nogixtqq-uc.a.run.app/v1/orgs/demo-acme/reps/alex-smith/persona/assign \
  -H "Authorization: Bearer pk_sandbox_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "analysis_ids": [
      "f2782fc7-5355-48bf-a314-d6bf90bc4907",
      "e667ee24-ac9a-4d8a-aebc-640b609ad213"
    ]
  }'
You get back a 202 with { job_id, status: "queued", created_at }.

Polling the job

curl https://parlay-api-dev-o7nogixtqq-uc.a.run.app/v1/orgs/demo-acme/reps/alex-smith/intel-jobs/<job_id> \
  -H "Authorization: Bearer pk_sandbox_YOUR_KEY"
When status === "completed", result contains the assignment:
{
  "id": "fa278916-52bb-40a1-8dee-01a927f3faf4",
  "status": "completed",
  "result": {
    "persona": "hard_worker",
    "confidence": 0.9,
    "justification": "Across both calls, the rep consistently demonstrates a methodical and process-driven approach...",
    "secondary_persona": null
  },
  "cost_usd_cents": 1,
  "completed_at": "2026-04-24T18:53:28.435+00:00"
}

Reading the assignment later

/persona/assign writes to persona_assignments. To read the latest at any time:
curl https://parlay-api-dev-o7nogixtqq-uc.a.run.app/v1/orgs/demo-acme/reps/alex-smith/persona \
  -H "Authorization: Bearer pk_sandbox_YOUR_KEY"
History (every prior assignment, AI or manual) is at /persona/history.

Manual override

If a manager knows the rep better than the model:
curl -X PUT \
  https://parlay-api-dev-o7nogixtqq-uc.a.run.app/v1/orgs/demo-acme/reps/alex-smith/persona \
  -H "Authorization: Bearer pk_sandbox_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "persona": "challenger",
    "justification": "Veteran seller — 8 years of enterprise experience. AI-assigned hard_worker doesn't reflect this."
  }'
This appends to history with source: "manual". The previous AI assignment is preserved in history but no longer the “current” one.

Methodology — same shape, different output

Replace /persona/ with /methodology/ and the response shape becomes { primary, secondary }:
{
  "primary": {
    "methodologies": { "slug": "spin", "name": "SPIN Selling", "description": "..." },
    "justification": "...",
    "source": "ai"
  },
  "secondary": {
    "methodologies": { "slug": "sandler", "name": "Sandler Selling System", "description": "..." },
    "justification": "...",
    "source": "ai"
  }
}
secondary may be null.

Synthesis — the coaching report

Synthesis takes either lookback_count (newest N analyses) or analysis_ids:
curl -X POST \
  https://parlay-api-dev-o7nogixtqq-uc.a.run.app/v1/orgs/demo-acme/reps/alex-smith/synthesis \
  -H "Authorization: Bearer pk_sandbox_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "lookback_count": 10 }'
Result shape:
{
  "result": {
    "summary": "This rep is demonstrating strong foundational selling skills...",
    "trend": { "direction": "improving", "note": "Call X demonstrates a noticeable uplift..." },
    "top_gaps": [
      { "category": "clarity", "observation": "...", "supporting_evidence": "..." }
    ],
    "action_plan": {
      "this_week": "Review call X and practice pausing instead of filler words...",
      "stretch": "Proactively address objections earlier using Sandler's Up-Front Contract..."
    },
    "score_averages": { "clarity": 87, "close": 91 /* etc */ }
  }
}
Read the latest at /synthesis/latest. History at /synthesis.

Webhooks for these jobs

Subscribe to:
  • persona.assigned — when persona_assign completes
  • methodology.assigned — when methodology_assign completes
  • profile.synthesized — when synthesis completes
Each carries { org_id, rep_id, job_id, result }. See the webhooks guide.

Doing this from MCP

For org "demo-acme" rep "alex-smith", assign a persona using their last 5 completed analyses, then generate a coaching synthesis with the same set. Show me both results side-by-side.
The model calls assign_rep_persona, polls, then generate_rep_synthesis, polls, and renders both for you.

Cost + latency reference

JobPathLatencyCost
persona_assignanalysis_ids15–30s~$0.01
persona_assignrecording_urls30s × N + 15–30s~0.02×N+0.02 × N + 0.01
methodology_assignanalysis_ids15–30s~$0.01
methodology_assignrecording_urls30s × N + 15–30s~0.02×N+0.02 × N + 0.01
synthesisanalysis_ids / lookback_count20–40s~$0.02