Lead Triage
AnthropicOfficialPublished by Anthropic
- Skill
- Workflow
- Business and productivity
- Apache-2.0
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
Lead Triage streamlines the sales process by analyzing inbound HubSpot leads to identify high-priority prospects. It evaluates leads across four dimensions—engagement, company fit, urgency, and recency—to produce a ranked call list. The skill provides actionable talking points for each lead, drafts personalized follow-up emails, and suggests optimal calendar slots for outreach. It operates with strict approval gates, ensuring the user retains full control over email sending and calendar scheduling. If HubSpot data is unavailable, the skill can process lead lists provided via CSV or text input.
What it does
- Fetches and filters inbound leads from HubSpot based on lifecycle stage.
- Scores leads using a multi-factor model including engagement, company fit, and urgency.
- Generates a ranked call list with talking points and activity summaries.
- Drafts personalized follow-up emails based on the owner's voice profile.
- Proposes available calendar slots for outreach calls.
- Renders a visual triage board as an artifact for easy review.
When to use it
- When you need to prioritize your daily sales outreach.
- When you are unsure which leads to contact first.
- When you want to quickly generate talking points and follow-up drafts for prospects.
- When you need to organize your pipeline into an actionable call list.
Advantages
- Reduces manual effort in analyzing CRM data.
- Provides objective ranking to help focus on the most promising leads.
- Maintains user control with explicit approval required for all actions.
- Adapts to both CRM-integrated and manual lead list workflows.
Usage examples
- “Prioritize my leads.”
- The agent pulls leads from HubSpot, scores them, and presents a ranked list with talking points and a visual artifact.
- “Who should I call first?”
- The agent identifies the highest-scoring leads based on engagement and urgency, providing a clear recommendation for your call list.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/anthropics/lead-triage/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip lead-triage.zip -d .agents/skills
Documentation by Anthropic
Lead Triage
Quick start
Pull inbound leads from HubSpot, score them, and surface a ranked call list with talking points. Drafts follow-ups and proposes calendar slots — never sends or books without owner approval.
User: "prioritize my leads"
→ Pull contacts: lifecycle stage Lead or MQL, status ≠ Unqualified
→ Score each across engagement, company fit, urgency, recency
→ Return ranked list (size adapts to volume) with talking points
→ Offer to draft follow-ups and propose calendar slotsWorkflow
Pull leads from HubSpot. Fetch contacts with
lifecyclestage=LeadorMQLandhs_lead_status≠Unqualified. Use the field list in reference/hubspot-scoring.md. If HubSpot is unavailable — not installed, not connected, or erroring — do not stop. Say so plainly and run the "No HubSpot?" path at the bottom of this file: ask for a CSV export or a rough pasted list, and score that instead.Empty portal check. If the pull returns zero contacts of any lifecycle stage, the portal is empty, not filtered wrong. Say so in one line, offer HubSpot's own setup (
manage_onboarding, actionSET_GOAL) or the "No HubSpot?" path, and do not diagnose lifecycle stages on a portal with nothing in it. The count is the test:get_user_detailsreturns anonboardedflag, but a portal can reportonboarded: falsewhile holding hundreds of contacts, so the flag alone never decides this.
Clarify if trigger is ambiguous. If the user said only "pipeline" without a qualifier, ask: "Quick pipeline overview (deal stages + total value) or prioritized call list?" — then route accordingly. Do not score leads on a bare "pipeline."
Score each lead. Apply the four-dimension model in reference/hubspot-scoring.md:
Engagement — email replies, opens, site visits in HubSpot (last 30 days only)
Company fit — industry and employee count vs. owner's ICP (default: any industry, 1–50 employees). Read these from the company associated with the lead, not from the contact record — see the scoring reference. When leads have no associated company and a lead-data connector (Apollo or Clay) is connected, the enrichment leg in the scoring reference fills industry and size from the lead's email domain. It is metered — say how many rows it would enrich and what that costs in credits, and run it only on the owner's yes for this run. Nothing enriched is written back to the CRM from here.
Urgency — lead age, stage duration, notes containing "urgent / ASAP / deadline / budget approved". The keyword check requires actually fetching note bodies via the contact → notes association — follow the "Fetch note bodies" section of the scoring reference; the note count alone cannot fire it.
Recency penalty — subtract points if last activity was <24 hours ago (already touched today)
Then check whether the scores actually separated. If the highest and lowest composite differ by less than 10 points, the CRM has no signal to rank on. Do not present the order as a ranking — run the flat-score path in the scoring reference, say plainly that the signals are empty, and order by CRM facts instead. A false ranking sends the owner to call the wrong person.
Build the ranked list. Sort descending by composite score. Adapt list size to volume:
≤10 leads → show all
11–30 leads → show top 5
30 leads → show top 8
For each lead: name, company, score, one-paragraph talking point, last activity summary. If engagement signals are all >30 days old, flag: "Engagement signals are stale — approach as cold outreach."
Offer follow-up drafts. Ask: "Draft follow-ups for any of these?" If yes, write one email per selected lead in the owner's voice per the shared voice profile. If that file has no profile yet, follow its "When there is no sample" instruction — ask for three emails the owner was happy with; if they decline, draft plain and neutral and say the drafts are un-voiced. Never invent a personality. Show drafts; do not send. If Mail is unavailable, hand the drafts over in chat as subject plus body for the owner to paste — that is a complete outcome.
Render the triage board as an artifact. After the short chat answer — never instead of it — build an HTML page using the house artifact style (
../../shared/artifact-style.md): a ranked table with each lead's composite score in mono, an urgency status pill per row (good / warn / critical), and a talking-points line under each lead. If the flat-score path fired, say so on the page and drop the pill colors to neutral.Offer calendar slots. Ask: "Propose call slots for any of these?" If yes, check Calendar for open 30-minute windows in the next two business days (avoid slots with existing events ±15 min). Propose two options per lead. Never create calendar events without explicit owner approval. If Calendar is unavailable, ask the owner for two or three windows they can offer and use those instead of inventing times.
Approval gates
Never send an email. Draft only; owner sends from their inbox.
Never create calendar events until approved by the user.
Never change lifecycle stage or mark a lead Unqualified unless the owner explicitly asks.
Never include
CustomerorEvangelistlifecycle contacts in the lead list.If zero leads match the filter, explain why and offer to check what lifecycle stages are in use — do not fabricate a list.
Reference
reference/hubspot-scoring.md — HubSpot field names, scoring weights, ICP defaults
reference/gotchas.md — edge cases: stale data, zero leads, pipeline disambiguation, customer contamination
reference/examples/happy-path-triage.md — worked output for a 7-lead list with draft and slot proposal
Closing offer
End with one line on what the triage produced, then the most relevant next step with its trigger phrase — usually "call list" (/call-list) to add calendar blocks around the ranking. Up to two others when they fit: "write this outreach" (outreach-composer) or "update the CRM" (crm-autopilot). Never more than three, and never re-offer something the owner already declined this session.
No HubSpot?
Paste or upload the lead list — a CSV export or even a rough list works. Scoring and talking points run the same; the ranked call list comes back as chat plus a file instead of writing to the CRM.
Using a tool that isn't listed
The connectors named in this skill are the tested paths, not a wall. If the owner wants this flow to use a tool that isn't connected or listed, offer build-connector — it checks the connector directory first and connects through Zapier otherwise, never hand-building against a raw API. Once the connection exists, the tool joins this skill like any other optional connector, under the same approval gates.
Files
- ATTRIBUTION.mdAdded by AutoGineer903 B
- LICENSELicence file added by AutoGineer11.3 KiB
- SKILL.md7.6 KiB
- reference/examples/happy-path-triage.md1.9 KiB
- reference/gotchas.md2.0 KiB
- reference/hubspot-scoring.md6.9 KiB
reference/hubspot-scoring.md
HubSpot Scoring — lead-triage
Field names, scoring weights, and ICP defaults.
Fields to pull
| HubSpot field | Used for |
|---|---|
firstname, lastname | Display |
company | Display. Usually empty — prefer the associated company's name, below. |
email | Follow-up draft recipient |
lifecyclestage | Filter (keep Lead, MQL) |
hs_lead_status | Filter (exclude Unqualified) + tie-break |
jobtitle | Authority tie-break |
hs_buying_role | Authority tie-break |
num_associated_deals | Tie-break — a lead with pipeline attached outranks one without |
hs_is_unworked | Tie-break — true means nobody has touched it yet |
createdate | Urgency — lead age |
notes_last_updated | Recency penalty. HubSpot labels this "Last Activity Date". There is no hs_last_activity_date on the contact object — do not look for one. |
num_notes | Pre-filter for the note-body fetch below — a count alone cannot fire the keyword signal |
hs_sales_email_last_replied | Engagement — reply signal |
hs_email_open | Engagement — open count (use only if within 30 days) |
hs_analytics_last_visit_timestamp | Engagement — site visit |
num_contacted_notes | Engagement — outreach volume |
Company fit fields live on the COMPANY record, not the contact
industry and numemployees exist on the contact object but are almost never
filled in. The populated copies live on the company associated with the contact.
Pull those instead:
| COMPANY field | Used for |
|---|---|
name | Display — the real company name |
industry | Company fit |
numberofemployees | Company fit — exact headcount |
hs_employee_range | Company fit — fallback when numberofemployees is empty |
Fetch the associated company for each lead, then read fit from there. Only fall
back to the contact-level industry / numemployees if there is no associated
company at all.
The enrichment leg: when there is no associated company
When every lead in a portal has no company
association, company fit scores 5 across the board and the dimension
contributes nothing. With a lead-data connector connected — Apollo or Clay,
peers per ../../../shared/connector-neutrality.md — fill the gap from the
lead's email domain instead of scoring it flat:
Collect the leads with no associated company and a business email domain (skip gmail, outlook, yahoo, icloud and the like — nothing to enrich).
Say the count and ask once. Enrichment is metered: each row spends credits. "32 leads have no company on file. Enriching them from their email domains costs roughly 32 credits in Clay. Go ahead?" Run only on a yes for this run; a no means the flat ladder below applies to those rows.
Enrich by domain:
Clay:
find-and-enrich-companyper domain, reading industry and employee count from the returned company data points. Batch throughfind-and-enrich-list-of-contactswhen the connector offers it for the whole set.Apollo:
apollo_organizations_enrichper domain, readingindustryandestimated_num_employees.
Score company fit from the enriched values using the same table as an associated company. Mark those rows "fit from enrichment" in the caveats.
Never write the enriched fields back to the CRM from this skill. Offer it as a
crm-autopilothygiene run afterward, behind its write gate, if the owner wants the company records created.
Without a lead-data connector, or on a no, the flat-score ladder stands.
Fetch note bodies for the urgency scan
The urgency keywords live in note bodies, and note bodies are engagements —
they never arrive with the contact property pull. num_notes only says a note
exists; the +15 keyword signal cannot fire unless the bodies are actually read.
How to do it without flooding the API:
Score every lead first without the note-keyword signal (provisional score).
Fetch associated notes only for the top ~25 leads by provisional score — or for every lead with
num_notes> 0 when fewer than 25 have notes.Pull via the contact → notes association and read the note body (
hs_note_body). One page of notes per lead, most recent first, is enough.Scan the bodies for the urgency keywords and re-score with the +15 where a keyword hits. Say in the caveats when notes existed but were not fetched (beyond the cap) rather than claiming they contained nothing.
Scoring model (0–100 composite)
Four dimensions, each 0–25. Sum for composite.
Engagement (0–25)
Only count signals from the last 30 days. Older signals score 0.
| Signal | Points |
|---|---|
| Email reply in last 14 days | +15 |
| Email open in last 7 days (no reply) | +8 |
| Site visit in last 7 days | +5 |
| >3 outreach attempts, no reply | −5 |
Company fit (0–25)
Default ICP if owner hasn't stated one: any industry, 1–50 employees.
| Match | Points |
|---|---|
| Industry + size both match ICP | 25 |
| Size matches, industry unknown | 15 |
| Industry matches, size unknown | 12 |
| Neither matches or both unknown | 5 |
Urgency (0–25)
| Signal | Points |
|---|---|
Note contains "urgent," "ASAP," "deadline," "budget approved" — requires the note-body fetch above; num_notes alone cannot fire this | +15 |
| Lead age 7–21 days (prime follow-up window) | +10 |
| Lead age <7 days | +5 |
| Lead age >60 days | −5 |
Recency penalty (subtracted from composite)
| Last activity | Subtract |
|---|---|
| <24 hours ago | −25 |
| 1–3 days ago | −10 |
| 4–7 days ago | −5 |
| >7 days ago | 0 |
Custom ICP (runtime override)
If the owner states an ICP at runtime ("focus on SaaS, 10–100 employees"), apply it for that session only.
When the scores come out flat
A CRM with no logged engagement scores every lead the same: ten leads, ten identical composites of 0. Sorting identical scores produces arbitrary order, and presenting that as a priority list is worse than saying nothing.
Check for this before showing a ranked list. If the top and bottom composite differ by less than 10 points, the model has not separated anything. Say so plainly:
"These leads score almost identically — your CRM has no logged emails, calls, or site visits for them, so the engagement and fit signals are all empty. Here they are ordered by what the CRM does know."
Then order by this ladder instead of by composite, and label it as such:
hs_lead_status—NEWbeforeIN_PROGRESSbefore emptyhs_is_unworked=true— nobody has touched it yeths_buying_role— containsDECISION_MAKER, thenCHAMPION, then the restjobtitle— seniority words (VP, Director, Head, Chief, Owner, Manager)num_associated_deals≥ 1 — pipeline already attachedcreatedate— newest first
Never present ladder order as a score. Show it as "ordered by CRM signal" and drop the numeric score column entirely, so the owner is not reading precision that does not exist.
Requirements and compatibility
Written for: Claude Code, Claude apps
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Declares allowed tools
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Anthropic
- Publisher
- Anthropic (Official)
- Source
- anthropics/knowledge-work-plugins · small-business/skills/lead-triage · commit e050c2e
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Anthropic or Anthropic.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download lead-triage.zip