Connect Pipedrive with Slack
Implementation Guide
Overview: Connecting Pipedrive and Slack
Sales teams that operate with Pipedrive as their CRM depend on real-time visibility into pipeline movement to coordinate deal pursuit, celebrate wins, and respond quickly to at-risk opportunities. Slack is the primary async communication layer in most modern sales organizations. Without a programmatic bridge between the two, pipeline updates are communicated manually—sales managers scrape Pipedrive dashboards and post summaries to Slack, creating latency, inconsistency, and alert fatigue from non-standardized messages. A well-implemented Pipedrive-to-Slack integration creates a reliable, automated signal layer that delivers contextually rich deal notifications directly to the right Slack channels and individuals at the moment events occur in Pipedrive.
This guide covers the implementation of this integration using Pipedrive's native webhook system and Slack's Block Kit message formatting API, deployed via both Make (formerly Integromat) and Pipedrive's native Zapier integration, with detailed treatment of Pipedrive's webhook event model, Slack's incoming webhook and chat.postMessage APIs, and the message formatting patterns that maximize actionability for sales teams.
Core Prerequisites
For Pipedrive, you need a Company Admin account to access webhook configuration at the company level, or a regular user account if you are configuring user-level webhooks only. Generate an API token from your Pipedrive account settings under Personal Preferences > API. The Pipedrive API token is a static token associated with your user account and does not use OAuth 2.0. For enterprise deployments where you need a service account token that is not tied to a specific user, create a dedicated Pipedrive user account for the integration and generate its token.
Alternatively, Pipedrive supports OAuth 2.0 for partner app integrations. If you are building a multi-tenant integration that operates across multiple Pipedrive company accounts, register an OAuth 2.0 app in the Pipedrive Developer Hub and request the following scopes: deals:read, activities:read, contacts:read, organizations:read, and users:read. The OAuth authorization URL is https://oauth.pipedrive.com/oauth/authorize, and the token endpoint is https://oauth.pipedrive.com/oauth/token.
For Slack, you need a Slack workspace with the ability to install apps. Create a Slack App at api.slack.com/apps. For simple one-way notification use cases (Pipedrive events posting to Slack), enable Incoming Webhooks in your Slack App configuration and generate a webhook URL for the target channel. For more sophisticated implementations—such as posting messages with interactive buttons that link back to Pipedrive deals, or sending DMs to specific users—use the chat.postMessage API method. This requires the following OAuth scopes in your Slack App: chat:write, chat:write.public (to post to channels the bot is not a member of), and users:read.email (to look up Slack user IDs by email address for DM routing).
Install the Slack App to your workspace and note the Bot User OAuth Token (prefixed with xoxb-). Add the bot to every Slack channel it needs to post to, or use the chat:write.public scope to post to any channel without requiring membership.
Top Enterprise Use Cases
The most universally valuable use case is deal stage change notifications delivered to a designated sales channel. When a deal moves from "Proposal Sent" to "Negotiation," or from "Negotiation" to "Closed Won," a structured Slack message is posted to a channel like #sales-pipeline with the deal name, value, owner, account name, and a direct link to the Pipedrive deal record. This real-time pulse eliminates the need for daily standups focused solely on pipeline status updates.
A second high-impact use case is "Closed Won" celebration posts. When a deal reaches the Won stage, the integration posts an enriched message to a #wins or #revenue channel, including the deal value, the sales rep's name, the deal duration from creation to close, and the account name. This creates a culture of visibility and recognition without any manual effort from the sales rep.
A third use case is overdue activity alerts. When a Pipedrive activity (call, email, meeting) passes its due date without being marked as done, the integration sends a Slack direct message to the activity's owner reminding them to complete or reschedule the activity, with a direct link to the associated deal. This serves as an automated SDR coaching mechanism and prevents deals from stalling due to missed follow-up.
A fourth use case is deal assignment notifications. When a deal is reassigned to a new owner in Pipedrive, the new owner receives a Slack DM with the deal summary and a prompt to review the deal notes and schedule a kick-off call. This accelerates deal handoff and reduces the ramp time for newly assigned reps.
Step-by-Step Implementation Guide
Configuring Pipedrive Webhooks
Pipedrive's webhook system allows you to subscribe to specific object events (deals, contacts, activities, organizations, persons) and action types (added, updated, merged, deleted). Register a webhook via the Pipedrive API:
curl -X POST https://api.pipedrive.com/v1/webhooks \
-H "Content-Type: application/json" \
-d {
"subscription_url": "https://hook.eu1.make.com/YOUR_MAKE_WEBHOOK_ID",
"event_action": "changed",
"event_object": "deal",
"api_token": "YOUR_PIPEDRIVE_API_TOKEN"
}
For "Closed Won" and "Deal Lost" events specifically, use event_action: "updated" on the deal object and filter in your processing logic based on the status field changing to won or lost. Pipedrive does not have a distinct webhook event for "deal won"—it is modeled as a deal update where current.status equals won and previous.status equals open.
A sample Pipedrive deal webhook payload for a stage change event is:
{
"v": 1,
"matches_filters": {
"current": []
},
"meta": {
"v": 1,
"action": "updated",
"object": "deal",
"id": 142,
"company_id": 8877,
"user_id": 504,
"timestamp": 1712345678,
"change_source": "app",
"is_bulk_update": false,
"pipedrive_service_name": false
},
"current": {
"id": 142,
"title": "Acme Corp - Enterprise License",
"value": 48000,
"currency": "USD",
"status": "open",
"stage_id": 7,
"stage_name": "Negotiation",
"pipeline_id": 2,
"pipeline_name": "Enterprise",
"person_name": "Sarah Mitchell",
"org_name": "Acme Corp",
"owner_name": "James Wu",
"owner_email": "[email protected]",
"close_time": null,
"update_time": "2024-04-15T10:23:45.000Z"
},
"previous": {
"stage_id": 5,
"stage_name": "Proposal Sent",
"update_time": "2024-04-10T14:00:00.000Z"
},
"event": "updated.deal"
}
In Make, after the webhook trigger captures this payload, add a Router module with separate branches: one branch for current.status == won, one for current.status == lost, one for stage changes (where current.stage_id != previous.stage_id and current.status == open), and one for general updates you want to ignore (to terminate those branches cleanly).
Constructing Slack Block Kit Messages
Rather than posting plain text messages, use Slack's Block Kit to construct rich, scannable deal notification cards. Block Kit messages are posted via POST https://slack.com/api/chat.postMessage with a JSON body. For a deal stage change notification, the Block Kit payload is:
{
"channel": "C0SALESCH1",
"text": "Deal Stage Update: Acme Corp - Enterprise License",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "📊 Deal Stage Update"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Deal:*\n<https://yourcompany.pipedrive.com/deal/142|Acme Corp - Enterprise License>"
},
{
"type": "mrkdwn",
"text": "*Value:*\n$48,000"
},
{
"type": "mrkdwn",
"text": "*Stage:*\n~~Proposal Sent~~ → *Negotiation*"
},
{
"type": "mrkdwn",
"text": "*Owner:*\nJames Wu"
},
{
"type": "mrkdwn",
"text": "*Account:*\nAcme Corp"
},
{
"type": "mrkdwn",
"text": "*Pipeline:*\nEnterprise"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Deal in Pipedrive"
},
"url": "https://yourcompany.pipedrive.com/deal/142",
"action_id": "view_deal_142"
}
]
},
{
"type": "context",
"elements": [
{
"type": "mrkdwn",
"text": "Updated at 10:23 AM · Apr 15, 2024"
}
]
}
]
}
The text field at the top level is required and serves as the notification fallback for mobile push notifications and accessibility tools; it is not displayed in the message body when blocks are present. Always include it.
Routing DMs to Deal Owners
For activity overdue alerts and deal assignment notifications, post a Slack DM directly to the deal owner rather than a channel. To do this, you need to resolve the Pipedrive user's email address to a Slack user ID. The owner's email is available in the webhook payload as current.owner_email. Use the Slack users.lookupByEmail method:
GET https://slack.com/api/[email protected]
Authorization: Bearer xoxb-YOUR-BOT-TOKEN
The response returns a user object with an id field (e.g., U012AB3CD). Use this user ID as the channel parameter in chat.postMessage to send a DM. If users.lookupByEmail returns users_not_found, the user is not in the Slack workspace; fall back to posting in the team sales channel and tagging the owner by name.
Make Module Configuration Summary
In Make, the complete scenario for deal stage change notifications uses the following module chain: Webhooks > Custom Webhook (trigger) → Router → [Branch 1] Text Parser (format currency) → HTTP > Make a Request (Slack users.lookupByEmail) → Slack > Create a Message (Block Kit payload) → [Branch 2] Slack > Create a Message (won notification to #wins channel) → [Branch 3] Router terminate.
Common Pitfalls & Troubleshooting
A channel_not_found error from the Slack chat.postMessage API indicates that the bot user has not been added to the target channel, or that the channel ID is incorrect. Slack channel IDs begin with C for public channels, G for private channels, and D for direct message threads. Verify the channel ID by calling GET https://slack.com/api/conversations.list and searching for the channel name in the response. Do not rely on channel names as identifiers; always use channel IDs, as names can be changed without affecting the ID.
A missing_scope error from the Slack API means your Slack App's Bot Token does not have the required OAuth scope for the API method you are calling. For example, calling users.lookupByEmail without the users:read.email scope will return this error. To add scopes, go to your Slack App configuration at api.slack.com, navigate to OAuth & Permissions, add the scope, and reinstall the app to your workspace. Reinstallation regenerates the Bot Token, so update your Make credential with the new token.
Pipedrive webhooks do not include a cryptographic signature for request verification (unlike Shopify and Stripe). To secure your Make webhook endpoint, enable Basic Authentication or append a secret token as a query parameter to your webhook URL and validate it in a Make filter at the start of your scenario. Alternatively, restrict your webhook receiver to Pipedrive's published IP ranges.
If your Make scenario fails and Pipedrive's webhook delivery receives a non-200 response, Pipedrive will retry delivery with exponential backoff for up to 5 attempts over approximately 24 hours. After 5 failures, the webhook subscription is automatically disabled. Monitor your Make scenario's execution history and error logs to catch silent failures before the webhook subscription is deactivated. Pipedrive will send an email notification to the webhook creator when a subscription is disabled due to repeated delivery failures.
A ratelimited error from the Slack API occurs when your app exceeds Slack's tier-based rate limits. The chat.postMessage method is subject to Tier 3 rate limits (approximately 50 requests per minute per workspace). For bulk notification scenarios—such as migrating historical Pipedrive data or processing a backlog of events—implement a delay between Slack API calls. In Make, use the Sleep module to add a 1-second pause between iterations in a repeating loop.