

How to Send Zoho CRM Deal Stage Updates to Slack with n8n
Fires a formatted Slack message to a channel whenever a Zoho CRM deal moves to a new pipeline stage, including deal name, owner, value, and the stage it moved to.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Sales teams of 5–30 reps who need instant Slack alerts when deals progress or stall, without polling Zoho CRM manually.
Not ideal for
Teams that need two-way Slack-to-CRM updates — this is a one-way notification only; use a different workflow for that.
Sync type
real-timeUse case type
notificationReal-World Example
A 12-person SaaS sales team routes all deal stage changes into a #deals Slack channel so the whole team sees wins and stalls as they happen. Before this, reps refreshed Zoho CRM 3–4 times a day and still missed stage changes for 2–3 hours. After setup, a Slack message fires within 30 seconds of any stage move, including deal value and owner name so managers can jump in without opening the CRM.
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 Name | Deal_Name | |
| Stage | Stage | |
| Owner | Owner | |
| Deal ID | id | |
4 optional fields▸ show
| Amount | Amount |
| Account Name | Account_Name |
| Close Date | Closing_Date |
| Modified Time | Modified_Time |
Step-by-Step Setup
n8n Canvas > + New Workflow
Create a new workflow in n8n
Open your n8n instance and click the '+ New Workflow' button in the top-right corner of the canvas screen. Give the workflow a clear name like 'Zoho CRM Deal Stage → Slack'. You'll land on a blank canvas with a single node prompt in the center. This is where you'll add the webhook trigger node first.
- 1Click '+ New Workflow' in the top-right corner
- 2Click the workflow title at the top and rename it to 'Zoho CRM Deal Stage → Slack'
- 3Click the '+ Add first step' button in the center of the canvas
Canvas > Add Node > Webhook
Add a Webhook trigger node
In the node search panel, type 'Webhook' and select the core Webhook node. Set the HTTP Method to POST and leave the path as the auto-generated UUID — you'll copy this URL into Zoho CRM in the next step. Switch the node to 'Test' mode first so you can capture a live payload from Zoho before building the rest of the workflow. The webhook URL will look like https://your-n8n-instance.com/webhook-test/[uuid].
- 1Type 'Webhook' in the node search box and select the Webhook node
- 2Set HTTP Method to 'POST'
- 3Copy the Test URL shown at the top of the node panel
- 4Leave Authentication set to 'None' for now
Zoho CRM > Setup > Automation > Actions > Webhooks
Configure Zoho CRM webhook to fire on stage changes
In Zoho CRM, navigate to Setup > Automation > Actions > Webhooks and click '+ New Webhook'. Name it 'n8n Deal Stage Trigger', paste the n8n Test URL into the URL field, and set the method to POST. Under 'Module', select 'Deals'. You'll set the actual trigger condition (stage field change) in the Workflow Rules step, not here — this step just registers the endpoint.
- 1Go to Setup > Automation > Actions > Webhooks
- 2Click '+ New Webhook'
- 3Set Method to POST and paste the n8n Test URL
- 4Under 'Module', select 'Deals'
- 5Under 'Parameters', add the merge fields: Deal Name, Stage, Amount, Owner, Account Name, Deal ID, Modified Time
- 6Click Save
Zoho CRM > Setup > Automation > Workflow Rules > + Create Rule
Create a Workflow Rule in Zoho CRM to fire on stage changes
Still in Zoho CRM, go to Setup > Automation > Workflow Rules and click '+ Create Rule'. Set the module to 'Deals' and the trigger to 'Field Update'. Set the condition to fire when the 'Stage' field is modified. Under Actions, attach the webhook you created in the previous step. This is what actually calls n8n when a deal moves stages — without this rule, the webhook never fires.
- 1Click '+ Create Rule' and set Module to 'Deals'
- 2Set Rule Trigger to 'Field Update'
- 3Under 'Field', select 'Stage' and check 'Any Change'
- 4Under Actions > Webhooks, attach the webhook you created in Step 3
- 5Click Save and Activate
n8n Canvas > Webhook Node > Listen for test event
Capture a test payload from Zoho CRM
Back in n8n, click your Webhook node and hit 'Listen for test event'. Then go to Zoho CRM and manually edit a test deal — change its Stage field to something different and save. Within a few seconds, n8n should receive the payload and show the incoming fields on the right side of the node. This live payload is what all downstream nodes will reference for field names.
- 1Click the Webhook node on the canvas
- 2Click 'Listen for test event' in the node panel
- 3Switch to Zoho CRM, open a test deal, and change the Stage field
- 4Click Save on the deal in Zoho CRM
- 5Return to n8n and confirm the payload appeared
Canvas > + > IF Node
Add an IF node to filter stage changes worth alerting
Click the '+' connector below the Webhook node and add an IF node. Set the condition to check whether the 'Stage' field from the webhook payload is not empty. This prevents the workflow from sending a Slack message if Zoho fires the webhook without a stage value — which can happen when other deal fields are updated simultaneously through Zoho automations. Route the True branch to the next step and leave the False branch empty.
- 1Click the '+' below the Webhook node and search for 'IF'
- 2Set Condition 1: Value 1 = {{ $json.Stage }}, Operation = 'is not empty'
- 3Click 'Add condition' and set Value 1 = {{ $json.Stage }}, Operation = 'is not equal to', Value 2 = ''
- 4Connect the True output to the next node
Canvas > + > Code Node > JavaScript
Add a Code node to build the Slack message
Click '+' on the True branch of the IF node and add a Code node. Set the language to JavaScript. Write logic here to format the Slack message text, including the deal name, stage, owner, and amount. You can also set an emoji based on the stage — Closed Won gets a trophy, Needs Analysis gets a magnifying glass, and so on. This keeps the Slack message readable without any additional Slack Block Kit setup.
- 1Click '+' on the True output of the IF node
- 2Search for 'Code' and select the Code node
- 3Set Language to 'JavaScript'
- 4Paste your formatting logic into the code editor (see Pro Tip below)
- 5Click 'Test step' to preview the output
Paste this into the Code node in Step 7. It formats the Amount with commas and a dollar sign, picks an emoji based on the deal stage, and builds a Zoho CRM deep link so team members can click straight into the deal from Slack.
JavaScript — Code Node// n8n Code Node — Deal Stage Slack Message Formatter▸ Show code
// n8n Code Node — Deal Stage Slack Message Formatter // Paste this into the Code node between the IF node and the Slack node const items = $input.all();
... expand to see full code
// n8n Code Node — Deal Stage Slack Message Formatter
// Paste this into the Code node between the IF node and the Slack node
const items = $input.all();
const stageEmojis = {
'Qualification': ':mag:',
'Needs Analysis': ':clipboard:',
'Value Proposition': ':bulb:',
'Identify Decision Makers': ':busts_in_silhouette:',
'Perception Analysis': ':bar_chart:',
'Proposal/Price Quote': ':memo:',
'Negotiation/Review': ':handshake:',
'Closed Won': ':trophy:',
'Closed Lost': ':x:'
};
return items.map(item => {
const data = item.json;
const stage = data.Stage || 'Unknown Stage';
const dealName = data.Deal_Name || 'Unnamed Deal';
const owner = data.Owner || 'Unassigned';
const accountName = data.Account_Name || '';
const dealId = data.id || '';
// Format amount as currency string
const rawAmount = parseFloat(data.Amount) || 0;
const formattedAmount = rawAmount.toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
maximumFractionDigits: 0
});
// Pick emoji or default
const emoji = stageEmojis[stage] || ':arrow_right:';
// Build Zoho CRM deep link
const crmBaseUrl = 'https://crm.zoho.com/crm/org/tab/Potentials';
const dealLink = dealId ? `<${crmBaseUrl}/${dealId}|View Deal>` : '';
// Build account context string
const accountStr = accountName ? ` (${accountName})` : '';
// Compose final message
const message = `${emoji} *${dealName}*${accountStr} moved to *${stage}* — ${formattedAmount} | Owner: ${owner}${dealLink ? ' | ' + dealLink : ''}`;
return {
json: {
message,
stage,
dealName,
owner,
formattedAmount
}
};
});
channel: {{channel}}
ts: {{ts}}
Canvas > + > Slack Node > Message > Send
Add the Slack node and configure the message
Click '+' after the Code node and search for 'Slack'. Select the Slack node and set the Resource to 'Message' and the Operation to 'Send'. Connect your Slack credential (OAuth2 — you'll need the chat:write scope). Set the Channel field to the target channel ID or name (e.g., #deals). In the Text field, reference the formatted message from the Code node: {{ $json.message }}.
- 1Click '+' after the Code node and search for 'Slack'
- 2Set Resource to 'Message', Operation to 'Send'
- 3Click 'Credential for Slack' and connect your Slack OAuth2 app
- 4Set Channel to '#deals' or paste the channel ID
- 5Set Text to {{ $json.message }}
- 6Optionally set Username to 'Deal Bot' and Icon to ':briefcase:'
Slack Node > Settings (gear icon) > Error Handling > Continue on Fail
Add error handling with a catch node
Click the three-dot menu on the Slack node and enable 'Continue on Fail'. Then add a second Slack node connected to the error output and configure it to message a private #alerts channel with the error details. This way, failed webhook deliveries don't silently disappear — your team sees the error in Slack rather than missing a deal update entirely.
- 1Click the Slack node, then click the Settings tab inside the node panel
- 2Toggle 'Continue on Fail' to ON
- 3Click '+' on the error output branch
- 4Add another Slack node pointing to a #workflow-alerts channel
- 5Set Text to 'Deal stage webhook failed: {{ $json.error.message }} for deal {{ $node["Webhook"].json.Deal_Name }}'
n8n Canvas > Workflow toggle (top-right) > Active
Activate the workflow and swap to the Production URL
Before activating, go back to your Webhook node and copy the Production URL (not the Test URL). Then go to Zoho CRM > Setup > Automation > Actions > Webhooks, edit the webhook you created in Step 3, and replace the Test URL with the Production URL. Back in n8n, toggle the workflow to Active using the switch in the top-right of the canvas. The workflow now runs on every real deal stage change.
- 1Click the Webhook node and copy the Production URL from the node panel
- 2Go to Zoho CRM > Setup > Automation > Actions > Webhooks
- 3Edit your webhook and replace the URL with the Production URL
- 4Save the webhook in Zoho CRM
- 5Return to n8n and toggle the workflow switch to Active
n8n Left Sidebar > Executions
Test with a live deal stage change
Go to Zoho CRM and move a real (or test) deal from one stage to another. Check your #deals Slack channel within 30 seconds. Then check the n8n Executions panel (left sidebar > Executions) to confirm the run shows as 'Success'. If it failed, click the execution to see exactly which node errored and what the payload looked like.
- 1Open Zoho CRM and change a deal's Stage field
- 2Check your #deals Slack channel for the notification
- 3Click 'Executions' in the n8n left sidebar
- 4Find the most recent execution and confirm it shows a green 'Success' badge
- 5Click into the execution to inspect each node's input and output data
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're self-hosting, you want to avoid per-task pricing at scale, or you need to run custom JavaScript logic before the Slack message fires — like picking emojis by stage, formatting currency, or building deep links into Zoho CRM. n8n also lets you add error routing, conditional branching, and a fallback alert channel without any additional cost. The one case where you'd pick something else: if nobody on your team is comfortable with a webhook URL, a JSON payload, or reading an execution log, Zapier's Zoho CRM + Slack Zap does the same job in about 6 minutes with zero configuration overhead.
On n8n Cloud, each deal stage change = 1 execution. The Starter plan includes 2,500 executions/month for $20. A sales team closing 80 deals/month across an average of 6 stage changes per deal = 480 executions/month — well inside the free tier if you're on self-hosted, or a fraction of the Starter plan on cloud. Zapier's equivalent (Zap with Zoho CRM trigger + Slack action) costs 2 tasks per run on their paid plans, so 480 events = 960 tasks/month — that's $29.99/month on the Professional plan. n8n self-hosted is $0 for the same volume. Even on n8n Cloud, you're saving roughly $10/month at this volume.
Zapier has a native Zoho CRM 'Updated Deal Stage' trigger that requires zero webhook configuration — it polls every 15 minutes, which is too slow for real-time alerts but dead simple to set up. Make's Zoho CRM module has a Watch Records trigger with a 5-minute poll interval and a cleaner field-mapping UI than n8n, which matters if your team changes the workflow frequently. Power Automate has a Zoho CRM connector but it's a premium connector ($15/user/month add-on) and the Zoho trigger options are limited compared to using a direct webhook. Pipedream's Zoho CRM source can use webhooks and has built-in TypeScript support, making it competitive with n8n for developers — the difference is Pipedream charges per invocation at scale while n8n self-hosted doesn't. n8n wins here if you want real-time delivery, custom code, and cost control in one place.
Three things you'll hit after going live. First: Zoho CRM's webhook payload doesn't include the previous stage value — only the current one. If you want to show 'moved FROM Qualification TO Proposal', you'd need to store the last known stage in n8n's static data or a separate table and compare on each run. Second: Zoho's webhook fires on any field update to the deal record if your Workflow Rule condition isn't tight enough — a rep updating a phone number will trigger your Slack message if the rule is set to 'Any Field' instead of 'Stage Field'. Double-check the rule condition after go-live. Third: The Amount field arrives as a bare number string ('48000') with no currency symbol or formatting. If your team operates in multiple currencies, the Zoho payload also doesn't include the currency code — you'll need to hardcode your base currency in the Code node or pull it from a separate Zoho API call.
Ideas for what to build next
- →Stage-specific Slack channels — Route different stage changes to different channels — Closed Won goes to #wins, Closed Lost goes to #postmortem, early stages go to #pipeline. Add a Switch node after the IF node to branch by stage value.
- →Daily deal pipeline digest — Add a second workflow with a Schedule trigger that queries Zoho CRM at 8am each day for all deals modified in the last 24 hours and posts a summary to #deals. Pairs with this real-time workflow so the team gets both instant alerts and a morning recap.
- →Slack reply triggers Zoho CRM note — Build a reverse workflow where a reply to a deal stage Slack message (using Slack's thread reply event) creates a note on the deal in Zoho CRM. Requires the Slack Events API and a second n8n workflow with a Zoho CRM 'Create Note' node.
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