Keep Notion and Todoist tasks in sync, always
Your tasks are “done” in Todoist, still “In progress” in Notion, and now you’re second-guessing which list to trust. That drift is sneaky. It starts as one missed update and turns into a weekly cleanup ritual.
Marketing managers feel it when campaigns have 30 moving parts. Agency owners run into it when clients want Notion visibility but the team lives in Todoist. And ops folks? They’re usually the ones asked to “just keep it aligned.” A Notion Todoist sync fixes the duplicate work so you update once and move on.
This workflow keeps tasks linked, prevents looping updates, and runs a daily repair pass for anything webhooks miss. You’ll see how it works, what you need, and what to customize so it fits your setup.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: Keep Notion and Todoist tasks in sync, always
flowchart LR
subgraph sg0["Schedule Flow"]
direction LR
n22["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Todoist"]
n23["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Notion"]
n24["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/compare.svg' width='40' height='40' /></div><br/>Compare Datasets"]
n25@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Exists/Completed in Notion", pos: "b", h: 48 }
n26["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Get Todoist Task"]
n27@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If Todoist ID exists", pos: "b", h: 48 }
n28["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Store Todoist ID"]
n29["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Mark as Incomplete in Todoist"]
n30["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Mark as Completed in Todoist"]
n31["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Delete Task in Todoist"]
n32@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items", pos: "b", h: 48 }
n33["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Get Notion Task"]
n34["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Update Task in Todoist"]
n35@{ icon: "mdi:swap-vertical", form: "rounded", label: "Pick Todoist Fields", pos: "b", h: 48 }
n36["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Map Notion to Todoist"]
n37["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Update task in Todoist befor.."]
n38["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Map Notion to Todoist1"]
n39["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Handle empty dates"]
n40["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Handle empty dates1"]
n41["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Handle empty dates2"]
n42["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Create task in Todoist"]
n43@{ icon: "mdi:swap-vertical", form: "rounded", label: "Add project ID", pos: "b", h: 48 }
n44["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Lock Todoist ID"]
n45@{ icon: "mdi:cog", form: "rounded", label: "Generate UUID", pos: "b", h: 48 }
n46["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Update section (Sync API)"]
n47@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Status changed", pos: "b", h: 48 }
n48@{ icon: "mdi:cog", form: "rounded", label: "Aggregate", pos: "b", h: 48 }
n49@{ icon: "mdi:swap-vertical", form: "rounded", label: "Prepare Batching Items", pos: "b", h: 48 }
n50@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items1", pos: "b", h: 48 }
n51@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Status is Done", pos: "b", h: 48 }
n52["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Lock Todoist ID1"]
n53["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Lock Todoist ID2"]
n54["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Update task in Todoist"]
n55@{ icon: "mdi:swap-vertical", form: "rounded", label: "Get mapped item", pos: "b", h: 48 }
n56@{ icon: "mdi:swap-vertical", form: "rounded", label: "Get mapped item1", pos: "b", h: 48 }
n57@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger", pos: "b", h: 48 }
n58@{ icon: "mdi:swap-vertical", form: "rounded", label: "Prepare summary data", pos: "b", h: 48 }
n59@{ icon: "mdi:swap-vertical", form: "rounded", label: "Prepare summary data1", pos: "b", h: 48 }
n60["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Merge"]
n61@{ icon: "mdi:swap-vertical", form: "rounded", label: "Prepare summary data2", pos: "b", h: 48 }
n62@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Filter out status changes", pos: "b", h: 48 }
n63["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Map Todoist to Notion"]
n64@{ icon: "mdi:swap-vertical", form: "rounded", label: "Map summary fields", pos: "b", h: 48 }
n65["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/html.dark.svg' width='40' height='40' /></div><br/>Convert to HTML Table"]
n66["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/html.dark.svg' width='40' height='40' /></div><br/>Generate email body"]
n67@{ icon: "mdi:swap-vertical", form: "rounded", label: "Get mapped item2", pos: "b", h: 48 }
n68@{ icon: "mdi:message-outline", form: "rounded", label: "Gmail", pos: "b", h: 48 }
n69["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Merge summary"]
n70@{ icon: "mdi:swap-vertical", form: "rounded", label: "Globals", pos: "b", h: 48 }
n153@{ icon: "mdi:location-exit", form: "rounded", label: "Retry limit reached", pos: "b", h: 48 }
n154@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set tries", pos: "b", h: 48 }
n155@{ icon: "mdi:swap-vertical", form: "rounded", label: "Update tries", pos: "b", h: 48 }
n156@{ icon: "mdi:cog", form: "rounded", label: "Wait", pos: "b", h: 48 }
n157@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Catch known error", pos: "b", h: 48 }
n158@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If tries left", pos: "b", h: 48 }
n156 --> n155
n60 --> n50
n60 --> n69
n23 --> n36
n22 --> n35
n48 --> n46
n154 --> n26
n155 --> n158
n45 --> n49
n158 --> n154
n158 --> n153
n69 --> n62
n43 --> n27
n47 --> n56
n51 --> n30
n51 --> n31
n33 --> n32
n55 --> n60
n32 --> n25
n32 --> n33
n24 --> n41
n24 --> n39
n24 --> n32
n26 --> n29
n26 --> n157
n56 --> n60
n67 --> n69
n50 --> n45
n57 --> n23
n57 --> n22
n57 --> n70
n28 --> n67
n157 --> n42
n157 --> n156
n39 --> n34
n64 --> n65
n66 --> n68
n40 --> n37
n41 --> n43
n35 --> n24
n27 --> n154
n27 --> n42
n58 --> n69
n65 --> n66
n36 --> n24
n63 --> n64
n59 --> n69
n61 --> n69
n42 --> n28
n42 --> n44
n31 --> n61
n38 --> n40
n49 --> n48
n34 --> n47
n34 --> n53
n34 --> n58
n54 --> n55
n62 --> n63
n46 --> n50
n25 --> n38
n25 --> n31
n30 --> n59
n29 --> n54
n29 --> n44
n37 --> n51
n37 --> n52
end
subgraph sg1["Flow 2"]
direction LR
n72@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Differences exist1", pos: "b", h: 48 }
n73@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Requires completion change1", pos: "b", h: 48 }
n74["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Create task in Notion"]
n75["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Update task in Notion"]
n76["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Mark as Done in Notion"]
n77["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Mark as Obsolete in Notion"]
n78["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Mark as In Progress in Notion"]
n79@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Only continue if not locked", pos: "b", h: 48 }
n80["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Lock Notion ID"]
n81["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Check if Todoist ID is locked"]
n82["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Update Description in Todoist"]
n83@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Description has changed in T..", pos: "b", h: 48 }
n84["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Update Description in Todoist1"]
n85@{ icon: "mdi:cog", form: "rounded", label: "Generate UUID1", pos: "b", h: 48 }
n86["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Update section (Sync API)1"]
n87["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Get Backlog Section ID"]
n88@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Notion Task not found", pos: "b", h: 48 }
n89["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Check if creating flag exists1"]
n90@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Only continue if flag does n..", pos: "b", h: 48 }
n91["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Set creating flag1"]
n92@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Neither focussed nor planned1", pos: "b", h: 48 }
n93["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Mark as Focussed in Notion"]
n94@{ icon: "mdi:cog", form: "rounded", label: "Todoist trigger reference", pos: "b", h: 48 }
n95["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Get Notion Task2"]
n96@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Notion Task found1", pos: "b", h: 48 }
n97@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch by Event", pos: "b", h: 48 }
n98@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If event is not :deleted", pos: "b", h: 48 }
n99@{ icon: "mdi:cog", form: "rounded", label: "Execution Data", pos: "b", h: 48 }
n100@{ icon: "mdi:cog", form: "rounded", label: "Execution Data1", pos: "b", h: 48 }
n101@{ icon: "mdi:cog", form: "rounded", label: "Execution Data2", pos: "b", h: 48 }
n102@{ icon: "mdi:cog", form: "rounded", label: "Execution Data3", pos: "b", h: 48 }
n103@{ icon: "mdi:cog", form: "rounded", label: "Execution Data4", pos: "b", h: 48 }
n104@{ icon: "mdi:swap-vertical", form: "rounded", label: "Globals1", pos: "b", h: 48 }
n105["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Map Todoist to Notion1"]
n106["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Get Todoist Task1"]
n107["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Get Notion Task1"]
n141["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Todoist Webhook"]
n146@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch by project", pos: "b", h: 48 }
n150@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Due date empty", pos: "b", h: 48 }
n151@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Has not been completed?", pos: "b", h: 48 }
n152@{ icon: "mdi:cog", form: "rounded", label: "End here", pos: "b", h: 48 }
n165@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set tries2", pos: "b", h: 48 }
n166@{ icon: "mdi:swap-vertical", form: "rounded", label: "Update tries2", pos: "b", h: 48 }
n167@{ icon: "mdi:cog", form: "rounded", label: "Wait2", pos: "b", h: 48 }
n168@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Catch known error2", pos: "b", h: 48 }
n169@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If tries left2", pos: "b", h: 48 }
n170@{ icon: "mdi:location-exit", form: "rounded", label: "Retry limit reached2", pos: "b", h: 48 }
n171["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Turn Markdown into Notion Bl.."]
n172@{ icon: "mdi:swap-vertical", form: "rounded", label: "Handle each block separately", pos: "b", h: 48 }
n173["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Append Notion Block"]
n167 --> n166
n165 --> n106
n166 --> n169
n150 --> n93
n99 --> n81
n85 --> n86
n169 --> n165
n169 --> n170
n100 --> n107
n101 --> n82
n101 --> n80
n102 --> n97
n103 --> n77
n97 --> n72
n97 --> n83
n97 --> n73
n141 --> n146
n107 --> n88
n95 --> n96
n106 --> n105
n106 --> n168
n146 --> n94
n168 --> n152
n168 --> n167
n72 --> n75
n72 --> n150
n96 --> n103
n91 --> n87
n173 --> n80
n74 --> n101
n74 --> n171
n88 --> n89
n88 --> n102
n75 --> n80
n87 --> n85
n87 --> n74
n105 --> n100
n76 --> n80
n151 --> n78
n151 --> n92
n151 --> n76
n98 --> n165
n98 --> n95
n94 --> n99
n94 --> n104
n93 --> n80
n77 --> n80
n79 --> n98
n73 --> n151
n172 --> n173
n81 --> n79
n78 --> n80
n92 --> n93
n89 --> n90
n171 --> n172
n83 --> n84
n90 --> n91
end
subgraph sg2["Flow 3"]
direction LR
n108@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Requires completion change", pos: "b", h: 48 }
n109@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Has been completed?", pos: "b", h: 48 }
n110@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Differences exist", pos: "b", h: 48 }
n111@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Only continue if not locked1", pos: "b", h: 48 }
n112["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Check if Notion ID is locked"]
n113["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Get Notion task"]
n114["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Check if creating flag exists"]
n115@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Only continue if flag does n..", pos: "b", h: 48 }
n116["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Set creating flag"]
n117@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Todoist ID exists?", pos: "b", h: 48 }
n118@{ icon: "mdi:swap-vertical", form: "rounded", label: "Get todoist ID", pos: "b", h: 48 }
n119@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Todoist ID exists", pos: "b", h: 48 }
n120@{ icon: "mdi:swap-vertical", form: "rounded", label: "Get todoist ID1", pos: "b", h: 48 }
n121@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Status changed but not empty", pos: "b", h: 48 }
n122@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Status is Obsolete?", pos: "b", h: 48 }
n123@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Status is not Done", pos: "b", h: 48 }
n124@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Neither focussed nor planned", pos: "b", h: 48 }
n125@{ icon: "mdi:cog", form: "rounded", label: "Notion trigger reference", pos: "b", h: 48 }
n126["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Notion Webhook"]
n127["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Store Todoist ID1"]
n128["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Mark as Completed in Todoist1"]
n129["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Update task in Todoist1"]
n130@{ icon: "mdi:swap-vertical", form: "rounded", label: "Globals2", pos: "b", h: 48 }
n131["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Mark as Incomplete in Todoist1"]
n132@{ icon: "mdi:cog", form: "rounded", label: "Generate UUID2", pos: "b", h: 48 }
n133["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Update section (Sync API)2"]
n134["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/redis.svg' width='40' height='40' /></div><br/>Lock Todoist ID4"]
n135["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Delete Task in Todoist2"]
n136["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Map Notion to Todoist2"]
n137["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/todoist.svg' width='40' height='40' /></div><br/>Get Todoist Task2"]
n138["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Create task in Todoist1"]
n139@{ icon: "mdi:cog", form: "rounded", label: "Execution Data5", pos: "b", h: 48 }
n140@{ icon: "mdi:cog", form: "rounded", label: "Execution Data6", pos: "b", h: 48 }
n143@{ icon: "mdi:swap-vertical", form: "rounded", label: "Extract IDs", pos: "b", h: 48 }
n144@{ icon: "mdi:swap-vertical", form: "rounded", label: "Split out Notion changes", pos: "b", h: 48 }
n145@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Body is array?", pos: "b", h: 48 }
n159@{ icon: "mdi:location-exit", form: "rounded", label: "Retry limit reached1", pos: "b", h: 48 }
n160@{ icon: "mdi:swap-vertical", form: "rounded", label: "Set tries1", pos: "b", h: 48 }
n161@{ icon: "mdi:swap-vertical", form: "rounded", label: "Update tries1", pos: "b", h: 48 }
n162@{ icon: "mdi:cog", form: "rounded", label: "Wait1", pos: "b", h: 48 }
n163@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Catch known error1", pos: "b", h: 48 }
n164@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If tries left1", pos: "b", h: 48 }
n162 --> n161
n160 --> n137
n143 --> n125
n161 --> n164
n145 --> n144
n145 --> n125
n132 --> n133
n118 --> n134
n164 --> n160
n164 --> n159
n126 --> n145
n139 --> n112
n140 --> n122
n113 --> n136
n120 --> n134
n110 --> n129
n137 --> n110
n137 --> n108
n137 --> n121
n137 --> n163
n116 --> n138
n119 --> n135
n163 --> n123
n163 --> n162
n123 --> n114
n117 --> n160
n117 --> n114
n109 --> n128
n109 --> n131
n122 --> n119
n122 --> n124
n136 --> n140
n138 --> n127
n138 --> n134
n135 --> n120
n129 --> n118
n125 --> n130
n125 --> n139
n144 --> n143
n108 --> n109
n133 --> n118
n112 --> n111
n124 --> n119
n124 --> n117
n111 --> n113
n121 --> n132
n114 --> n115
n128 --> n118
n131 --> n118
n115 --> n116
end
subgraph sg3["Notion-Todoist Sync Setup Helper Flow"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Get projects"]
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Get sections"]
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/notion.dark.svg' width='40' height='40' /></div><br/>Get Notion Databases"]
n3["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Prep Dropdown"]
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Prep Dropdown1"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Generate config"]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/form.svg' width='40' height='40' /></div><br/>Choose Notion Database"]
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/form.svg' width='40' height='40' /></div><br/>Choose Todoist Project"]
n17["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Get Notion Database ID"]
n18["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Get Todoist Project ID"]
n19["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/form.svg' width='40' height='40' /></div><br/>Notion-Todoist Sync Setup He.."]
n21["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/form.svg' width='40' height='40' /></div><br/>Return config JSON"]
n0 --> n4
n1 --> n5
n3 --> n6
n4 --> n7
n5 --> n21
n2 --> n3
n6 --> n17
n7 --> n18
n17 --> n0
n18 --> n1
n19 --> n2
end
subgraph sg4["Flow 5"]
direction LR
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Verify security token", pos: "b", h: 48 }
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Get variables"]
n13["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>OAuth redirect"]
n14["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Exchange Tokens"]
n15["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Respond with success"]
n16["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Respond with error"]
n11 --> n8
n13 --> n11
n14 --> n15
n14 --> n16
n8 --> n14
n8 --> n16
end
subgraph sg5["Todoist Webhook Setup Helper Flow"]
direction LR
n9@{ icon: "mdi:cog", form: "rounded", label: "Generate security token", pos: "b", h: 48 }
n10["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Store variables"]
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/form.svg' width='40' height='40' /></div><br/>Redirect to Auth Page"]
n20["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/form.svg' width='40' height='40' /></div><br/>Todoist Webhook Setup Helper"]
n10 --> n12
n9 --> n10
n20 --> n9
end
subgraph sg6["Flow 7"]
direction LR
n142@{ icon: "mdi:cog", form: "rounded", label: "Execute Workflow", pos: "b", h: 48 }
n147["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Webhook"]
n148@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch", pos: "b", h: 48 }
n149@{ icon: "mdi:cog", form: "rounded", label: "Execute Workflow1", pos: "b", h: 48 }
n148 --> n142
n148 --> n149
n147 --> n148
end
subgraph sg7["Execute Workflow Flow"]
direction LR
n71@{ icon: "mdi:play-circle", form: "rounded", label: "Execute Workflow Trigger", pos: "b", h: 48 }
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n57,n19,n20,n71 trigger
class n25,n27,n47,n51,n62,n157,n158,n72,n73,n79,n83,n88,n90,n92,n96,n97,n98,n146,n150,n151,n168,n169,n108,n109,n110,n111,n115,n117,n119,n121,n122,n123,n124,n145,n163,n164,n8,n148 decision
class n23,n28,n33,n44,n52,n53,n74,n75,n76,n77,n78,n80,n81,n89,n91,n93,n95,n107,n173,n112,n113,n114,n116,n127,n134,n2 database
class n34,n37,n42,n46,n54,n86,n141,n126,n129,n133,n138,n0,n1,n13,n14,n15,n16,n147 api
class n36,n38,n39,n40,n41,n63,n87,n105,n171,n136,n3,n4,n5,n17,n18,n11,n10 code
class n142 disabled
class n147 disabled
class n148 disabled
class n149 disabled
class n71 disabled
classDef customIcon fill:none,stroke:none
class n22,n23,n24,n26,n28,n29,n30,n31,n33,n34,n36,n37,n38,n39,n40,n41,n42,n44,n46,n52,n53,n54,n60,n63,n65,n66,n69,n74,n75,n76,n77,n78,n80,n81,n82,n84,n86,n87,n89,n91,n93,n95,n105,n106,n107,n141,n171,n173,n112,n113,n114,n116,n126,n127,n128,n129,n131,n133,n134,n135,n136,n137,n138,n0,n1,n2,n3,n4,n5,n6,n7,n17,n18,n19,n21,n11,n13,n14,n15,n16,n10,n12,n20,n147 customIcon
The Challenge: Task Lists That Drift Out of Sync
Managing work in two places sounds harmless until the first busy week hits. Someone updates a due date in Todoist on their phone. Another person changes the task status in Notion during a planning session. Now you’ve got two versions of the truth, and the team wastes time reconciling details instead of finishing work. Worse, the mistakes are quiet: a task looks unassigned, a deadline slips a day, or a “deleted” item was actually something you needed for reporting. After a while, people stop trusting the system and start pinging each other for confirmation.
The friction compounds. Here’s where it usually breaks down.
- Updates happen in the wrong app, so you end up doing the same edit twice.
- Webhooks are not perfect, and missed events create little pockets of inconsistency that grow over time.
- Two-way syncing can create “ping-pong” loops where one update triggers another, then another.
- Deleting tasks is risky, because “oops” deletions are permanent and reporting gets messy.
The Fix: Two-Way Notion ↔ Todoist Sync (With Safeguards)
This automation uses real-time webhooks from both Notion and Todoist to keep tasks aligned within a couple of seconds. When a change comes in, the workflow doesn’t blindly overwrite the other side. It first fetches the current version of the task from both systems, compares what changed, and only then applies the right update. To prevent infinite loops (an update in Notion triggers Todoist, which triggers Notion again), it uses Redis to “lock” that task ID for about 15 seconds. Notion is treated as the primary source of truth, and instead of hard-deleting tasks, the workflow uses an “Obsolete” status so you don’t lose history by accident. On top of that, a daily full sync runs to repair any inconsistencies that slipped through because, frankly, webhooks can’t be trusted 100%.
The workflow starts when Notion or Todoist sends a webhook about a task change. Then n8n retrieves both task records, checks what changed, and updates the other app while a short Redis lock prevents repeat-trigger loops. Finally, the daily sync does a sweep and can send a summary if it had to fix anything.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say your team handles 40 tasks a week and you typically touch each task twice: once in Notion during planning, once in Todoist while executing. If each “double update” costs maybe 1–2 minutes, that’s roughly 1–2 hours a week burned on busywork, plus the occasional cleanup session when statuses drift. With this workflow, you update in either app and let the sync handle the rest (plus the daily full sync that repairs mismatches). For many teams, that’s a couple hours back every week and a lot fewer “wait, which one is right?” moments.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Notion for your task database and statuses.
- Todoist to execute tasks and manage projects.
- Redis (get it from Redis Cloud or your own server)
Skill level: Intermediate. You’ll be connecting accounts, matching database properties, and doing careful mapping once.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A task changes in Notion or Todoist. Each side has a registered webhook, so edits (create, update, status changes) can kick off the sync within seconds.
The workflow fetches the current truth from both apps. Instead of assuming the webhook payload is complete, n8n retrieves the latest task data from Notion and Todoist, then compares fields like name, due date, and status.
A short Redis “lock” prevents infinite loops. When a task syncs from Notion to Todoist (or the other direction), Redis blocks re-processing for about 15 seconds using the task ID, so you don’t get a noisy back-and-forth.
The other side updates, and a daily full sync repairs edge cases. Status mapping handles “Done” and “Obsolete,” the Todoist task ID is stored in Notion so items stay linked, and a scheduled daily workflow fixes drift if a webhook was missed.
You can easily modify field mapping and status rules to match your internal process. See the full implementation guide below for customization options.
Watch Out For
- Notion credentials can expire or lack access to the right workspace/database. If things break, check the integration token permissions and the database share settings first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Redis misconfiguration causes the nastiest failures because loop protection depends on it. If you see repeated sync triggers, verify the Redis connection and confirm the lock key is being written.
Common Questions
Plan for about 60–90 minutes if your Notion database and Todoist project already exist.
Yes, but you’ll want someone detail-oriented to handle the field mapping carefully. No coding, just configuration and testing.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in Redis hosting (often free or cheap at small volume).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
You’ll mainly customize the mapping rules: Notion “Status” to Todoist sections, Notion “Priority” to Todoist priority, and what “Obsolete” should do on the Todoist side. If your team uses extra fields (like “Owner” or “Client”), add them to the mapping in the Set/Edit Fields steps and the update requests. Many teams also change the “Notion is the source of truth” behavior so Todoist can override due dates while Notion owns status. Test those rules on a small project first, because the sync is fast and mistakes propagate quickly.
Usually it’s permissions: the integration token can’t see the database, or the database wasn’t shared with the integration. It can also be a stale credential in n8n, so re-save the Notion credential and reselect it in the Notion nodes. If it fails only on certain tasks, double-check the database property names match exactly (case matters) and that your “Status” options include “Obsolete.”
For most small teams, it comfortably handles day-to-day task changes in real time, because each sync run is just a handful of API calls plus a Redis lock. On n8n Cloud Starter, you can typically support a steady stream of updates as long as you’re not syncing huge databases every few minutes. If you self-host, capacity mostly depends on your server and API rate limits from Notion/Todoist, not n8n itself.
Often, yes. Two-way sync with loop prevention is where simpler tools get fiddly, and you can end up paying more just to add branching logic and retries. n8n also gives you the self-hosting option, which is handy if you want lots of executions without watching a meter. The tradeoff is setup time: you’ll spend longer mapping things once. If you want, Talk to an automation expert and we’ll tell you quickly if this is worth it for your volume.
Once this is running, your task system stops being fragile. You’ll spend less time “maintaining the list” and more time actually finishing what’s on it.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.