Lead Triage Router
Scores inbound leads with a tunable ICP-fit and intent rubric, assigns a tier and a routing owner from your territory rules, and prints the exact signals behind every score so reps can see why a lead reached them.
At a glance
Lead Triage Router is an AI skill that you can use in Claude Code, Codex, or type.com.
- Updated
See an example
Example output from a sample run. Company names and figures are sample data.
Lead triage and routing: 19 inbound leads, as of 2026-09-22
5 Tier A leads are sales-ready now, led by Derek Nwosu at Kestrel Payments (94.0), routed to Alex Rivera on a 2h SLA. The rest split into 3 Tier B, 7 Tier C, 1 Tier D and 3 disqualified, including a 69.2 founder lead below the 10-employee floor.
Tier A and B leads
| Tier | Score | Lead | Fit | Intent | Route (SLA) |
|---|---|---|---|---|---|
| A | 94.0 | Derek Nwosu, Kestrel Payments | 90.0 | 100.0 | enterprise-na / Alex Rivera (2h) |
| A | 86.0 | Priya Shah, Northwind Logistics | 90.0 | 80.0 | enterprise-na / Alex Rivera (2h) |
| A | 83.8 | Paulo Mendes, Vertex Freight | 89.0 | 76.0 | enterprise-apac / Wei Chen (4h) |
| A | 83.2 | Ken Arai, Meridian Manufacturing | 88.0 | 76.0 | enterprise-apac / Wei Chen (4h) |
| A | 72.7 | Marcus Feld, Atlas Bio Labs | 86.0 | 52.7 | enterprise-emea / Ingrid Solberg (4h) |
| B | 67.8 | Amara Osei, Cascade Fintech | 81.0 | 48.0 | sdr-outbound / SDR pod 1 (12h) |
| B | 57.6 | Mira Lindqvist, Lantern Bay Hotels | 52.0 | 66.0 | sdr-outbound / SDR pod 1 (12h) |
| B | 52.8 | Robert Kline, Silverline Energy | 88.0 | 0.0 | enterprise-na / Alex Rivera (8h) |
…plus 7 Tier C, 1 Tier D and 3 disqualified leads in the full report. Scoring: total = 0.60 x fit + 0.40 x (intent x recency); intent shown after recency.
Why Marcus Feld scored 72.7: fit 86.0 from 3,200 employees +30, revenue $900,000,000 +20, Healthcare +14, Germany +8 and a director title +14. Intent 62.0 from a started trial +30, pricing page views +8, 2 content downloads +8, 4 sessions +8 and a webinar +8, discounted x0.85 because his last activity was 21d ago, giving 52.7.
Routing load
| Queue | Owner | Leads |
|---|---|---|
| sdr-sequence | SDR pod 2 | 7 |
| marketing-nurture | (none) | 4 |
| enterprise-na | Alex Rivera | 3 |
| enterprise-apac | Wei Chen | 2 |
| sdr-outbound | SDR pod 1 | 2 |
| enterprise-emea | Ingrid Solberg | 1 |
Next actions
- Work Tier A immediately; qualify Tier B before routing to an AE; sequence Tier C, do not call; Tier D is marketing nurture only.
- Robert Kline (Silverline Energy, referral) has fit 88.0 but no activity date on record, so intent scored 0.0.
- Disqualified to marketing-nurture: Sana Iqbal, Tiny Tools Co (4 employees is below the 10 floor); Bill Hartley, Peak Staff Group (blocked industry: Staffing); Jen Larkin, Solstice Apparel Supply (personal email domain gmail.com).
- Hana Kovacs (Brightwater Utilities) is missing employee_count and annual_revenue_usd; missing fields score zero rather than guessing.
Inputs: an inbound lead export, territory routing rules and the scoring rubric in config/rubric.json.
Produced by running bash examples/run.sh on the sample data bundled with this skill.
How to use Lead Triage Router
- type.com: Choose Use Skill to add Lead Triage Router to your type.com workspace.
- Claude Code: Download the skill and extract it into
~/.claude/skills/lead-triage-router/(or.claude/skills/lead-triage-router/in a project). Then ask Claude to use Lead Triage Router. - Codex: Download the skill and extract it into
~/.agents/skills/lead-triage-router/(or.agents/skills/lead-triage-router/in a repository). Then ask Codex to use Lead Triage Router.
AI agents can read this page as Markdown or fetch the raw SKILL.md.
Frequently asked questions
What is Lead Triage Router?
Lead Triage Router is an AI skill that you can use in Claude Code, Codex, or type.com.
What does Lead Triage Router do?
Scores inbound leads with a tunable ICP-fit and intent rubric, assigns a tier and a routing owner from your territory rules, and prints the exact signals behind every score so reps can see why a lead reached them.
Can I use Lead Triage Router in Claude Code or Codex?
Yes. Lead Triage Router is a standard Agent Skills folder with a SKILL.md file. Download it and extract it into ~/.claude/skills/ for Claude Code or ~/.agents/skills/ for Codex.
Who created Lead Triage Router?
The type.com team created Lead Triage Router. The type.com team reviews every skill before it is published in the Skills Library.
Related guide
Browse the technical files
--- name: lead-triage-router description: Scores inbound leads with a tunable ICP-fit and intent rubric, assigns a tier and a routing owner from your territory rules, and prints the exact signals behind every score so reps can see why a lead reached them. --- # Lead Triage and Router Takes a raw inbound lead export and produces a tiered, routed, explainable work list. The rubric lives in `config/rubric.json`, not in the code, so marketing and sales can argue about weights in a pull request instead of in a meeting. ## Before you run This skill ships scripts and sample data alongside this SKILL.md. Before running any command: 1. **Get the files.** Make sure the skill's other files (`scripts/`, `examples/` and anything else listed with this skill) are in your working folder at the same relative paths. Some environments load only SKILL.md; if yours did, fetch each file from this skill's published files and write it to the matching path. In Type, read them with the skill-file tools. Anywhere else, the Type Skills Library API lists every file with its path, content and `sha256`: GET `https://api.type.com/api/public/library/skills` and take the entry with slug `lead-triage-router`. 2. **Check the copies are exact.** Compare each file's size in bytes, not characters (and its hash, where your tools report one), with the published version before running. A copy written out from the published file is fine once its byte size and hash match; never run a script you summarised or reconstructed from memory. 3. **Run from the skill's folder**, calling interpreters explicitly: `python3 scripts/…` and `bash examples/run.sh`. 4. **Try the sample first.** If the skill ships `examples/run.sh` and `examples/expected_output.txt`, run `bash examples/run.sh`; its output should match the expected file exactly. If it doesn't, stop and report the first differing line rather than running on real data. ## When to use this - Daily or hourly triage of form fills, trials, and content downloads when the volume has outgrown a human reading each one. - Rebuilding lead scoring after an ICP change, a new segment, or a territory reshuffle — run the new rubric against last month's leads and compare. - Auditing an existing scoring model: this shows its reasoning, whereas most CRM scoring does not. ## Inputs `DATA_CONTRACT.md` has the exact columns, types, and units. You need: 1. `leads.csv` — one row per lead, firmographics plus intent counters. 2. `routing.csv` — the territory/queue rules, in priority order. 3. `config/rubric.json` — weights, bands, tiers, disqualifiers (ships with sensible B2B SaaS defaults). ### Gathering the inputs through Type integrations - **HubSpot**: export contacts with `email`, `jobtitle`, `company`, `num_employees` (or the enriched company property), `annualrevenue`, `industry`, `country`, `hs_analytics_source`, `createdate`, and `notes_last_contacted`. Page-view and session counters come from the HubSpot analytics properties or from your product analytics tool. - **Salesforce**: `Lead` object plus any enrichment fields (Clearbit, ZoomInfo, Apollo) that populate employee count, revenue, and industry. - **Attio**: the People object joined to the linked Company record. - **Product analytics (Amplitude, PostHog, GA4, warehouse)**: pricing page views, sessions, trial starts. Aggregate to a 30-day window ending on the date you pass to `--as-of` so the counters and the recency multiplier agree. - **Routing rules**: usually a spreadsheet RevOps already maintains. If not, write it once by hand from the contract; it changes rarely. If an enrichment field is missing, leave it blank. Blank fields score zero and are listed in the data-quality section — do not guess values, because a guessed employee count silently inflates a tier. ## Running it ```bash python3 scripts/lead_triage.py \ --leads path/to/leads.csv \ --routing path/to/routing.csv \ --config config/rubric.json \ --as-of 2026-09-22 ``` - `--as-of` is required and drives the intent recency multiplier. - `--fallback-queue NAME` sets where leads go when no routing rule matches (default `unrouted`); those leads are counted separately in the summary. - `--json` emits the full scored record, contribution by contribution. - Bad input exits `2` naming the file, row, and column. See `examples/run.sh` for a complete working invocation. ## How the score works ``` total = fit_weight x fit_score + intent_weight x (intent_score x recency_multiplier) ``` - **Fit (0-100)** sums five firmographic bands — employee count, revenue, industry, country, and title seniority — then normalizes against `fit.max_points`. Title matching is whole-word, so "Director" does not match the executive keyword list, and a multi-word keyword such as "head of" must match consecutive whole words, so "Forehead Office Manager" scores as a manager, not a head of function. An industry that is listed but scores below the `_default` is labelled as low-fit, not as an ICP industry. - **Intent (0-100)** sums weighted behavioural signals. Count signals have a per-signal cap (three pricing-page views should not outscore a demo request), and the total is capped at `intent.max_points`. - **Recency multiplier** discounts intent by how long ago the lead last did anything. A lead with no activity date is discounted to the floor rather than treated as fresh. - **Disqualifiers** run before tiering. A personal email domain, a blocked industry or country, or a company below the employee floor sends the lead to the nurture queue with the reason attached, whatever it scored. - **Tier** is the highest band whose `min_score` the total meets. - **Routing** walks the rules in `priority` then `rule_id` order and takes the first match on tier, segment, and region. `*` is a wildcard; keep one catch-all rule at the bottom. ## Tuning Edit `config/rubric.json`: - `fit_weight` / `intent_weight` must sum to 1.0. Product-led motions usually run 0.4 / 0.6; enterprise outbound-heavy motions run 0.7 / 0.3. - `fit.*_bands`, `industry_points`, `country_points`, `title_bands` — the ICP itself. Points are arbitrary units; only their ratio matters. - `intent.signals` — add a field here and the contract, and it is scored. Caps stop one loud signal from dominating. - `tiers[].min_score` — move these first when the A tier is too big for the team to work inside the SLA. - `disqualifiers` — the hard filters, kept separate from scoring on purpose. After any change, rerun against a week of known leads and check the tier counts against what the team can actually handle. ## Reading and presenting the output - **Summary** gives the tier distribution and average score. If Tier A is more than about 15% of volume, thresholds are too loose. - **Routing load** is the operational number: how many leads each queue and rep just received. Check it against capacity before you send the assignments. - **Per-lead blocks** are the deliverable. The `fit` and `intent` lines reconstruct the score exactly — paste them into the CRM note or the Slack handoff so the rep never has to ask "why did I get this?" - **Data quality** tells you what enrichment is missing. Persistent blanks there are a better investment than another weight change. ## Limits - It scores the *record*, not the person's real buying intent. A rubric cannot see a stalled budget cycle or a competitor already in the account. - Keyword title matching is coarse. Unusual or non-English titles land in the default band; add keywords rather than accepting the drift. - Counts are taken as given. If the 30-day window in the export does not end on `--as-of`, the recency multiplier and the counters disagree and scores skew. - No deduplication: two form fills from the same person are two leads. Dedupe in the export, or in the CRM, first. - No write-back. It does not assign owners in the CRM, send notifications, or enroll anyone in a sequence. - Disqualifiers are rules, not judgment. A 4-person company with a real budget still gets filtered; review the DQ list weekly rather than trusting it blindly.