Buying committees
Auto-discover the buying committee behind an opportunity, classify each member's role, track engagement, and alert when a champion goes silent.
Buying committees
Instead of hand-building a static org chart, Pact auto-discovers the buying
committee behind an opportunity from the signals you already have — linked
contacts, opportunity contacts, email and sequence activity, meeting attendees,
and account timeline — then classifies each member's role, scores their
engagement, and alerts when a champion goes quiet. The API is under /v1
(committee routes) and is gated by the sales module.
Live
Backed by the core.buyer_group engine (discoverer, role classifier, engagement
tracker, silence detector, org-chart builder, store) and the committee_members
and committee_alerts tables. Every query threads tenant_id through the store
layer, so committees are strictly tenant-isolated.
Discovery
POST /v1/committees/discover assembles candidate members from contacts,
opportunity_contacts, sequence events, account timeline, and notes, deduped on
email. Re-running discovery on an existing committee is
POST /v1/committees/{id}/refresh.
Role classification
Each candidate is classified into one of a fixed role set:
champion, decision_maker, influencer, blocker, mobilizer, user, or
unknown. Classification has two paths:
- Deterministic rule classifier (the default) — runs offline against title heuristics and activity signals. No external dependency; used in CI and when no Anthropic key is configured.
- LLM-augmented classifier — active when
ANTHROPIC_API_KEYis set andBUYER_GROUP_USE_LLM=1. Sends the candidate's title, signals, and evidence excerpts to Claude and expects a typed JSON return ofrole / confidence / reasoning / supporting_evidence.
Operators can override a classification manually via
PATCH /v1/committees/{id}/members/{member_id} — the override is audit-logged —
and every member's classification carries an evidence trail at
GET /v1/committees/{id}/members/{member_id}/evidence.
Engagement and silence alerts
Engagement is scored 0-100 per member with a decay function so recent activity
weighs more heavily. The silence detector flags any member — a champion in
particular — who has been silent longer than the committee's threshold (default
14 days, DEFAULT_SILENCE_THRESHOLD_DAYS), upserting a committee_alerts row
and stamping committee_members.silence_alert_at. Alerts surface in a global feed
that operators acknowledge or resolve.
Endpoints
| Method & path | Purpose |
|---|---|
POST /v1/committees/discover | Kick off discovery for an opportunity |
GET /v1/committees/{id} | Full committee with members + alerts |
POST /v1/committees/{id}/refresh | Re-run discovery |
PATCH /v1/committees/{id}/members/{member_id} | Manual role override (audit-logged) |
GET /v1/committees/{id}/members/{member_id}/evidence | Evidence trail for a member |
GET /v1/committees/alerts | Global alert feed |
POST /v1/committees/alerts/{id}/acknowledge | Acknowledge or resolve an alert |
GET /v1/opportunities/{opp_id}/committee | Committee for an opportunity |
GET /v1/accounts/{account_id}/committee | Combined account-level view |
The org-chart builder renders the committee as nodes and edges — peer links and reporting links inferred from titles — so the opportunity detail page, the account stakeholders tab, and the alerts feed all read from one source of truth.