Intermediate~15 min setupCommunication & CRMVerified April 2026
Slack logo
Close logo

How to Send Daily Close Pipeline Updates to Slack with Power Automate

A scheduled Power Automate flow queries Close CRM each morning for pipeline metrics, overdue tasks, and upcoming activities, then posts a formatted summary to a Slack channel.

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

Best for

Sales managers at Microsoft-stack companies who want a daily 9 AM Slack digest of team pipeline health without building a custom dashboard.

Not ideal for

Teams that need real-time deal alerts — use a webhook-triggered flow instead of a scheduled one for that.

Sync type

scheduled

Use case type

notification

Real-World Example

💡

A 12-person inside sales team at a B2B SaaS company was holding a 15-minute standup every morning just to review who had overdue tasks in Close. Managers were pulling reports manually and copying numbers into Slack by hand. After this flow ran for two weeks, standups dropped to 5 minutes — the Slack digest covered overdue activities, pipeline value by stage, and upcoming calls before anyone opened their laptop.

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.

Close CRM API key with read access to opportunities, tasks, and users across all team members (generate at Close > Settings > API Keys)
Power Automate account with a plan that supports HTTP connector — HTTP is a Premium connector and requires a Power Automate Premium or per-flow plan (not the free tier)
Slack workspace admin or app installation permission to authorize the Power Automate Slack connector
The target Slack channel already created (e.g., #sales-pipeline) and the bot user added as a member if it's a private channel
Manager-level Close account used to generate the API key so the query returns deals across all reps, not just the authenticated user's own records

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Deal Display Namedisplay_name
Pipeline Valuevalue
Status Labelstatus_label
Assigned Rep Nameassigned_to_name
Task Descriptiontext
Task Due Datedue_date
Task Assigned Repassigned_to_name
3 optional fields▸ show
Lead Company Namelead_name
Expected Close Datedate_won
Last Updateddate_updated

Step-by-Step Setup

1

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

Open Power Automate and Create a 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 trigger type that fires on a timer, not on an event. You'll immediately see a dialog asking for flow name, start date, and recurrence. Name it something like 'Daily Close Pipeline Digest'.

  1. 1Click 'My flows' in the left sidebar
  2. 2Click '+ New flow' in the top-right area
  3. 3Select 'Scheduled cloud flow' from the dropdown
  4. 4Enter a flow name: 'Daily Close Pipeline Digest'
  5. 5Set recurrence to every 1 Day, starting at 9:00 AM in your team's timezone
What you should see: You'll land in the flow editor with a 'Recurrence' trigger card already placed at the top of the canvas showing your schedule settings.
Common mistake — Power Automate schedules in UTC by default. If you set 9:00 AM without adjusting the timezone field inside the Recurrence trigger, it will fire at 9 AM UTC — which is 4 AM Eastern or 1 AM Pacific. Open the Recurrence trigger card and set the 'Time zone' field explicitly.
2

Flow editor > + New step > Search 'HTTP' > HTTP action

Connect to Close CRM via HTTP Action

Close does not have a native Power Automate connector, so you'll use the built-in 'HTTP' action to call Close's REST API directly. Click '+ New step', search for 'HTTP', and select the 'HTTP' action (not 'HTTP webhook'). Close's API base URL is https://api.close.com/api/v1/. You'll authenticate using Basic Auth — your Close API key goes in the Username field, and the Password field stays blank.

  1. 1Click '+ New step' below the Recurrence trigger
  2. 2Type 'HTTP' in the search bar and select the 'HTTP' action
  3. 3Set Method to 'GET'
  4. 4Set URI to 'https://api.close.com/api/v1/opportunity/?_limit=100&_order_by=date_updated&status_type=active'
  5. 5Expand 'Show advanced options', set Authentication to 'Basic', enter your Close API key as Username, leave Password blank
What you should see: The HTTP action card shows your URI, GET method, and Basic authentication configured. No red error indicators on the card.
Common mistake — The Close API key is a per-user credential — make sure you're using an API key from a manager-level account that has visibility across the whole team's pipeline, not a rep's individual key. Go to Close > Settings > API Keys to generate one.
3

Flow editor > + New step > Search 'Parse JSON' > Data Operation: Parse JSON

Parse the Close API Response

The HTTP action returns a raw JSON string. You need to extract fields like deal name, value, status, and assigned user before you can format the message. Add a 'Parse JSON' action immediately after the HTTP step. In the Content field, reference the HTTP action's Body output using dynamic content. For the Schema, paste in the JSON structure from Close's opportunity response — the key fields are id, display_name, value, status_label, lead_name, assigned_to_name, and date_updated.

  1. 1Click '+ New step' and search for 'Parse JSON'
  2. 2Select 'Parse JSON' under 'Data Operation'
  3. 3In the Content field, click 'Add dynamic content' and select 'Body' from the HTTP step
  4. 4Click 'Generate from sample', paste a sample Close opportunity API response, and click 'Done'
  5. 5Confirm the schema shows 'data' as an array containing opportunity objects
What you should see: The Parse JSON card shows a green schema with fields like data, display_name, value, assigned_to_name listed as recognized properties.
Common mistake — If the Parse JSON schema doesn't include a field you need later (like assigned_to_name), the dynamic content picker won't show it. Go back and regenerate the schema from a real API response that includes all the fields — pull one from Postman or the Close API Explorer first.
4

Flow editor > + New step > HTTP action (second instance)

Query Overdue Activities from Close

A useful pipeline digest includes overdue tasks, not just open deals. Add a second HTTP action to query Close's activity endpoint. You'll filter for tasks that are past due by using Close's date_done__lt parameter set to today's date. Use a Power Automate expression to generate today's date dynamically: utcNow('yyyy-MM-dd'). This second HTTP call runs in parallel with the first, keeping the flow fast.

  1. 1Click '+ New step' and add another HTTP action
  2. 2Set Method to 'GET'
  3. 3Set URI to: concat('https://api.close.com/api/v1/task/?is_complete=false&date__lt=', utcNow('yyyy-MM-dd'), '&_limit=50')
  4. 4Type the URI directly in the field and use the 'Expression' tab in dynamic content to insert utcNow('yyyy-MM-dd') inline
  5. 5Apply the same Basic Auth as Step 2
What you should see: A second HTTP action card appears with a dynamic URI that includes today's date. When you run a test, the response Body contains an array of overdue tasks.
5

Flow editor > + New step > Parse JSON (second instance)

Parse the Overdue Tasks Response

Add a second 'Parse JSON' action to handle the task query response. Follow the same process as Step 3 — set Content to the Body of the second HTTP action, and generate the schema from a sample task object. Key fields to capture are id, assigned_to_name, text (the task description), due_date, and lead_name. Rename this action 'Parse Overdue Tasks' to keep the canvas readable.

  1. 1Add a 'Parse JSON' action after the second HTTP step
  2. 2Set Content to the Body output of the overdue tasks HTTP action
  3. 3Click 'Generate from sample' and paste a sample Close task object
  4. 4Rename the action to 'Parse Overdue Tasks' by clicking the three-dot menu > Rename
What you should see: Two Parse JSON cards are now on the canvas — one for opportunities, one for tasks — each with distinct, readable names.
Common mistake — Power Automate sometimes auto-wraps parallel steps inside a condition block if you click 'Add a parallel branch' accidentally. If your second HTTP action appears inside a branch instead of the main sequence, drag it out or delete and re-add it in the correct position.
6

Flow editor > + New step > Data Operation > Compose

Calculate Pipeline Summary Metrics

Before posting to Slack, compute aggregate numbers: total open pipeline value and count of overdue tasks. Add a 'Compose' action for each metric. For total pipeline value, use the expression: sum(body('Parse_JSON')?['data'], 'value'). For overdue task count: length(body('Parse_Overdue_Tasks')?['data']). These Compose outputs give you single values you can drop into the Slack message without looping.

  1. 1Add a 'Compose' action and name it 'Total Pipeline Value'
  2. 2In Inputs, paste expression: div(sum(body('Parse_JSON')?['data'], 'value'), 100) — Close stores value in cents
  3. 3Add a second 'Compose' action named 'Overdue Task Count'
  4. 4In Inputs, paste expression: length(body('Parse_Overdue_Tasks')?['data'])
What you should see: Two Compose action cards appear. Running a test shows a dollar-formatted number in Total Pipeline Value and an integer in Overdue Task Count.
Common mistake — Close stores opportunity values in cents (integer), not dollars. Dividing by 100 in the expression gives you the correct dollar amount. Skipping this step means your Slack message will show $1,250,000 when the real pipeline value is $12,500.
7

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

Build the Slack Message with Apply to Each

Now format the digest. Add an 'Apply to each' action (found under 'Control') and set its input to the data array from the opportunities Parse JSON step. Inside the loop, add a 'Compose' action that builds one line per deal using dynamic content fields: display_name, assigned_to_name, status_label, and the value field. Use a simple format like: '• [display_name] — [assigned_to_name] — $[value] — [status_label]'. This produces a line-item list you'll join into a single string before posting.

  1. 1Click '+ New step', go to 'Control', and select 'Apply to each'
  2. 2Set the 'Select an output from previous steps' field to body('Parse_JSON')?['data']
  3. 3Inside the loop, add a 'Compose' action
  4. 4Build the message line using dynamic content: concat('• ', items('Apply_to_each')?['display_name'], ' — ', items('Apply_to_each')?['assigned_to_name'], ' — $', string(div(items('Apply_to_each')?['value'], 100)), ' — ', items('Apply_to_each')?['status_label'])
  5. 5Name this inner Compose 'Format Deal Line'
What you should see: The Apply to each card expands to show the inner Compose action. Test run output shows a formatted string for each open deal in the pipeline.
Common mistake — Apply to each loops run sequentially in Power Automate by default. If you have 80+ deals, this can take 3-4 minutes to complete. Turn on concurrency in the Apply to each settings (up to 50 parallel) to cut this to under 30 seconds — but note that parallel loops do not guarantee message order.
8

Flow editor > + New step > Data Operation > Join

Join Deal Lines into One String

After the Apply to each loop, the formatted deal lines are stored as an array of Compose outputs. You need to join them into a single block of text for the Slack message. Add a 'Join' action (under Data Operation) after the loop. Set the 'From' field to the outputs of the Format Deal Line Compose action using the expression: outputs('Format_Deal_Line'). Set the Join With field to a newline character using the expression: decodeUriComponent('%0A').

  1. 1Add a 'Join' action after the Apply to each loop
  2. 2In the 'From' field, use expression: outputs('Format_Deal_Line')
  3. 3In 'Join With', use expression: decodeUriComponent('%0A') to insert newlines between each deal line
  4. 4Name this action 'Join Deal Lines'
What you should see: The Join action card shows both fields populated. A test run shows a multi-line string with one deal per line, separated by line breaks.
9

Flow editor > + New step > Search 'Slack' > Post message in a chat or channel

Connect Slack and Configure the Channel

Add a 'Post message in a chat or channel' action from the Slack connector. Search for 'Slack' in the action picker — Power Automate has a native Slack connector. When you add it for the first time, it will prompt you to sign in to Slack and authorize the Power Automate app. Make sure you authorize it in the correct Slack workspace. Set Post As to 'Flow bot', select your channel name (e.g., #sales-pipeline), and leave the message body empty for now.

  1. 1Click '+ New step' and search for 'Slack'
  2. 2Select 'Post message in a chat or channel'
  3. 3Click 'Sign in' to create a new Slack connection — authorize in the browser popup
  4. 4Set 'Post As' to 'Flow bot'
  5. 5Set 'Channel Name' to your target channel, e.g. #sales-pipeline
What you should see: The Slack action shows a green connection indicator with your workspace name. The channel dropdown populates with channels from your workspace.
Common mistake — The Power Automate Slack connector posts as a bot user named 'Power Automate'. You cannot rename this bot inside Power Automate — it's a connector-level limitation. If you want a custom bot name like 'Pipeline Bot', you'll need to create a Slack app and call the Slack API directly via HTTP action instead.
10

Flow editor > Slack action > Message Text field

Compose the Full Slack Message

Now build the final message text inside the Slack action's Message Text field. Combine the pipeline header, the joined deal list, and the overdue task count into one formatted block. Use dynamic content and expressions to pull from the Compose actions created in Steps 6 and 8. Structure the message with a header line, total pipeline value, number of overdue tasks, and the full deal list beneath.

  1. 1Click inside the 'Message Text' field of the Slack action
  2. 2Type a header: '*📊 Daily Pipeline Report — ' then use expression formatDateTime(utcNow(), 'MMMM d, yyyy') to append today's date, then close with '*'
  3. 3Add a newline then: '*Total Open Pipeline:* $' followed by dynamic content from the 'Total Pipeline Value' Compose
  4. 4Add another line: '*Overdue Tasks:* ' followed by dynamic content from 'Overdue Task Count' Compose
  5. 5Add a blank line then paste the output of 'Join Deal Lines' to list all deals
What you should see: The Message Text field shows a multi-section message with bold headers, the pipeline total, overdue count, and the full deal list all visible in the field preview.
Common mistake — Map fields using the variable picker — don't type field names manually. Hand-typed variable names often have invisible spacing errors that produce blank output.
11

Flow editor > Test (top right) > Manually > Run flow

Test and Activate the Flow

Before turning the flow on, run a manual test. Click 'Test' in the top-right toolbar, select 'Manually' and then 'Run flow'. Watch the run history panel on the right — each action card will show a green checkmark or red X. Check that the Slack message appears in your channel with correct data and formatting. Once the test passes, click 'Save' and confirm the flow is toggled to 'On' in My flows.

  1. 1Click 'Test' in the top-right corner of the flow editor
  2. 2Select 'Manually' and click 'Run flow'
  3. 3Watch each action card turn green as the run progresses
  4. 4Open your Slack channel to verify the message arrived and looks correct
  5. 5Click 'Save' and then navigate to 'My flows' to confirm the flow status shows 'On'
What you should see: A formatted Slack message appears in #sales-pipeline with today's date, total pipeline value in dollars, overdue task count, and a bulleted list of open deals with rep names and stage labels.
Common mistake — If the test succeeds but the scheduled run doesn't fire the next morning, check 'Run history' in My flows. Power Automate sometimes skips the first scheduled run after creation if the start time has already passed for the day. Edit the Recurrence trigger and set an explicit start date/time in the future to force it onto the correct schedule.

Paste this into a 'Compose' action placed right after the two Parse JSON steps. It builds a complete formatted Slack Block Kit message as a JSON string using Power Automate expressions, giving you bold headers, dividers, and color-coded sections instead of plain text. Reference the output of this Compose action in the Slack 'Post message' action's 'Blocks' field (not the Message Text field).

JavaScript — Code Step{
▸ Show code
{
  "blocks": [
    {

... expand to see full code

{
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "@{concat('📊 Daily Pipeline Report — ', formatDateTime(utcNow(), 'MMMM d, yyyy'))}"
      }
    },
    {
      "type": "section",
      "fields": [
        {
          "type": "mrkdwn",
          "text": "@{concat('*Total Open Pipeline:*\n$', string(outputs('Total_Pipeline_Value')))}"
        },
        {
          "type": "mrkdwn",
          "text": "@{concat('*Overdue Tasks:*\n', string(outputs('Overdue_Task_Count')), ' tasks past due')}"
        }
      ]
    },
    {
      "type": "divider"
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "@{concat('*Open Deals:*\n', outputs('Join_Deal_Lines'))}"
      }
    },
    {
      "type": "context",
      "elements": [
        {
          "type": "mrkdwn",
          "text": "@{concat('Generated at ', formatDateTime(utcNow(), 'h:mm tt'), ' UTC · Data from Close CRM')}"
        }
      ]
    }
  ]
}
Power Automate
▶ Test flow
executed
Slack
Close
Close
🔔 notification
received

Scaling Beyond More than 100 active deals in Close+ Records

If your volume exceeds More than 100 active deals in Close records, apply these adjustments.

1

Paginate the Close API

Close's API returns a maximum of 100 records per request. If your pipeline has more than 100 active deals, you need to loop through pages using the _skip parameter. Add a 'Do until' loop in Power Automate that increments _skip by 100 on each iteration and stops when the response's has_more field is false.

2

Filter Before You Fetch

Instead of pulling all active opportunities and filtering in Power Automate, push filters to the Close API query string. Filter by date_updated__gt to fetch only deals touched in the last 7 days, or by status_type to exclude inactive pipelines. Fewer records returned means faster loop execution and less risk of hitting the 30-minute timeout.

3

Enable Loop Concurrency

With 100+ deals, a sequential Apply to each loop can take 5-10 minutes. Turn on concurrency in the loop settings and set parallelism to 20. This cuts run time by roughly 80%. Note that concurrent loops may produce Slack message lines in a different order each run — sort the deals by value or status in the API query to get a deterministic output.

4

Cap the Slack Message Length

Slack has a 3,000-character limit on Block Kit text fields and a 4,000-character limit on plain message text. At 100 deals with long names, you'll hit this. Add a condition before the Join action that truncates the deal array to the top 30 deals by value, and append a footer line: 'Showing top 30 of [total] deals — view full report in Close.'

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 company is already on Microsoft 365 and your IT team manages data governance through the Power Platform. Power Automate's scheduled flows are reliable, the Slack connector works out of the box, and you can store the Close API key in Azure Key Vault without any custom infrastructure. The one scenario where you'd pick something else: if nobody on your team has a Power Automate Premium license. The HTTP connector — which is required to call Close's API — is gated behind Premium. If that's your situation, Make.com handles this same flow for $9/month with a native HTTP module on every plan.

Cost

The cost math here is straightforward. This flow uses roughly 55 action executions per daily run (2 HTTP calls + 1 Parse JSON each + ~50 loop iterations for a mid-size pipeline + 1 Slack post). At 30 runs per month, that's 1,650 action executions. Power Automate's per-user Premium plan costs $15/month and includes 40,000 executions/month — so this workflow uses about 4% of your quota. If you already pay for Microsoft 365 E3 or E5, check whether Power Automate Premium is bundled; it often is for enterprise agreements. Compare that to Make.com at $9/month for 10,000 operations, which covers this workflow comfortably at a lower price if you're buying standalone.

Tradeoffs

Make.com schedules are more flexible — you can set a cron-style schedule down to the minute, while Power Automate's Recurrence trigger only supports intervals (every N minutes/hours/days). For a daily digest, this doesn't matter. Zapier's 'Delay' and 'Schedule' triggers are simpler to set up in 10 minutes, but formatting the Close data into a clean Slack message requires Zapier Formatter, and multi-step message construction gets awkward fast. n8n gives you the most control — you can write JavaScript directly to sort, group, and format deals however you want — but you need to self-host or pay for n8n cloud, and the setup time is 3x longer. Power Automate wins here specifically if you're inside a Microsoft org where sharing flows with colleagues, adding co-owners, and auditing run history inside the Power Platform admin center are non-negotiable requirements.

Three things you'll hit after setup. First, the scheduled flow will occasionally show a 'succeeded' status in run history but no message in Slack — this is almost always the Slack connector token expiring silently. Re-authenticate the Slack connection in the Power Automate Connections page every 60-90 days or when users report a missing digest. Second, Close's API rate limit is 100 requests per second per API key, which you won't hit with a once-daily flow, but if you add more flows using the same API key, watch for 429 responses. Third, the Close API's assigned_to_name field returns the rep's display name as a string, which is great for Slack readability — but if reps have inconsistent display names (nicknames vs. full names), the digest will show 'JBrooks' for one rep and 'Jennifer Brooks' for another. Standardize display names in Close's user settings before this becomes a manager complaint.

Ideas for what to build next

  • Add Per-Rep Breakdown SectionsGroup deals by assigned rep inside the Apply to each loop and post a separate Slack section per rep. This turns a flat list into a structured team scorecard and makes it easier to spot whose pipeline is thin.
  • Post Individual Overdue Task DMs to RepsAdd a second Slack action inside the overdue task loop that sends each rep a direct message listing only their own overdue items. Keeps the channel digest clean while still creating individual accountability.
  • Log the Digest Summary to a SharePoint ListAfter posting to Slack, add a 'Create item' action to a SharePoint list that records date, total pipeline value, and overdue count. This builds a historical trend dataset you can chart in Power BI without paying for a Close analytics add-on.

Related guides

Was this guide helpful?
Slack + Close overviewPower Automate profile →