Intermediate~20 min setupCommunication & Project ManagementVerified April 2026
Slack logo
Wrike logo

How to Send Wrike Milestone Alerts to Slack with n8n

Automatically posts a celebratory Slack message to a team channel whenever a Wrike task marked as a milestone is completed.

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

Best for

Engineering or project teams using Wrike for milestone tracking who want instant, no-manual-effort Slack shoutouts when major deliverables close.

Not ideal for

Teams that close dozens of milestones per day — repeated Slack pings will create noise; use a daily digest workflow instead.

Sync type

real-time

Use case type

notification

Real-World Example

💡

A 20-person product team at a B2B SaaS company uses Wrike to track quarterly roadmap milestones. Before this workflow, the PM had to manually post in #product-updates every time a phase closed — and often forgot, or posted hours later. Now, the moment a milestone task flips to Completed in Wrike, a formatted Slack message fires to the channel in under 30 seconds, tagging the assignee and naming the project.

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 n8n

Copy the pre-built n8n blueprint and paste it straight into n8n. 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.

Wrike account with API access enabled and a personal or service account API token generated from Wrike's API settings
Wrike webhook creation permissions — typically requires Account Admin role to register webhooks via the v4 API
Slack app created at api.slack.com with the chat:write OAuth scope, installed to your workspace, and invited to the target channel
n8n instance running (cloud or self-hosted) with network access to both api.slack.com and www.wrike.com/api/v4
Wrike milestone tasks configured with a consistent field or task type that distinguishes milestones from regular tasks — needed for the filter step

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Task IDtaskId
Task Titletitle
Task Statusstatus
Responsible User IDsresponsibleIds
Assignee First NamefirstName
Assignee Last NamelastName
Completion DateupdatedDate
Slack Channel
2 optional fields▸ show
Parent Folder/Project IDparentIds
Task Permalinkpermalink

Step-by-Step Setup

1

n8n Dashboard > Workflows > New Workflow

Create a new n8n workflow

Log into your n8n instance (cloud at app.n8n.cloud or self-hosted). Click the orange 'New Workflow' button in the top right of the Workflows dashboard. Give it a clear name — something like 'Wrike Milestone → Slack Celebration'. You'll land on an empty canvas with a single 'Add first step' prompt in the center.

  1. 1Log in to your n8n instance
  2. 2Click 'New Workflow' in the top right
  3. 3Click the pencil icon next to 'My Workflow' and rename it to 'Wrike Milestone → Slack Celebration'
  4. 4Click the canvas center prompt 'Add first step'
What you should see: You should see an empty workflow canvas with the name updated in the top bar and the node picker panel open on the right side.
2

Canvas > Add Node > Webhook

Add the Webhook trigger node

In the node picker, search for 'Webhook' and select it. This node will receive real-time POST requests from Wrike whenever a task status changes. Set the HTTP Method to POST and leave the path as the auto-generated UUID — copy this URL, you'll need it in Wrike. Set Authentication to 'None' for now; you'll lock it down in the production checklist.

  1. 1Type 'Webhook' in the node search box
  2. 2Click the 'Webhook' node (not HTTP Request)
  3. 3Set HTTP Method to 'POST'
  4. 4Copy the full Webhook URL shown under 'Webhook URLs > Test URL'
What you should see: The Webhook node appears on the canvas and shows a test URL in the format https://your-instance.app.n8n.cloud/webhook-test/[uuid]. The node panel shows HTTP Method: POST.
Common mistake — n8n provides two URLs: a Test URL (only active when you click 'Listen for Test Event') and a Production URL (always active after activation). Register the Production URL in Wrike, not the Test URL, or events will silently drop after you finish testing.
n8n
+
click +
search apps
Slack
SL
Slack
Add the Webhook trigger node
Slack
SL
module added
3

Wrike > Account Settings > Apps & Integrations > Wrike API

Register the webhook in Wrike

Open Wrike in a separate tab. Navigate to your Account settings, then the API section to access Wrike's webhook configuration. You need to create a webhook that fires on task status changes. Wrike webhooks are created via the Wrike API — paste your n8n Production Webhook URL as the hook URL, and set the event filter to 'TaskStatusChanged'. If your team uses the Wrike API app or a third-party Wrike webhook manager, the steps follow the same pattern.

  1. 1Open Wrike and go to Account Settings (bottom-left avatar > Settings)
  2. 2Click 'Apps & Integrations', then 'Wrike API'
  3. 3Generate or copy your Wrike API access token
  4. 4Use Wrike's POST /webhooks API endpoint with your n8n URL and event type 'TaskStatusChanged'
  5. 5Confirm the webhook appears in GET /webhooks response with status 'active'
What you should see: A GET /webhooks call to Wrike returns your new webhook entry with a status of 'active' and your n8n URL in the hookUrl field.
Common mistake — Wrike webhooks are account-scoped by default but can be filtered to specific folder IDs. If you want only one project's milestones to trigger this — not every task status change across the account — pass the optional folderId parameter when creating the webhook. Skipping this will flood n8n with every task update company-wide.
4

n8n Canvas > Webhook Node > Listen for Test Event

Test the webhook with a sample payload

Back in n8n, click your Webhook node and hit 'Listen for Test Event'. Switch to Wrike, mark any milestone task as Completed, then return to n8n. The canvas should show a green data bubble on the Webhook node. Click the node to inspect the incoming JSON — you'll see the task ID, status, project ID, and author fields. This is the data you'll filter and format in later steps.

  1. 1Click the Webhook node on the canvas
  2. 2Click 'Listen for Test Event' in the node panel
  3. 3Switch to Wrike and complete any milestone task
  4. 4Return to n8n and wait for the green dot to appear on the Webhook node
  5. 5Click the node and review the Input tab to see the raw JSON payload
What you should see: The Webhook node shows a green checkmark and the Input panel displays a JSON object with fields including taskId, status, projectId, authorId, and updatedDate.
Common mistake — Copy the webhook URL carefully — it expires if you regenerate it, and any scenarios using the old URL will silently stop working.
n8n
▶ Run once
executed
Slack
Wrike
Wrike
🔔 notification
received
5

Canvas > + > IF Node

Add a Filter node to catch only milestone completions

Not every task update should trigger a Slack message — only completed milestones. Add an IF node after the Webhook. Set Condition 1 to check that the incoming status field equals 'Completed'. Set Condition 2 to check that a custom field you've set on Wrike milestone tasks (e.g. a boolean 'isMilestone' field or a specific task type) equals true. Both conditions must pass for the workflow to continue. Anything that fails routes to the False branch, which you can leave empty or connect to a 'No Operation' node.

  1. 1Click the '+' connector after the Webhook node
  2. 2Search for 'IF' and select the IF node
  3. 3Click 'Add Condition', set left value to '{{ $json.body.status }}', operator to 'equals', right value to 'Completed'
  4. 4Click 'Add Condition', set left value to '{{ $json.body.taskType }}' or your milestone custom field path, operator to 'equals', right value to 'Milestone'
  5. 5Set 'Combine Conditions' to 'AND'
What you should see: The IF node shows two conditions joined by AND. Running the test data routes it to the True (green) output branch.
Common mistake — Wrike task types and custom field paths vary by account configuration. Open the raw webhook payload you captured in Step 4 and locate your exact field names before building the condition. Using a wrong path silently routes everything to the False branch — no error, just silence.
Slack
SL
trigger
filter
Condition
matches criteria?
yes — passes through
no — skipped
Wrike
WR
notified
6

Canvas > + > HTTP Request Node

Fetch full task details from Wrike API

The webhook payload gives you a task ID but not the full task title, assignee name, or project name. Add an HTTP Request node to call the Wrike API and retrieve complete task details. Use a GET request to https://www.wrike.com/api/v4/tasks/{{taskId}} with your Bearer token in the Authorization header. This returns the task title, description, responsible party IDs, and parent folder IDs you'll need for the Slack message.

  1. 1Click '+' after the True output of the IF node
  2. 2Search for 'HTTP Request' and add it
  3. 3Set Method to GET
  4. 4Set URL to 'https://www.wrike.com/api/v4/tasks/{{ $json.body.taskId }}'
  5. 5Add Header: Authorization = 'Bearer YOUR_WRIKE_API_TOKEN'
  6. 6Click 'Execute Node' to verify the response
What you should see: The HTTP Request node returns a JSON response with a 'data' array containing one object — the full task record including title, status, description, responsibleIds, and parentIds.
Common mistake — Wrike rate limits the v4 API to 100 requests per minute per access token. For a low-volume milestone workflow this is fine, but if you're also running other n8n workflows against the same Wrike token, you could hit this cap. Use separate API tokens per workflow to avoid cross-workflow throttling.
7

Canvas > + > HTTP Request Node

Resolve assignee name from Wrike contacts

The task response gives you responsibleIds — a list of user ID strings, not names. Add a second HTTP Request node to call GET https://www.wrike.com/api/v4/contacts/{{responsibleId}} to resolve the first responsible user's name. Extract the firstName and lastName fields from the response. This name will appear in the Slack message so the team knows who closed the milestone.

  1. 1Click '+' after the task detail HTTP Request node
  2. 2Add another HTTP Request node
  3. 3Set Method to GET
  4. 4Set URL to 'https://www.wrike.com/api/v4/contacts/{{ $json.data[0].responsibleIds[0] }}'
  5. 5Add the same Authorization header with your Wrike token
  6. 6Execute the node and confirm firstName and lastName appear in the response
What you should see: The contacts API returns a data array with one object containing firstName, lastName, and email for the milestone assignee.
Common mistake — If a milestone has no assignee, responsibleIds will be an empty array and this expression will throw a runtime error. Wrap it with a Check Null node or use the Code node to default to 'Unassigned' when the array is empty.

Paste this into the Code node in Step 8. It pulls task title, assignee name, completion date, and permalink from the three upstream HTTP Request nodes, formats the date to a readable string, handles missing assignees gracefully, and returns a single message object ready for the Slack node.

JavaScript — Code Node// Code Node: Build Wrike Milestone Celebration Slack Message
▸ Show code
// Code Node: Build Wrike Milestone Celebration Slack Message
// Runs after: Webhook → IF → HTTP Task Details → HTTP Contact Details
const taskData = $node['HTTP Request - Task Details'].json.data[0];

... expand to see full code

// Code Node: Build Wrike Milestone Celebration Slack Message
// Runs after: Webhook → IF → HTTP Task Details → HTTP Contact Details

const taskData = $node['HTTP Request - Task Details'].json.data[0];
const contactData = $node['HTTP Request - Contact Details'].json.data;

// Resolve assignee name — default to 'the team' if no assignee found
let assigneeName = 'the team';
if (contactData && contactData.length > 0) {
  const contact = contactData[0];
  assigneeName = `${contact.firstName} ${contact.lastName}`.trim();
}

// Format the completion date from ISO 8601 to readable string
const rawDate = taskData.updatedDate || new Date().toISOString();
const completionDate = new Date(rawDate).toLocaleDateString('en-US', {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
});

// Build the task title and permalink
const taskTitle = taskData.title || 'Untitled Milestone';
const permalink = taskData.permalink || '';
const linkLine = permalink ? `\n🔗 ${permalink}` : '';

// Compose the celebration message
const message = [
  `🎉 Milestone crushed! *${taskTitle}* was just completed by ${assigneeName}. Great work, team! 💪`,
  `📅 ${completionDate}${linkLine}`,
].join('\n');

// Return single item — Slack node reads $json.message
return [{ json: { message } }];
8

Canvas > + > Code Node

Build the celebration message with a Code node

Add a Code node to assemble the final Slack message from all the data you've collected. This is where you compose the emoji-rich celebration text, inject the task title, assignee name, project name, and completion date. The Code node gives you full JavaScript access to all upstream node outputs via $node. Write the output as a single object with a 'message' key that the Slack node will consume.

  1. 1Click '+' after the contacts HTTP Request node
  2. 2Search for 'Code' and select the Code node (not Function)
  3. 3Set Language to 'JavaScript'
  4. 4Paste your message-building script into the editor (see Pro Tip below)
  5. 5Click 'Execute Node' and verify the output contains a formatted 'message' string
What you should see: The Code node output panel shows a single item with a 'message' field containing the fully formatted Slack celebration text including emojis, task title, assignee, and date.
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.

Paste this into the Code node in Step 8. It pulls task title, assignee name, completion date, and permalink from the three upstream HTTP Request nodes, formats the date to a readable string, handles missing assignees gracefully, and returns a single message object ready for the Slack node.

JavaScript — Code Node// Code Node: Build Wrike Milestone Celebration Slack Message
▸ Show code
// Code Node: Build Wrike Milestone Celebration Slack Message
// Runs after: Webhook → IF → HTTP Task Details → HTTP Contact Details
const taskData = $node['HTTP Request - Task Details'].json.data[0];

... expand to see full code

// Code Node: Build Wrike Milestone Celebration Slack Message
// Runs after: Webhook → IF → HTTP Task Details → HTTP Contact Details

const taskData = $node['HTTP Request - Task Details'].json.data[0];
const contactData = $node['HTTP Request - Contact Details'].json.data;

// Resolve assignee name — default to 'the team' if no assignee found
let assigneeName = 'the team';
if (contactData && contactData.length > 0) {
  const contact = contactData[0];
  assigneeName = `${contact.firstName} ${contact.lastName}`.trim();
}

// Format the completion date from ISO 8601 to readable string
const rawDate = taskData.updatedDate || new Date().toISOString();
const completionDate = new Date(rawDate).toLocaleDateString('en-US', {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
});

// Build the task title and permalink
const taskTitle = taskData.title || 'Untitled Milestone';
const permalink = taskData.permalink || '';
const linkLine = permalink ? `\n🔗 ${permalink}` : '';

// Compose the celebration message
const message = [
  `🎉 Milestone crushed! *${taskTitle}* was just completed by ${assigneeName}. Great work, team! 💪`,
  `📅 ${completionDate}${linkLine}`,
].join('\n');

// Return single item — Slack node reads $json.message
return [{ json: { message } }];
9

Canvas > + > Slack Node > Send Message

Connect the Slack node and configure the message

Add a Slack node after the Code node. Select 'Send Message' as the operation. Connect your Slack credentials (OAuth2 — you'll need to create a Slack app with chat:write scope). Set the Channel field to the target channel ID or name (e.g. #project-wins). Set the Message Text field to '{{ $json.message }}' to pull from the Code node output. Toggle 'Include Link Preview' off to keep the message clean.

  1. 1Click '+' after the Code node
  2. 2Search for 'Slack' and select the Slack node
  3. 3Set Resource to 'Message', Operation to 'Send'
  4. 4Click 'Credential for Slack API' and connect your Slack OAuth2 app
  5. 5Set Channel to your target channel (e.g. '#project-wins' or paste the channel ID)
  6. 6Set Message Text to '{{ $json.message }}'
  7. 7Click 'Execute Node' to send a test message
What you should see: A celebration message appears in your target Slack channel within a few seconds, with the correct task name, assignee, and date populated.
Common mistake — Slack's chat:write scope only allows the bot to post in channels it has been invited to. If the message silently fails with a 'not_in_channel' error, open Slack, go to the channel, and type /invite @YourBotName.
10

n8n Canvas > Workflow Settings > Error Workflow

Add error handling with an Error Trigger node

Production workflows need to surface failures. Add an Error Trigger node as a separate workflow (or use n8n's built-in error workflow setting). Go to Workflow Settings > Error Workflow and point it to a simple fallback workflow that sends a Slack DM to the workflow owner whenever this workflow fails. This catches Wrike API timeouts, Slack auth failures, or malformed payloads.

  1. 1Click the Settings icon (gear) in the top right of the canvas
  2. 2Click 'Error Workflow'
  3. 3Select an existing error-handler workflow or create a new one with an Error Trigger + Slack DM node
  4. 4Save the setting and close the panel
What you should see: The Workflow Settings panel shows the name of your error-handler workflow next to 'Error Workflow'. Any future execution failures will route there automatically.
11

n8n Canvas > Workflow Toggle (top right)

Activate the workflow

Click the toggle in the top right of the canvas to switch the workflow from Inactive to Active. n8n will now listen on the Production Webhook URL permanently. Confirm the Wrike webhook is pointed at the Production URL (not the Test URL). Mark a real milestone complete in Wrike and verify the Slack message fires within 30 seconds. Check the Executions log in n8n to confirm a successful run.

  1. 1Click the grey toggle switch in the top right corner of the canvas
  2. 2Confirm it turns orange/green and reads 'Active'
  3. 3Switch to Wrike and mark a milestone task complete
  4. 4Check the target Slack channel for the celebration message
  5. 5In n8n, click 'Executions' in the left sidebar to review the run log
What you should see: The Executions log shows a green 'Success' entry with the correct timestamp. The Slack channel shows your celebration message with real task and assignee data.

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 n8n for this if your team self-hosts or has privacy requirements that rule out cloud iPaaS tools, if you want to write a few lines of JavaScript to control the exact Slack message format without fighting a visual template builder, or if you're already running n8n for other Wrike or Slack workflows and want to keep everything in one place. The one scenario where you'd pick something else: if your team has zero technical users and nobody wants to touch a webhook registration or a Code node — Zapier's Wrike + Slack integration gets you a basic completion notification in 10 minutes with no API calls required.

Cost

The cost math is simple. This workflow runs 3 executions per milestone event: one for the Webhook trigger, one for the task details HTTP Request, and one for the contacts HTTP Request. (The IF node, Code node, and Slack node don't count as separate executions in n8n's billing model — they run within the same execution.) If your team closes 40 milestones per month, that's 40 executions. n8n Cloud's Starter plan includes 2,500 executions per month for $20. You will not get close to that limit with this workflow. Self-hosted n8n is free with no execution cap, making it the cheapest option at any volume.

Tradeoffs

Zapier has a native Wrike trigger called 'New Completed Task' that requires zero API setup — no webhook registration, no token management. For a simple notification, Zapier is genuinely faster to configure. The downside: you can't call the Wrike contacts API mid-zap without a paid Zapier plan and a multi-step Zap, and message formatting is limited to Zapier's text template syntax. Make (formerly Integromat) handles the multi-API-call pattern well with its HTTP module and has a visual router for per-project channel mapping, but the scenario builder takes longer to learn than n8n's canvas. Power Automate has a Wrike connector in preview but it's unreliable — field mappings break after Wrike API updates and Microsoft's update cycle for third-party connectors is slow. Pipedream is the closest alternative to n8n here: full Node.js, same webhook approach, and built-in Slack and Wrike API steps. The difference is cost — Pipedream's free tier caps at 10,000 invocations per month and then jumps to $19/month, while self-hosted n8n stays free indefinitely. For this specific workflow, n8n wins on cost and control.

Three things you'll hit after setup. First, Wrike's webhook payload structure is not well-documented for edge cases: if the task belongs to multiple parent folders (common when Wrike's folder hierarchy is deeply nested), parentIds is an array with multiple entries and your folder lookup will only resolve the first one — which may be a sub-folder, not the top-level project name. Test with a real milestone that has a complex hierarchy before launch. Second, Slack's Block Kit formatting is not available when you set the message in the plain-text Message field of n8n's Slack node — to use blocks, rich formatting, or buttons, you need to switch the Slack node to use the 'blocks' parameter and pass a JSON array, which requires updating the Code node output accordingly. Third, if your Wrike account is in a non-US data center (Wrike offers EU hosting), the API base URL changes from www.wrike.com/api/v4 to app-eu.wrike.com/api/v4 — using the wrong base URL returns a 401 even with a valid token.

Ideas for what to build next

  • Add a project name lookupThe current workflow displays the task title but not which project it belongs to. Add a third HTTP Request node that calls GET /folders/{{parentId}} to fetch the project name and include it in the Slack message — especially useful when multiple projects share similar milestone names.
  • Build a weekly milestone digestRun a second n8n workflow on a cron schedule every Friday that queries the Wrike API for all milestones completed that week and posts a single summary message to Slack instead of individual pings — better for high-velocity teams.
  • Create a Slack thread for milestone retrospectivesAfter the celebration message posts, use the Slack API's chat.postMessage with thread_ts to automatically start a threaded conversation asking the team what went well — turning each milestone into a lightweight retrospective prompt without leaving Slack.

Related guides

Was this guide helpful?
Slack + Wrike overviewn8n profile →