Intermediate~15 min setupCommunication & CRMVerified April 2026
Slack logo
Zoho CRM logo

How to Send Zoho CRM Deal Stage Alerts to Slack with Power Automate

Automatically posts a Slack message to a specified channel whenever a deal moves to a new pipeline stage in Zoho CRM.

Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.

Best for

Microsoft-stack sales teams who already use Power Automate and want deal stage alerts in Slack without adding another tool.

Not ideal for

Teams needing sub-minute alert speed — Power Automate's Zoho CRM connector polls on a schedule, so use Make or n8n with a webhook if latency matters.

Sync type

scheduled

Use case type

notification

Real-World Example

💡

A 12-person SaaS sales team at a mid-market software company posts all deal stage changes to a #pipeline Slack channel. Before this flow, reps opened Zoho CRM manually 4-5 times a day to check for updates and still missed stage changes for 2-3 hours. Now the flow runs every 15 minutes, and the whole team sees wins, stalls, and closures the moment the next poll fires.

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

Zoho CRM account with at minimum read access to the Deals module and permission to use third-party integrations
Slack workspace with permission to add apps, and access to the target channel (e.g., #pipeline)
Power Automate account with a license that includes premium connectors — the Zoho CRM connector is premium and requires a Power Automate Premium or per-flow plan
A SharePoint site you have edit access to, used to create the DealStageTracker list for storing last-known deal stages between flow runs
Admin or sufficient permissions in your Microsoft 365 tenant to create new Connections in Power Automate for both Zoho CRM and Slack

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Deal IDid
Deal NameDeal_Name
StageStage
Modified TimeModified_Time
Last Stage (SharePoint)
4 optional fields▸ show
Account NameAccount_Name
Deal OwnerOwner
AmountAmount
Closing DateClosing_Date

Step-by-Step Setup

1

make.powerautomate.com > My flows > + New flow > Scheduled cloud flow

Open Power Automate and create a new Scheduled flow

Go to make.powerautomate.com and sign in. In the left sidebar, click 'My flows', then click '+ New flow' at the top. Select 'Scheduled cloud flow' from the dropdown — this is the correct type because the Zoho CRM connector does not support instant triggers for deal stage changes. Give the flow a name like 'Zoho Deal Stage → Slack Alert'.

  1. 1Sign in at make.powerautomate.com
  2. 2Click 'My flows' in the left sidebar
  3. 3Click '+ New flow' near the top of the page
  4. 4Select 'Scheduled cloud flow' from the dropdown menu
  5. 5Name the flow 'Zoho Deal Stage → Slack Alert' and click 'Create'
What you should see: You should see the flow designer open with a 'Recurrence' trigger block already placed at the top of the canvas.
Common mistake — Do not choose 'Automated cloud flow' — Zoho CRM's Power Automate connector does not fire instant triggers on field changes. Scheduled is the correct choice here.
2

Flow canvas > Recurrence trigger > Interval / Frequency fields

Configure the Recurrence trigger interval

Click the 'Recurrence' trigger block that was auto-placed on the canvas. Set the Interval to '15' and the Frequency to 'Minute'. This means the flow will poll Zoho CRM every 15 minutes for stage changes. You can reduce this to 5 minutes if your plan allows more runs, but 15 minutes is a reasonable default that avoids burning through your monthly run quota.

  1. 1Click the 'Recurrence' trigger block on the canvas
  2. 2Set 'Interval' to 15
  3. 3Set 'Frequency' to 'Minute'
  4. 4Leave Start time blank unless you want the flow to begin at a specific time
  5. 5Click anywhere outside the block to collapse it
What you should see: The Recurrence block should now show '15 Minute' as the configured schedule.
Common mistake — The default polling interval is often 15 minutes. If you need faster delivery, check whether your plan supports shorter intervals before assuming it's a bug.
Power Automate
+
click +
search apps
Slack
SL
Slack
Configure the Recurrence tri…
Slack
SL
module added
3

Flow canvas > + New step > Search 'Zoho CRM' > Get Records

Add a Zoho CRM 'Get Records' action

Click '+ New step' below the Recurrence block. In the search bar, type 'Zoho CRM' and select the Zoho CRM connector. Choose the action 'Get Records'. This action queries Zoho CRM for deals that match a filter — you will use it to find deals whose Stage field was updated in the last 15 minutes. If you have not connected Zoho CRM yet, Power Automate will prompt you to sign in and authorize the connection inline.

  1. 1Click '+ New step' below the Recurrence trigger
  2. 2Type 'Zoho CRM' in the connector search bar
  3. 3Click the Zoho CRM connector icon
  4. 4Select the 'Get Records' action from the action list
  5. 5If prompted, click 'Sign in' and authorize with your Zoho CRM credentials
What you should see: The 'Get Records' action block appears on the canvas. If this is your first connection, you will see a green 'Connected' indicator next to your Zoho account email.
Common mistake — The Zoho CRM connector uses OAuth2. Make sure the account you authorize has at minimum read access to the Deals module — a profile with view-only CRM permissions will work.
4

Flow canvas > Get Records block > Module Name / Criteria / Per Page fields

Configure the Get Records filter for recent stage changes

Inside the 'Get Records' action, set Module Name to 'Deals'. In the 'Criteria' field, enter a COQL-style filter to return only deals modified in the last 15 minutes. You will use a Power Automate expression to build the cutoff timestamp dynamically. Set 'Page' to 1 and 'Per Page' to 50 unless you expect more than 50 stage changes per 15-minute window.

  1. 1Set 'Module Name' to 'Deals'
  2. 2Click inside the 'Criteria' field and select 'Expression'
  3. 3Enter the expression: concat('(Modified_Time:greater_than:', addMinutes(utcNow(), -15), ')')
  4. 4Set 'Per Page' to 50
  5. 5Leave 'Page' at 1
What you should see: The Get Records block shows Module Name as 'Deals' and the Criteria field contains your dynamic timestamp expression.
Common mistake — The Zoho CRM connector returns ALL modified deals, not just stage changes. You must filter by the Stage field in a later step — the API does not support filtering on field-level change history directly.
Slack
SL
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Zoho CRM
ZO
notified
5

Flow canvas > + New step > SharePoint > Get items (or Azure Table Storage > Get entities)

Initialize a variable to track the previous stage

Because the Zoho CRM API does not expose field change history through this connector, you need to store deal stage state between runs. The most practical approach for teams without Azure infrastructure is to use a SharePoint list or an Azure Table as a state store. Add a 'Get items' action from SharePoint (or 'Get entities' from Azure Table Storage) to retrieve the last known stage for each deal ID. This step fetches that stored state so you can compare it against what Zoho returns.

  1. 1Click '+ New step'
  2. 2Search for 'SharePoint' and select 'Get items'
  3. 3Connect to your SharePoint site and select the list you created to store deal stages (e.g., 'DealStageTracker')
  4. 4Set a filter query: DealID eq '<deal id from Zoho step>' — you will bind this dynamically inside the Apply to each loop in a later step
  5. 5Leave Top Count at 1 to return only the most recent stored record per deal
What you should see: The SharePoint 'Get items' block appears connected. At this stage the deal ID binding will show as an empty field — you will wire it up inside the loop in Step 6.
Common mistake — You must create the SharePoint list before running the flow. It needs at minimum two columns: DealID (single line of text) and LastStage (single line of text). Missing this list will cause a 404 error on first run.
6

Flow canvas > + New step > Control > Apply to each

Add an 'Apply to each' loop over returned deals

Click '+ New step' and add an 'Apply to each' control. Set the input to the 'value' output from the 'Get Records' Zoho step — this is the array of deals returned by the API. Inside this loop, all subsequent steps (the stage comparison, the SharePoint lookup, the Slack post) will execute once per deal. Move the SharePoint 'Get items' step from Step 5 inside this loop by dragging it in, then bind the DealID filter to the current deal's 'id' dynamic value.

  1. 1Click '+ New step', select 'Control', then 'Apply to each'
  2. 2Click inside 'Select an output from previous steps' and choose the 'value' array from the Zoho Get Records step
  3. 3Drag the SharePoint 'Get items' block inside the Apply to each loop
  4. 4In the SharePoint filter query, bind DealID to the current item's 'id' field from Zoho using dynamic content
  5. 5Confirm the loop shows the SharePoint step nested inside it
What you should see: The Apply to each block wraps the SharePoint step. The loop label reads 'Apply to each - value' indicating it will iterate over each deal returned by Zoho.
7

Flow canvas > Apply to each loop > + Add an action > Control > Condition

Add a Condition to detect stage changes

Inside the Apply to each loop, add a 'Condition' control after the SharePoint Get items step. Set the left value to the current deal's 'Stage' field (from Zoho dynamic content), the operator to 'is not equal to', and the right value to the LastStage field from the SharePoint item. This comparison tells the flow: only proceed if the stage in Zoho differs from what was stored last run. The 'If yes' branch is where the Slack message and state update will go.

  1. 1Inside the Apply to each loop, click '+ Add an action'
  2. 2Select 'Control' then 'Condition'
  3. 3Set the left value to the 'Stage' dynamic content from the Zoho Get Records step
  4. 4Set the operator to 'is not equal to'
  5. 5Set the right value to the 'LastStage' field from the SharePoint Get items output
What you should see: A Condition block appears inside the loop with two branches labeled 'If yes' and 'If no'. The condition reads: Stage is not equal to LastStage.
Common mistake — If the SharePoint list has no existing entry for a deal (first time the deal is seen), the LastStage value will be null. The 'not equal to' condition will evaluate as true and send a Slack message. Add a secondary condition check for null if you want to suppress first-seen notifications.
8

Flow canvas > Apply to each > Condition > If yes > Add an action > Slack > Post message

Post a Slack message in the 'If yes' branch

Inside the 'If yes' branch of the Condition, click 'Add an action'. Search for 'Slack' and select the Slack connector. Choose the action 'Post message'. Connect your Slack workspace when prompted. Set Channel to the target channel name (e.g., #pipeline). Build the message text using dynamic content from Zoho — include Deal Name, Account Name, previous Stage from SharePoint, and the new Stage from Zoho.

  1. 1Inside the 'If yes' branch, click 'Add an action'
  2. 2Search 'Slack' and select the Slack connector
  3. 3Choose 'Post message' from the action list
  4. 4Authorize Slack by clicking 'Sign in' and completing OAuth
  5. 5Set Channel to '#pipeline' (or your preferred channel name)
  6. 6In the Message field, enter: 🔔 Deal Update: [Deal Name] moved from [LastStage] → [Stage] | Account: [Account Name] | Owner: [Owner Name]
What you should see: The Slack 'Post message' block appears in the 'If yes' branch showing your channel and message template with dynamic values bound.
Common mistake — The Slack connector in Power Automate posts as the OAuth-authorized user by default, not as a bot. If you want a bot name and icon, you need a Slack incoming webhook URL instead — use the HTTP action to POST to it rather than the native Slack connector.
message template
🔔 New Record: {{text}} {{user}}
channel: {{channel}}
ts: {{ts}}
#sales
🔔 New Record: Jane Smith
Company: Acme Corp
9

Flow canvas > Apply to each > Condition > If yes > Add an action > SharePoint > Update item / Create item

Update the SharePoint state record

Still inside the 'If yes' branch, after the Slack step, add a SharePoint action to update the stored stage. If the deal already exists in your SharePoint list, use 'Update item'. If it might be new, use a branching pattern: check if SharePoint returned any items, then use 'Create item' or 'Update item' accordingly. Set the DealID column to the current deal's id and the LastStage column to the new Stage value from Zoho.

  1. 1Click 'Add an action' below the Slack step inside the 'If yes' branch
  2. 2Search 'SharePoint' and select 'Update item'
  3. 3Set Site Address and List Name to your DealStageTracker list
  4. 4Set the ID field to the SharePoint item ID returned from the Get items step
  5. 5Set LastStage to the current Zoho deal's 'Stage' dynamic value
What you should see: The SharePoint 'Update item' action appears below the Slack step. It shows the LastStage field bound to the Zoho Stage value.
10

Flow canvas > Save > Test > Manually > Run flow

Test the flow with a live deal stage change

Click 'Save' in the top right of the flow designer, then click 'Test' (also top right). Select 'Manually' and click 'Run flow'. While the test runs, go into Zoho CRM and manually move a deal from one stage to another. Wait for the test run to complete — it may take 30-60 seconds. Check the run history to confirm the Apply to each loop processed the deal and the Slack step shows as green.

  1. 1Click 'Save' in the top right corner of the flow designer
  2. 2Click 'Test' in the top right
  3. 3Select 'Manually' and click 'Run flow'
  4. 4In a separate tab, open Zoho CRM and move a deal to a different pipeline stage
  5. 5Return to Power Automate and watch the run complete, then click 'Run history' to inspect each step's output
What you should see: The run history shows all steps green. The Apply to each step shows at least one iteration. The Slack step shows a successful post. Your #pipeline channel receives the formatted deal stage message.
Common mistake — If the run completes but no Slack message appears, the Condition likely evaluated as false because the deal stage matched the stored LastStage. Temporarily delete the SharePoint record for your test deal and run again to force a mismatch.
Power Automate
▶ Test flow
executed
Slack
Zoho CRM
Zoho CRM
🔔 notification
received
11

make.powerautomate.com > My flows > [Flow Name] > Turn on / Run history

Turn on the flow and monitor the first 24 hours

After a successful test, click 'Turn on' if the flow is still in draft. The flow will now run automatically every 15 minutes. Check the 'Run history' page after the first few automated runs to confirm no errors appear. Look specifically at the Apply to each loop iteration counts — if a run shows 0 iterations, Zoho returned no modified deals in that window, which is normal during off-hours.

  1. 1Navigate to 'My flows' in the left sidebar
  2. 2Click on your flow name to open the detail page
  3. 3Click 'Turn on' if shown (it may already be on after saving)
  4. 4Check back after 15 minutes and click 'Run history'
  5. 5Expand the most recent run and confirm each step shows a green checkmark
What you should see: The flow detail page shows 'On' status with a green indicator. Run history shows completed runs every 15 minutes with no failed steps.

Paste this expression into the Message field of the Slack 'Post message' action in Power Automate. It conditionally adds a celebration emoji for Closed Won deals and a warning emoji for stalled stages, making Slack messages scannable at a glance without any extra steps.

JavaScript — Code Stepif(
▸ Show code
if(
  equals(triggerBody()?['Stage'], 'Closed Won'),
  concat('🎉 CLOSED: ', triggerBody()?['Deal_Name'], ' | $', triggerBody()?['Amount'], ' | Owner: ', triggerBody()?['Owner']?['name']),

... expand to see full code

if(
  equals(triggerBody()?['Stage'], 'Closed Won'),
  concat('🎉 CLOSED: ', triggerBody()?['Deal_Name'], ' | $', triggerBody()?['Amount'], ' | Owner: ', triggerBody()?['Owner']?['name']),
  if(
    or(
      equals(triggerBody()?['Stage'], 'Closed Lost'),
      equals(triggerBody()?['Stage'], 'Dead')
    ),
    concat('❌ Lost: ', triggerBody()?['Deal_Name'], ' moved to ', triggerBody()?['Stage'], ' | Owner: ', triggerBody()?['Owner']?['name']),
    concat('🔔 Stage Change: ', triggerBody()?['Deal_Name'], ' → ', triggerBody()?['Stage'], ' | $', triggerBody()?['Amount'], ' | Close: ', triggerBody()?['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

VerdictWhy n8n for this workflow

Use Power Automate for this if your team is already inside the Microsoft 365 ecosystem and you do not want to add another subscription. The Zoho CRM connector exists, the Slack connector exists, and SharePoint is already available for state management — you are not buying anything new. Power Automate also makes it easy to add approvals, Teams notifications, or Excel logging later without leaving the Microsoft stack. The one scenario where you should skip Power Automate: if your team needs alerts in under 2 minutes. Power Automate's Zoho CRM connector has no webhook support for deal stage changes, so you are stuck polling. Make solves this with a native Zoho CRM webhook trigger that fires in seconds.

Cost

The math on cost: Power Automate Premium costs $15/user/month and includes 40,000 flow runs. Each execution of this flow uses roughly 4-6 actions (Recurrence + Get Records + Apply to each iterations + Condition + Slack + SharePoint). At 15-minute polling with an average of 3 deal changes per run, you are spending about 9 actions per run × 96 runs/day × 30 days = roughly 26,000 actions per month. That fits inside the Premium plan. If your pipeline is busier — say 20 deals changing per poll cycle — you are looking at 57,600+ actions/month and may need to buy additional flow capacity at $40/500K runs. Make's equivalent setup costs $9/month and handles this volume with room to spare.

Tradeoffs

Make fires this in real-time via webhook — no polling, no SharePoint state store, no 15-minute lag. That is a real structural advantage. Zapier has a Zoho CRM trigger called 'Updated Deal' that polls every 1-15 minutes depending on plan, similar to Power Automate but simpler to configure — no SharePoint needed because Zapier handles deduplication internally. n8n gives you full control over the state store with native database nodes and lets you write JavaScript directly if Zoho's API returns something unexpected. Pipedream's Zoho CRM source can poll on a cron and ships with built-in deduplication. Power Automate wins here if and only if you need this to live inside Microsoft infrastructure, need to hand it off to a non-technical admin who already knows Power Automate, or need to chain it with Teams, Outlook, or SharePoint in the same flow.

Three things you will hit after setup: First, Zoho CRM OAuth tokens expire and the connection will break without warning, usually at the worst time. Set up flow failure alerts (Flow detail > Edit > … > Settings > Send failure email) so you know immediately. Second, the Zoho CRM connector's criteria field is finicky — even a single misformatted timestamp causes the Get Records action to return 0 results silently instead of throwing an error. Build a parallel branch that posts to Slack if the array length is unexpectedly 0 for three consecutive runs. Third, if your Zoho admin renames a pipeline stage — even by changing capitalization — the stored SharePoint value will never match the new Zoho value, and you will get a Slack alert for every deal on every poll until you manually update the state store. Document your stage names and lock them down before going live.

Ideas for what to build next

  • Add a daily digest instead of per-change alertsChange the Recurrence to daily at 8 AM, collect all deals that changed in the last 24 hours, and post a single formatted Slack message summarizing all stage movements. This reduces Slack noise for high-volume pipelines.
  • Route alerts to different Slack channels by stageAdd a Switch control inside the Apply to each loop that checks the new Stage value and posts to #wins for Closed Won, #at-risk for stalled stages, and #pipeline for everything else. Takes about 20 minutes to configure.
  • Write deal stage history back to Zoho CRM as a noteIn the 'If yes' branch after the Slack post, add a Zoho CRM 'Create Record' action to write a note on the deal recording the stage transition and the timestamp. This gives you an audit trail inside Zoho without needing a separate tool.

Related guides

Was this guide helpful?
Slack + Zoho CRM overviewPower Automate profile →