

How to Send Lost Deal Alerts from Zoho CRM to Slack with Power Automate
When a deal is marked as lost in Zoho CRM, Power Automate fires a webhook, extracts the reason code and competitor data, and posts a formatted alert to a designated Slack management channel.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Sales ops teams already running Microsoft 365 who need management alerted instantly when deals close-lost with structured reason and competitor data.
Not ideal for
Teams not in the Microsoft ecosystem — Make handles this same flow cheaper and with less setup friction if you're starting fresh.
Sync type
real-timeUse case type
notificationReal-World Example
A 22-person B2B SaaS sales team uses this to post every closed-lost deal to a private #lost-deals Slack channel visible to the VP of Sales and RevOps lead. Before this flow, reason codes sat in Zoho unread for days and competitive intel (which rival won the deal) never surfaced to leadership until the quarterly review. Now the VP sees a Slack card within 90 seconds of a rep marking a deal lost, including the loss reason and competitor field, and can follow up with the rep the same day.
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 Power Automate
Copy the pre-built Power Automate blueprint and paste it straight into Power Automate. 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 | |
| Closing Reason | Closing_Reason | |
| Amount | Amount | |
| Account Name | Account_Name | |
| Deal Owner | Owner | |
3 optional fields▸ show
| Competitor | Competitor |
| Close Date | Closing_Date |
| Description / Loss Notes | Description |
Step-by-Step Setup
make.powerautomate.com > My flows > + New flow > Automated cloud flow
Set Up the Zoho CRM Webhook Trigger in Power Automate
Go to make.powerautomate.com and click 'My flows' in the left sidebar, then click '+ New flow' and select 'Automated cloud flow'. Name the flow something like 'Zoho Lost Deal → Slack Alert'. In the trigger search bar, type 'Zoho CRM' and select the connector. Choose the trigger 'When a record is created or updated' — this is the correct trigger for catching stage changes in Zoho CRM deals.
- 1Click 'My flows' in the left sidebar
- 2Click '+ New flow' then select 'Automated cloud flow'
- 3Enter a flow name, e.g. 'Zoho Lost Deal → Slack Alert'
- 4In the trigger search bar type 'Zoho CRM'
- 5Select 'When a record is created or updated' as the trigger
Flow canvas > Zoho CRM trigger card > Module Name dropdown
Configure the Zoho CRM Trigger for Deals Module
Inside the trigger card, set the 'Module Name' dropdown to 'Deals'. Leave the trigger set to fire on both creates and updates — you cannot filter to updates-only at the trigger level in this connector. The filtering to lost deals happens in a Condition step later. Make sure your Zoho CRM Connection is authenticated before moving forward; Power Automate will prompt you to sign in if no connection exists yet.
- 1Click inside the Zoho CRM trigger card to expand its settings
- 2Click the 'Module Name' dropdown and select 'Deals'
- 3If prompted, click 'Sign in' to create a new Zoho CRM Connection and authenticate with your Zoho account
- 4Confirm the Connection shows your Zoho org domain in the connection label
Flow canvas > + New step > Control > Condition
Add a Condition to Filter for Lost Stage Only
Click '+ New step' and search for 'Condition' — select the built-in Control action named 'Condition'. This is where you isolate only deals whose Stage field equals 'Closed Lost'. In the left value box, click inside and select 'Stage' from the dynamic content picker (this is the Deal_Stage field from Zoho). Set the operator to 'is equal to' and type 'Closed Lost' in the right value box exactly as it appears in your Zoho CRM picklist.
- 1Click '+ New step' below the trigger card
- 2Search for 'Condition' and select the 'Condition' Control action
- 3Click the left value box and choose 'Stage' from the dynamic content panel
- 4Set the middle dropdown to 'is equal to'
- 5Type 'Closed Lost' in the right value box (match the exact spelling in your Zoho picklist)
Flow canvas > Condition > No branch > + Add an action > Control > Terminate
Add a Terminate Action in the 'No' Branch
Click inside the 'No' branch of your Condition. Add a 'Terminate' action from the Control connector. Set Status to 'Succeeded' and leave the message blank. This cleanly ends the flow run for any deal update that is not a lost deal, keeping your flow run history clean and avoiding unnecessary Slack noise.
- 1Click '+ Add an action' inside the 'No' branch
- 2Search for 'Terminate' and select the Control action
- 3Set the 'Status' field to 'Succeeded'
- 4Leave the 'Code' and 'Message' fields empty
Flow canvas > Condition > Yes branch > + Add an action > Data Operation > Parse JSON
Add a Parse JSON Action to Extract Zoho Deal Fields
Inside the 'Yes' branch, click '+ Add an action' and search for 'Parse JSON' — it lives under the Data Operation connector. In the 'Content' field, insert the dynamic content output from the Zoho CRM trigger (typically labeled 'body' or the raw record output). You need to provide a schema so Power Automate can surface individual fields like Deal_Name, Closing_Reason, Competitor, and Amount as named tokens. Click 'Generate from sample' and paste a real Zoho deal JSON payload to auto-generate the schema.
- 1Click '+ Add an action' inside the 'Yes' branch
- 2Search 'Parse JSON' and select 'Parse JSON' under Data Operation
- 3In the 'Content' field, select the raw body output from the Zoho CRM trigger via the dynamic content panel
- 4Click 'Generate from sample', paste a real Zoho CRM deal record JSON, and click 'Done'
- 5Verify that fields like Deal_Name, Closing_Reason, and Competitor appear in the generated schema
Flow canvas > Condition > Yes branch > + Add an action > Data Operation > Compose
Add a Compose Action to Build the Slack Message
Add a 'Compose' action (Data Operation connector) in the Yes branch after Parse JSON. Use this to construct the Slack Block Kit JSON payload. This gives you full control over the message format before passing it to the Slack action. Build a JSON object with a 'blocks' array that includes a header block with the deal name, a section block with loss reason and competitor, and a context block with deal amount and close date.
- 1Click '+ Add an action' after the Parse JSON step
- 2Search 'Compose' and select 'Compose' under Data Operation
- 3Click inside the 'Inputs' field and switch to the expression editor
- 4Paste the Block Kit JSON structure (see pro_tip_code below) referencing Parse JSON dynamic tokens
- 5Click 'OK' to save the expression
channel: {{channel}}
ts: {{ts}}
Flow canvas > Yes branch > + Add an action > Slack > Post message (V2)
Connect to Slack and Configure the Post Message Action
Add a new action and search for 'Slack'. Select the 'Post message (V2)' action. If you don't have a Slack connection yet, click 'Sign in' and authenticate with the Slack workspace where you want alerts posted. For the 'Channel' field, type or select the management channel (e.g., #lost-deals). In the 'Message Text' field, enter a plain-text fallback. In the 'Blocks' field, reference the output of your Compose step.
- 1Click '+ Add an action' after the Compose step
- 2Search 'Slack' and select 'Post message (V2)'
- 3Click 'Sign in' to create a Slack Connection if none exists; authorize Power Automate in your Slack workspace
- 4Set the 'Channel' field to your target channel (e.g., #lost-deals)
- 5In the 'Blocks' field, select the 'Outputs' dynamic token from the Compose step
Flow canvas > Slack action > ... menu > Configure run after
Add Error Handling with a Parallel Branch
Select the Slack 'Post message' action card, click the three-dot menu, and choose 'Configure run after'. Enable the 'has failed' and 'has timed out' checkboxes. Below the Slack action, add a parallel branch that fires only on failure: add another 'Post message' action to a different Slack channel (e.g., #automation-errors) with a static alert that the lost deal notification failed. Include the flow run ID using the expression workflow()['run']['name'] so your team can trace the failed run.
- 1Click the '...' menu on the Slack Post message action card
- 2Select 'Configure run after'
- 3Check the 'has failed' and 'has timed out' boxes, then click Done
- 4Click '+ Add a parallel branch' and add a second Slack 'Post message' action
- 5Set the error channel to #automation-errors and include the expression workflow()['run']['name'] in the message body
make.powerautomate.com > My flows > [Your Flow] > 28 day run history
Test the Flow with a Real Zoho Deal
Save the flow, then go to your Zoho CRM account and find an existing test deal. Change its Stage to 'Closed Lost', set a Closing Reason, and fill in the Competitor field. Wait up to 60 seconds for Power Automate's polling interval to pick up the change. Back in Power Automate, click '28 day run history' in the flow detail page to see if a run fired. Click into the run to inspect each step's inputs and outputs.
- 1Save the flow by clicking the 'Save' button in the top right
- 2Open Zoho CRM in a separate tab and navigate to a test deal
- 3Set Stage to 'Closed Lost', fill in Closing Reason and Competitor, and save
- 4Wait 60 seconds then return to Power Automate
- 5Click '28 day run history' on your flow's detail page and inspect the latest run
make.powerautomate.com > My flows > [Your Flow] > Detail page > Owners / Run only users
Turn the Flow On and Set Run-Only Permissions
If the flow is still in draft or off state, toggle it to 'On' from the flow detail page. Then click 'Edit' next to 'Run only users' at the bottom of the flow detail screen. This controls who can trigger a manual run — for an automated flow you can leave this as owner-only, but document the owning account clearly. Add at least one co-owner under 'Owners' so the flow doesn't orphan if the original creator's account is deactivated.
- 1Navigate to the flow's detail page and confirm the status toggle reads 'On'
- 2Scroll to the 'Owners' section at the bottom of the detail page
- 3Click 'Edit' next to Owners and add a second owner (e.g., your team's shared admin account)
- 4Save the ownership change
Paste this expression into the Compose action's Inputs field (switch to the Expression tab in the dynamic content panel). It builds a complete Slack Block Kit payload using dynamic tokens from the Parse JSON step, formats the Amount as currency, and truncates the Description field to 200 characters so Slack cards stay readable. Replace 'body' references with the actual Parse JSON output token names if they differ in your schema.
JavaScript — Code Step{▸ Show code
{
"blocks": [
{... expand to see full code
{
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": concat('🔴 Deal Lost: ', body('Parse_JSON')?['Deal_Name'])
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": concat('*Loss Reason:*\n', body('Parse_JSON')?['Closing_Reason'])
},
{
"type": "mrkdwn",
"text": concat('*Competitor:*\n', if(empty(body('Parse_JSON')?['Competitor']), 'Not specified', body('Parse_JSON')?['Competitor']))
},
{
"type": "mrkdwn",
"text": concat('*Deal Value:*\n$', body('Parse_JSON')?['Amount'])
},
{
"type": "mrkdwn",
"text": concat('*Owner:*\n', body('Parse_JSON')?['Owner'])
}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": concat('*Notes:* ', substring(if(empty(body('Parse_JSON')?['Description']), 'No notes provided.', body('Parse_JSON')?['Description']), 0, min(200, length(if(empty(body('Parse_JSON')?['Description']), 'No notes provided.', body('Parse_JSON')?['Description'])))))
}
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": concat('Account: *', body('Parse_JSON')?['Account_Name'], '* | Close Date: ', body('Parse_JSON')?['Closing_Date'])
}
]
}
]
}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 Power Automate for this if your organization is already running Microsoft 365 and your IT team manages connections through the Microsoft admin center. The Zoho CRM connector is pre-built and maintained, Power Automate's error handling and run history are genuinely good for debugging production issues, and if you're already paying for a Microsoft 365 Business Premium plan, the per-user Power Automate license may already be included. The one scenario where you'd skip Power Automate entirely: if you have no Microsoft footprint whatsoever. Paying $15/user/month just for this flow when Make would run it for $9/month total is hard to justify.
Cost math is straightforward. This flow consumes approximately 3–4 actions per run (trigger check, condition, parse JSON, compose, Slack post — but trigger checks don't always count toward your action quota). At 50 lost deals per month, you're looking at 150–200 action runs. The Power Automate per-user plan includes 40,000 actions/month, so you won't come close to the limit. The real cost is the license: $15/user/month for the plan that unlocks the Zoho CRM premium connector. Make runs this same flow for $9/month total on their Core plan, which covers 10,000 operations. Zapier's equivalent comes in at $19.99/month on the Professional plan. Power Automate is mid-range on price but the cheapest option if you're already paying for Microsoft 365 E3 or higher.
Zapier has a cleaner Zoho CRM trigger setup — their 'New or Updated Deal in Stage' filter is built into the trigger itself, so you skip the Condition step entirely. That's a genuine time-saver. Make gives you better message formatting control through its HTTP module with Slack's raw API, letting you send rich Block Kit payloads without the limitations of the native Slack connector. n8n wins if you want to self-host and pay nothing per run — their Zoho CRM node and Slack node both handle this workflow in about 6 nodes, and you can add JavaScript transformations inline. Pipedream is fastest to set up if you already know JavaScript and want sub-10-second trigger latency via Zoho's push webhooks. Power Automate still makes sense here when your IT department requires all integrations to live within the Microsoft tenant for compliance and visibility reasons — that's a real constraint in enterprise environments and it's where Power Automate wins by default.
Three things you'll hit after setup. First, Zoho CRM fires multiple update events for a single save when Zoho workflows or Blueprint automation also touch the record — you'll see duplicate Slack messages and spend time wondering why. Fix it with concurrency control set to 1 on the flow. Second, the Zoho CRM connector's token refresh isn't bulletproof — flows that go days without running sometimes wake up with a stale OAuth token and fail with a 401 until you manually re-authenticate the connection. Put a monitoring alert on flow failure emails so you catch this before management notices missing notifications. Third, Power Automate's dynamic content panel doesn't always surface nested JSON fields from Zoho cleanly — fields inside objects (like Owner being an object with 'name' and 'id' sub-properties) show up as the full object string rather than a readable name. You'll need Parse JSON with a precise schema, or an explicit expression like body('Parse_JSON')?['Owner']?['name'], to pull out the rep's display name rather than posting a raw ID to Slack.
Ideas for what to build next
- →Build a Weekly Lost Deal Digest — Add a separate Scheduled cloud flow that runs every Monday morning, queries Zoho CRM for all deals closed-lost in the past 7 days using the 'Search records' action, and posts a grouped summary to #lost-deals showing loss reasons ranked by frequency. This gives leadership a pattern view alongside the real-time individual alerts.
- →Log Lost Deals to a SharePoint List for Trend Reporting — After the Slack post action in your Yes branch, add a SharePoint 'Create item' action to write each lost deal to a SharePoint list with columns for reason code, competitor, amount, and date. Connect that list to a Power BI report so your RevOps team can slice loss reasons by rep, product line, and competitor over time.
- →Auto-Create a Follow-Up Task in Zoho CRM — Add a Zoho CRM 'Create record' action at the end of the Yes branch to create a follow-up Activity/Task assigned to the deal owner with a due date of 2 business days, prompting them to document a full loss analysis. This closes the loop between the Slack alert and structured loss data capture.
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