Intermediate~20 min setupCommunication & CRMVerified April 2026
Slack logo
Pipedrive logo

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-time

Use case type

notification

Real-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.

/mo
505005K50K

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

Skip the setup

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.

n8n instance running and accessible via a public URL (Cloud, VPS, or localhost with ngrok tunnel)
Pipedrive account with Admin access to create webhooks under Settings > Tools & Integrations
Slack Bot Token (xoxb-) with chat:write scope, and the bot invited to every notification channel
Pipedrive stage IDs for your pipeline — find these at Settings > Pipelines or via GET /stages in the Pipedrive API
n8n Slack credential created with your Bot Token before starting Step 7

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Deal Titlebody.current.title
Deal Valuebody.current.value
Currencybody.current.currency
Current Stage IDbody.current.stage_id
Previous Stage IDbody.previous.stage_id
Deal Owner Namebody.current.owner_name
Deal IDbody.current.id
3 optional fields▸ show
Pipeline IDbody.current.pipeline_id
Expected Close Datebody.current.expected_close_date
Organization Namebody.current.org_name

Step-by-Step Setup

1

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.

  1. 1Click '+ New Workflow' in the top-right corner
  2. 2Click the workflow name field at the top and type 'Pipedrive → Slack Deal Stage Alerts'
  3. 3Click the default 'Start' node and press Delete to remove it
What you should see: You should see a blank canvas with the workflow name displayed at the top.
2

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.

  1. 1Click the '+' button on the canvas
  2. 2Type 'Webhook' in the search box and select the 'Webhook' core node
  3. 3Set HTTP Method to 'POST'
  4. 4Set Response Mode to 'Respond Immediately'
  5. 5Copy the Production webhook URL shown in the node panel
What you should see: The Webhook node appears on the canvas showing a URL ending in '/webhook/[unique-id]'. The node panel shows 'Respond Immediately' selected under Response Mode.
Common mistake — n8n gives you two URLs — 'Test URL' and 'Production URL'. Use the Production URL in Pipedrive. The Test URL only works while the workflow editor is open and listening.
n8n
+
click +
search apps
Slack
SL
Slack
Add a Webhook trigger node
Slack
SL
module added
3

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.

  1. 1In Pipedrive, click your avatar and select 'Settings'
  2. 2Navigate to 'Tools & Integrations' then click 'Webhooks'
  3. 3Click '+ Add Webhook'
  4. 4Paste your n8n Production webhook URL into 'Endpoint URL'
  5. 5Set Event Action to 'Updated' and Event Object to 'Deal'
  6. 6Click 'Save'
What you should see: The webhook appears in your Pipedrive webhook list with a green status indicator. Pipedrive sends a test ping — check your n8n Webhook node execution log to confirm it received a payload.
Common mistake — Pipedrive fires this webhook for ANY deal update — field edits, note additions, and stage changes all trigger it. You'll add a filter in Step 5 to isolate stage changes only.
4

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.

  1. 1Click the Webhook node to open its panel
  2. 2Click 'Listen for Test Event' at the bottom of the panel
  3. 3Switch to Pipedrive and drag a deal to a new stage
  4. 4Return to n8n and confirm the payload appears in the Output tab
What you should see: The Output tab on the Webhook node shows the full Pipedrive deal payload with fields like 'id', 'title', 'value', 'currency', 'stage_id', and a 'meta' object containing 'action': 'updated'.
Common mistake — If the Output tab stays empty after 30 seconds, Pipedrive could not reach your n8n URL. This usually means your n8n instance is running on localhost without a tunnel. Use ngrok or deploy n8n to a cloud instance before proceeding.
n8n
▶ Run once
executed
Slack
Pipedrive
Pipedrive
🔔 notification
received
5

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.

  1. 1Click the '+' connector from the Webhook node
  2. 2Search for 'IF' and select the 'IF' core node
  3. 3Click 'Add Condition' and set the left value to expression: {{ $json.body.previous.stage_id }}
  4. 4Set the operator to 'Not Equal'
  5. 5Set the right value to expression: {{ $json.body.current.stage_id }}
What you should see: The IF node shows two output branches labeled 'true' and 'false'. When you run a test with a stage-change payload, the data routes through the 'true' branch.
Common mistake — Filters are the most common place setups break. Double-check the field name and value exactly match what your app sends — a single capital letter difference will block everything.
Slack
SL
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Pipedrive
PI
notified
6

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.

  1. 1Click the '+' on the 'true' output of the IF node
  2. 2Search for 'Code' and select the 'Code' core node
  3. 3Set Language to 'JavaScript'
  4. 4Paste the stage-mapping and message-building code into the code editor (see Pro Tip below)
  5. 5Click 'Execute Node' to test with the captured payload
What you should see: The Code node output shows a single item with fields: 'channel', 'message_text', 'stage_name', 'deal_title', 'deal_value', 'owner_name', and 'deal_url'.
Common mistake — Stage IDs in Pipedrive are account-specific integers. Do not guess them. Find yours at Settings > Pipelines — hover over a stage and check the URL for '?stage_id=XX', or use the Pipedrive API GET /stages endpoint.

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,
  }
}];
message template
🔔 New Record: {{text}} {{user}}
channel: {{channel}}
ts: {{ts}}
#sales
🔔 New Record: Jane Smith
Company: Acme Corp
7

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.

  1. 1Click '+' from the Code node and search for 'Slack'
  2. 2Select Resource: 'Message', Operation: 'Post'
  3. 3In the Channel field, click the expression toggle and type: {{ $json.channel }}
  4. 4In the Text field, click the expression toggle and type: {{ $json.message_text }}
  5. 5Click 'Create new credential' and paste your Slack Bot Token (starts with xoxb-)
  6. 6Click 'Save' on the credential
What you should see: The Slack node shows a green credential badge. Running a test execution posts a correctly formatted message to the target Slack channel within 2-3 seconds.
Common mistake — If you see 'channel_not_found', the bot has not been invited to that channel. In Slack, open the channel, type /invite @YourBotName, and press Enter.
8

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.

  1. 1Click the three-dot menu (⋮) on the Slack node
  2. 2Select 'Settings'
  3. 3Toggle 'Continue on Error' to ON
  4. 4Add a second Slack node connected to the error output
  5. 5Set its channel to a private ops channel like #workflow-errors
  6. 6Set the message text to: 'Deal stage alert failed. Deal ID: {{ $json.body.current.id }}. Error: {{ $json.error.message }}'
What you should see: A second Slack node appears connected to the error path of the first Slack node. Testing with an invalid channel name routes through this error branch and posts the failure message to your ops channel.
9

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'.

  1. 1Click the 'Inactive' toggle in the top-right of the canvas
  2. 2Confirm the modal prompt by clicking 'Activate Workflow'
  3. 3Open Pipedrive and move a deal to a new stage
  4. 4Check the target Slack channel for the notification
  5. 5Open n8n > Executions to verify the run shows green 'Success'
What you should see: The toggle shows 'Active' in green. The Executions panel shows a successful run with a timestamp matching your test deal move. The Slack channel shows the formatted deal stage message.
Common mistake — Activating the workflow starts consuming your n8n execution quota if you're on n8n Cloud. On self-hosted n8n, check your database storage — every execution is logged and the table grows fast on high-activity Pipedrive accounts.

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

VerdictWhy n8n for this workflow

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

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.

Tradeoffs

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 DigestBuild 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 TierExtend 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 NotesUse 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

Was this guide helpful?
Slack + Pipedrive overviewn8n profile →