

How to Send Copper Lead Alerts to Slack with Power Automate
Polls Copper for new or reassigned leads and sends a formatted Slack direct message to the assigned sales rep within minutes.
Steps and UI details are based on platform versions at time of writing — check each platform for the latest interface.
Best for
Microsoft 365 teams who already use Power Automate and need lead assignment alerts without adding another automation tool.
Not ideal for
Teams needing sub-60-second alert delivery — Copper has no native webhook, so polling adds latency.
Sync type
scheduledUse case type
notificationReal-World Example
A 12-person B2B sales team at a managed IT services company uses this to ping reps in Slack the moment a new inbound lead is assigned in Copper. Before this flow, reps logged into Copper manually and routinely missed freshly assigned leads for 2-3 hours. Now the assigned rep gets a Slack DM within 5 minutes of assignment, including the lead name, company, phone number, and a direct link to the Copper record.
What Will This Cost?
Drag the slider to your expected monthly volume.
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
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.
Field Mapping
Map these fields between your apps.
| Field | API Name | |
|---|---|---|
| Required | ||
| Lead Name | name | |
| Assignee ID | assignee_id | |
| Date Modified | date_modified | |
| Lead ID | id | |
| Assignee Email | email | |
5 optional fields▸ show
| Company Name | company_name |
| Phone Numbers | phone_numbers |
| Email Addresses | email_addresses |
| Lead Status | status |
| Lead Source | customer_source_id |
Step-by-Step Setup
make.powerautomate.com > My flows > + New flow > Scheduled cloud flow
Open Power Automate and start a new Scheduled flow
Go to make.powerautomate.com and sign in with your Microsoft 365 account. In the left sidebar, click 'My flows', then click '+ New flow' at the top. Select 'Scheduled cloud flow' from the dropdown. Because Copper does not expose webhooks, you will poll it on a recurring interval — every 5 minutes is a practical starting point. Name the flow something like 'Copper Lead Assignment Alert'.
- 1Navigate to make.powerautomate.com and sign in
- 2Click 'My flows' in the left sidebar
- 3Click '+ New flow' in the top toolbar
- 4Select 'Scheduled cloud flow'
- 5Set the flow name to 'Copper Lead Assignment Alert', interval to 5, and unit to Minutes, then click 'Create'
Flow canvas > + New step > Search 'HTTP' > HTTP action
Add an HTTP action to call the Copper Leads API
Click '+ New step' below the Recurrence trigger. In the action search bar, type 'HTTP' and select the 'HTTP' action (not HTTP + Swagger). You will use this to call Copper's REST API directly, since there is no native Copper connector in Power Automate. Set Method to POST and the URI to 'https://api.copper.com/developer_api/v1/leads/search'. This endpoint accepts a JSON body to filter leads modified after a specific timestamp.
- 1Click '+ New step'
- 2Type 'HTTP' in the search bar and select the 'HTTP' action
- 3Set Method to 'POST'
- 4Set URI to 'https://api.copper.com/developer_api/v1/leads/search'
- 5Under 'Headers', add: X-PW-AccessToken (your Copper API key), X-PW-Application (developer_api), X-PW-UserEmail (your Copper login email), Content-Type (application/json)
HTTP action > Body field > Expression editor
Build the Copper leads search request body
In the HTTP action's Body field, you need to pass a JSON filter that returns only leads modified in the last 5 minutes. Use a Power Automate expression to calculate the timestamp dynamically. Click the Body field, then open the expression editor. The body should filter by 'minimum_updated_date' set to 5 minutes ago. Also request the 'assignee_id' and 'date_modified' fields to detect reassignment.
- 1Click inside the Body field of the HTTP action
- 2Paste the following JSON, replacing the date value with an expression: {"minimum_updated_date": EXPRESSION, "page_size": 25}
- 3Click the Expression tab and enter: formatDateTime(addMinutes(utcNow(), -5), 'yyyy-MM-ddTHH:mm:ssZ') to generate the lookback timestamp
- 4Confirm the full body reads: {"minimum_updated_date": "@{formatDateTime(addMinutes(utcNow(), -5), 'yyyy-MM-ddTHH:mm:ssZ')}", "page_size": 25}
Flow canvas > + New step > Search 'Parse JSON' > Data Operations - Parse JSON
Parse the Copper API response with Parse JSON
After the HTTP action, click '+ New step' and search for 'Parse JSON'. Select the 'Data Operations - Parse JSON' action. Set the Content field to the Body output from the previous HTTP step. You need to provide a schema so Power Automate can reference individual fields like lead name, assignee ID, and phone number in later steps. Use the schema provided in the pro tip section or generate one by pasting a sample Copper lead response.
- 1Click '+ New step' and search 'Parse JSON'
- 2Select 'Data Operations - Parse JSON'
- 3In the 'Content' field, click and select 'Body' from the HTTP action's dynamic content panel
- 4Click 'Generate from sample', paste a real Copper lead JSON response, and click 'Done'
- 5Verify the schema shows fields including id, name, assignee_id, phone_numbers, and date_modified
Flow canvas > + New step > Built-in > Apply to each
Add an Apply to Each loop over the returned leads
Copper's search endpoint returns an array of leads. You need to loop through each one and send a separate Slack message per lead. Click '+ New step', search for 'Apply to each', and select it. In the 'Select an output from previous steps' field, choose the parsed array body from the Parse JSON action. All remaining steps — the Copper assignee lookup and the Slack message — will live inside this loop.
- 1Click '+ New step'
- 2Search 'Apply to each' and select it under 'Built-in'
- 3Click inside 'Select an output from previous steps'
- 4From the dynamic content panel, select the array output from Parse JSON (it will be labeled 'Body' or the top-level array key)
- 5Confirm the loop card is now wrapping a blank interior — all next steps go inside here
Apply to each loop > + Add an action > HTTP
Resolve the assignee ID to a name and email via HTTP
Copper stores the assigned rep as a numeric assignee_id, not a name. Inside the Apply to each loop, add another HTTP action to call 'GET https://api.copper.com/developer_api/v1/users/{assignee_id}' to fetch the rep's name and email. Use the same four Copper API headers from Step 2. You will use the rep's email to look up their Slack user in the next step.
- 1Inside the Apply to each loop, click '+ Add an action'
- 2Search 'HTTP' and select the HTTP action
- 3Set Method to 'GET'
- 4Set URI to: https://api.copper.com/developer_api/v1/users/ then append the 'assignee_id' dynamic token from the Parse JSON output
- 5Add the same four Copper API headers: X-PW-AccessToken, X-PW-Application, X-PW-UserEmail, Content-Type
Paste this into a 'Compose' action placed immediately after the Parse JSON step for the assignee lookup. It builds the complete Slack message body as a single expression, including a formatted timestamp and a fallback for missing phone numbers. Reference this Compose action's output in the Slack 'Send a direct message' Body field.
JavaScript — Code Stepconcat(▸ Show code
concat( '🔔 New lead assigned to you ',
... expand to see full code
concat(
'🔔 New lead assigned to you
',
'*Name:* ', items('Apply_to_each')?['name'], '
',
'*Company:* ', if(empty(items('Apply_to_each')?['company_name']), '_(no company)_', items('Apply_to_each')?['company_name']), '
',
'*Phone:* ', if(empty(items('Apply_to_each')?['phone_numbers']), '_(no phone)_', first(items('Apply_to_each')?['phone_numbers'])?['number']), '
',
'*Source:* ', if(empty(items('Apply_to_each')?['customer_source_id']), '_(unknown)_', string(items('Apply_to_each')?['customer_source_id'])), '
',
'*Status:* ', items('Apply_to_each')?['status'], '
',
'*Assigned to:* ', body('Parse_JSON_2')?['name'], '
',
'*View in Copper:* https://app.copper.com/companies/', string(items('Apply_to_each')?['id']), '/leads/', string(items('Apply_to_each')?['id'])
)Apply to each loop > + Add an action > Parse JSON
Parse the assignee API response
Add a second Parse JSON action inside the loop to extract the rep's name and email from the user lookup response. Set Content to the Body of the assignee HTTP action. Generate the schema from a sample Copper user response — it should include fields like id, name, and email. You will use the email field to address the Slack DM in the next step.
- 1Inside the loop, click '+ Add an action'
- 2Search and select 'Data Operations - Parse JSON'
- 3Set Content to the Body output from the assignee HTTP action
- 4Click 'Generate from sample' and paste a sample Copper user object with id, name, and email
- 5Click 'Done' and verify 'name' and 'email' appear as available dynamic content tokens
Apply to each loop > + Add an action > Slack > Look up Slack user by email
Look up the Slack user by email
Inside the loop, add a new action and search for 'Slack'. Select the Slack connector, then choose the action 'Look up Slack user by email'. This returns the Slack user ID needed to send a direct message. Set the Email field to the email token from the assignee Parse JSON step. If this is your first Slack action, Power Automate will prompt you to create a Slack Connection — sign in with the Slack account that has the permissions to look up users and send DMs.
- 1Inside the loop, click '+ Add an action'
- 2Search 'Slack' and select the Slack connector
- 3Choose 'Look up Slack user by email'
- 4In the Email field, insert the 'email' dynamic token from the assignee Parse JSON action
- 5If prompted, click 'Sign in' to create a Slack Connection and authorize with your Slack workspace admin account
Apply to each loop > + Add an action > Slack > Send a direct message
Add the Slack 'Send a direct message' action
Still inside the loop, add another Slack action and select 'Send a direct message'. Set the 'User Name or ID' field to the Slack user ID returned by the lookup action in Step 8. In the Message Text field, compose the alert using dynamic tokens. Include the lead's name, company, phone number, assigned date, and a direct link to the Copper record formatted as a URL. Keep the message scannable — one or two lines per data point.
- 1Inside the loop, click '+ Add an action'
- 2Search 'Slack' and select 'Send a direct message'
- 3In 'User Name or ID', insert the 'User ID' dynamic token from the Slack user lookup action
- 4In 'Message Text', build the alert: '🔔 New lead assigned to you\n*Name:* [name token]\n*Company:* [company token]\n*Phone:* [phone token]\n*View in Copper:* https://app.copper.com/companies/[id token]/leads/[id token]'
- 5Save the action
channel: {{channel}}
ts: {{ts}}
Apply to each loop > + Add an action (before HTTP lookup) > Control > Condition
Add a Condition to filter only newly assigned leads
Right now the flow alerts on any lead modified in the last 5 minutes — including name edits, status changes, and note additions that are not assignment events. To narrow it down, add a Condition action at the top of the loop (before the assignee lookup) that checks whether the lead's 'assignee_id' is not null and whether 'date_modified' is within your lookback window. This cuts noise significantly for active teams who update leads frequently.
- 1Inside the loop, click '+ Add an action' at the very top of the loop (drag to reorder if needed)
- 2Search 'Condition' and select 'Control - Condition'
- 3In the left condition field, insert the 'assignee_id' dynamic token
- 4Set the operator to 'is not equal to'
- 5Set the right field to 'null' (type the word null or leave blank depending on your Power Automate version) — move the remaining steps into the 'If yes' branch
Flow canvas > Save > Test > Manually > Run flow
Test, enable, and monitor the flow
Click 'Save' in the top toolbar, then click 'Test' and choose 'Manually' to trigger an immediate run. In Copper, create a test lead and assign it to a real rep. Return to Power Automate and watch the run history — green checkmarks on each action mean the flow executed cleanly. Check the target rep's Slack DMs to confirm the message arrived. Once validated, the flow runs automatically every 5 minutes with no further action needed.
- 1Click 'Save' in the top toolbar
- 2Click 'Test', select 'Manually', then click 'Run flow'
- 3Open Copper and create or reassign a test lead to a rep whose email matches a Slack account
- 4Return to Power Automate and watch the run detail page for green checkmarks on each step
- 5Check the assigned rep's Slack DMs to confirm the formatted alert arrived
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
Use Power Automate for this if your organization is already in the Microsoft 365 ecosystem and your IT team controls Slack and Copper access centrally. The main advantage: your Slack Connection and HTTP credentials live inside your tenant's managed environment, which matters for teams with compliance requirements around data leaving Microsoft's infrastructure. Power Automate also lets you store the Copper API key in an Environment Variable tied to your Power Platform environment — a cleaner secret-management story than most other platforms offer natively. That said, if your team has no existing Power Automate footprint, pick Make instead — the setup is 40% faster and you won't need to manage a Premium connector license just to make an HTTP call.
Power Automate's pricing for this flow is straightforward but adds up at scale. Each flow run consumes Power Platform requests: roughly 8 actions per run (Recurrence, HTTP search, Parse JSON, Apply to each, HTTP user lookup, Parse JSON, Slack lookup, Slack DM). At 5-minute polling that is 288 runs per day, or about 8,640 runs per month. On the Power Automate Premium plan at $15/user/month, you get 40,000 Power Platform requests per user — this flow fits comfortably. The hidden cost is the HTTP connector itself: it is a Premium connector, meaning every user whose account runs this flow needs a Premium license. Make's equivalent setup costs $9/month flat for up to 10,000 operations, with no per-user premium requirement — cheaper by roughly 40% for small teams.
Zapier handles this use case with a simpler UI — their Copper 'New Lead' trigger is a native connector that avoids the manual HTTP setup entirely, saving about 30 minutes of configuration. Make is faster to build (no Parse JSON steps needed — it parses HTTP responses automatically) and supports HTTP natively on its free tier. n8n lets you run the whole flow self-hosted with no polling costs at all, and the Copper HTTP node plus Slack node are pre-built. Pipedream gives you real webhooks if you proxy Copper events through a custom endpoint, dropping latency from 5 minutes to under 5 seconds. Power Automate wins here specifically when your IT security team needs everything inside Azure AD, or when you are already paying for a Power Automate Premium license as part of a Dynamics 365 bundle and the marginal cost is zero.
Three things you will hit after going live. First, Copper's search API returns leads modified within your window regardless of which field changed — a rep adding a note triggers an alert the same as a reassignment. You need to implement the activity log check described in the next steps section, or your reps will start ignoring the bot within a week. Second, Power Automate's Apply to each loop runs actions sequentially by default, not in parallel — if 15 leads come in during one poll cycle, the loop takes 15x your per-iteration time, which can exceed 5 minutes and cause your next scheduled run to overlap. Turn on concurrency control and cap it at degree 1. Third, the Copper Users API returns a phone number and email that may differ from what is in your Slack directory — particularly at companies where personal Gmail addresses are used in Copper but corporate addresses are in Slack. Build a mapping table in SharePoint early rather than debugging mismatches rep by rep after launch.
Ideas for what to build next
- →Post to a shared #new-leads Slack channel in addition to DMs — Add a second Slack action inside the loop that posts a summary to a team channel like #sales-leads. This gives sales managers visibility into all assigned leads without needing to check Copper directly.
- →Log each alert to a SharePoint list for deduplication and audit trail — Before sending the Slack message, check a SharePoint list for the lead ID. If it already exists, skip the message. If not, add it and proceed. This eliminates duplicate alerts from boundary-case polling and gives you a searchable record of every notification sent.
- →Extend the alert to cover lead reassignments, not just new assignments — Add a second HTTP call that fetches the lead's previous assignee_id from Copper's activity log endpoint and compares it to the current one. If they differ, modify the Slack message to say 'Lead reassigned to you from [previous rep name]' so the new rep has full context.
Related guides
How to Share Notion Meeting Notes to Slack with Pipedream
~15 min setup
How to Share Notion Meeting Notes to Slack with Power Automate
~15 min setup
How to Share Notion Meeting Notes to Slack with n8n
~20 min setup
How to Send Notion Meeting Notes to Slack with Zapier
~8 min setup
How to Share Notion Meeting Notes to Slack with Make
~12 min setup
How to Create Notion Tasks from Slack with Pipedream
~15 min setup