A Bangalore B2B SaaS team ran a 30-minute SDR triage call every morning to decide which inbound leads went to which account executive. Three people, five days a week — roughly 7.5 hours of meeting time weekly to route 40 leads. We replaced the meeting with a 16-node n8n workflow that enriches each lead with Apollo, scores it, and posts it to the right AE's Slack channel within 90 seconds of form submission. This post is the full build: nodes, credentials, scoring logic, error handling, and the cost per lead.
What does this lead-routing pipeline do?
It catches an inbound form submission via webhook, enriches the lead with Apollo's People Enrichment API to fill in company size, industry, and seniority, scores the lead 0–100 with a Code node, decides territory by company region, and posts a formatted card to the owning AE's Slack channel with a "Claim" button. Low-score leads route to a nurture list instead. Tested on n8n v1.62 with Apollo's API, July 2025.
Why kill the SDR triage meeting?
The daily triage call is where good leads go to wait. A lead that submits at 4 PM sits untouched until the next morning's meeting — a 16-hour gap that Harvard Business Review's lead-response study found cuts qualification odds sharply. Apollo's enrichment plus deterministic scoring does in 90 seconds what three humans did in 30 minutes, and it runs at 4 PM as happily as at 9 AM. We have shipped this pattern for two B2B clients, and both kept the daily standup — they just stopped using it to route leads.
The 16 nodes, grouped
Step 1: Set up the Apollo and Slack credentials
Apollo uses a single API key passed in the X-Api-Key header — generate it under Settings → Integrations → API in your Apollo account. Note that enrichment consumes credits, billed per credit on metered plans, and a full enrichment including a phone number can cost 9 or more credits. Slack needs a bot token with chat:write and the channels the bot is invited to.
reveal_phone_number: false. We left it on during a test run and burned through 1,400 credits in two days. For routing, email plus company data is enough — phone enrichment can happen later, only for claimed leads.
Step 2: The Apollo enrichment node
Node 4 is an HTTP Request to Apollo's People Enrichment endpoint. You pass the lead's email and optionally name and domain; Apollo returns title, seniority, company headcount, and industry. The node config:
{
"parameters": {
"method": "POST",
"url": "https://api.apollo.io/api/v1/people/match",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "X-Api-Key", "value": "={{ $credentials.apolloApi.apiKey }}" },
{ "name": "Content-Type", "value": "application/json" }
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({\n email: $json.email,\n reveal_personal_emails: false,\n reveal_phone_number: false\n}) }}"
},
"name": "Apollo Enrich",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2
} Verify this node by enriching your own work email first — the response person object should return your real title and company headcount. If person is null, the email is not in Apollo's database, so your scoring logic must handle the null gracefully.
Step 3: The scoring Code node
Node 7 is where the triage decision lives. It scores 0–100 from company size, seniority, and a target-industry list. This is the logic that used to live in three SDRs' heads:
// n8n Code node — lead scoring
const p = $json.person || {};
let score = 0; // Company size (headcount)
const size = p.organization?.estimated_num_employees || 0;
if (size >= 1000) score += 40;
else if (size >= 200) score += 30;
else if (size >= 50) score += 20;
else score += 5;
// Seniority of the contact
const senior = (p.seniority || '').toLowerCase();
if (['c_suite', 'vp', 'head'].includes(senior)) score += 35;
else if (['director', 'manager'].includes(senior)) score += 20;
else score += 5;
// Target industry bonus
const targets = ['software', 'financial services', 'logistics'];
if (targets.includes((p.organization?.industry || '').toLowerCase())) score += 25;
return [{ json: { ...$json, lead_score: Math.min(score, 100) } }];
Step 4: Route by region and post to Slack
Node 10 reads person.organization.country (or a state field for India) and routes to the AE who owns that territory. Node 12 posts a Slack Block Kit card with a Claim button. The Slack node body:
{
"parameters": {
"resource": "message",
"operation": "post",
"channel": "={{ $json.ae_channel }}",
"blocksUi": "={{ JSON.stringify([\n { type: 'section', text: { type: 'mrkdwn',\n text: 'New lead — score ' + $json.lead_score + '/100\\n' +\n $json.email + ' · ' + ($json.person?.title || 'Unknown') + '\\n' +\n ($json.person?.organization?.name || '') + ' · ' +\n ($json.person?.organization?.estimated_num_employees || '?') + ' staff' } },\n { type: 'actions', elements: [\n { type: 'button', text: { type: 'plain_text', text: 'Claim' },\n style: 'primary', value: $json.email } ] }\n]) }}"
},
"name": "Post To AE Channel",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2
} - Apollo API key in the
X-Api-Keyheader - Phone enrichment disabled to save credits
- Slack bot invited to every AE channel
- Scoring bands agreed with the sales lead, not guessed
- Null-person handling in the Code node
- Territory map matches your AE assignments
- Google Sheets log row for every routed lead
How do you handle errors and edge cases?
Three things break this pipeline. First, Apollo returns null for unknown emails — your Code node must default the score (we give unknowns a flat 10 and route them to nurture). Second, Apollo rate-limits and occasionally 429s during bursts — wrap the enrichment node's "retry on fail" with 3 attempts and a 2-second backoff. Third, a lead whose region matches no AE — add a fallback Switch output that posts to a shared #unrouted channel so nothing silently vanishes. We log every lead to Google Sheets regardless of branch, which is how you audit "did this lead actually get routed" later.
How much does this cost per lead?
The cost is Apollo credits plus a flat infra cost. With phone enrichment off, a typical enrichment is 1–2 credits per lead.
Apollo dominates the cost, so the credit discipline from Step 1 matters more than the infra choice. Our AI and automation team usually negotiates an annual Apollo plan with bulk credits for clients at this volume.
One detail teams miss: the scoring bands are the whole game, and they are not a technical decision. We always run a calibration session with the sales lead where we pull 30 leads the team already qualified by hand, run them through the Code node, and compare. If the workflow's "qualified" band disagrees with the humans more than twice, the bands are wrong, not the humans. We tune the headcount and seniority weights until the agreement is tight, then lock them. This one-hour exercise is what makes the AEs trust the Slack card enough to act on it without second-guessing — and trust is the only thing that actually replaces the meeting.
When should you not build this?
If you get fewer than 10 inbound leads a week, the triage meeting is cheaper than the maintenance. If your leads are mostly known existing accounts, Apollo enrichment adds little — you already have the data in your CRM. And if your AEs do not actually act on Slack notifications, automating the routing just moves the bottleneck; fix the response culture first. Automation amplifies a working process, it does not create one.
Real example: the Bangalore SaaS team
The client had three AEs split by region (India, SEA, rest-of-world) and a daily triage call that everyone disliked. After we shipped this flow, the median time from form submit to first AE touch dropped from about 14 hours to 22 minutes, and the SDRs reclaimed 7.5 hours a week for actual outbound. We built the same enrich-score-route spine into the sales pipeline for Radiant Finance, where speed-to-lead directly moved their conversion rate.
The triage meeting felt productive, but it was really just three people reading the same form fields out loud. The workflow does it in ninety seconds and never skips a 4 PM lead.
Frequently asked questions
How accurate is Apollo's enrichment for Indian companies?
Coverage is strong for funded startups and mid-to-large firms, weaker for small unfunded SMBs. For Indian leads, expect a null rate around 20–30% on smaller companies. Your scoring must default gracefully when the person object is null.Can I route by something other than region?
Yes. The territory Switch can route on company size, industry, or a round-robin counter stored in a database node. We have built round-robin, named-account, and size-tier routing variants depending on how the sales team is structured.Does this replace a CRM?
No. It routes leads and logs them; it does not store the deal lifecycle. Pair it with HubSpot, Pipedrive, or a custom CRM. The Slack card is the triage layer, not the system of record.How do I stop burning Apollo credits on duplicates?
Add a Google Sheets or database lookup keyed on email plus date before the enrichment node. If the lead already arrived today, skip Apollo. This cut one client's duplicate-driven credit spend by about 12%.What if Apollo returns a 429 rate-limit error?
Enable "retry on fail" on the enrichment node with 3 attempts and a 2-second backoff. Apollo's burst limits are generous for steady inbound flow but can trip during a campaign spike.How long does it take to build?
A working v1 takes 5 to 7 working days, most of it spent agreeing the scoring bands and territory map with your sales lead rather than wiring nodes.Want this lead-routing pipeline live on your Slack this month?
We ship a self-hosted n8n enrich-score-route workflow for B2B teams in 7 working days. Suitable if you route 40+ inbound leads a week and your AEs live in Slack. No slides — bring your scoring rules and we will wire them.
Book a 20-min CallRelated reading
