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

How to Share Close Prospects to Slack with Pipedream

When a Close opportunity reaches a target stage, Pipedream fires a webhook, pulls full prospect details and conversation history from Close, and posts a structured research brief to a designated Slack channel for team input.

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

Best for

Inside sales teams of 5–30 people who prep together before high-value calls and need deal context surfaced in Slack without anyone digging through Close manually.

Not ideal for

Teams that need two-way Slack-to-Close updates — this is read-only from Close; use a different approach if reps need to log call notes back from Slack.

Sync type

real-time

Use case type

notification

Real-World Example

💡

A 12-person B2B SaaS sales team moves deals to 'Demo Scheduled' in Close and needs the whole team to weigh in on the prospect before the call. Before this workflow, the AE would copy-paste company info into a Slack message manually — taking 10 minutes per deal and often skipping conversation history entirely. Now Pipedream fires within seconds of the stage change, posting company size, deal value, last 3 email snippets, and a direct Close link into #deal-research so anyone can add context before the call.

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, Contacts, and Activities — generate this in Close under Settings > API Keys
Slack app installation permission for your workspace — you need the ability to add apps or admin pre-approval to complete the OAuth flow
Pipedream account with Environment Variables access to store your Close API key securely
A Slack channel already created for deal research (e.g. #deal-research) with the relevant teammates already in it

Optional

At least one opportunity in Close at or near the target stage so you can trigger a real test event during setup

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Company Namelead_name
Opportunity Valuevalue
Opportunity Statusstatus_label
Assigned User IDassigned_to
Contact Namecontacts[0].display_name
Close Opportunity URLid
Recent Activity Snippetsactivities[].subject / activities[].body_preview
3 optional fields▸ show
Contact Emailcontacts[0].emails[0].email
Expected Close Dateexpected_date
Lead Sourcelead.source

Step-by-Step Setup

1

pipedream.com > Workflows > New Workflow

Create a new Pipedream Workflow

Go to pipedream.com and log in. Click 'New Workflow' in the top-right corner of the dashboard. You'll land on the workflow builder canvas with an empty trigger slot at the top. Give the workflow a name like 'Close → Slack Prospect Research Brief' so it's easy to find later.

  1. 1Click 'New Workflow' in the top-right of the Pipedream dashboard
  2. 2Click the trigger slot labeled 'Add a trigger'
  3. 3Type 'Close' in the search box
  4. 4Select 'Close (CRM)' from the app list
What you should see: You should see the Close trigger configuration panel open on the right side of the canvas.
Common mistake — Pipedream has both an HTTP trigger and app-specific triggers. Do not select 'HTTP / Webhook' — select the Close app trigger specifically so auth is handled for you.
2

Trigger Step > Close CRM > Opportunity Status Changed

Configure the Close trigger event

In the Close trigger panel, choose 'New Activity' or 'Opportunity Status Changed' as your event — use 'Opportunity Status Changed' for stage-based research briefs. Connect your Close account via Connected Accounts by clicking 'Connect Close CRM' and entering your Close API key. Set the Status filter to the stage that signals a call is coming, such as 'Demo Scheduled' or 'Negotiating'.

  1. 1Select 'Opportunity Status Changed' from the Close event dropdown
  2. 2Click 'Connect Close CRM' and paste your Close API key into the dialog
  3. 3Click 'Save' to confirm the connection
  4. 4Set the 'Status' filter field to your target stage, e.g. 'Demo Scheduled'
  5. 5Click 'Test Trigger' to pull a sample event
What you should see: Pipedream shows a green 'Connected' badge next to Close CRM and displays a sample opportunity payload in the trigger output panel.
Common mistake — Close's webhook for opportunity status fires on every status change, including moves backward. If you don't set the Status filter, you'll post to Slack every time a deal moves to any stage, including 'Lost'.
Pipedream
+
click +
search apps
Slack
SL
Slack
Configure the Close trigger …
Slack
SL
module added
3

Workflow Canvas > + Add Step > Node.js Code

Add a Node.js step to fetch full opportunity details

The trigger payload gives you the opportunity ID and basic fields, but it won't include the full contact list, all custom fields, or conversation history. Add a Node.js code step immediately after the trigger to call the Close REST API and pull the complete opportunity record. This ensures the Slack message has everything the team needs without a second manual lookup.

  1. 1Click the '+' button below the trigger step
  2. 2Select 'Run Node.js code' from the step menu
  3. 3Rename the step to 'fetch_opportunity_details' using the step name field at the top
What you should see: A Node.js code editor opens with a default async function template ready for your code.
4

Workflow Canvas > fetch_opportunity_details > Code Editor

Write the Close API fetch logic

Paste your Node.js code into the code step to hit Close's opportunity endpoint and activity endpoint. Use your Close API key stored as a Pipedream environment variable — never hardcode it in the step. The code should return a structured object with company name, deal value, assigned user, contact emails, and the last 3 activity summaries. Click 'Test' to verify the API call returns real data.

  1. 1Open Pipedream Settings > Environment Variables and add CLOSE_API_KEY
  2. 2Paste the fetch code into the Node.js editor (see pro tip below)
  3. 3Click 'Test' to run the step against the sample trigger payload
  4. 4Verify the returned object contains company_name, deal_value, and activities array
What you should see: The step output panel shows a JSON object with populated fields — company name, deal value, contact info, and an array of recent activity objects.
Common mistake — Close's activity endpoint paginates at 100 items. If you request 'all activities' without a limit, you'll get back far more data than Slack can display and risk hitting Close's rate limit of 100 requests/10 seconds.
5

Workflow Canvas > + Add Step > Node.js Code

Add a step to resolve the assigned user name

The Close opportunity record stores assigned_to as a user ID like 'user_abc123', not a display name. Add a second Node.js step to call Close's /user/{id} endpoint and resolve it to a readable name before it appears in the Slack message. Skipping this step means teammates see an opaque ID in the 'AE' field of the Slack post.

  1. 1Click '+' below the fetch_opportunity_details step
  2. 2Select 'Run Node.js code'
  3. 3Rename the step to 'resolve_user_name'
  4. 4Use steps.fetch_opportunity_details.$return_value.assigned_to as the user ID input
  5. 5Call GET https://api.close.com/api/v1/user/{id}/ and return the display_name
What you should see: Step output shows a plain string like 'Sarah Kim' that you can reference directly in the Slack message.
Common mistake — If the opportunity has no assigned user, assigned_to is null and the API call will throw a 404. Add a null check before the fetch and return 'Unassigned' as the fallback.

Paste this code into a Node.js step named 'fetch_opportunity_details' placed immediately after the Close trigger. It calls the Close opportunity endpoint, resolves the assigned user's display name in the same step, and returns a clean object ready to reference in your Slack Block Kit payload — no separate user-resolution step needed.

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 = process.env.CLOSE_API_KEY;
    const opportunityId = steps.trigger.event.data.id;
    const baseURL = 'https://api.close.com/api/v1';
    const auth = { username: apiKey, password: '' };

    // Fetch full opportunity record
    const oppResponse = await axios.get(`${baseURL}/opportunity/${opportunityId}/`, { auth });
    const opp = oppResponse.data;

    // Resolve assigned user to display name
    let assignedName = 'Unassigned';
    if (opp.assigned_to) {
      try {
        const userResponse = await axios.get(`${baseURL}/user/${opp.assigned_to}/`, { auth });
        assignedName = userResponse.data.display_name || 'Unassigned';
      } catch (e) {
        console.log(`Could not resolve user ${opp.assigned_to}: ${e.message}`);
      }
    }

    // Fetch last 3 activities for this lead
    const activityResponse = await axios.get(`${baseURL}/activity/`, {
      auth,
      params: {
        lead_id: opp.lead_id,
        _limit: 3,
        _order: '-date_created',
      },
    });

    const activities = activityResponse.data.data.map((a) => ({
      type: a._type,
      subject: a.subject || a.direction || 'Activity',
      preview: (a.body_preview || a.note || '').substring(0, 280),
      date: a.date_created,
    }));

    // Build Close opportunity URL
    const closeUrl = `https://app.close.com/opportunity/${opportunityId}/`;

    return {
      company_name: opp.lead_name,
      deal_value: opp.value ? `$${Number(opp.value).toLocaleString()}` : 'Not set',
      status: opp.status_label,
      assigned_to_name: assignedName,
      contact_name: opp.contacts?.[0]?.display_name || 'Unknown contact',
      contact_email: opp.contacts?.[0]?.emails?.[0]?.email || 'No email on file',
      expected_date: opp.expected_date || 'Not set',
      lead_source: opp.lead?.source || 'Unknown',
      activities,
      close_url: closeUrl,
    };
  },
});
6

Workflow Canvas > + Add Step > Slack > Send Message to Channel

Add a Slack step and connect your workspace

Click '+' below the user resolution step and search for 'Slack'. Select the 'Send a Message to a Channel' action. Click 'Connect Slack' — this opens an OAuth flow where you authorize Pipedream to post to your workspace. You'll need to be a Slack admin or have permission to install apps. Select the target channel (e.g. #deal-research) from the dropdown.

  1. 1Click '+' and search for 'Slack'
  2. 2Select 'Send a Message to a Channel'
  3. 3Click 'Connect Slack' and complete the OAuth authorization
  4. 4Select your target channel from the Channel dropdown, e.g. '#deal-research'
  5. 5Leave the message body blank for now — you'll fill it in the next step
What you should see: You see a green 'Connected' badge next to Slack and your workspace name appears in the account selector.
Common mistake — The OAuth scope Pipedream requests is chat:write. If your Slack workspace requires admin approval for new app installs, you'll need to get that approved before the workflow can post — test this before going to production.
Pipedream settings
Connection
Choose a connection…Add
click Add
Slack
Log in to authorize
Authorize Pipedream
popup window
Connected
green checkmark
7

Workflow Canvas > Slack Step > Blocks Field

Build the Slack Block Kit message

In the Slack step's 'Blocks' field, build a structured Block Kit payload that organizes the prospect data into readable sections. Use Slack's Block Kit Builder (app.slack.com/block-kit-builder) to prototype your layout first, then paste the JSON into Pipedream's Blocks field. Reference upstream step outputs using Pipedream's double-brace syntax: {{steps.fetch_opportunity_details.$return_value.company_name}}. Include a header block with the company name, a section block for deal value and assigned AE, a divider, and a context block with the last 3 activity snippets.

  1. 1Click into the 'Blocks' field in the Slack step
  2. 2Paste your Block Kit JSON structure
  3. 3Replace static values with Pipedream variable references like {{steps.fetch_opportunity_details.$return_value.company_name}}
  4. 4Add a 'Reply in thread' or button block pointing to the Close opportunity URL
  5. 5Click 'Test' to send a real message to your channel
What you should see: A formatted Slack message appears in #deal-research with the company name as a header, deal value and AE name in a two-column section, and recent email snippets below a divider.
Common mistake — Slack's Block Kit text fields have a 3,000 character limit per block. If a conversation history snippet is long, truncate it to 300 characters in your Node.js step before passing it to Slack — otherwise the post will silently fail.
8

Workflow Canvas > Step Settings (···) > Error Handling

Add error handling with a fallback notification

Add a final Node.js step after the Slack step configured to run on error. In Pipedream, click the step settings (three dots) on any step and toggle 'Continue on error' if you want the workflow to proceed even when Close is slow. Alternatively, add a separate error handler step that pings a #alerts channel with the failure reason. This prevents silent failures where a deal moves to 'Demo Scheduled' but no research brief appears in Slack.

  1. 1Click the '···' menu on the fetch_opportunity_details step
  2. 2Toggle 'Continue workflow on error' if you want non-blocking behavior
  3. 3Add a new Node.js step at the end labeled 'error_alert'
  4. 4Use $.send.http or the Slack step to post to #alerts if any upstream step fails
  5. 5Reference the error object via process.env or the workflow's error context
What you should see: When you intentionally break the Close API key to simulate failure, the error_alert step fires and posts a message to #alerts with the step name and error message.
9

Workflow Canvas > Event History

Test end-to-end with a real Close opportunity

In Close, manually move a real test opportunity to your target stage. In Pipedream, click 'Event History' on the workflow to watch for the incoming event. Confirm all three steps executed: the opportunity fetch returned data, the user name resolved correctly, and the Slack message posted with the right company and deal value. Check the Slack channel directly to verify formatting looks correct on desktop and mobile.

  1. 1Move a test opportunity to your target stage in Close
  2. 2Open Pipedream > Workflows > [your workflow] > Event History
  3. 3Click the incoming event to expand the step-by-step execution log
  4. 4Verify each step shows a green checkmark and populated output
  5. 5Check #deal-research in Slack to confirm the message arrived and is formatted correctly
What you should see: The Event History shows all steps green. The Slack channel shows a formatted brief with correct company name, deal value, AE name, and 3 activity snippets within 5 seconds of the stage change in Close.
Pipedream
▶ Deploy & test
executed
Slack
Close
Close
🔔 notification
received
10

Workflow Builder > Deploy > Settings > Concurrency

Deploy the workflow and set concurrency settings

Click 'Deploy' in the top-right corner of the workflow builder. Pipedream will activate the webhook listener for Close events. Before finishing, go to the workflow's Settings tab and configure the concurrency limit. For this use case, 1 concurrent execution is enough — if two deals change stage simultaneously, Pipedream will queue the second event rather than running both at once and potentially hitting Close rate limits.

  1. 1Click the blue 'Deploy' button in the top-right
  2. 2Navigate to the workflow's Settings tab
  3. 3Set 'Max concurrent executions' to 1 or 2
  4. 4Confirm the workflow status shows 'Active' in the workflow list
What you should see: The workflow status badge shows 'Active' in green. The Close webhook URL in the trigger step is live and accepting events.
Common mistake — Pipedream free tier workflows pause after 30 days of inactivity. If your team goes on holiday for a month and no deals move stages, the workflow may need a manual re-deploy when you return.

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 anyone who can write basic JavaScript — even just enough to read an API response and pick out fields. The Close API returns a nested JSON object and you need two API calls (opportunity + activity) to build a useful brief. Pipedream's Node.js steps handle that in a single step with real error handling, which you can't do in Zapier without code steps that feel bolted on. The other reason to pick Pipedream here is latency: the webhook fires and the Slack message lands in under 5 seconds of the stage change in Close. If your team uses 'Demo Scheduled' as a trigger to jump on pre-call research, 5 seconds matters more than you'd think. The one scenario where you'd pick something else: if your team has zero coding tolerance and needs a point-and-click setup, Make handles this same flow with its HTTP module and is easier to maintain without writing code.

Cost

Pipedream's credit model charges 1 credit per workflow step execution. This workflow has 4-5 steps (trigger, opportunity fetch, user lookup, optional dedup, Slack post). At 5 credits per run and 200 deals moving to 'Demo Scheduled' per month, you're burning 1,000 credits/month. Pipedream's free tier includes 10,000 credits/month, so you have room for 2,000 runs before paying anything. The paid tier starts at $29/month for 50,000 credits. Make, by comparison, charges 5 operations for a comparable flow and their free tier caps at 1,000 ops/month — you'd hit that ceiling at 200 deals. Zapier charges per task and at 200 multi-step zaps, you're on the $49/month Starter plan. Pipedream is the cheapest option here by a meaningful margin until you're running thousands of deals per month.

Tradeoffs

Zapier's Close integration has a polished 'New Opportunity' trigger with dropdown field selectors — no code needed to map company name into a Slack message, and non-technical ops managers can maintain it. Make's HTTP module lets you chain the two Close API calls in one scenario with visual mapping, which is easier to audit than Node.js for teams that prefer visual tools. n8n has a Close node with built-in activity fetching, so you skip writing the API calls entirely — that's a genuine time saver during setup. Power Automate has no native Close connector, so you'd need its HTTP action for both API calls anyway, which gives you all of Pipedream's complexity with none of its developer ergonomics. Pipedream is still the right call here because the Close API response structure requires real code to extract and format cleanly — the visual platforms either can't do the nested array traversal without workarounds, or they can but it takes longer to configure than writing 40 lines of JavaScript.

Three things you'll run into after going live. First, Close's webhook can double-fire when an opportunity is updated by an automation rule at the same time a rep manually changes the status — you'll get two identical Slack posts within a second of each other. Build the dedup check from day one, not after you get complaints. Second, the activity endpoint returns all activity types including system events like 'Opportunity created' — if you don't filter by type (email, call, note), your brief will include noise like status-change log entries that mean nothing to your team. Filter to _type in ['Email', 'Call', 'Note'] before slicing the top 3. Third, Pipedream's free tier workflows go idle after 30 days without an event. If your pipeline goes quiet for a month (holidays, quarter end), check that the workflow is still active before your team starts missing briefs — the fix is just clicking 'Resume' but you have to notice it stopped first.

Ideas for what to build next

  • Add a Slack Thread Reply CollectorExtend the workflow to listen for replies in the Slack thread and log them back as notes on the Close opportunity — giving the AE a record of team research input without leaving Close.
  • Enrich with Company Data Before PostingAdd a Clearbit or Apollo.io lookup step between the Close fetch and the Slack post to append headcount, industry, and tech stack to the brief — so the team gets external context alongside CRM history.
  • Build a Daily Digest VersionCreate a separate scheduled Pipedream workflow that runs each morning at 8am, queries Close for all deals moving to target stages in the next 48 hours, and posts a single digest message to #deal-research instead of one message per deal.

Related guides

Was this guide helpful?
Slack + Close overviewPipedream profile →