

How to Send Pipedrive Deal Stage Alerts to Slack with n8n
Fires a Slack message to a specific channel the moment a deal moves to a new pipeline stage in Pipedrive, with deal name, value, owner, and stage embedded in the message.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Sales teams that want instant, stage-specific Slack alerts without paying per-task fees as deal volume grows.
Not ideal for
Teams without a server or cloud instance to host n8n — use Make or Zapier instead for fully managed hosting.
Sync type
real-timeUse case type
notificationReal-World Example
A 12-person B2B SaaS sales team posts to #deals-won in Slack the instant a deal hits Closed Won, and to #pipeline-updates for every earlier stage move. Before this workflow, managers checked Pipedrive manually twice a day and routinely missed same-day closes. After setup, the team sees an average of 6-8 stage notifications per day with deal value, owner name, and a direct link to the Pipedrive deal record.
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 | ||
| Deal Title | body.current.title | |
| Deal Value | body.current.value | |
| Currency | body.current.currency | |
| Current Stage ID | body.current.stage_id | |
| Previous Stage ID | body.previous.stage_id | |
| Deal Owner Name | body.current.owner_name | |
| Deal ID | body.current.id | |
3 optional fields▸ show
| Pipeline ID | body.current.pipeline_id |
| Expected Close Date | body.current.expected_close_date |
| Organization Name | body.current.org_name |
Step-by-Step Setup
n8n Canvas > + New Workflow
Create a new n8n workflow
Open your n8n instance and click the '+ New Workflow' button in the top-right corner of the canvas. Give it a name like 'Pipedrive → Slack Deal Stage Alerts'. You'll start with an empty canvas and a single 'Start' node placeholder. Delete that placeholder — you'll replace it with a webhook trigger in the next step.
- 1Click '+ New Workflow' in the top-right corner
- 2Click the workflow name field at the top and type 'Pipedrive → Slack Deal Stage Alerts'
- 3Click the default 'Start' node and press Delete to remove it
Canvas > + > Search 'Webhook' > Webhook (Core)
Add a Webhook trigger node
Click the '+' button in the center of the canvas to open the node browser. Search for 'Webhook' and select the core Webhook node. Set the HTTP method to POST. n8n will generate a unique webhook URL — copy this URL immediately, you'll paste it into Pipedrive in the next step. Switch the 'Response Mode' to 'Respond Immediately' so Pipedrive's webhook doesn't time out waiting for a reply.
- 1Click the '+' button on the canvas
- 2Type 'Webhook' in the search box and select the 'Webhook' core node
- 3Set HTTP Method to 'POST'
- 4Set Response Mode to 'Respond Immediately'
- 5Copy the Production webhook URL shown in the node panel
Pipedrive > Settings > Tools & Integrations > Webhooks > + Add Webhook
Register the webhook in Pipedrive
Go to your Pipedrive account, open Settings, and navigate to Tools & Integrations > Webhooks. Click '+ Add Webhook'. Paste the n8n Production webhook URL into the Endpoint URL field. Set the Event Action to 'Updated' and the Event Object to 'Deal'. Leave authentication blank unless your n8n instance is public-facing, in which case add HTTP Basic Auth credentials here and mirror them in your n8n Webhook node.
- 1In Pipedrive, click your avatar and select 'Settings'
- 2Navigate to 'Tools & Integrations' then click 'Webhooks'
- 3Click '+ Add Webhook'
- 4Paste your n8n Production webhook URL into 'Endpoint URL'
- 5Set Event Action to 'Updated' and Event Object to 'Deal'
- 6Click 'Save'
n8n Canvas > Webhook Node > Listen for Test Event
Test the webhook with a real deal move
In n8n, click 'Listen for Test Event' on the Webhook node. In Pipedrive, open any deal and drag it to a different stage. Return to n8n — you should see the raw JSON payload appear in the Webhook node's output panel on the right. Expand the 'current' and 'previous' objects inside 'meta' to confirm you can see stage_id in both. This live payload becomes your field map for the next steps.
- 1Click the Webhook node to open its panel
- 2Click 'Listen for Test Event' at the bottom of the panel
- 3Switch to Pipedrive and drag a deal to a new stage
- 4Return to n8n and confirm the payload appears in the Output tab
Canvas > + > Search 'IF' > IF (Core)
Add an IF node to filter stage changes only
Add an IF node connected to the Webhook node. You need to confirm the deal's stage_id actually changed — Pipedrive fires the webhook for all deal edits, not just stage moves. In the payload, the relevant path is 'body.previous.stage_id' and 'body.current.stage_id'. Set the IF condition to check that these two values are NOT equal. Deals that did not change stage exit through the 'false' branch and stop there.
- 1Click the '+' connector from the Webhook node
- 2Search for 'IF' and select the 'IF' core node
- 3Click 'Add Condition' and set the left value to expression: {{ $json.body.previous.stage_id }}
- 4Set the operator to 'Not Equal'
- 5Set the right value to expression: {{ $json.body.current.stage_id }}
Canvas > IF Node (true branch) > + > Search 'Code' > Code (Core)
Add a Code node to resolve stage name and build the message
The Pipedrive webhook gives you stage_id (a number) not the stage name. Add a Code node on the 'true' branch of the IF node. Use a JavaScript object that maps your stage IDs to readable names — you'll find your stage IDs in Pipedrive under Settings > Pipeline. The Code node also builds the Slack message text and decides which Slack channel to target based on stage. This avoids hardcoding channel names in the Slack node and keeps all routing logic in one place.
- 1Click the '+' on the 'true' output of the IF node
- 2Search for 'Code' and select the 'Code' core node
- 3Set Language to 'JavaScript'
- 4Paste the stage-mapping and message-building code into the code editor (see Pro Tip below)
- 5Click 'Execute Node' to test with the captured payload
Paste this into the Code node (Step 6). It maps stage IDs to names and Slack channels, formats the message with emoji and currency, and routes Closed Won deals to a separate celebration channel. Update the stageMap object with your own Pipedrive stage IDs — the structure stays the same.
JavaScript — Code Node// n8n Code Node — Pipedrive Deal Stage Notification Builder▸ Show code
// n8n Code Node — Pipedrive Deal Stage Notification Builder // Replace stage IDs in stageMap with your actual Pipedrive stage IDs // Find them at: Pipedrive > Settings > Pipelines
... expand to see full code
// n8n Code Node — Pipedrive Deal Stage Notification Builder
// Replace stage IDs in stageMap with your actual Pipedrive stage IDs
// Find them at: Pipedrive > Settings > Pipelines
const item = $input.first().json;
const currentStageId = String(item.body?.current?.stage_id);
const dealTitle = item.body?.current?.title ?? 'Unknown Deal';
const dealValue = item.body?.current?.value ?? 0;
const currency = item.body?.current?.currency ?? 'USD';
const ownerName = item.body?.current?.owner_name ?? 'Unassigned';
const orgName = item.body?.current?.org_name ?? 'No Company';
const dealId = item.body?.current?.id;
const dealUrl = `https://app.pipedrive.com/deals/${dealId}`;
// Map your Pipedrive stage IDs to readable names and target Slack channels
const stageMap = {
'10': { name: 'Qualified', channel: '#pipeline-updates', emoji: '🔍' },
'11': { name: 'Demo Scheduled', channel: '#pipeline-updates', emoji: '📅' },
'12': { name: 'Demo Done', channel: '#pipeline-updates', emoji: '✅' },
'13': { name: 'Proposal Sent', channel: '#pipeline-updates', emoji: '📄' },
'14': { name: 'Negotiation', channel: '#pipeline-updates', emoji: '🤝' },
'15': { name: 'Closed Won', channel: '#deals-won', emoji: '🎉' },
'16': { name: 'Closed Lost', channel: '#deals-lost', emoji: '❌' },
};
const stage = stageMap[currentStageId];
if (!stage) {
throw new Error(`Unknown stage ID: ${currentStageId}. Add it to stageMap in the Code node.`);
}
// Format currency value
const formattedValue = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: currency,
maximumFractionDigits: 0,
}).format(dealValue);
// Build the Slack message text
let messageText;
if (currentStageId === '15') {
messageText = [
`🎉 *DEAL CLOSED WON: ${dealTitle}*`,
`👤 Owner: ${ownerName} | 🏢 ${orgName} | 💰 ${formattedValue}`,
`🔗 ${dealUrl}`,
].join('\n');
} else {
messageText = [
`${stage.emoji} *Deal Advanced:* ${dealTitle} moved to *${stage.name}*`,
`👤 Owner: ${ownerName} | 🏢 ${orgName} | 💰 ${formattedValue}`,
`🔗 ${dealUrl}`,
].join('\n');
}
return [{
json: {
channel: stage.channel,
message_text: messageText,
stage_name: stage.name,
deal_title: dealTitle,
deal_value: dealValue,
owner_name: ownerName,
deal_url: dealUrl,
}
}];channel: {{channel}}
ts: {{ts}}
Canvas > Code Node > + > Search 'Slack' > Slack > Message > Post
Connect a Slack node to post the notification
Add a Slack node connected to the Code node. Set Resource to 'Message' and Operation to 'Post'. For the Channel field, use the expression '{{ $json.channel }}' so the Code node controls routing. For the Text field, use '{{ $json.message_text }}'. Connect your Slack credential — you'll need a Slack Bot Token with chat:write scope. The bot must be invited to every channel you plan to post in.
- 1Click '+' from the Code node and search for 'Slack'
- 2Select Resource: 'Message', Operation: 'Post'
- 3In the Channel field, click the expression toggle and type: {{ $json.channel }}
- 4In the Text field, click the expression toggle and type: {{ $json.message_text }}
- 5Click 'Create new credential' and paste your Slack Bot Token (starts with xoxb-)
- 6Click 'Save' on the credential
Canvas > Slack Node > ⋮ Menu > Settings > Continue on Error
Add error handling with a separate Slack alert
Add an Error Trigger node as a second, separate workflow or connect an 'On Error' path from the Slack node to a second Slack message node that posts to a private #n8n-errors channel. This catches Slack API failures and Pipedrive payload parsing errors before they silently drop deals. In n8n, click the three-dot menu on any node and select 'Settings' to configure error output behavior.
- 1Click the three-dot menu (⋮) on the Slack node
- 2Select 'Settings'
- 3Toggle 'Continue on Error' to ON
- 4Add a second Slack node connected to the error output
- 5Set its channel to a private ops channel like #workflow-errors
- 6Set the message text to: 'Deal stage alert failed. Deal ID: {{ $json.body.current.id }}. Error: {{ $json.error.message }}'
n8n Canvas > Top-right toggle > Activate
Activate the workflow
Click the 'Inactive' toggle in the top-right corner of the n8n canvas to set the workflow to 'Active'. This switches from the test webhook URL to the production webhook URL and enables continuous execution. Confirm activation by moving a deal in Pipedrive and checking the target Slack channel within 10-15 seconds. Also check the n8n Executions log to confirm the run shows as 'Success'.
- 1Click the 'Inactive' toggle in the top-right of the canvas
- 2Confirm the modal prompt by clicking 'Activate Workflow'
- 3Open Pipedrive and move a deal to a new stage
- 4Check the target Slack channel for the notification
- 5Open n8n > Executions to verify the run shows green 'Success'
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 you have a developer or a technically confident ops person on your team and you're already self-hosting or open to a small VPS. The two concrete reasons: first, n8n's Code node lets you embed your entire stage-to-channel routing map in JavaScript — no extra 'Router' or 'Filter' nodes needed, just one block of logic that's easy to audit and update. Second, there are zero per-task costs. A Pipedrive account with 30 reps moving deals aggressively could generate 500+ stage change events per month — on n8n Community Edition that costs nothing. The one scenario where you'd skip n8n: if your team has no one comfortable reading a webhook payload or editing a JavaScript object, go to Make instead. Make's visual router handles stage branching without code and takes 20 minutes to set up.
Cost math is simple. Each deal stage change triggers one n8n execution consuming two or three nodes (Webhook, IF, Code, Slack). At 25 stage moves per day across your team, that's roughly 750 executions per month. On n8n Cloud Starter ($20/month), the plan includes 2,500 executions — you're at 30% capacity with room to add more workflows. On self-hosted n8n, it's free indefinitely outside server costs (a $6/month Hetzner VPS handles this easily). Compare that to Zapier, where this workflow hits two tasks per trigger — at 750 events/month, you'd use 1,500 tasks and blow past the free tier (100 tasks) immediately, landing on the $29.99/month Starter plan minimum. Make is cheapest at high volume: 750 operations/month fits inside Make's free tier (1,000 ops). But Make adds friction when you need to update stage names — a JavaScript object in n8n takes 30 seconds to edit vs. rebuilding a Make Router branch.
Here's the honest platform comparison. Zapier's Pipedrive trigger ('Updated Deal') is the most reliable on the market — it's been in production for years and Zapier's infrastructure handles retry logic automatically. If your team already uses Zapier and deal volume is under 200 stage changes per month, stay there. Make's visual Router module is genuinely better than n8n's IF node for teams that have 5+ stage-to-channel mappings — you can see all the routes at a glance without reading code. Power Automate has a Pipedrive connector but it requires polling (no native webhook trigger), which means a 1-15 minute delay between stage move and Slack message — that's a real problem for fast-moving sales floors. Pipedream executes faster than n8n on cold starts and has built-in Pipedrive event sources, but costs money past 3 workflows. n8n wins here specifically because the Code node eliminates the need for a separate routing layer, keeping the workflow at 4 nodes instead of 8.
Three things you'll hit after you go live. First, Pipedrive occasionally sends duplicate webhook events within 500ms of each other for a single user action — you'll see two identical Slack messages appear in rapid succession. Fix it by adding a deduplication check using n8n's $workflow.staticData to store the last processed deal ID and timestamp. Second, the owner_name field comes pre-resolved in the webhook payload, but if a deal has no assigned owner it returns an empty string — your Slack message will show 'Owner: ' with nothing after it. Add a null coalesce in the Code node: ownerName ?? 'Unassigned'. Third, if your Pipedrive pipeline has custom stages that were renamed after you built the stageMap, the stage ID stays the same but the name in your map is now stale — Slack messages will show the old name until you manually update the Code node. There's no way to make this dynamic without adding a Pipedrive API call to fetch stage names at runtime, which adds latency and an API dependency.
Ideas for what to build next
- →Add a Daily Pipeline Digest — Build a second n8n workflow on a daily CRON trigger that calls the Pipedrive API to summarize all deals by stage and posts a single morning digest to #sales-team — replaces the ad-hoc manual reporting this workflow was designed to eliminate.
- →Route by Deal Value Tier — Extend the Code node logic to post high-value deals (e.g. over $50K) to a separate #big-deals channel with a different message format, so leadership gets a dedicated feed without watching the full pipeline channel.
- →Write Slack Replies Back to Pipedrive Notes — Use the Slack Events API to listen for emoji reactions on deal stage messages and trigger a separate n8n workflow that writes the reaction context as a note on the Pipedrive deal, closing the feedback loop without switching apps.
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