This workflow corresponds to n8n.io template #2544 — we link there as the canonical source.
This workflow follows the HTTP Request → Notion 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": "9OLVUSrFkmemkibm",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Add Canvas Assignments to Notion",
"tags": [],
"nodes": [
{
"id": "6499272f-d3ba-42ad-a81b-2545588c233d",
"name": "Compare Datasets",
"type": "n8n-nodes-base.compareDatasets",
"position": [
960,
720
],
"parameters": {
"options": {
"multipleMatches": "first"
},
"fuzzyCompare": true,
"mergeByFields": {
"values": [
{
"field1": "plannable_id",
"field2": "property_id"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "f9116861-991b-4706-a085-692ca224db35",
"name": "Get Item Data",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
1380,
800
],
"parameters": {
"url": "=https://canvas.wisc.edu/api/v1{{ $json.html_url }}",
"options": {},
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.1
},
{
"id": "150f7823-2cd5-4d8b-b7ff-3599931d3eef",
"name": "Markdown",
"type": "n8n-nodes-base.markdown",
"position": [
1560,
800
],
"parameters": {
"html": "={{ $json.description || $json.message || \"\" }}",
"options": {},
"destinationKey": "markdown"
},
"typeVersion": 1
},
{
"id": "37c9f59a-b719-4581-a655-ca29bc5bf0c2",
"name": "Isn't locked",
"type": "n8n-nodes-base.filter",
"position": [
1860,
700
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "71698fe2-253e-41a6-af5f-a83935a538f5",
"operator": {
"type": "dateTime",
"operation": "before"
},
"leftValue": "={{ $json.lock_info.unlock_at || $json.unlock_at }}",
"rightValue": "={{ new Date().toISOString() }}"
},
{
"id": "68077b61-78b5-435c-ab55-95ec8efc872b",
"operator": {
"type": "object",
"operation": "notExists",
"singleValue": true
},
"leftValue": "={{ $json.lock_info }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "d358bbc9-be68-4854-a502-7f9b46ffd72f",
"name": "Is Canvas Complete?",
"type": "n8n-nodes-base.if",
"position": [
1260,
1040
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "c3eb24c1-05b5-4d0a-8b6d-16f40f5c3a5a",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.different.planner_override.inputA.marked_complete }}",
"rightValue": ""
},
{
"id": "fdb38474-9435-46dd-9d32-438adb83c844",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.different.submissions.inputA.submitted }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.1
},
{
"id": "6d47f934-b8f2-49be-bfa8-9d20fbce89ef",
"name": "Notion",
"type": "n8n-nodes-base.notion",
"position": [
720,
780
],
"parameters": {
"filters": {
"conditions": [
{
"key": "Last edited time|last_edited_time",
"condition": "after",
"lastEditedTime": "={{ new Date(new Date().setMonth((new Date()).getMonth() - 1)).toISOString() }}"
}
]
},
"options": {},
"resource": "databasePage",
"operation": "getAll",
"returnAll": true,
"databaseId": {
"__rl": true,
"mode": "list",
"value": "20c84001-a0eb-4a0d-8d35-67ed8d9ddf5b",
"cachedResultUrl": "https://www.notion.so/20c84001a0eb4a0d8d3567ed8d9ddf5b",
"cachedResultName": "Tasks"
},
"filterType": "manual"
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "3df9cbdb-7741-43eb-8269-62286692362f",
"name": "Planner",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
720,
620
],
"parameters": {
"url": "=https://canvas.wisc.edu/api/v1/planner/items",
"options": {
"response": {
"response": {}
}
},
"sendQuery": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"queryParameters": {
"parameters": [
{
"name": "start_date",
"value": "={{ new Date(Date.now() - 7*8.64e7).toISOString() }}"
},
{
"name": "per_page",
"value": "75"
},
{
"name": "end_date",
"value": "={{ new Date(Date.now() + (21*8.64e7)).toISOString() }}"
}
]
}
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.1
},
{
"id": "1651eb13-e7d9-439e-b15f-af76034a735e",
"name": "Notion is complete",
"type": "n8n-nodes-base.filter",
"position": [
1460,
1320
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "14de38b8-831a-4944-815d-16bcc14442f8",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.different.property_status.inputB }}",
"rightValue": "Completed"
}
]
}
},
"typeVersion": 2
},
{
"id": "c077c145-e378-47b0-a54d-a975688a26bc",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
500,
780
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "2 0,9,11,13,15,17,20 * * *"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "cf68e21c-e4b6-4cdb-a4d0-26765644a66b",
"name": "Not an event",
"type": "n8n-nodes-base.filter",
"position": [
1220,
680
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b47a1e14-63e0-496c-861a-2292bffeb988",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.plannable_type }}",
"rightValue": "calendar_event"
},
{
"id": "09133354-b229-4c7b-be3c-d0e24f7c5043",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.plannable_type }}",
"rightValue": "announcement"
}
]
}
},
"typeVersion": 2.1
},
{
"id": "7f62a67a-caec-427b-9538-cb32d796e30a",
"name": "Update Override",
"type": "n8n-nodes-base.httpRequest",
"position": [
1840,
1240
],
"parameters": {
"url": "=https://canvas.wisc.edu/api/v1/planner/overrides/{{ $json.different.planner_override ? $json.different.planner_override.inputA.id : \"\"}}",
"method": "PUT",
"options": {},
"jsonBody": "={\n \"id\":{{ $json.different.planner_override ? `\"${$json.different.planner_override.inputA.id}\"` : null }},\n \"plannable_id\":\"{{ $json.keys.plannable_id }}\",\n \"plannable_type\":\"assignment\",\n \"user_id\":\"487387\",\n \"marked_complete\":true\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "a80b4902-f6f0-49d1-a51a-ab31d8eab566",
"name": "Override Exists",
"type": "n8n-nodes-base.if",
"position": [
1640,
1320
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "bbba649a-2129-417b-a6b0-9df0ada03f22",
"operator": {
"type": "object",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $json.different.planner_override }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.1
},
{
"id": "c8cb72a7-b4c5-40a3-9a46-202bcbafef02",
"name": "New Override",
"type": "n8n-nodes-base.httpRequest",
"position": [
1840,
1400
],
"parameters": {
"url": "=https://canvas.wisc.edu/api/v1/planner/overrides",
"method": "POST",
"options": {},
"jsonBody": "={\n \"id\":null,\n \"plannable_id\":\"{{ $json.keys.plannable_id }}\",\n \"plannable_type\":\"assignment\",\n \"user_id\":\"487387\",\n \"marked_complete\":true\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
},
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "8ede1bdb-2e7d-4555-be1c-d89ded239908",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1100,
500
],
"parameters": {
"width": 518.839856887148,
"height": 80,
"content": "## Add new Canvas assignments to Notion"
},
"typeVersion": 1
},
{
"id": "97698dc4-f8ce-44a1-bf78-87ff21bc8768",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1240,
940
],
"parameters": {
"width": 518.839856887148,
"height": 80,
"content": "### If an assignment is submitted on Canvas, complete it on Notion"
},
"typeVersion": 1
},
{
"id": "5aef8e5f-249d-4b83-bf52-94b9f7079fc0",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1240,
1200
],
"parameters": {
"width": 518.839856887148,
"height": 80,
"content": "### If I mark an assignment as submitted on Notion, complete it on Canvas"
},
"typeVersion": 1
},
{
"id": "f95585f4-2672-45b6-9a5b-a3351dabb375",
"name": "Merge Item Data",
"type": "n8n-nodes-base.merge",
"position": [
1700,
700
],
"parameters": {
"mode": "combine",
"options": {
"clashHandling": {
"values": {
"resolveClash": "preferInput1"
}
}
},
"combinationMode": "mergeByPosition"
},
"typeVersion": 2.1
},
{
"id": "d406a907-8190-429e-939a-12f004e8a6e5",
"name": "Merge OpenAI Ranking",
"type": "n8n-nodes-base.merge",
"position": [
2160,
720
],
"parameters": {
"mode": "combine",
"options": {},
"combinationMode": "mergeByPosition"
},
"typeVersion": 2.1
},
{
"id": "eaed6285-89c1-4862-82ce-45eb1cfd71f2",
"name": "Add to Notion",
"type": "n8n-nodes-base.notion",
"position": [
2340,
720
],
"parameters": {
"title": "={{ $json.plannable.title }}",
"simple": false,
"blockUi": {
"blockValues": [
{
"textContent": "={{ $json.markdown.slice(0,1900) }}"
}
]
},
"options": {},
"resource": "databasePage",
"databaseId": {
"__rl": true,
"mode": "list",
"value": "20c84001-a0eb-4a0d-8d35-67ed8d9ddf5b",
"cachedResultUrl": "https://www.notion.so/20c84001a0eb4a0d8d3567ed8d9ddf5b",
"cachedResultName": "Tasks"
},
"propertiesUi": {
"propertyValues": [
{
"key": "ID|rich_text",
"textContent": "={{ $json.plannable_id.toString() }}"
},
{
"key": "Due Date|date",
"date": "={{ $json.plannable.due_at }}{{ $json.plannable.todo_date }}",
"includeTime": false
},
{
"key": "Class|rich_text",
"textContent": "={{ $json.context_name.replace(/:.*/, \"\") }}"
},
{
"key": "Link|url",
"urlValue": "=https://canvas.wisc.edu{{ $json.html_url }}",
"ignoreIfEmpty": true
},
{
"key": "=Priority|select",
"selectValue": "=Should Do"
},
{
"key": "Estimate|select",
"selectValue": "={{ $json.choices[0].message.content.parseJson().estimate }}"
}
]
}
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"executeOnce": false,
"typeVersion": 2
},
{
"id": "404388e4-0a67-4004-9fc4-e76608a186a6",
"name": "Mark Notion as complete",
"type": "n8n-nodes-base.notion",
"position": [
1660,
1040
],
"parameters": {
"pageId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.different.id.inputB }}"
},
"options": {},
"resource": "databasePage",
"operation": "update",
"propertiesUi": {
"propertyValues": [
{
"key": "Status|status",
"statusValue": "Completed"
}
]
}
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "ef20ff89-3624-44e8-8042-3c2e685f7234",
"name": "Notion isn't started",
"type": "n8n-nodes-base.filter",
"position": [
1460,
1040
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "14de38b8-831a-4944-815d-16bcc14442f8",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.different.property_status.inputB }}",
"rightValue": "Not Started"
}
]
}
},
"typeVersion": 2
},
{
"id": "624d5053-ab37-4799-872b-340c9cce0d1f",
"name": "Update Due Date",
"type": "n8n-nodes-base.notion",
"position": [
720,
1280
],
"parameters": {
"pageId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.different.id.inputB }}"
},
"options": {},
"resource": "databasePage",
"operation": "update",
"propertiesUi": {
"propertyValues": [
{
"key": "=Due Date|date",
"date": "={{ $json.different.plannable.inputA.due_at }}{{ $json.different.plannable.inputA.todo_date }}",
"includeTime": false
}
]
}
},
"credentials": {
"notionApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "a5465ca0-e46c-4516-b65a-c78d47f4f5ec",
"name": "OpenAI Categorization",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
2000,
820
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"method": "POST",
"options": {},
"jsonBody": "={\n \"model\": \"gpt-4o\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a skilled college course TA. Your job is to estimate the amount of effort that it will take students to complete an assignment, and because your professor is quirky you are doing this based on T-Shirt sizes (XS, S, M, L, XL) and only based on the title and description. Evaluate the whole assignment as a unit. If the assignment description is vague, default to \\\"M\\\".\\nGuidelines: Task Estimation thresholds: XS: >5 mins (email) S: >15 mins (quiz) M: >45 mins (worksheet) L: >3 hours (essay) XL: >6 hours (website).\\nSome classes have misleading assignment lengths. Overrides:\\n-Math 234 quizzes are only one question, so they should be S\"\n },\n {\n \"role\": \"user\",\n \"content\": \"<AssignmentTitle>\\n{{ JSON.stringify($json.plannable.title).replace(/^\"(.*)\"$/, '$1') }}\\n</AssignmentTitle>\\n<CourseName>\\n{{ JSON.stringify($json.context_name).replace(/^\"(.*)\"$/, '$1') }}\\n</CourseName>\\n<AssignmentDescription>\\n{{ JSON.stringify($json.markdown.slice(0, 3000)).replace(/^\"(.*)\"$/, '$1') }}\\n</AssignmentDescription>\"\n }\n ],\n \"temperature\": 0.7,\n \"response_format\": {\n \"type\": \"json_schema\",\n \"json_schema\": {\n \"name\": \"task_complexity\",\n \"description\": \"Estimates the complexity of a given task in T-shirt sizes\",\n \"strict\": true,\n \"schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"estimate\": {\n \"type\": \"string\",\n \"description\": \"The complexity of the task\",\n \"enum\": [\n \"XS\",\n \"S\",\n \"M\",\n \"L\",\n \"XL\"\n ]\n }\n },\n \"additionalProperties\": false,\n \"required\": [\n \"estimate\"\n ]\n }\n }\n }\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openAiApi"
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "d47acd27-fefe-4934-b4f9-ba8bfbd84396",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
500,
620
],
"parameters": {
"path": "refresh",
"options": {}
},
"typeVersion": 1.1
},
{
"id": "1fc4134f-9fb3-4790-8c97-56e5de022bb0",
"name": "Different Due Dates",
"type": "n8n-nodes-base.filter",
"position": [
520,
1280
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "040882f6-d239-4cb8-97eb-599d5772060e",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ DateTime.fromISO($json.different.plannable.inputA.due_at).toISODate() }}",
"rightValue": "={{ $json.different.property_due_date.inputB.start }}"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "ac774b29-ae67-48d3-a309-019e622eb60d",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
500,
1160
],
"parameters": {
"width": 518.839856887148,
"height": 80,
"content": "### Update due date in Notion if it changed"
},
"typeVersion": 1
}
],
"active": true,
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"executionOrder": "v1",
"saveManualExecutions": true,
"saveDataSuccessExecution": "none"
},
"versionId": "7be9a466-c7c5-45a2-9068-07d53357d89f",
"connections": {
"Notion": {
"main": [
[
{
"node": "Compare Datasets",
"type": "main",
"index": 1
}
]
]
},
"Planner": {
"main": [
[
{
"node": "Compare Datasets",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Planner",
"type": "main",
"index": 0
},
{
"node": "Notion",
"type": "main",
"index": 0
}
]
]
},
"Markdown": {
"main": [
[
{
"node": "Merge Item Data",
"type": "main",
"index": 1
}
]
]
},
"Isn't locked": {
"main": [
[
{
"node": "Merge OpenAI Ranking",
"type": "main",
"index": 0
},
{
"node": "OpenAI Categorization",
"type": "main",
"index": 0
}
]
]
},
"Not an event": {
"main": [
[
{
"node": "Get Item Data",
"type": "main",
"index": 0
},
{
"node": "Merge Item Data",
"type": "main",
"index": 0
}
]
]
},
"Get Item Data": {
"main": [
[
{
"node": "Markdown",
"type": "main",
"index": 0
}
]
]
},
"Merge Item Data": {
"main": [
[
{
"node": "Isn't locked",
"type": "main",
"index": 0
}
]
]
},
"Override Exists": {
"main": [
[
{
"node": "Update Override",
"type": "main",
"index": 0
}
],
[
{
"node": "New Override",
"type": "main",
"index": 0
}
]
]
},
"Compare Datasets": {
"main": [
[
{
"node": "Not an event",
"type": "main",
"index": 0
}
],
[],
[
{
"node": "Is Canvas Complete?",
"type": "main",
"index": 0
},
{
"node": "Different Due Dates",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Planner",
"type": "main",
"index": 0
},
{
"node": "Notion",
"type": "main",
"index": 0
}
]
]
},
"Notion is complete": {
"main": [
[
{
"node": "Override Exists",
"type": "main",
"index": 0
}
]
]
},
"Different Due Dates": {
"main": [
[
{
"node": "Update Due Date",
"type": "main",
"index": 0
}
]
]
},
"Is Canvas Complete?": {
"main": [
[
{
"node": "Notion isn't started",
"type": "main",
"index": 0
}
],
[
{
"node": "Notion is complete",
"type": "main",
"index": 0
}
]
]
},
"Merge OpenAI Ranking": {
"main": [
[
{
"node": "Add to Notion",
"type": "main",
"index": 0
}
]
]
},
"Notion isn't started": {
"main": [
[
{
"node": "Mark Notion as complete",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Categorization": {
"main": [
[
{
"node": "Merge OpenAI Ranking",
"type": "main",
"index": 1
}
]
]
}
}
}
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.
httpHeaderAuthnotionApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Syncs assignments and completion states to and fro between Canvas LMS and a Notion database. Automatically triggers every 2 hours during the schoolday by default (meaning 7 times a day), but also supports manual refreshing via webhooks.
Source: https://n8n.io/workflows/2544/ — 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.
Disparador 1.8. Uses itemLists, postgres, emailSend, httpRequest. Scheduled trigger; 85 nodes.
This solution enables you to manage all your Notion and Todoist tasks from different workspaces as well as your calendar events in a single place. This is 2 way sync with partial support for recurring
Sync your Google Contacts with your Notion database.
Notion to Clockify Sync Template. Uses scheduleTrigger, clockify, compareDatasets, stopAndError. Webhook trigger; 68 nodes.
This workflow synchronizes three entities from Notion to Clockify, allowing tracked time to be linked to client-related projects or tasks.