This workflow corresponds to n8n.io template #4186 — we link there as the canonical source.
This workflow follows the Agent → Chat Trigger recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "3o3yvFscE37KIUjy",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "ULTIMATE Personal Todoist Agent",
"tags": [],
"nodes": [
{
"id": "e83836e8-890e-4c64-bec7-6030e118c8f3",
"name": "Todoist Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
260,
0
],
"parameters": {
"options": {
"maxIterations": 100,
"systemMessage": "=You are TodoistAssistant, a friendly AI who can read and write the user\u2019s Todoist data. When given a natural-language request:\n\n\u2022 Determine the single best action to take (e.g. create a task, list overdue tasks, update a project, add a comment).\n\u2022 If one action isn\u2019t enough, you may perform up to two steps in sequence (for example, look up the Inbox project ID, then create a task).\n\u2022 Fill in only the parameters the user has specified; leave out any field that\u2019s not mentioned.\n\u2022 Provide a link to a task or project if user asks for it.\n\u2022 Always reply with a brief, user-facing confirmation or error message.\n\u2022 Never expose internal IDs, OAuth tokens, raw JSON responses, your own planning steps or raw tools instructions.\n\u2022 Answer in the same language the user used.",
"returnIntermediateSteps": false
}
},
"typeVersion": 1.7
},
{
"id": "36b24a37-4b11-4f5c-b3dd-a954f6043924",
"name": "When Executed by Another Workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
0,
0
],
"parameters": {
"workflowInputs": {
"values": [
{
"name": "sessionID"
},
{
"name": "chatInput"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "f9f428fb-774b-4290-9d9a-cccedf0a3874",
"name": "Orchestrator",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
260,
-400
],
"parameters": {
"options": {}
},
"typeVersion": 1.9
},
{
"id": "b3ac4991-69da-42c9-bae4-26de2269fb44",
"name": "When chat message received",
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
"position": [
0,
-400
],
"parameters": {
"options": {}
},
"typeVersion": 1.1
},
{
"id": "6a798f48-c82f-47ea-bf95-9bffa2db62ec",
"name": "Call Todoist Agent",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
500,
-180
],
"parameters": {
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $workflow.id }}"
},
"description": "Call this tool to get info about user's tasks and manage them.",
"workflowInputs": {
"value": {
"chatInput": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('chatInput', ``, 'string') }}",
"sessionID": "={{ $input.item.json.sessionId }}"
},
"schema": [
{
"id": "sessionID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "sessionID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "chatInput",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "chatInput",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"typeVersion": 2.2
},
{
"id": "80dad4ec-d119-4658-805a-26bf750c4def",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
80,
220
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "chatgpt-4o-latest",
"cachedResultName": "chatgpt-4o-latest"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "5fe3733a-212a-470a-8aa7-93faa04f5d68",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
340,
-180
],
"parameters": {},
"typeVersion": 1.3
},
{
"id": "165ee878-007e-4fff-9d06-0c1b718b7fdb",
"name": "OpenAI Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
160,
-180
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "chatgpt-4o-latest",
"cachedResultName": "chatgpt-4o-latest"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "555662ec-c297-41ea-bd1c-8314fc9d7267",
"name": "Get All Tasks",
"type": "n8n-nodes-base.todoistTool",
"position": [
280,
220
],
"parameters": {
"filters": {
"filter": "={{ $fromAI(\"filter\", \"\", \"string\") }}"
},
"operation": "getAll",
"returnAll": true,
"authentication": "oAuth2",
"descriptionType": "manual",
"toolDescription": "=List tasks via the Todoist \u201cadvanced filter\u201d syntax.\n\nParameters \n\u2022 filter (string) \u2013 main query. Build it from the user\u2019s words using Todoist\u2019s grammar: \n \u203a Relative dates: today, tomorrow, next 7 days, overdue \n \u203a Absolute dates: 20 May, 2025-06-01 \n \u203a Priority: p1 \u2026 p4 (p1 is normal, p4 is extremely high)\n \u203a Labels: @reading, @\u0437\u0432\u043e\u043d\u043e\u043a (label names are case-insensitive) \u2014 call label_get_all to see acceptable ones \n \u203a Projects / Sections: ##Project Name / ##Project::Section \u2014 call project_get_all to see acceptable ones\n \u203a No date: no date \n \u203a Boolean operators: & (AND), | (OR), ! (NOT) \n \u203a Parentheses allowed.\n\nIt's more reliable to use IDs instead of names in query.\n\nNever populate ids, projectId, sectionId, or labelId unless the user provided the exact numeric value (> 0), and in that case omit filter.\n\nCombine multiple clauses with **&** unless the user explicitly says \u201c\u0438\u043b\u0438\u201d / \u201cor\u201d.\n\nIf the filter includes @label, assume the label exists; the agent must have already called \"Get All Labels\".\n\nIf the user asks about available filters, mind calling \"Get All Labels\" to provide correct labels.\n\nIf the user asks about available filters, mind calling \"Get All Projects\" to provide correct projects.\n\n\u2022 lang \u2013 (string) user language code; pass \u201cru\u201d if the request was in Russian, otherwise omit.\n\nNever pass ids, projectId, sectionId, or labelId unless the user gave the exact numeric value (>0).\n\nOutput only a concise list (e.g. \u201cX overdue tasks: \u2026\u201d) and hide raw IDs."
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "13b0cc4d-e965-40ec-87a1-71cf09d2e1b7",
"name": "Get a Task",
"type": "n8n-nodes-base.todoistTool",
"position": [
440,
220
],
"parameters": {
"taskId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Task_ID', ``, 'string') }}",
"operation": "get",
"authentication": "oAuth2",
"descriptionType": "manual",
"toolDescription": "Fetch a single task by task_id and show user-readable fields (content, due date, status). Required: Task_ID. Do not expose internal IDs."
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "0e1ab623-99b2-444c-bfa1-5b9175b48cd7",
"name": "Create a Task",
"type": "n8n-nodes-base.todoistTool",
"position": [
600,
220
],
"parameters": {
"labels": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Label_Names_or_IDs', ``, 'string') }}",
"content": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Content', ``, 'string') }}",
"options": {
"dueLang": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Due_String_Locale', ``, 'string') }}",
"section": "={{ $fromAI('Section_ID', ``, 'number') }}",
"parentId": "={{ $fromAI('Parent_ID', ``, \"number\") }}",
"priority": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Priority', ``, 'number') }}",
"dueString": "={{ $fromAI('Due_String', ``, 'string') }}",
"description": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Description', ``, 'string') }}",
"dueDateTime": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Due_Date_Time', ``, 'string') }}"
},
"project": {
"__rl": true,
"mode": "id",
"value": "={{ $fromAI('Project_ID','','string') || undefined }}"
},
"authentication": "oAuth2",
"descriptionType": "manual",
"toolDescription": "Create a new task.\nRequired: content.\nOptional: project_id, section_id, labels, due_date_time, priority, description.\n\nIf the user does NOT mention a project, find a suitable one calling project_get_all. If nothing is suitable, call this task **without** a project_id (Todoist will put it in Inbox automatically).\nReturn a short confirmation, no raw IDs."
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "96fcd691-7931-4567-8827-deab0a982f78",
"name": "Update a Task",
"type": "n8n-nodes-base.todoistTool",
"position": [
760,
220
],
"parameters": {
"taskId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Task_ID', ``, 'string') }}",
"operation": "update",
"updateFields": {
"labels": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Label_Names_or_IDs', ``, 'string') }}",
"content": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Content', ``, 'string') }}",
"dueLang": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Due_String_Locale', ``, 'string') }}",
"priority": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Priority', ``, 'number') }}",
"dueString": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Due_String', ``, 'string') }}",
"description": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Description', ``, 'string') }}",
"dueDateTime": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Due_Date_Time', ``, 'string') }}"
},
"authentication": "oAuth2",
"descriptionType": "manual",
"toolDescription": "Update an existing task\u2019s properties (content, description, due date, labels, priority). Required: task_id."
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "6cc4b5f1-db09-4abd-a7fc-96cfa7abc39a",
"name": "Mark Task as Done",
"type": "n8n-nodes-base.todoistTool",
"position": [
920,
220
],
"parameters": {
"taskId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Task_ID', ``, 'string') }}",
"operation": "close",
"authentication": "oAuth2",
"descriptionType": "manual",
"toolDescription": "Mark the given task as completed. Required: Task_ID."
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "20471ae9-8cc5-4996-8880-51a2db040be5",
"name": "Reopen a Task",
"type": "n8n-nodes-base.todoistTool",
"position": [
1080,
220
],
"parameters": {
"taskId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Task_ID', ``, 'string') }}",
"operation": "reopen",
"authentication": "oAuth2",
"descriptionType": "manual",
"toolDescription": "Reopen a previously completed task. Required: Task_ID.\n"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "6c7ab7dc-075e-49c9-a339-a89a52ce6d6a",
"name": "Move a Task",
"type": "n8n-nodes-base.todoistTool",
"position": [
1260,
220
],
"parameters": {
"taskId": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Task_ID', ``, 'string') }}",
"options": {
"parent": "={{ $fromAI('Parent_ID', ``, 'number') }}",
"section": "={{ $fromAI('Section_ID', ``, 'number') }}"
},
"project": {
"__rl": true,
"mode": "id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Project_Name_or_ID', ``, 'string') }}"
},
"operation": "move",
"authentication": "oAuth2",
"descriptionType": "manual",
"toolDescription": "Move a task to another project / section or make it a sub-task. Required: Task_ID; provide project_id/section_id/parent_id as needed."
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "d37afed5-4089-44c4-bd90-deb05e65af2a",
"name": "Get All Projects",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
280,
400
],
"parameters": {
"url": "https://api.todoist.com/rest/v2/projects",
"options": {
"pagination": {
"pagination": {
"parameters": {
"parameters": [
{
"name": "cursor",
"value": "={{ $response.next_cursor }}"
}
]
},
"requestInterval": 10
}
}
},
"authentication": "predefinedCredentialType",
"toolDescription": "Return the user\u2019s full project list. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "c22513f5-71e9-48ce-bce3-a26681e95fae",
"name": "Get a Project",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
440,
400
],
"parameters": {
"url": "={{ `https://api.todoist.com/rest/v2/projects/${$fromAI('Project_ID','','string')}` }}",
"options": {
"pagination": {
"pagination": {
"parameters": {
"parameters": [
{
"name": "cursor",
"value": "={{ $response.next_cursor }}"
}
]
},
"requestInterval": 10
}
}
},
"authentication": "predefinedCredentialType",
"toolDescription": "Fetch one project by project_id. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "e22a8f09-ab4d-4db5-875f-b47e66139460",
"name": "Create a Project",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
600,
400
],
"parameters": {
"url": "https://api.todoist.com/rest/v2/projects",
"body": "={\n \"name\": \"{{ $fromAI(\"project_name\", \"The name of the project\", \"string\", \"New project\") }}\",\n \"description\": \"{{ $fromAI(\"project_description\", \"Project description\", \"string\") }}\",\n \"parent_id\": \"{{ $fromAI(\"parent_project_id\", \"ID of parent project, if needed\", \"string\", \"\") }}\",\n \"color\": \"{{ $fromAI(\"color\", \"Color from available range\", \"string\", \"charcoal\") }}\",\n \"is_favorite\": {{ $fromAI(\"is_favourite\", \"\", \"boolean\") }}\n}",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "raw",
"authentication": "predefinedCredentialType",
"rawContentType": "application/json",
"toolDescription": "Create a new project. Required: name. Optional: description, color, parent_id, is_favorite. If the user did not mention it, just skip it and leave this values empty.\n\n**Available colors**: berry_red, red, orange, yellow, olive_green, lime_green, green, mint_green, teal, sky_blue, light_blue, blue, grape, violet, lavender, magenta, salmon, charcoal, grey, taup. If user asks for any other, choose the one that suits best or leave empty.\n",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "4002115e-f01e-4f9a-826a-4284bb33e88e",
"name": "Update a Project",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
760,
400
],
"parameters": {
"url": "={{ `https://api.todoist.com/rest/v2/projects/${$fromAI('Project_ID','','string')}` }}",
"method": "POST",
"options": {},
"jsonBody": "={\n \"name\": \"{{ $fromAI(\"project_name\", \"The name of the project\", \"string\", \"New project\") }}\",\n \"description\": \"{{ $fromAI(\"project_description\", \"Project description\", \"string\") }}\",\n \"parent_id\": \"{{ $fromAI(\"parent_project_id\", \"ID of parent project, if needed\", \"string\", \"\") }}\",\n \"color\": \"{{ $fromAI(\"color\", \"Color from available range\", \"string\", \"charcoal\") }}\",\n \"is_favorite\": {{ $fromAI(\"is_favourite\", \"\", \"boolean\") }}\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Update a project. Required: Project_ID. Optional: name, description, color, parent_id, is_favorite. If the user did not mention it, just skip it and leave this values empty.\n\n**Available colors**: berry_red, red, orange, yellow, olive_green, lime_green, green, mint_green, teal, sky_blue, light_blue, blue, grape, violet, lavender, magenta, salmon, charcoal, grey, taup. If user asks for any other, choose the one that suits best or leave empty.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "82f5b3d9-1444-47a9-b034-0cc296206ec2",
"name": "Archive a Project",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
920,
400
],
"parameters": {
"url": "={{ `https://api.todoist.com/rest/v2/projects/${$fromAI('Project_ID','','string')}/archive` }}",
"method": "POST",
"options": {},
"authentication": "predefinedCredentialType",
"toolDescription": "Marks a project as archived. For personal projects, this will archive it just for the initiating user (leaving it visible to any other collaborators). For workspace projects, this will archive it for all workspace users, removing it from view. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "43a92f6c-f55c-4cad-bb00-090310e4d4d0",
"name": "Get Archived Projects",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1080,
400
],
"parameters": {
"url": "https://api.todoist.com/api/v1/projects/archived",
"options": {
"pagination": {
"pagination": {
"parameters": {
"parameters": [
{
"name": "cursor",
"value": "={{ $response.next_cursor }}"
}
]
},
"requestInterval": 10
}
}
},
"authentication": "predefinedCredentialType",
"toolDescription": "Return the user\u2019s archived project list. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "71114ba0-5f5b-4033-884a-8f38f8f5d6b1",
"name": "Unarchive a Project",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1260,
400
],
"parameters": {
"url": "={{ `https://api.todoist.com/rest/v2/projects/${$fromAI('Project_ID','','string')}/unarchive` }}",
"method": "POST",
"options": {},
"authentication": "predefinedCredentialType",
"toolDescription": "Marks a previously archived project as active again. For personal projects, this will make the project visible again for the initiating user. For workspace projects, this will make the project visible again for all applicable workspace users. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "7092954e-93e1-440f-aa64-60b708ed7443",
"name": "Get All Sections",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
280,
580
],
"parameters": {
"url": "https://api.todoist.com/rest/v2/sections",
"options": {
"pagination": {
"pagination": {
"parameters": {
"parameters": [
{
"name": "cursor",
"value": "={{ $response.next_cursor }}"
}
]
},
"requestInterval": 10
}
}
},
"authentication": "predefinedCredentialType",
"toolDescription": "Return the user\u2019s full sections list. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "2a0a5f63-7c3c-40c0-9d86-c7f3f8b2fd15",
"name": "Get a Section",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
440,
580
],
"parameters": {
"url": "=https://api.todoist.com/rest/v2/sections/{{ $fromAI(\"Section_ID\", \"\", \"number\") }}",
"options": {},
"authentication": "predefinedCredentialType",
"toolDescription": "Fetch one section by section_id. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "196aa7d8-5830-48fe-bf8b-e6e0ce093417",
"name": "Create a Section",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
600,
580
],
"parameters": {
"url": "https://api.todoist.com/rest/v2/sections",
"method": "POST",
"options": {},
"jsonBody": "={\n \"name\": \"{{ $fromAI(\"section_name\", \"\", \"string\") }}\",\n \"project_id\": {{ $fromAI (\"Project_ID\", \"\", \"number\") }}\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Create a new project. Required: name, project_id. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "fb63f214-410a-42a8-b0b5-98492f57868f",
"name": "Update a Section",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
760,
580
],
"parameters": {
"url": "={{ `https://api.todoist.com/rest/v2/sections/${$fromAI('Section_ID','','string')}` }}",
"method": "POST",
"options": {},
"jsonBody": "={\n \"name\": \"{{ $fromAI(\"section_name\", \"\", \"string\") }}\"\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Update a section name. Required: Section_ID, name. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "60b3dc22-bf0a-40c5-b373-62163cbe25ec",
"name": "Delete a Section",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
900,
580
],
"parameters": {
"url": "=https://api.todoist.com/rest/v2/sections/{{ $fromAI(\"Section_ID\", \"\", \"number\") }}",
"method": "DELETE",
"options": {},
"authentication": "predefinedCredentialType",
"toolDescription": "Delete a section. Required: Section_ID. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "29aaeb54-4350-4fc6-b8e1-3f7eaed20dba",
"name": "Get All Labels",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
280,
760
],
"parameters": {
"url": "https://api.todoist.com/rest/v2/labels",
"options": {},
"authentication": "predefinedCredentialType",
"toolDescription": "Return the user\u2019s full labels list. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "c868ad86-38c6-4061-aff4-abfa4b665e3e",
"name": "Get a Label",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
440,
760
],
"parameters": {
"url": "=https://api.todoist.com/rest/v2/labels/{{ $fromAI(\"Label_ID\", \"\", \"number\") }}",
"options": {},
"authentication": "predefinedCredentialType",
"toolDescription": "Fetch one label by Label_ID. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "5c3e5bc5-711e-408f-86cd-472f357b2e51",
"name": "Create a Label",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
600,
760
],
"parameters": {
"url": "https://api.todoist.com/rest/v2/labels",
"method": "POST",
"options": {
"pagination": {
"pagination": {
"parameters": {
"parameters": [
{
"name": "cursor",
"value": "={{ $response.next_cursor }}"
}
]
},
"requestInterval": 10
}
}
},
"jsonBody": "={\n \"name\": \"{{ $fromAI(\"name\") }}\",\n \"color\": \"{{ $fromAI(\"color\", \"\", \"string\", \"charcoal\") }}\",\n \"is_favorite\": {{ $fromAI(\"is_favourite\", \"\", \"boolean\", \"false\")}}\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Create a new label. Required: name. Optional: color, is_favorite. If the user did not mention it, just skip it leaving the values empty.\n\n**Available colors**: berry_red, red, orange, yellow, olive_green, lime_green, green, mint_green, teal, sky_blue, light_blue, blue, grape, violet, lavender, magenta, salmon, charcoal, grey, taup. If user asks for any other, choose the one that suits best or leave empty.\n",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "4c853013-c820-42c8-a78b-809d86f32ffd",
"name": "Update a Label",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
760,
760
],
"parameters": {
"url": "={{ `https://api.todoist.com/rest/v2/labels/${$fromAI('Label_ID','','string')}` }}",
"method": "POST",
"options": {
"pagination": {
"pagination": {
"parameters": {
"parameters": [
{
"name": "cursor",
"value": "={{ $response.next_cursor }}"
}
]
},
"requestInterval": 10
}
}
},
"jsonBody": "={\n \"name\": \"{{ $fromAI(\"name\"), \"\", \"\"}}\",\n \"color\": \"{{ $fromAI(\"color\", \"\", \"string\", \"charcoal\") }}\",\n \"is_favorite\": {{ $fromAI(\"is_favourite\", \"\", \"boolean\", \"false\")}}\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Update a section name. Required: Label_ID. Optional: name, color, is_favorite. If the user did not mention it, just skip it leaving the values empty. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "9a737bf5-df4d-4790-868c-df0839ea048e",
"name": "Delete a Label",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
900,
760
],
"parameters": {
"url": "={{ `https://api.todoist.com/rest/v2/labels/${$fromAI('Label_ID','','string')}` }}",
"method": "DELETE",
"options": {},
"authentication": "predefinedCredentialType",
"toolDescription": "Delete a label. Required: Label_ID. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "de99b281-e3b4-4e6f-b7c1-f715c9ffac49",
"name": "Add a Comment",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
280,
940
],
"parameters": {
"url": "https://api.todoist.com/rest/v2/comments",
"method": "POST",
"options": {},
"jsonBody": "={\n \"content\": \"{{ $fromAI(\"comment\") }}\",\n \"task_id\": {{ $fromAI(\"Task_ID\", \"\", \"number\") }}\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Create a comment for a task. Only text comments, files are not supported at the time. Required: comment, Task_ID. Do not expose internal IDs.",
"nodeCredentialType": "todoistOAuth2Api"
},
"credentials": {
"todoistOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "1b0d6203-775e-4bba-a880-ebc6acfa5e3d",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-920,
-460
],
"parameters": {
"width": 760,
"height": 1360,
"content": "# \ud83e\ude84 Ultimate Personal **Todoist Agent**\n\nTurn natural-language requests into perfectly-organized Todoist tasks\u2014all on autopilot inside **n8n**.\n\n> \u201cAdd *Finish quarterly report by Friday afternoon*\u201d \u2192 the agent creates the task, sets the due date & priority, and even drops it into the right project. \u2728\n\n---\n\n\n## \ud83d\udee0\ufe0f What you\u2019ll need\n\n| Credential | Where it\u2019s used | How to set it up |\n| ------------------ | -------------------------------------- | --------------------------------------------------------------------------------------------- |\n| **OpenAI API** | Orchestrator & LLM nodes | Paste your OpenAI secret key into an **OpenAI** credential in n8n. |\n| **Todoist OAuth2** | Todoist node **and** HTTP Request node | Log in **Todoist** from your browser to set up credential in n8n. |\n\n> That\u2019s it\u2014no webhooks, no extra secrets.\n> *Tested with **gpt\u20114o\u2011latest** \u2013 the fastest & most accurate model in our trials.*\n\n---\n\n\n## \u26a1 Quick\u2011start (5\u202fminutes)\n\n1. **Import** the JSON template (hit **\u25b6\ufe0f Try it out** on the n8n template page or drag\u2011drop the file into your canvas).\n2. **Select your credentials** in the two credential dropdowns.\n3. Click **Test workflow**. In the sample Function node, tweak the `message` field (e.g. *\u201cTomorrow at 9\u202fam: write blog post\u201d*). Run \u2192 watch your new Todoist task appear.\n4. (Optional) Swap the Function node for your favourite chat trigger (Telegram, Slack, WhatsApp, Discord, you name it).\n\nBoom\u2014your personal Todoist genie is alive! \ud83e\uddde\u200d\u2642\ufe0f\n\n---\n\n\n## \ud83c\udf9b\ufe0f Customising & extending\n\n| Idea | How to do it |\n| ------------------------- | ---------------------------------------------------------------------------------------- |\n| **Notion / Sheets sync** | After the Todoist Agent node, add a Notion or Google Sheets node to log completed items. |\n| **Voice commands** | Swap the chat trigger for a Speech\u2011to\u2011Text node (e.g. Whisper). |\n\n---\n\n\n## \ud83e\udd1d Need custom automations?\n\nWant me to build or tweak something for you?\n\u2192 Email **[maxemelyanenko@gmail.com](mailto:maxemelyanenko@gmail.com)** and let\u2019s make it happen!\n\n---\n\n\n## \u26a0\ufe0f What\u2019s *not* included (yet)\n\n* Shared projects & other Todoist **Pro/Business** endpoints.\n* File attachments in the comments.\n* Editing comments.\n\nPull requests welcome! \ud83d\ude4c\n"
},
"typeVersion": 1
},
{
"id": "cdaf3b99-5b31-4893-b63a-02382e0d88d1",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-60,
-460
],
"parameters": {
"color": 2,
"width": 740,
"height": 420,
"content": "*The Orchestrator is an example.* In production you can drop it and simply expose the **Todoist Agent**\nas a tool for any other agent workflow."
},
"typeVersion": 1
}
],
"active": true,
"settings": {
"executionOrder": "v1"
},
"versionId": "e0e6901b-0581-404d-9970-86b07a56cf92",
"connections": {
"Get a Task": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get a Label": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Move a Task": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Add a Comment": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create a Task": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get All Tasks": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get a Project": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get a Section": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Reopen a Task": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "Orchestrator",
"type": "ai_memory",
"index": 0
}
]
]
},
"Update a Task": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create a Label": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Delete a Label": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get All Labels": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Update a Label": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create a Project": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Create a Section": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Delete a Section": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get All Projects": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get All Sections": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Update a Project": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Update a Section": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Archive a Project": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Mark Task as Done": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Todoist Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Call Todoist Agent": {
"ai_tool": [
[
{
"node": "Orchestrator",
"type": "ai_tool",
"index": 0
}
]
]
},
"OpenAI Chat Model1": {
"ai_languageModel": [
[
{
"node": "Orchestrator",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Unarchive a Project": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Get Archived Projects": {
"ai_tool": [
[
{
"node": "Todoist Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"When chat message received": {
"main": [
[
{
"node": "Orchestrator",
"type": "main",
"index": 0
}
]
]
},
"When Executed by Another Workflow": {
"main": [
[
{
"node": "Todoist Agent",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
openAiApitodoistOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Turn plain-language chat like “Tomorrow 9 AM: write blog post” into neatly organised Todoist tasks with GPT-4o and n8n—zero code.
Source: https://n8n.io/workflows/4186/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Splitout Redis. Uses executeWorkflowTrigger, n8n, redis, splitOut. Event-driven trigger; 46 nodes.
3770. Uses executeWorkflowTrigger, n8n, redis, agent. Event-driven trigger; 46 nodes.
Designing agent tools for outcome rather than utility has been a long recommended practice of mine and it applies well when it comes to building MCP servers; In gist, agents to be making the least amo
🔥📈🤖 AI Agent for n8n Creators Leaderboard - Find Popular Workflows. Uses httpRequest, limit, lmChatOpenAi, executeWorkflowTrigger. Event-driven trigger; 43 nodes.
🔥📈🤖 AI Agent for n8n Creators Leaderboard - Find Popular Workflows. Uses httpRequest, limit, lmChatOpenAi, executeWorkflowTrigger. Event-driven trigger; 43 nodes.