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

How to Send Daily Close Pipeline Updates to Slack with Pipedream

A scheduled Pipedream workflow that pulls pipeline metrics, upcoming tasks, and overdue activities from Close every morning and 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 5-30 person inside sales teams who want a daily Slack digest without paying for a BI tool or asking reps to update dashboards manually.

Not ideal for

Teams that need real-time deal alerts — use a webhook-based workflow instead so updates fire within seconds of a stage change.

Sync type

scheduled

Use case type

reporting

Real-World Example

💡

A 12-person SaaS inside sales team runs this every weekday at 8:00 AM. Before the automation, managers pulled Close reports manually each morning, a process that took 15-20 minutes and often happened late or not at all. Now, #sales-pipeline gets a formatted Slack message before standup: total open pipeline value, deals moved yesterday, tasks due today, and a list of overdue activities by rep name.

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 Pipedream

Copy the pre-built Pipedream blueprint and paste it straight into Pipedream. 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 API key with read access to Opportunities, Tasks, and Users — generate it in Close under Settings > API > Generate API Key
Slack workspace admin access or permission to install apps — needed to authorize Pipedream's OAuth connection during step 8
Pipedream account on any plan — the free tier supports scheduled workflows with up to 10,000 credits/month
A dedicated Slack channel for pipeline updates — create '#sales-pipeline' or similar before building the workflow so it appears in the channel dropdown

Optional

Close user IDs mapped to real names if you want per-rep breakdowns — the API returns 'user_name' as a string so no lookup step is needed for this workflow

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Pipeline Total Valuevalue
Deal Lead Namelead_name
Assigned Repuser_name
Expected Close Dateclose_date
Deal Status Labelstatus_label
Task Due Datedue_date
Task Typetype
Task Assigned Toassigned_to
1 optional field▸ show
Opportunity Last Updatedupdated

Step-by-Step Setup

1

pipedream.com > Workflows > New Workflow

Create a new Pipedream workflow

Go to pipedream.com and sign in. Click 'New Workflow' in the top-right corner. You'll land on the workflow canvas with an empty trigger slot at the top. Give your workflow a name immediately — something like 'Daily Close Pipeline Digest' — using the pencil icon next to 'Untitled Workflow' at the top of the page. Naming it now prevents confusion when you have multiple workflows running.

  1. 1Click 'New Workflow' in the top-right corner of the Workflows dashboard
  2. 2Click the pencil icon next to 'Untitled Workflow' at the top of the canvas
  3. 3Type 'Daily Close Pipeline Digest' and press Enter
What you should see: You should see an empty workflow canvas with your chosen name displayed at the top and a single empty trigger slot labeled 'Add a trigger'.
Common mistake — Pipedream autosaves drafts, but a workflow doesn't run until you deploy it. You'll see a yellow 'Draft' badge until step 10 — that's expected.
2

Workflow Canvas > Add a trigger > Schedule > Cron Expression

Set the Schedule trigger

Click the 'Add a trigger' block at the top of the canvas. In the trigger search panel, type 'Schedule' and select the 'Schedule' source built into Pipedream. Choose 'Cron Expression' for full control over timing — the simple interval option doesn't let you target specific days of the week. Enter a cron expression for your desired time, for example '0 8 * * 1-5' fires at 8:00 AM UTC Monday through Friday. Adjust the UTC offset to match your team's timezone.

  1. 1Click 'Add a trigger' on the canvas
  2. 2Type 'Schedule' in the search box and select the Pipedream-native Schedule source
  3. 3Select 'Cron Expression' as the schedule type
  4. 4Enter '0 8 * * 1-5' in the cron field (adjust UTC offset for your timezone)
  5. 5Click 'Save and continue'
What you should see: The trigger block turns blue and shows your cron expression. You'll see a 'Next occurrence' timestamp confirming when the workflow will next fire.
Common mistake — Pipedream Schedule triggers run in UTC. If your team is in US Eastern time, subtract 5 hours (EST) or 4 hours (EDT) from your intended local time when writing the cron expression.
Pipedream
+
click +
search apps
Slack
SL
Slack
Set the Schedule trigger
Slack
SL
module added
3

Workflow Canvas > + Add a step > Apps > Close > Make API Request

Connect your Close account

Click '+ Add a step' below the trigger block. Search for 'Close' and select the Close app. Choose the action 'Make API Request' — this gives you direct access to Close's REST API, which is more flexible than the pre-built actions for this reporting use case. In the step configuration panel, connect your Close account by clicking 'Connect Account' and entering your Close API key (found in Close under Settings > API). Pipedream stores this as a Connected Account you can reuse across workflows.

  1. 1Click '+ Add a step' and search for 'Close'
  2. 2Select the Close app from the results
  3. 3Choose 'Make API Request' as the action
  4. 4Click 'Connect Account' in the step panel
  5. 5Paste your Close API key and click 'Connect'
What you should see: You should see a green checkmark next to your Close account name in the step panel, confirming the API key was accepted.
Common mistake — Close uses HTTP Basic Auth with your API key as the username and an empty password. Pipedream's Close integration handles this automatically, but if you're building a raw HTTP step instead, you must base64-encode 'apikey:' with a trailing colon.
Pipedream settings
Connection
Choose a connection…Add
click Add
Slack
Log in to authorize
Authorize Pipedream
popup window
Connected
green checkmark
4

Close Step > Method > URL > Query Parameters

Fetch open pipeline opportunities from Close

In the Close 'Make API Request' step, configure the request to hit the Opportunities endpoint. Set the Method to GET and the URL to 'https://api.close.com/api/v1/opportunity/?status_type=active&_limit=200'. This returns up to 200 active opportunities with their value, status, assigned user, and expected close dates. You'll use this data to calculate pipeline totals and identify deals by rep in later steps. Add a query parameter '_fields' with value 'id,lead_id,lead_name,value,status_label,user_name,date_won,close_date,updated' to keep the response payload small.

  1. 1Set Method to 'GET'
  2. 2Set URL to 'https://api.close.com/api/v1/opportunity/?status_type=active&_limit=200'
  3. 3Add query parameter '_fields' with value 'id,lead_id,lead_name,value,status_label,user_name,date_won,close_date,updated'
  4. 4Click 'Test' to run the step and confirm data returns
What you should see: The test result panel shows a JSON response with a 'data' array containing active opportunity objects. Each object should include lead_name, value, user_name, and close_date fields.
Common mistake — Close's default API limit is 200 records per request. If your pipeline has more than 200 active deals, you'll need pagination using the '_skip' parameter. The pro tip code section handles this.
5

Workflow Canvas > + Add a step > Apps > Close > Make API Request

Fetch overdue and today's tasks from Close

Add a second Close 'Make API Request' step. This call targets the Tasks endpoint to retrieve activities due today or overdue. Set the URL to 'https://api.close.com/api/v1/task/?is_complete=false&_order_by=due_date&_limit=100'. You'll filter in the next step using JavaScript, but pulling all incomplete tasks here gives you the full dataset. Close tasks include type (call, email, follow-up), due date, assigned user, and the associated lead name — all fields you need for the daily digest.

  1. 1Click '+ Add a step' and select Close again
  2. 2Choose 'Make API Request'
  3. 3Set Method to 'GET'
  4. 4Set URL to 'https://api.close.com/api/v1/task/?is_complete=false&_order_by=due_date&_limit=100'
  5. 5Click 'Test' to confirm task objects return with due_date and assigned_to fields
What you should see: Test result shows a JSON array of incomplete task objects, each containing 'due_date', 'assigned_to', 'lead_name', and 'type' fields.
6

Workflow Canvas > + Add a step > Code > Run Node.js code

Add a Node.js step to calculate pipeline metrics

Click '+ Add a step' and choose 'Run Node.js code'. This is the core logic step — it takes the raw Close API responses from steps 4 and 5 and computes the numbers you'll post to Slack. You'll calculate total open pipeline value, count deals per rep, identify deals with close dates that have already passed, and split tasks into 'due today' vs 'overdue' buckets. Paste the code from the pro tip section into this step. The step references previous step outputs using Pipedream's 'steps' object.

  1. 1Click '+ Add a step'
  2. 2Select 'Code' from the step type options
  3. 3Choose 'Run Node.js code'
  4. 4Paste the provided code into the editor
  5. 5Click 'Test' and confirm the output object contains pipelineTotal, dealsByRep, overdueTasks, and todayTasks keys
What you should see: The step output panel shows a structured object with keys like pipelineTotal (a dollar number), dealsByRep (an array of rep summaries), overdueTasks (filtered array), and todayTasks (filtered array).
Common mistake — Pipedream step outputs are referenced using 'steps.step_name.$return_value'. If you rename a step, update all downstream references. Check the step name in the grey header of each step — Pipedream auto-generates names like 'close' and 'close_1' that you should rename to 'fetch_opportunities' and 'fetch_tasks' for clarity.
7

Workflow Canvas > + Add a step > Code > Run Node.js code

Format the Slack message with Block Kit

Add another Node.js code step specifically for message formatting. Close API values come back with amount in cents for currency fields — you must divide by 100 to get dollars. Build a Slack Block Kit payload here rather than a plain text string. Block Kit lets you use bold headers, dividers, and bullet lists that render cleanly on both desktop and mobile Slack. This step outputs a single 'blocks' array that the next step passes directly to the Slack API.

  1. 1Click '+ Add a step' and select 'Run Node.js code'
  2. 2Rename the step to 'format_message' using the step header
  3. 3Build the blocks array using the metrics from the previous step output
  4. 4Click 'Test' and verify the output contains a valid 'blocks' array with header, section, and divider types
What you should see: Step output shows a 'blocks' array. Pasting it into Slack's Block Kit Builder at app.slack.com/block-kit-builder should render a readable message with a header, pipeline total, and task lists.
Common mistake — Close stores opportunity values in the currency's smallest unit (cents for USD). A deal worth $15,000 comes back as 1500000. Divide by 100 before displaying. Skipping this step produces numbers that are 100x too large in your Slack message.
8

Workflow Canvas > + Add a step > Apps > Slack > Send Message to a Channel

Connect your Slack account

Add a new step and search for 'Slack'. Select the 'Send Message to a Channel' action. Click 'Connect Account' and authorize Pipedream to post to your Slack workspace. Pipedream uses OAuth and will redirect you to Slack's permission screen. Grant the 'chat:write' and 'chat:write.public' scopes — you need both to post to channels your Slack app hasn't been explicitly added to. After authorization, you'll return to Pipedream with a Connected Account badge.

  1. 1Click '+ Add a step' and search for 'Slack'
  2. 2Select 'Send Message to a Channel'
  3. 3Click 'Connect Account' and follow the Slack OAuth flow
  4. 4Confirm 'chat:write' and 'chat:write.public' are included in the permission screen
  5. 5Click 'Allow' and return to Pipedream
What you should see: A green 'Connected' badge appears next to your Slack workspace name in the step panel. The Channel dropdown becomes active.
Common mistake — If you authorize with a personal Slack account rather than a workspace admin account, you may not have permission to post to private channels. Use a dedicated bot token if you need to post to restricted channels — set it up in your Slack app at api.slack.com/apps.
9

Slack Step > Channel > Notification Text > Blocks

Configure the Slack message step

In the Slack step, select your target channel from the Channel dropdown — for example '#sales-pipeline' or '#daily-standup'. Set the 'Notification Text' field to something like 'Daily Pipeline Update — see below' (this appears in push notifications and desktop alerts). In the 'Blocks' field, reference the output of your format_message step using the expression picker: type '{{' and select 'steps.format_message.$return_value.blocks'. Leave 'Text' blank since you're using blocks. Toggle 'unfurl_links' off to prevent Slack from expanding any lead URLs in the message.

  1. 1Select your target Slack channel from the Channel dropdown
  2. 2Set Notification Text to 'Daily Pipeline Update — see message below'
  3. 3Click into the Blocks field and type '{{' to open the expression picker
  4. 4Navigate to steps.format_message.$return_value.blocks and select it
  5. 5Set unfurl_links to false
What you should see: The Blocks field shows a dynamic expression reference like '{{steps.format_message.$return_value.blocks}}'. The channel name is selected and visible in the Channel field.
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.
10

Workflow Canvas > Test Workflow button (top of canvas)

Test the full workflow end-to-end

Click 'Test Workflow' at the top of the canvas to run all steps in sequence using a simulated trigger event. Watch each step go green or red in order. If the Close steps succeed but the Slack step fails, the error message in the step panel will tell you whether it's a channel permission issue or a malformed blocks payload. Once all steps are green, click the Slack channel to confirm the message posted and that formatting looks correct on mobile and desktop. Fix any field alignment or text truncation issues in the format_message code step before deploying.

  1. 1Click 'Test Workflow' at the top of the canvas
  2. 2Watch each step's status indicator turn green sequentially
  3. 3Open your Slack channel and confirm the message rendered correctly
  4. 4Check the message on mobile Slack to confirm Block Kit renders cleanly
  5. 5Return to Pipedream and fix any formatting issues in the format_message step
What you should see: All steps show green status indicators. A real message appears in your Slack channel with a header, pipeline total, deals-by-rep section, and task lists.
Pipedream
▶ Deploy & test
executed
Slack
Close
Close
🔔 notification
received
11

Workflow Canvas > Deploy button (top-right)

Deploy the workflow

Click the blue 'Deploy' button in the top-right of the canvas. The yellow 'Draft' badge changes to green 'Active'. Pipedream will now execute this workflow automatically on your cron schedule. Verify the next scheduled run time shown in the trigger block matches your intention — for '0 8 * * 1-5' UTC, you should see the next weekday at 08:00 UTC listed. Set up a Pipedream error alert under Settings > Notifications so you get an email if the workflow fails silently on a given morning.

  1. 1Click the blue 'Deploy' button in the top-right corner
  2. 2Confirm the badge changes from yellow 'Draft' to green 'Active'
  3. 3Check the trigger block for the 'Next run' timestamp
  4. 4Go to Settings > Notifications and enable error email alerts
  5. 5Wait for the first scheduled run and confirm the Slack message arrives
What you should see: The workflow status badge shows green 'Active'. The trigger block displays a 'Next run' timestamp matching your cron schedule. Your Slack channel receives the digest at the scheduled time.
Common mistake — Pipedream free tier workflows pause if you exceed the monthly credit limit. A workflow with 4 steps running once per weekday uses roughly 80 credits/month — well within the free tier's 10,000 credit allowance. But if you add more steps or run more frequently, check your credit usage under Settings > Billing.

Paste this into a single Node.js code step between your Close fetch steps and the Slack step. It handles pagination for pipelines over 200 deals, splits tasks into overdue vs. today buckets, formats currency correctly, and builds the full Block Kit payload in one pass. Reference it downstream in the Slack step as steps.build_digest.$return_value.blocks.

JavaScript — Code Stepimport axios from 'axios';
▸ Show code
import axios from 'axios';
export default defineComponent({
  async run({ steps, $ }) {

... expand to see full code

import axios from 'axios';

export default defineComponent({
  async run({ steps, $ }) {
    const apiKey = steps.fetch_opportunities.$auth.api_key;
    const authHeader = 'Basic ' + Buffer.from(apiKey + ':').toString('base64');

    // Paginate Close opportunities if > 200 deals exist
    let allOpps = [];
    let skip = 0;
    const limit = 200;
    while (true) {
      const res = await axios.get('https://api.close.com/api/v1/opportunity/', {
        headers: { Authorization: authHeader },
        params: {
          status_type: 'active',
          _limit: limit,
          _skip: skip,
          _fields: 'id,lead_name,value,status_label,user_name,close_date,updated',
        },
      });
      const data = res.data?.data ?? [];
      allOpps = allOpps.concat(data);
      if (data.length < limit) break;
      skip += limit;
    }

    // Pipeline totals
    const pipelineTotal = allOpps.reduce((sum, o) => sum + (o.value || 0), 0) / 100;
    const today = new Date();
    today.setHours(0, 0, 0, 0);

    const overdueDeals = allOpps.filter(o => o.close_date && new Date(o.close_date) < today);

    // Group deals by rep
    const byRep = {};
    for (const opp of allOpps) {
      const rep = opp.user_name || 'Unassigned';
      if (!byRep[rep]) byRep[rep] = { count: 0, value: 0 };
      byRep[rep].count++;
      byRep[rep].value += (opp.value || 0) / 100;
    }

    // Split tasks
    const rawTasks = steps.fetch_tasks.$return_value?.data ?? [];
    const todayStr = today.toISOString().split('T')[0];
    const overdueTasks = rawTasks.filter(t => t.due_date && t.due_date < todayStr);
    const todayTasks = rawTasks.filter(t => t.due_date && t.due_date === todayStr);

    const fmt = (n) => n.toLocaleString('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });

    // Build Block Kit payload
    const blocks = [
      {
        type: 'header',
        text: { type: 'plain_text', text: `📊 Daily Pipeline Update — ${today.toDateString()}` },
      },
      { type: 'divider' },
      {
        type: 'section',
        fields: [
          { type: 'mrkdwn', text: `*Total Open Pipeline*\n${fmt(pipelineTotal)}` },
          { type: 'mrkdwn', text: `*Active Deals*\n${allOpps.length}` },
          { type: 'mrkdwn', text: `*Overdue Deals*\n${overdueDeals.length}` },
          { type: 'mrkdwn', text: `*Tasks Due Today*\n${todayTasks.length}` },
        ],
      },
      { type: 'divider' },
      {
        type: 'section',
        text: { type: 'mrkdwn', text: '*Pipeline by Rep*' },
      },
      ...Object.entries(byRep).map(([rep, data]) => ({
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `• *${rep}*: ${data.count} deals — ${fmt(data.value)}`,
        },
      })),
      { type: 'divider' },
      {
        type: 'section',
        text: { type: 'mrkdwn', text: `*Overdue Tasks (${overdueTasks.length})*` },
      },
      ...overdueTasks.slice(0, 10).map(t => ({
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `⚠️ ${t.type} — *${(t.lead_name || 'Unknown').slice(0, 40)}* | ${t.assigned_to || 'Unassigned'} | Due: ${t.due_date}`,
        },
      })),
      { type: 'divider' },
      {
        type: 'section',
        text: { type: 'mrkdwn', text: `*Due Today (${todayTasks.length})*` },
      },
      ...todayTasks.slice(0, 10).map(t => ({
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `📋 ${t.type} — *${(t.lead_name || 'Unknown').slice(0, 40)}* | ${t.assigned_to || 'Unassigned'}`,
        },
      })),
    ];

    return { blocks, pipelineTotal, dealCount: allOpps.length };
  },
});

Scaling Beyond 200+ active opportunities in Close pipeline+ Records

If your volume exceeds 200+ active opportunities in Close pipeline records, apply these adjustments.

1

Use pagination for large pipelines

Close's API returns a maximum of 200 records per request. The pro tip code handles this with a while loop incrementing the _skip parameter until fewer than 200 records return. Without this, teams with 200+ active deals will get incomplete pipeline totals in their digest.

2

Cap Slack message rows to avoid hitting Slack's block limit

Slack Block Kit payloads are capped at 50 blocks per message. If you have many overdue tasks or deals, use .slice(0, 10) on each list before building blocks — as shown in the pro tip code. For larger lists, post a truncated summary and include a direct link to the Close report.

3

Watch Pipedream execution time for large datasets

Pipedream times out Node.js steps after 60 seconds on the free tier and 300 seconds on paid plans. Paginating through 1,000+ deals while building Block Kit can approach this limit. If you're seeing timeout errors, split the data fetch and the formatting into separate steps to distribute the execution time.

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 Pipedream for this if your team has any developer capacity at all. The scheduled trigger is rock-solid, the Node.js step handles Close's pagination quirk in 10 lines, and you can format Block Kit payloads exactly how you want without fighting a visual builder. The one scenario where you'd pick something else: if the person maintaining this workflow will never touch code and needs to hand it off to a non-technical manager — in that case, Zapier's simpler step model is easier to explain.

Cost

Pipedream's free tier gives you 10,000 credits/month. This workflow uses 4 steps per run. Pipedream charges 1 credit per step execution, so each morning run costs 4 credits. At 22 weekday runs/month, that's 88 credits/month — well under the free limit. You'd need to run this workflow 28 times per day before approaching the free tier ceiling. Make's free tier also covers this at zero cost, but Make charges per operation and counts each API call separately, so a paginated Close fetch (5 requests) costs 5 operations vs. Pipedream's 1 step credit. At current pricing, Pipedream is cheaper for this use case by roughly $0 — both are free at this volume.

Tradeoffs

Make has a better visual debugger for inspecting intermediate data — if you're building this for the first time and the Close response confuses you, Make's inspector shows each field in a cleaner UI than Pipedream's JSON panel. Zapier's pre-built Close and Slack actions are faster to configure for simple setups, but Zapier can't handle Close API pagination without a paid Code step, which adds cost. n8n runs this entirely on your own infrastructure if data privacy is a concern — Close customer data never leaves your server. Power Automate is the wrong tool here unless your team is already deep in the Microsoft 365 ecosystem; its Slack and Close connectors are thin and the scheduler is less predictable. Pipedream wins because pagination, formatting, and posting are all one workflow with no plugin dependencies and a free execution budget that fits this use case exactly.

Three things you'll hit after setup. First, Close's 'value' field comes back in cents — a $25,000 deal returns as 2500000. Missing this makes your pipeline total look like you're running a hedge fund. Divide by 100 before any display. Second, the Close Tasks API returns due_date as a date string in 'YYYY-MM-DD' format, but the Opportunities API returns close_date in the same format — both compare cleanly with JavaScript's string comparison, which makes overdue detection simple, but only if you don't accidentally compare against a JavaScript Date object with a timezone offset attached. Stick to string comparison: 'due_date < todayStr' where todayStr is today's ISO date string. Third, Slack will silently drop your message if the blocks array exceeds 50 items. No error, no warning — the post just doesn't happen. Always cap list lengths with .slice() before building the payload.

Ideas for what to build next

  • Add per-rep Slack DMs alongside the channel postExtend the workflow with a Slack 'Send Direct Message' step that loops through the byRep data and sends each rep only their own deals and tasks — reduces noise for reps who don't need to see the full team view.
  • Post a weekly performance summary on FridaysAdd a second scheduled workflow with a Friday-only cron expression that pulls Close's won/lost deals from the past 7 days and posts a win/loss ratio and revenue closed to the same Slack channel.
  • Trigger a real-time alert when a deal goes overdueBuild a separate Pipedream workflow using Close's webhook for opportunity updates — fire a Slack alert the moment a deal's close date passes without a status change, rather than waiting for the morning digest.

Related guides

Was this guide helpful?
Slack + Close overviewPipedream profile →