Intermediate~15 min setupCommunication & Project ManagementVerified April 2026
Slack logo
Todoist logo

How to Send Weekly Todoist Reports to Slack with Power Automate

A scheduled Power Automate flow that pulls completed Todoist tasks from the past 7 days, counts them by project, and posts a formatted summary message to a Slack channel every Monday morning.

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

Best for

Teams already in the Microsoft 365 ecosystem who want recurring leadership-facing Slack digests without writing code

Not ideal for

Teams needing real-time task notifications — use a webhook-based Zapier or Make flow instead

Sync type

scheduled

Use case type

reporting

Real-World Example

💡

A 12-person product team at a B2B SaaS company uses this to post every Monday at 9am to #product-updates with a count of tasks completed per project the previous week. Before this flow, the team lead spent 20 minutes every Friday manually screenshotting Todoist and pasting numbers into Slack. Now the message arrives automatically with zero manual effort, and leadership sees consistent formatting every single week.

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 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.

Todoist account with tasks completed in at least one project during the past 7 days (for test data)
Todoist API token — found under Settings > Integrations > Developer in the Todoist web app
Slack workspace where you have permission to post messages to the target channel
Power Automate account — a Microsoft 365 Business Basic license or higher includes Power Automate; a standalone Power Automate per-user plan also works
Permission to create OAuth connections in your Microsoft tenant — if IT restricts connector creation, request approval before starting

Field Mapping

Map these fields between your apps.

FieldAPI Name
Required
Task Contentcontent
Completed Atcompleted_at
Project IDproject_id
Slack Channel
Report Date Range
Total Task Count
3 optional fields▸ show
Task IDid
User IDuser_id
Due Datedue

Step-by-Step Setup

1

make.powerautomate.com > My flows > + New flow > Scheduled cloud flow

Create a new Scheduled cloud flow

Go to make.powerautomate.com and sign in. From the left sidebar click 'My flows', then click '+ New flow' at the top. Select 'Scheduled cloud flow' from the dropdown — this is the option that runs on a timer, which is exactly what weekly reporting needs. Give the flow a name like 'Weekly Todoist Report to Slack'.

  1. 1Click 'My flows' in the left sidebar
  2. 2Click '+ New flow' in the top menu bar
  3. 3Select 'Scheduled cloud flow'
  4. 4Enter a flow name: 'Weekly Todoist Report to Slack'
  5. 5Set the start date to the next Monday at 9:00 AM in your local timezone
What you should see: You should see the flow designer open with a single recurrence trigger block already on the canvas labeled 'Recurrence'.
Common mistake — Do not choose 'Automated cloud flow' — that waits for an event trigger. This report needs to run on a timer, so Scheduled is the correct type.
2

Flow canvas > Recurrence trigger > Show advanced options

Configure the recurrence schedule

Click the 'Recurrence' trigger block on the canvas to expand its settings. Set Interval to '1' and Frequency to 'Week'. Set 'On these days' to 'Monday'. Set 'At these hours' to '9' and 'At these minutes' to '0'. This schedules the flow to fire every Monday at 9:00 AM in whatever timezone the flow uses.

  1. 1Click the 'Recurrence' block to expand settings
  2. 2Set Interval to '1' and Frequency to 'Week'
  3. 3Click 'Show advanced options'
  4. 4Check 'Monday' under 'On these days'
  5. 5Set 'At these hours' to '9' and 'At these minutes' to '0'
What you should see: The Recurrence block summary should read 'Every 1 Week on Monday at 09:00'.
Common mistake — Power Automate's recurrence trigger runs in UTC by default unless you explicitly set the time zone field in advanced options. If your team is in EST, UTC 9:00 AM is 4:00 AM local — set the time zone field explicitly.
3

Flow canvas > + New step > Search connectors > Todoist > Get tasks

Connect your Todoist account

Click '+ New step' below the Recurrence trigger. In the search bar type 'Todoist' and select it from the connector list. Choose the action 'Get tasks'. When prompted, click 'Sign in' and authenticate with your Todoist credentials — Power Automate will store this as a named Connection you can reuse across flows.

  1. 1Click '+ New step'
  2. 2Type 'Todoist' in the search bar
  3. 3Select the Todoist connector
  4. 4Choose the action 'Get tasks'
  5. 5Click 'Sign in' and complete Todoist OAuth authentication
What you should see: The Todoist action block shows your account email in the connection field and displays the 'Get tasks' configuration panel.
Common mistake — The Power Automate Todoist connector uses the Todoist REST API v1, which only returns currently active tasks — it does NOT return completed tasks. You will need to add a separate HTTP action to call the Todoist Sync API endpoint for completed tasks in the next step.
Power Automate settings
Connection
Choose a connection…Add
click Add
Slack
Log in to authorize
Authorize Power Automate
popup window
Connected
green checkmark
4

Flow canvas > + New step > HTTP action

Fetch completed tasks via HTTP action

Because the native Todoist connector cannot retrieve completed tasks, add an HTTP action to call Todoist's Sync API directly. Click '+ New step', search for 'HTTP', and select the HTTP action. Set method to GET and URI to 'https://api.todoist.com/sync/v9/items/completed/get_all'. Add a header: Authorization = 'Bearer YOUR_TODOIST_API_TOKEN'. Add a query parameter 'since' using the expression for 7 days ago so you only pull the past week's completions.

  1. 1Click '+ New step'
  2. 2Search for 'HTTP' and select the HTTP connector
  3. 3Set Method to 'GET'
  4. 4Set URI to 'https://api.todoist.com/sync/v9/items/completed/get_all'
  5. 5Add Header: Key = 'Authorization', Value = 'Bearer ' followed by your Todoist API token
  6. 6Add Query Parameter: Key = 'since', Value = expression addDays(utcNow(), -7)
What you should see: The HTTP block shows green after a test run and the Body output contains a JSON array of completed task objects with fields like 'content', 'project_id', and 'completed_at'.
Common mistake — Your Todoist API token is found under Todoist Settings > Integrations > Developer > API token. Store it in Power Automate Environment Variables or Azure Key Vault — never paste it as plain text in the action block for a production flow.
5

Flow canvas > + New step > Data Operation > Parse JSON

Parse the JSON response

The HTTP action returns raw JSON text. Add a 'Parse JSON' action so Power Automate can reference individual fields from each completed task. Click '+ New step', search 'Parse JSON', and select it. Set Content to the Body output from the HTTP step. For the Schema, click 'Generate from sample' and paste a sample response from Todoist's API docs to auto-generate the schema.

  1. 1Click '+ New step'
  2. 2Search 'Parse JSON' and select it under Data Operation
  3. 3Click the Content field and select 'Body' from the HTTP step dynamic content
  4. 4Click 'Generate from sample'
  5. 5Paste a sample Todoist completed tasks JSON response and click 'Done'
What you should see: The Parse JSON block shows a valid schema with item properties like 'content', 'project_id', 'completed_at', and 'user_id' listed as available dynamic content fields.
Common mistake — If Todoist returns an empty array (no completions that week), the Parse JSON step will still succeed but downstream 'Apply to each' loops will simply execute zero times. Add a condition after this step to check if length(body('Parse_JSON')?['items']) is greater than 0 before building the message — otherwise Slack receives a confusingly empty report.
6

Flow canvas > + New step > Variables > Initialize variable

Count completions per project with a compose action

Add a 'Initialize variable' action to create an integer variable named 'TaskCount' set to 0. Then add an 'Apply to each' action, passing in the items array from Parse JSON. Inside the loop, add an 'Increment variable' action on TaskCount by 1. This gives you a total completed task count. For per-project breakdowns, add a second string variable 'ProjectLines' and use Append to string variable inside the loop to build one line per task with its project_id and content.

  1. 1Add 'Initialize variable': Name = 'TaskCount', Type = Integer, Value = 0
  2. 2Add 'Initialize variable': Name = 'ProjectLines', Type = String, Value = (empty)
  3. 3Add 'Apply to each' and set the input to the items array from Parse JSON
  4. 4Inside the loop, add 'Increment variable' on TaskCount by 1
  5. 5Inside the loop, add 'Append to string variable' on ProjectLines with value: concat('• ', items('Apply_to_each')?['content'], ' [', items('Apply_to_each')?['project_id'], ']', ' ')
What you should see: After a test run with sample data, the TaskCount variable holds the correct integer total and ProjectLines holds a newline-separated list of task names.
7

Flow canvas > + New step > Data Operation > Compose

Build the formatted report message

Add a 'Compose' action to assemble the full Slack message text. Use the expression editor to combine static text with the variables you built. Include the report week date range, total task count, and the ProjectLines string. This is the string you will pass directly into the Slack message body. Format it with Slack's mrkdwn syntax — asterisks for bold, newlines for spacing.

  1. 1Click '+ New step', search 'Compose', and select it
  2. 2Click the Inputs field and open the expression editor
  3. 3Enter the concat expression combining header text, TaskCount, and ProjectLines
  4. 4Include a date range header using formatDateTime(addDays(utcNow(),-7),'MMM d') and formatDateTime(utcNow(),'MMM d, yyyy')
  5. 5Preview the output by clicking 'Test' on the flow with sample data
What you should see: The Compose output preview shows a clean multi-line string like '*Weekly Progress Report: Jan 13 – Jan 19, 2025* ✅ Tasks completed: 14 • Finish onboarding doc [project_123] ...'
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.
8

Flow canvas > + New step > Slack > Post message

Connect your Slack account

Click '+ New step' and search for 'Slack'. Select the Slack connector, then choose the action 'Post message'. When the connection prompt appears, click 'Sign in' and authorize Power Automate to post to your Slack workspace. You'll be redirected to Slack's OAuth screen — make sure you're logged in to the correct workspace before approving.

  1. 1Click '+ New step'
  2. 2Search 'Slack' in the connector search bar
  3. 3Select 'Post message' action
  4. 4Click 'Sign in' in the connection panel
  5. 5Approve the OAuth request in the Slack authorization screen
What you should see: The Slack action block shows your workspace name in the connection field and displays the channel and message configuration fields.
Common mistake — The Power Automate Slack connector posts as the authenticated user by default, not as a bot. If leadership sees messages from a personal account name, create a dedicated Slack app with a bot token and use the HTTP connector to call Slack's chat.postMessage API instead.
9

Flow canvas > Slack > Post message > Channel + Message Text

Configure the Slack message

In the 'Post message' action, set the Channel field to the Slack channel where reports should go (e.g. #leadership-updates). Set the Message Text field to the Outputs value from your Compose action. Enable the 'As User' toggle if you want the message attributed to your account, or leave it off to post as the connected app name. Optionally set a Thread timestamp field blank so messages always post as new top-level messages.

  1. 1Click the Channel field and type or select your target channel name
  2. 2Click the Message Text field and select 'Outputs' from the Compose step in dynamic content
  3. 3Leave Thread Timestamp blank to ensure top-level posting
  4. 4Optionally set 'As User' based on your team's preference
What you should see: The Slack action block shows the correct channel name and the Compose output token in the Message Text field.
Common mistake — Channel names in Power Automate's Slack connector must be entered without the # symbol. Entering '#leadership-updates' instead of 'leadership-updates' causes the action to fail with a 'channel_not_found' error.
10

Flow designer toolbar > Save > Test > Manually > Run flow

Test the flow end-to-end

Click 'Save' in the top right, then click 'Test' and choose 'Manually'. Power Automate will run the flow immediately using live data. Watch the run history — each step shows a green checkmark or red X with the full input/output payload. Check your Slack channel to confirm the message arrived with correct formatting and accurate task counts.

  1. 1Click 'Save' in the top right toolbar
  2. 2Click 'Test' then select 'Manually'
  3. 3Click 'Run flow' to trigger an immediate execution
  4. 4Click each step in the run history to inspect its input/output JSON
  5. 5Open the target Slack channel to verify the message content
What you should see: All steps show green checkmarks in the run history, and your Slack channel shows the formatted weekly report message with the correct date range and task count.
Power Automate
▶ Test flow
executed
Slack
Todoist
Todoist
🔔 notification
received
11

make.powerautomate.com > My flows > [Flow name] > Run history

Enable the flow and monitor the first scheduled run

After a successful test, the flow is active but confirm it shows 'On' status in My flows. The first automated run will fire at your configured Monday 9:00 AM time. Check 'Run history' the following Monday to confirm it executed without errors. Set up an email alert under the flow's '...' menu > 'Edit run-only permissions' to get notified if the flow fails.

  1. 1Navigate to My flows and confirm your flow shows 'On' status
  2. 2Click the flow name to open its detail page
  3. 3Review 'Run history' after the first scheduled Monday run
  4. 4Click '...' on the flow card and set up failure alert emails
What you should see: The flow detail page shows a successful run entry in Run history with a green status after the first Monday execution.
Common mistake — Confirm your workflow timezone matches your business timezone — n8n uses the instance timezone by default. Also verify the workflow is saved and set to Active, since Schedule Triggers won't fire on inactive workflows.

Paste this expression into a Compose action placed after the Parse JSON step. It uses Power Automate's built-in expression language to build a grouped summary string — counting completions per project_id without needing a loop variable per project. Reference the Compose output in your Slack message field.

JavaScript — Code Step// Power Automate Compose action expression
▸ Show code
// Power Automate Compose action expression
// Groups completed tasks by project_id and builds a formatted summary
// Paste into the Inputs field of a Compose action using the Expression tab

... expand to see full code

// Power Automate Compose action expression
// Groups completed tasks by project_id and builds a formatted summary
// Paste into the Inputs field of a Compose action using the Expression tab

concat(
  '*Weekly Progress Report: ',
  formatDateTime(addDays(utcNow(), -7), 'MMM d'),
  ' – ',
  formatDateTime(utcNow(), 'MMM d, yyyy'),
  '*',
  '
✅ *Tasks completed: ',
  string(length(body('Parse_JSON')?['items'])),
  '*

',
  join(
    body('Parse_JSON')?['items'],
    '
'
  )
)

Scaling Beyond 500+ tasks completed per week across the workspace+ Records

If your volume exceeds 500+ tasks completed per week across the workspace records, apply these adjustments.

1

Handle API pagination

The Todoist Sync API returns a maximum of 200 items per request by default. If your team completes more than 200 tasks a week, add an 'offset' query parameter and loop the HTTP call until the returned count is less than the limit. Power Automate's Do Until loop handles this cleanly.

2

Cap Slack message length

Slack's chat.postMessage API has a 40,000 character limit per message. At high task volumes, listing every task individually will hit this. Switch to a project-level summary (counts per project) rather than individual task names to keep the message under the limit.

3

Batch variable appends carefully

Appending to a string variable inside an Apply to each loop with 500+ iterations creates 500+ sequential variable update calls. This dramatically slows the flow runtime and may hit Power Automate's 30-day action count limits on lower-tier plans. Switch to building an array variable and joining it once outside the loop.

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 Power Automate for this if your organization already runs on Microsoft 365. The Slack and HTTP connectors are included in your existing license, the recurrence scheduling is rock solid, and IT teams familiar with Azure can audit and govern these flows without learning a new tool. If your team is already using Make or Zapier for other automations and has no Microsoft footprint, the overhead of a Power Automate account just for this one flow isn't worth it — build it in Make instead where the HTTP module and scheduling are both on the free tier.

Cost

A Power Automate per-user plan costs $15/month. This flow uses roughly 12-15 actions per weekly run: recurrence trigger, HTTP call, Parse JSON, 2 variable inits, 1 Apply to each with ~10 iterations at average volume, 1 Compose, 1 Slack post. That's well under Power Automate's 5,000 actions/day limit even on the base plan. The real cost is the plan itself — $15/month for one flow is expensive. If you're already paying for Microsoft 365 Business Basic or higher, Power Automate is included and the marginal cost is $0. Zapier would charge $19.99/month (Starter) for the same flow. Make handles it on the free tier at this run volume. If you're not already in the Microsoft ecosystem, Make is cheaper by $15/month.

Tradeoffs

Make handles the Todoist completed-tasks HTTP call more cleanly — its HTTP module lets you chain requests with built-in pagination handling, and the JSON parse is automatic. For this specific use case, that saves one action block. Zapier's Formatter step makes the date range string easier to build without expression syntax, but Zapier can't natively call arbitrary HTTP endpoints on its Starter plan without a Webhook step workaround. n8n gives you the most control — you'd write the grouping logic in a Function node with 10 lines of JavaScript and handle pagination in a loop node, but that requires self-hosting or an n8n Cloud subscription. Power Automate is the right call here specifically when the flow owner is a business analyst comfortable with Microsoft tools but not a developer — the expression editor is more approachable than n8n code and the scheduler is more reliable than Zapier's free-tier polling delays.

Two things will bite you after setup. First, the Todoist Sync API uses Unix-style ISO 8601 timestamps in UTC, but Power Automate's formatDateTime function expects specific format strings — if you get the format pattern wrong, your date range header will show '01/01/0001' or throw an InvalidTemplate error at runtime. Test the expression in the Power Automate expression tester before going live. Second, Slack's Power Automate connector posts messages as the authenticated user's identity, not a named bot. Leadership will see messages from 'Sarah Chen' instead of 'Progress Bot', which creates confusion when Sarah leaves the company and the connection breaks. Plan from day one to use an HTTP action calling Slack's chat.postMessage with a bot token if clean branding matters to your stakeholders.

Ideas for what to build next

  • Add per-project task count breakdownExtend the Apply to each loop to group completions by project name. You'll need a second HTTP call to Todoist's /projects endpoint to resolve project_id values to human-readable names before building the Slack message.
  • Post to multiple Slack channels based on projectAdd a Switch action after the loop to route project-specific summaries to different channels — engineering completions to #eng-updates, marketing tasks to #marketing-updates — instead of one catch-all report.
  • Log each weekly report to a SharePoint listAdd a SharePoint 'Create item' action at the end of the flow to archive every report with its date, task count, and full message text. This gives leadership a searchable history without relying on Slack's message retention limits.

Related guides

Was this guide helpful?
Slack + Todoist overviewPower Automate profile →