This workflow corresponds to n8n.io template #13388 — we link there as the canonical source.
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": "TckxPn8Et62aAgUP",
"name": "Sync Fizzy Cards into Basecamp Todos",
"tags": [
{
"id": "nY4Y2BAklcA0nSbM",
"name": "Fizzy",
"createdAt": "2026-02-13T14:28:15.351Z",
"updatedAt": "2026-02-13T14:28:15.351Z"
}
],
"nodes": [
{
"id": "95404f80-67d4-4cfd-b47c-049375fa16c2",
"name": "Set Basecamp account ID",
"type": "n8n-nodes-base.code",
"position": [
64,
912
],
"parameters": {
"jsCode": "// Configuration - Set your Basecamp Account ID here\nconst BASECAMP_ACCOUNT_ID = \"<Put your account ID Here>\";\n\n// Pass through webhook data and add account ID\nconst webhookData = $input.first().json;\n\nreturn {\n ...webhookData,\n basecampAccountId: BASECAMP_ACCOUNT_ID\n};"
},
"typeVersion": 2
},
{
"id": "a005d45d-2c21-4d83-9c3e-fb6ec2e8058a",
"name": "Find todo and prepare update",
"type": "n8n-nodes-base.code",
"position": [
2848,
896
],
"parameters": {
"jsCode": "// Get the original route data from Route by Action1 node\nconst routeData = $('Check if New Card').first().json;\n\n// Extract values from route data\nconst fizzyCardId = routeData.fizzyCardId;\nconst fizzyAction = routeData.fizzyAction;\nconst assigneeIds = routeData.assigneeIds;\nconst projectId = routeData.projectId;\nconst cardTitle = routeData.cardTitle;\nconst cardDescription = routeData.cardDescription;\n\n// Get all todos from merged results\nconst allTodos = $input.all().map(item => item.json);\n\nconsole.log(`Searching for Fizzy ID: ${fizzyCardId} among ${allTodos.length} todos`);\n\n// Find the matching todo by Fizzy ID in the description\nconst fizzyIdPattern = new RegExp(`Fizzy ID:\\\\s*${fizzyCardId}`, 'i');\nconst matchedTodo = allTodos.find(todo => {\n if (!todo.description) return false;\n const matches = fizzyIdPattern.test(todo.description);\n if (matches) {\n console.log(`Found matching todo: ${todo.id} - ${todo.title}`);\n }\n return matches;\n});\n\nif (!matchedTodo) {\n const availableTodos = allTodos.map(t => `ID: ${t.id}, Title: ${t.title}, Description: ${t.description?.substring(0, 100) || 'N/A'}`).join('\\n');\n throw new Error(`No todo found with Fizzy ID: \"${fizzyCardId}\".\\n\\nSearched ${allTodos.length} todos.\\n\\nAvailable todos:\\n${availableTodos}`);\n}\n\nconsole.log(`Successfully matched todo ${matchedTodo.id} for Fizzy card ${fizzyCardId}`);\n\n// Prepare the output based on action type\nlet output = {\n todoId: matchedTodo.id,\n projectId: projectId,\n fizzyAction: fizzyAction,\n currentAssignees: matchedTodo.assignees || [],\n assigneeIds: assigneeIds,\n cardTitle: cardTitle,\n cardDescription: cardDescription,\n fizzyCardId: fizzyCardId,\n currentStatus: matchedTodo.status,\n currentCompleted: matchedTodo.completed\n};\n\n// For status changes, determine the new status\nif (fizzyAction === 'card_closed') {\n output.shouldComplete = true;\n output.shouldReopen = false;\n} else if (fizzyAction === 'card_reopened') {\n output.shouldComplete = false;\n output.shouldReopen = true;\n} else if (fizzyAction === 'card_postponed' || fizzyAction === 'card_auto_postponed' || fizzyAction === 'card_sent_back_to_triage') {\n // Basecamp doesn't have a \"postponed\" status, so we'll uncomplete it\n output.shouldComplete = false;\n output.shouldReopen = true;\n}\n\nreturn output;"
},
"typeVersion": 2
},
{
"id": "8598d428-8223-49b6-95bd-4fbc93fe92ef",
"name": "Receive Fizzy webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-160,
912
],
"parameters": {
"path": "fizzyxbasecamp",
"options": {},
"httpMethod": "POST",
"responseMode": "lastNode"
},
"typeVersion": 2.1
},
{
"id": "f4fdb48e-3aff-4ac6-bdfb-0396d47ffeaf",
"name": "Fetch Basecamp projects",
"type": "n8n-nodes-base.httpRequest",
"position": [
288,
816
],
"parameters": {
"url": "=https://3.basecampapi.com/{{ $('Set Basecamp account ID').first().json.basecampAccountId }}/projects.json",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "basecamp4OAuth2Api"
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "6df604c8-d556-48ac-9f1a-1f8d2166c399",
"name": "Fetch Basecamp people",
"type": "n8n-nodes-base.httpRequest",
"position": [
288,
1008
],
"parameters": {
"url": "=https://3.basecampapi.com/{{ $('Set Basecamp account ID').first().json.basecampAccountId }}/people.json",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "basecamp4OAuth2Api"
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "d7a1fe7e-8937-411b-9cbf-b55cf4aa1b93",
"name": "Combine projects and people",
"type": "n8n-nodes-base.merge",
"position": [
512,
912
],
"parameters": {},
"typeVersion": 3
},
{
"id": "eedefdae-d447-4f4f-b0e9-4dd6889e704d",
"name": "Match project and get todoset",
"type": "n8n-nodes-base.code",
"position": [
880,
912
],
"parameters": {
"jsCode": "// Get the Fizzy board name from webhook node\nconst webhookData = $('Receive Fizzy webhook').first().json;\nconst fizzyBoardName = webhookData.body.board.name;\nconst fizzyAction = webhookData.body.action;\n\n// Get all Basecamp projects\nconst basecampProjects = $('Fetch Basecamp projects').all();\n\n// Get all Basecamp people\nconst basecampPeople = $('Fetch Basecamp people').all();\n\n// Find matching project (case-insensitive)\nconst matchedProject = basecampProjects.find(item => \n item.json.name.toLowerCase() === fizzyBoardName.toLowerCase()\n);\n\nif (!matchedProject) {\n throw new Error(`No Basecamp project found matching Fizzy board: \"${fizzyBoardName}\"`);\n}\n\n// Extract project ID\nconst projectId = matchedProject.json.id;\n\n// Find the \"To-dos\" todoset in the dock\nconst todoset = matchedProject.json.dock.find(item => \n item.name === 'todoset'\n);\n\nif (!todoset) {\n throw new Error(`No todoset found in project: \"${matchedProject.json.name}\"`);\n}\n\nconst todosetId = todoset.id;\n\n// Return the IDs to pass to next node\nreturn {\n projectId: projectId,\n todosetId: todosetId,\n boardName: fizzyBoardName,\n fizzyAction: fizzyAction,\n webhookData: webhookData,\n basecampPeople: basecampPeople.map(p => p.json)\n};"
},
"typeVersion": 2
},
{
"id": "7f931279-850c-4168-a9fa-ef9594c9f376",
"name": "Fetch project todolists",
"type": "n8n-nodes-base.httpRequest",
"position": [
1088,
912
],
"parameters": {
"url": "=https://3.basecampapi.com/{{ $('Set Basecamp account ID').first().json.basecampAccountId }}/buckets/{{$json.projectId}}/todosets/{{$json.todosetId}}/todolists.json",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "basecamp4OAuth2Api"
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.3
},
{
"id": "7c0a17ba-5b36-4c8d-897a-1050d0a22fd6",
"name": "Match todolist and assignees",
"type": "n8n-nodes-base.code",
"position": [
1280,
912
],
"parameters": {
"jsCode": "// Get webhook data from previous node\nconst previousNodeData = $('Match project and get todoset').first().json;\nconst webhookData = previousNodeData.webhookData;\nconst basecampPeople = previousNodeData.basecampPeople;\nconst fizzyAction = previousNodeData.fizzyAction;\n\n// Get the first tag from Fizzy card\nconst fizzyTags = webhookData.body.eventable.tags;\n\n// Default to \"Fizzy Todo\" if no tags present\nconst firstTag = (fizzyTags && fizzyTags.length > 0) ? fizzyTags[0] : \"Fizzy Todo\";\n\n// Get all todolists from current input\nconst todolists = $input.all();\n\n// Find matching todolist (case-insensitive)\nconst matchedTodolist = todolists.find(item => {\n const todolistTitle = item.json.title.toLowerCase();\n const tagToMatch = firstTag.toLowerCase();\n return todolistTitle === tagToMatch;\n});\n\n// Get projectId from previous node\nconst projectId = previousNodeData.projectId;\n\n// Match assignees by email\nconst fizzyAssignees = webhookData.body.eventable.assignees || [];\nconst assigneeIds = [];\n\nfor (const fizzyAssignee of fizzyAssignees) {\n const fizzyEmail = fizzyAssignee.email_address.toLowerCase();\n \n const matchedPerson = basecampPeople.find(person => \n person.email_address.toLowerCase() === fizzyEmail\n );\n \n if (matchedPerson) {\n assigneeIds.push(matchedPerson.id);\n }\n}\n\n// Get the Fizzy card ID for mapping\nconst fizzyCardId = webhookData.body.eventable.id;\nconst fizzyCardTitle = webhookData.body.eventable.title;\n\n// Base data object\nconst baseData = {\n projectId: projectId,\n cardTitle: fizzyCardTitle,\n cardDescription: webhookData.body.eventable.description || '',\n assigneeIds: assigneeIds,\n fizzyAction: fizzyAction,\n fizzyCardId: fizzyCardId,\n todosetId: previousNodeData.todosetId,\n basecampAccountId: $('Set Basecamp account ID').first().json.basecampAccountId,\n firstTag: firstTag,\n isDefaultList: (fizzyTags && fizzyTags.length > 0) ? false : true\n};\n\n// If todolist found, add todolistId and route normally\nif (matchedTodolist) {\n return {\n ...baseData,\n todolistId: matchedTodolist.json.id,\n todolistFound: true\n };\n} else {\n // If no todolist found, flag for creation\n return {\n ...baseData,\n todolistFound: false,\n newTodolistName: firstTag\n };\n}"
},
"typeVersion": 2
},
{
"id": "c19a89c1-da76-4676-be36-327e80b5c639",
"name": "Fetch active todos",
"type": "n8n-nodes-base.httpRequest",
"position": [
2576,
1184
],
"parameters": {
"url": "=https://3.basecampapi.com/{{ $json.basecampAccountId }}/buckets/{{ $json.projectId }}/todolists/{{ $json.todolistId }}/todos.json",
"options": {
"pagination": {
"pagination": {
"nextURL": "={{ $response.headers['link']?.match(/<([^>]+)>;\\s*rel=\"next\"/)?.[1] }}",
"paginationMode": "responseContainsNextURL",
"completeExpression": "={{ !$response.headers['link'] || !$response.headers['link'].includes('rel=\"next\"') }}",
"paginationCompleteWhen": "other"
}
}
},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "basecamp4OAuth2Api"
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "5196689a-ec15-4e80-8299-4a02a9dd832b",
"name": "Fetch completed todos",
"type": "n8n-nodes-base.httpRequest",
"position": [
2576,
1328
],
"parameters": {
"url": "=https://3.basecampapi.com/{{ $json.basecampAccountId }}/buckets/{{ $json.projectId }}/todolists/{{ $json.todolistId }}/todos.json?completed=true",
"options": {
"pagination": {
"pagination": {
"nextURL": "={{ $response.headers['link']?.match(/<([^>]+)>;\\s*rel=\"next\"/)?.[1] }}",
"paginationMode": "responseContainsNextURL",
"completeExpression": "={{ !$response.headers['link'] || !$response.headers['link'].includes('rel=\"next\"') }}",
"paginationCompleteWhen": "other"
}
}
},
"sendQuery": true,
"authentication": "predefinedCredentialType",
"queryParameters": {
"parameters": [
{}
]
},
"nodeCredentialType": "basecamp4OAuth2Api"
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.4
},
{
"id": "43594424-0b87-4df3-83e2-d93556158ccd",
"name": "Combine all todos",
"type": "n8n-nodes-base.merge",
"position": [
2848,
1248
],
"parameters": {},
"typeVersion": 3
},
{
"id": "2c3c4aff-dff1-4e21-a665-21c4dcaa511e",
"name": "Create new todolist",
"type": "n8n-nodes-basecamp.basecamp4",
"position": [
1472,
1168
],
"parameters": {
"name": "={{$json.newTodolistName}}",
"bucketId": "={{$json.projectId}}",
"resource": "todolist",
"operation": "createTodolist",
"todosetId": "={{$json.todosetId}}",
"description": "=Auto-created from Fizzy",
"requestOptions": {}
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "25a7038f-8230-4490-92b7-0b4715e349ed",
"name": "Check if todolist exists",
"type": "n8n-nodes-base.if",
"position": [
1472,
912
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "todolist_exists",
"operator": {
"type": "boolean",
"operation": "true"
},
"leftValue": "={{ $json.todolistFound }}",
"rightValue": true
}
]
}
},
"typeVersion": 2
},
{
"id": "795ff0a3-df67-4715-955a-6bbaf542b89d",
"name": "Add new todolist ID",
"type": "n8n-nodes-base.code",
"position": [
1680,
1168
],
"parameters": {
"jsCode": "// Get the created todolist data\nconst createdTodolist = $input.first().json;\n\n// Get the original data from Match Todolist & Assignees node\nconst originalData = $('Match todolist and assignees').first().json;\n\n// Merge the new todolist ID with the original data\nreturn {\n ...originalData,\n todolistId: createdTodolist.id,\n todolistFound: true\n};"
},
"typeVersion": 2
},
{
"id": "8a8b7b46-1dc6-4890-8d19-ac2148038970",
"name": "Create new todo",
"type": "n8n-nodes-basecamp.basecamp4",
"position": [
2112,
896
],
"parameters": {
"notify": true,
"content": "={{$json.cardTitle}}",
"bucketId": "={{$json.projectId}}",
"resource": "todo",
"operation": "createTodo",
"todolistId": "={{$json.todolistId}}",
"assigneeIds": "={{$json.assigneeIds}}",
"description": "=Fizzy ID: {{$json.fizzyCardId}} - Please Don't Delete!\n\n{{$json.cardDescription}}",
"requestOptions": {}
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "0507e272-9632-4894-9c84-bc658b16f016",
"name": "Check if assignment change",
"type": "n8n-nodes-base.if",
"position": [
3264,
896
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "is_assign",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.fizzyAction }}",
"rightValue": "card_assigned"
},
{
"id": "a3e33eb6-a171-4648-863c-8c0c1f05098a",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.fizzyAction }}",
"rightValue": "card_unassigned"
}
]
}
},
"typeVersion": 2
},
{
"id": "3c2632f9-66a0-4faf-8ecf-3d3116cf375e",
"name": "Update todo assignees",
"type": "n8n-nodes-basecamp.basecamp4",
"position": [
3488,
800
],
"parameters": {
"todoId": "={{$json.todoId}}",
"content": "={{$json.cardTitle}}",
"bucketId": "={{$json.projectId}}",
"resource": "todo",
"operation": "updateTodo",
"todoFields": {
"notify": {
"notify": true
},
"assigneeIds": {
"assigneeIds": "={{$json.assigneeIds}}"
},
"description": {
"description": "=Fizzy ID: {{$json.fizzyCardId}} - Please Don't Delete!\n\n{{$json.cardDescription}}"
}
},
"requestOptions": {}
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "c8806e91-b8cc-4c56-8a55-e02a468451f0",
"name": "Check if card closed",
"type": "n8n-nodes-base.if",
"position": [
3488,
992
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "is_closed",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.fizzyAction }}",
"rightValue": "card_closed"
}
]
}
},
"typeVersion": 2
},
{
"id": "69001a54-92c8-40ae-966b-7d4e8e8d69ec",
"name": "Mark todo as complete",
"type": "n8n-nodes-basecamp.basecamp4",
"position": [
3712,
896
],
"parameters": {
"todoId": "={{$json.todoId}}",
"bucketId": "={{$json.projectId}}",
"resource": "todo",
"operation": "completeTodo",
"requestOptions": {}
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "20166541-01ea-4862-9816-7707b89ce8e5",
"name": "Mark todo as incomplete",
"type": "n8n-nodes-basecamp.basecamp4",
"position": [
3936,
1088
],
"parameters": {
"todoId": "={{$json.todoId}}",
"bucketId": "={{$json.projectId}}",
"resource": "todo",
"operation": "uncompleteTodo",
"requestOptions": {}
},
"credentials": {
"basecamp4OAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "5c87b77a-1c95-4af3-9286-1adc4cfb7816",
"name": "Check if card reopened",
"type": "n8n-nodes-base.if",
"position": [
3712,
1088
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "is_reopen",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.fizzyAction }}",
"rightValue": "card_reopened"
},
{
"id": "8a109a14-f93a-4815-a804-ed0c5cdb235b",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.fizzyAction }}",
"rightValue": "card_postponed"
},
{
"id": "00f74454-0323-4c43-9ae3-f6fcf4bf2ab2",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.fizzyAction }}",
"rightValue": "card_auto_postponed"
},
{
"id": "cc752d9a-97bb-4e00-820e-e3934484e133",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.fizzyAction }}",
"rightValue": "card_sent_back_to_triage"
}
]
}
},
"typeVersion": 2
},
{
"id": "1b6b8631-160d-40e1-8d41-f4f623cbf688",
"name": "Setup instructions",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
-80
],
"parameters": {
"width": 880,
"height": 624,
"content": "## Setup steps\n\n**1. Install Basecamp community node**\nInstall from: https://www.npmjs.com/package/n8n-nodes-basecamp\n\n**2. Configure Basecamp credentials**\nCreate integration: https://launchpad.37signals.com/integrations\nAdd credentials in n8n with your Client ID and Client Secret\n\n**3. Set your account ID**\nUpdate the \"Set Basecamp account ID\" node with your Account ID\n\n**4. Prepare your Basecamp project**\n- Create project matching your Fizzy board name exactly\n- Enable Todos tool in project settings\n\n**5. Configure Fizzy webhook**\n\n- Each board needs its own webhook:\n- Click globe icon in Fizzy board\n- Paste webhook URL from \"Receive Fizzy webhook\" node\n- Enable all events\n\n## How it works\n\nThis workflow syncs Fizzy cards to Basecamp todos in real-time. When cards are created, assigned, or closed in Fizzy, the corresponding todos update automatically in Basecamp. Card tags determine the todolist, and assignees sync by email match."
},
"typeVersion": 1
},
{
"id": "8cfb232e-0c3e-4434-a7d6-1325fcf3bc9b",
"name": "Initial setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
-224,
656
],
"parameters": {
"color": 7,
"width": 896,
"height": 624,
"content": "Receives webhook from Fizzy and fetches Basecamp data"
},
"typeVersion": 1
},
{
"id": "43c90a16-2901-4f80-9fcf-8d58b9f22aa1",
"name": "Project matching",
"type": "n8n-nodes-base.stickyNote",
"position": [
816,
656
],
"parameters": {
"color": 7,
"width": 1072,
"height": 800,
"content": "Matches Fizzy Data to Basecamp Data (Projects, Todoset, Todolist)"
},
"typeVersion": 1
},
{
"id": "17f46172-7d8a-4025-bec1-c8a1ae2f86d8",
"name": "Create path",
"type": "n8n-nodes-base.stickyNote",
"position": [
2016,
656
],
"parameters": {
"color": 7,
"width": 336,
"height": 800,
"content": "Creates new todo when fizzy card status is equal to published (New)"
},
"typeVersion": 1
},
{
"id": "150593f5-f87e-4b15-8ba1-50edc2990fd2",
"name": "Update path",
"type": "n8n-nodes-base.stickyNote",
"position": [
2480,
656
],
"parameters": {
"color": 7,
"width": 592,
"height": 960,
"content": "Updates existing todo when card changes"
},
"typeVersion": 1
},
{
"id": "a8b2a1c5-1e62-45a5-84bf-887365f3dff7",
"name": "Status changes",
"type": "n8n-nodes-base.stickyNote",
"position": [
3168,
656
],
"parameters": {
"color": 7,
"width": 992,
"height": 816,
"content": "Handles assignment updates and completion status"
},
"typeVersion": 1
},
{
"id": "b98f4005-336a-4e44-be28-840e6952ccf0",
"name": "Check if New Card",
"type": "n8n-nodes-base.if",
"position": [
2128,
1168
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "action_create",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.fizzyAction }}",
"rightValue": "card_published"
}
]
}
},
"typeVersion": 2
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "1dc5ca67-d4d3-46c9-a197-f620d70ce5a7",
"connections": {
"Check if New Card": {
"main": [
[
{
"node": "Create new todo",
"type": "main",
"index": 0
}
],
[
{
"node": "Fetch active todos",
"type": "main",
"index": 0
},
{
"node": "Fetch completed todos",
"type": "main",
"index": 0
}
]
]
},
"Combine all todos": {
"main": [
[
{
"node": "Find todo and prepare update",
"type": "main",
"index": 0
}
]
]
},
"Fetch active todos": {
"main": [
[
{
"node": "Combine all todos",
"type": "main",
"index": 0
}
]
]
},
"Add new todolist ID": {
"main": [
[
{
"node": "Check if New Card",
"type": "main",
"index": 0
}
]
]
},
"Create new todolist": {
"main": [
[
{
"node": "Add new todolist ID",
"type": "main",
"index": 0
}
]
]
},
"Check if card closed": {
"main": [
[
{
"node": "Mark todo as complete",
"type": "main",
"index": 0
}
],
[
{
"node": "Check if card reopened",
"type": "main",
"index": 0
}
]
]
},
"Fetch Basecamp people": {
"main": [
[
{
"node": "Combine projects and people",
"type": "main",
"index": 1
}
]
]
},
"Fetch completed todos": {
"main": [
[
{
"node": "Combine all todos",
"type": "main",
"index": 1
}
]
]
},
"Receive Fizzy webhook": {
"main": [
[
{
"node": "Set Basecamp account ID",
"type": "main",
"index": 0
}
]
]
},
"Check if card reopened": {
"main": [
[
{
"node": "Mark todo as incomplete",
"type": "main",
"index": 0
}
]
]
},
"Fetch Basecamp projects": {
"main": [
[
{
"node": "Combine projects and people",
"type": "main",
"index": 0
}
]
]
},
"Fetch project todolists": {
"main": [
[
{
"node": "Match todolist and assignees",
"type": "main",
"index": 0
}
]
]
},
"Set Basecamp account ID": {
"main": [
[
{
"node": "Fetch Basecamp projects",
"type": "main",
"index": 0
},
{
"node": "Fetch Basecamp people",
"type": "main",
"index": 0
}
]
]
},
"Check if todolist exists": {
"main": [
[
{
"node": "Check if New Card",
"type": "main",
"index": 0
}
],
[
{
"node": "Create new todolist",
"type": "main",
"index": 0
}
]
]
},
"Check if assignment change": {
"main": [
[
{
"node": "Update todo assignees",
"type": "main",
"index": 0
}
],
[
{
"node": "Check if card closed",
"type": "main",
"index": 0
}
]
]
},
"Combine projects and people": {
"main": [
[
{
"node": "Match project and get todoset",
"type": "main",
"index": 0
}
]
]
},
"Find todo and prepare update": {
"main": [
[
{
"node": "Check if assignment change",
"type": "main",
"index": 0
}
]
]
},
"Match todolist and assignees": {
"main": [
[
{
"node": "Check if todolist exists",
"type": "main",
"index": 0
}
]
]
},
"Match project and get todoset": {
"main": [
[
{
"node": "Fetch project todolists",
"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.
basecamp4OAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Automatically sync Fizzy cards to Basecamp todos in real-time. When cards are created, assigned, completed, or reopened in Fizzy, the changes sync instantly to your Basecamp project. Card tags determine which todolist items go to, and team members are matched by email. n8n…
Source: https://n8n.io/workflows/13388/ — 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.
This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di
This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .
This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c
Sign PDF documents with legally-compliant digital signatures using X.509 certificates. Supports multiple PAdES signature levels (B, T, LT, LTA) with optional visible stamps.
📡 This workflow serves as the central Alpha Vantage API fetcher for Tesla trading indicators, delivering cleaned 20-point JSON outputs for three timeframes: , , and . It is required by the following a