

How to Send Close Lead Assignments to Slack with n8n
When a lead is assigned in Close, n8n fires a webhook, pulls company size, lead source, and contact details, then posts a formatted message to the assigned rep's dedicated Slack channel.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Inside sales teams with dedicated per-rep Slack channels who need instant context on new leads without opening Close
Not ideal for
Teams with more than 20 reps or dynamic channel naming — use Zapier's built-in Slack lookup table instead to avoid maintaining a static channel map in n8n
Sync type
real-timeUse case type
notificationReal-World Example
A 12-person SaaS sales team uses this to ping each rep's private Slack channel the moment Close assigns them a lead. Before this workflow, reps got assignment emails buried in their inbox and would sometimes wait 45 minutes before making first contact. Now the Slack message hits within 10 seconds of assignment and includes company size, lead source, and the primary phone number so the rep can dial immediately.
What Will This Cost?
Drag the slider to your expected monthly volume.
Each platform counts differently — Zapier: 1 task per trigger. Make: 1 operation per module per record. n8n: 1 execution per run.





Prices shown for annual billing. Based on published pricing as of April 2026.
Estimated ROI
1000
min saved/mo
$583
labor value/mo
Free
no platform cost
Based on ~2 min manual effort per operation at $35/hr fully loaded labor cost.
Implementation
Import this workflow directly into n8n
Copy the pre-built n8n blueprint and paste it straight into n8n. All modules, filters, and field mappings are already configured — you just need to connect your accounts.
Before You Start
Make sure you have everything ready.
Field Mapping
Map these fields between your apps.
| Field | API Name | |
|---|---|---|
| Required | ||
| Lead ID | id | |
| Assigned User ID | assigned_to | |
| Lead Display Name | display_name | |
| Primary Contact Name | contacts[0].name | |
| Changed Fields Array | changed_fields | |
5 optional fields▸ show
| Lead Source | source |
| Lead Status | status_label |
| Primary Contact Email | contacts[0].emails[0].email |
| Primary Phone Number | contacts[0].phones[0].phone |
| Company Size | custom.cf_YOUR_FIELD_KEY |
Step-by-Step Setup
Close > Settings > Integrations > Webhooks > Add Webhook
Create a webhook in Close
Log into Close and go to Settings > Integrations > Webhooks. Click 'Add Webhook'. You'll enter a URL here — leave the tab open because you'll paste n8n's URL in the next step. Set the event to 'Lead Updated' since Close fires assignment changes under that event type, not a dedicated assignment event.
- 1Click your avatar in the bottom-left corner of Close
- 2Select 'Settings' from the dropdown
- 3Click 'Integrations' in the left sidebar
- 4Click 'Webhooks', then click the blue 'Add Webhook' button
- 5Select 'Lead Updated' as the event type and leave the URL field blank for now
n8n > New Workflow > + Add Node > Webhook
Set up the n8n Webhook trigger node
In n8n, create a new workflow and add a Webhook node as the trigger. Set the HTTP method to POST. n8n will generate a unique webhook URL — copy it. Switch back to Close and paste this URL into the webhook configuration you started in Step 1. Save the Close webhook.
- 1Click '+ New Workflow' in the n8n sidebar
- 2Click the '+' node button and search for 'Webhook'
- 3Set HTTP Method to 'POST'
- 4Copy the generated Production URL shown in the node panel
- 5Paste the URL into the Close webhook URL field and save
n8n > Webhook Node > Listen for Test Event
Test the webhook with a real Close assignment
In n8n, click 'Test Workflow' so the Webhook node starts listening. Go to Close, open any lead, and change the assigned user to someone else. Return to n8n — the Webhook node should show a green execution with a full payload. Inspect the JSON to confirm you can see the 'assigned_to' field and the lead's contact data.
- 1Click 'Test Workflow' in the top toolbar of your n8n canvas
- 2Open Close in a separate tab and open any lead record
- 3Change the 'Assigned To' field to a different user and save
- 4Return to n8n and click the Webhook node to view the incoming payload
n8n Canvas > + Add Node > IF
Add an IF node to filter assignment changes only
Add an IF node directly after the Webhook node. Close's 'Lead Updated' payload includes a 'changed_fields' array listing which fields changed. Set your IF condition to check whether 'assigned_to' appears in that array. Only route payloads that contain this value down the 'true' branch — everything else hits the 'false' branch and stops.
- 1Click the '+' connector on the right side of the Webhook node
- 2Search for 'IF' and add it
- 3Set Condition to: String, Value 1 = {{ $json.changed_fields.join(',') }}, Operation = 'Contains', Value 2 = 'assigned_to'
- 4Leave the 'false' branch unconnected — it will simply stop execution
n8n Canvas > + Add Node > HTTP Request
Fetch full lead details from Close API
The webhook payload contains a lead ID but may not include all the fields you want in your Slack message — specifically custom fields like company size. Add an HTTP Request node on the 'true' branch to GET the full lead record from Close's REST API. Use the lead ID from the webhook payload in the URL.
- 1Click the '+' connector on the 'true' output of the IF node
- 2Search for 'HTTP Request' and add it
- 3Set Method to 'GET'
- 4Set URL to: https://api.close.com/api/v1/lead/{{ $('Webhook').item.json.data.id }}/
- 5Under Authentication, select 'Basic Auth' and enter your Close API key as the username with a blank password
n8n Canvas > + Add Node > Code
Resolve the assigned user's name and Slack channel
The Close payload gives you an assigned_to value like 'user_abc123' — not a human name and not a Slack channel. Add a Code node to map this user ID to a display name and their Slack channel. Define a static lookup object inside the code. This is the most maintainable approach for teams under 20 reps.
- 1Click the '+' connector on the HTTP Request node output
- 2Search for 'Code' and add it
- 3Select 'Run Once for All Items' mode
- 4Paste the mapping code (see pro tip) into the JavaScript editor
- 5Click 'Test Step' to confirm the output includes repName and slackChannel fields
This single Code node handles both the user-to-channel lookup and the Slack Block Kit message assembly. Paste it in Step 6's Code node, replacing the two separate Code nodes if you prefer a single step. Update the 'repLookup' object with your actual Close user IDs and Slack channel names before testing.
JavaScript — Code Node// n8n Code Node — Lead Assignment Notification Builder▸ Show code
// n8n Code Node — Lead Assignment Notification Builder // Combines user lookup + Block Kit message formatting // Paste into a Code node connected after the HTTP Request (Close API) node
... expand to see full code
// n8n Code Node — Lead Assignment Notification Builder
// Combines user lookup + Block Kit message formatting
// Paste into a Code node connected after the HTTP Request (Close API) node
const lead = $('HTTP Request').item.json;
const webhookData = $('Webhook').item.json;
// Map Close user IDs to rep names and Slack channels
// Replace these with your actual Close user IDs
const repLookup = {
'user_7f3kd92': { name: 'James Okafor', channel: '#leads-james' },
'user_4a1mn58': { name: 'Sarah Chen', channel: '#leads-sarah' },
'user_9x2pq71': { name: 'Marcus Webb', channel: '#leads-marcus' },
};
const assignedUserId = webhookData.data.assigned_to;
const rep = repLookup[assignedUserId] || { name: 'Unknown Rep', channel: '#leads-unassigned' };
// Pull primary contact details safely
const contacts = lead.contacts || [];
const primaryContact = contacts[0] || {};
const contactName = primaryContact.name || 'No contact listed';
const contactEmail = (primaryContact.emails && primaryContact.emails[0]) ? primaryContact.emails[0].email : 'No email';
const contactPhone = (primaryContact.phones && primaryContact.phones[0]) ? primaryContact.phones[0].phone : 'No phone';
// Pull custom fields — update key to match your Close account
const companySize = lead.custom && lead.custom['cf_company_size'] ? lead.custom['cf_company_size'] : 'Unknown';
const leadUrl = `https://app.close.com/leads/${lead.id}/`;
// Build Slack Block Kit payload
const blocks = [
{
type: 'header',
text: { type: 'plain_text', text: `🎯 New Lead Assigned: ${lead.display_name}`, emoji: true }
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: `*Assigned To:*\n${rep.name}` },
{ type: 'mrkdwn', text: `*Lead Source:*\n${lead.source || 'Not set'}` },
{ type: 'mrkdwn', text: `*Company Size:*\n${companySize}` },
{ type: 'mrkdwn', text: `*Status:*\n${lead.status_label || 'Unknown'}` }
]
},
{
type: 'section',
fields: [
{ type: 'mrkdwn', text: `*Contact:*\n${contactName}` },
{ type: 'mrkdwn', text: `*Phone:*\n${contactPhone}` },
{ type: 'mrkdwn', text: `*Email:*\n${contactEmail}` }
]
},
{
type: 'actions',
elements: [
{
type: 'button',
text: { type: 'plain_text', text: 'Open in Close', emoji: true },
url: leadUrl,
style: 'primary'
}
]
}
];
return [{
json: {
slackChannel: rep.channel,
repName: rep.name,
blocks: JSON.stringify(blocks),
fallbackText: `New lead assigned to ${rep.name}: ${lead.display_name} (${contactPhone})`,
leadId: lead.id,
leadUrl: leadUrl
}
}];n8n Canvas > + Add Node > Code
Format the Slack message with lead details
Add another Code node to build the final Slack Block Kit message. Block Kit gives you structured sections with bold labels, making the lead details scannable at a glance. Pull company name, lead source, company size, primary contact name, and primary phone from the HTTP Request node's output.
- 1Click the '+' connector on the user-lookup Code node
- 2Add another Code node
- 3Build the blocks array with a header block and a fields section block
- 4Reference lead data using $('HTTP Request').item.json syntax
- 5Include a fallback text property for Slack clients that don't render Block Kit
n8n Canvas > + Add Node > Slack > Send Message
Add and configure the Slack node
Add the Slack node and connect your Slack account via OAuth. Set the Resource to 'Message' and Operation to 'Send'. Set the Channel field to the dynamic slackChannel value from your Code node output. Set the Message field to the blocks array. Make sure you toggle 'Send as Bot' on so the message comes from your integration bot, not your personal Slack account.
- 1Click '+' and search for 'Slack', then select the Slack node
- 2Click 'Create New Credential' and complete the OAuth flow with your Slack workspace
- 3Set Resource to 'Message' and Operation to 'Send'
- 4Set Channel to: {{ $json.slackChannel }}
- 5Enable 'Blocks' toggle and paste in the blocks reference, set Text fallback
n8n > Workflow Settings > Error Workflow
Add error handling with an Error Trigger node
Close does not retry failed webhook deliveries. If your Slack node fails — rate limit, wrong channel, token expiry — the assignment notification is lost silently. Add a separate Error Workflow in n8n's workflow settings that pings a #alerts channel with the failed execution ID. This takes 3 minutes and saves real lead loss.
- 1Click the three-dot menu at the top of the canvas and select 'Settings'
- 2Under 'Error Workflow', click 'Select Workflow' and create a new one
- 3In the new error workflow, add an Error Trigger node and connect it to a Slack node
- 4Configure the Slack node to post to #alerts with the message: 'Lead notification failed. Execution: {{ $json.executionId }}'
- 5Save both workflows
n8n > Workflow Canvas > Activate toggle (top right)
Activate the workflow and validate end-to-end
Switch the Webhook node's URL from Test to Production in the Close webhook settings. Toggle the workflow to Active in n8n. Assign a real lead in Close to a real rep and confirm the message appears in their Slack channel within 15 seconds. Check that the company size, lead source, and contact fields are all populated correctly.
- 1Go back to Close Settings > Integrations > Webhooks and update the URL to the n8n Production URL
- 2In n8n, click the grey 'Inactive' toggle in the top-right of the canvas to set it to 'Active'
- 3Open Close and reassign a test lead to a rep whose channel is set up
- 4Check the rep's Slack channel for the notification within 15 seconds
- 5Open n8n's Executions log and confirm the run shows green
Going live
Production Checklist
Before you turn this on for real, confirm each item.
Troubleshooting
Common errors and how to fix them.
Frequently Asked Questions
Common questions about this workflow.
Analysis
Use n8n for this if your team self-hosts infrastructure, wants zero per-task cost at scale, or needs the Code node to handle non-standard Close custom fields. n8n's webhook-to-Slack path adds roughly 3-5 seconds of latency on self-hosted instances with modest hardware, which is fine for sales notifications. The one case where you should pick Zapier instead: your ops person doesn't write code and you have more than 15 reps with complex routing logic. Zapier's Slack lookup table and Paths feature handle dynamic channel routing without touching a single line of JavaScript.
Cost math is simple. This workflow runs once per lead assignment — one webhook execution, one HTTP Request to Close, one Slack post. At 200 lead assignments per month on n8n Cloud, you're using 600 operations (three nodes firing per execution). n8n Cloud's Starter plan includes 2,500 operations for $20/month, so you have headroom for 833 assignments before hitting the ceiling. Self-hosted n8n costs you $0 in platform fees — just server costs, typically $5-10/month on a small VPS. Zapier would run the same 200 assignments on their Professional plan at $49/month. n8n saves you $29-44/month for the identical outcome.
Make handles this use case well with its built-in Close module and Slack Send Message action — no HTTP Request node needed, which cuts one step. Make's visual data mapping is faster to configure than n8n's Code node for anyone unfamiliar with JavaScript. Zapier has a Close trigger called 'New Lead' but lacks a native 'Lead Assigned' trigger, forcing you to use webhooks anyway — same complexity as n8n, higher cost. Power Automate has no Close connector at all, so you'd be writing custom HTTP actions for everything; it's the wrong tool here. Pipedream's Close component is maintained and handles the webhook trigger cleanly, but the free tier caps at 10,000 invocations per day — more than enough, though Pipedream's pricing jumps steeply if you add compute-heavy steps. n8n wins on cost and code flexibility for teams already running it.
Three things you'll hit after setup. First: Close's 'Lead Updated' event fires for status changes, tag edits, note additions — anything. If you misconfigure the IF filter, you'll blast Slack with every single edit. Test the filter explicitly with a non-assignment update before going live. Second: Close custom fields use auto-generated keys like 'cf_7a3bc91' that are unique to your organization. The field you call 'Company Size' in the UI maps to a different key in every Close account — always check the raw API response to confirm the exact key before deploying. Third: Slack's Block Kit 'button' element with a URL requires your Slack app to have the links:write scope enabled, or the button renders without the clickable link. Check your app scopes at api.slack.com/apps if the 'Open in Close' button appears but doesn't work.
Ideas for what to build next
- →Add lead score or deal value to the notification — Pull additional Close custom fields like estimated deal value or lead score into the Block Kit message. Reps can then prioritize callbacks within their queue without opening Close.
- →Build a daily digest of uncontacted assigned leads — Add a second workflow on a Schedule trigger that queries Close's API for leads assigned in the last 24 hours with no logged calls. Post a digest to each rep's channel every morning at 8am.
- →Log rep acknowledgement back to Close — Add a Slack interactive button to the notification that lets reps click 'Acknowledged' — use n8n's Webhook node to catch that click and log a note on the Close lead automatically.
Related guides
How to Share Notion Meeting Notes to Slack with Pipedream
~15 min setup
How to Share Notion Meeting Notes to Slack with Power Automate
~15 min setup
How to Share Notion Meeting Notes to Slack with n8n
~20 min setup
How to Send Notion Meeting Notes to Slack with Zapier
~8 min setup
How to Share Notion Meeting Notes to Slack with Make
~12 min setup
How to Create Notion Tasks from Slack with Pipedream
~15 min setup