This workflow corresponds to n8n.io template #12789 — 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "f791a053-fb25-448a-983a-b34701115af3",
"name": "-> POST",
"type": "n8n-nodes-base.set",
"position": [
64,
-288
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "69f54d46-1290-42ea-816a-60b13fbaf6a6",
"name": "method",
"type": "string",
"value": "POST"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "cb9c04d5-08a2-4009-a635-57b7f4a433fa",
"name": "-> GET",
"type": "n8n-nodes-base.set",
"position": [
64,
-448
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "69f54d46-1290-42ea-816a-60b13fbaf6a6",
"name": "method",
"type": "string",
"value": "GET"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "ff19ddfc-6e14-421e-84d4-996ed328b67d",
"name": "-> PUT",
"type": "n8n-nodes-base.set",
"position": [
64,
-128
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "69f54d46-1290-42ea-816a-60b13fbaf6a6",
"name": "method",
"type": "string",
"value": "PUT"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "09c5b816-e377-44be-8c35-d19b6491a54d",
"name": "-> DELETE",
"type": "n8n-nodes-base.set",
"position": [
64,
32
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "69f54d46-1290-42ea-816a-60b13fbaf6a6",
"name": "method",
"type": "string",
"value": "DELETE"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "05be6952-adf6-4644-8874-24b959de3923",
"name": "v1/seg1",
"type": "n8n-nodes-base.webhook",
"position": [
-224,
-432
],
"parameters": {
"path": "/api/v1/:lvl1",
"options": {},
"httpMethod": [
"GET",
"POST",
"PUT",
"DELETE"
],
"responseMode": "responseNode",
"multipleMethods": true
},
"typeVersion": 2.1
},
{
"id": "67fac35a-dd3c-4371-ae47-b519f5734c56",
"name": "v1/seg2",
"type": "n8n-nodes-base.webhook",
"position": [
-224,
-240
],
"parameters": {
"path": "/api/v1/:lvl1/:lvl2",
"options": {},
"httpMethod": [
"GET",
"POST",
"PUT",
"DELETE"
],
"responseMode": "responseNode",
"multipleMethods": true
},
"typeVersion": 2.1
},
{
"id": "b7ea32cb-3d54-4919-8887-4821af6f1180",
"name": "v1/seg3",
"type": "n8n-nodes-base.webhook",
"position": [
-224,
-48
],
"parameters": {
"path": "/api/v1/:lvl1/:lvl2/:lvl3",
"options": {},
"httpMethod": [
"GET",
"POST",
"PUT",
"DELETE"
],
"responseMode": "responseNode",
"multipleMethods": true
},
"typeVersion": 2.1
},
{
"id": "389e112b-176e-43c6-8a98-0346e09bf94f",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
-720
],
"parameters": {
"color": 7,
"width": 1056,
"height": 928,
"content": "## Streamlining data \nWe initialize global data for the _REQUEST, and set up our _CFG. We then clear the JSON, so we have a clean separation of global data vs. data flow."
},
"typeVersion": 1
},
{
"id": "be718c7a-86a8-4bae-af41-d66e0a15ca5f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-320,
-720
],
"parameters": {
"color": 7,
"width": 288,
"height": 928,
"content": "## API routing levels \n3 levels provide a solid base\n### To add more:\n- Copy the highest-level Webhook-node\n- Add another variable to the end of the path: `/:lvl4`\n- Connect the outputs to the corresponding mode Set-node"
},
"typeVersion": 1
},
{
"id": "1d9e81f2-8af2-4df2-9e96-c30357d4518a",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1056,
-720
],
"parameters": {
"width": 624,
"height": 928,
"content": "# Build REST APIs quickly\n## How it works\nThis template combines webhooks and streamlines data flow for bootstrapping API implementations in n8n.\n\n## Setup\n- This template requires no setup\n- Feel free to set global option in the _CFG node and add/remove levels as needed\n\n## What it can be used for\n- Backend-APIs by using JSON-responses\n- Serving interactive websites by responding with HTML\n- Great for fast, early prototyping\n\n## Notes\n### Direct node notation & \"global\" naming\n- Many nodes don't pass-through data, so relying on $json makes for very cumbersome workflows full of branches -> merges (only to do a DB query, for example)\n- We use global notation instead to keep workflows clean. This template uses the format \"_GLOBAL_NODE_NAME\" for globals, which can be accessed at any point after their execution with $('_GLOBAL_NODE_NAME').item.json\n- See examples in the blue section\n### Noop-nodes\n- No operation nodes help mark entry-points and make it easier to re-route sections\n### n8n restrictions (as of v 2.3.4)\n- webhooks with path variables automatically add a hash as url base\n- webhooks can only map 1:1 to a path level, so each level requires its own webhook"
},
"typeVersion": 1
},
{
"id": "3eb25422-1765-4dba-8500-d08197abcb99",
"name": "_CFG",
"type": "n8n-nodes-base.code",
"position": [
640,
-208
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "$input.item.json = {\n debug: true,\n defaults: {\n invalid_route: {\n response: 'requested endpoint not available',\n status_code: 400\n }\n },\n db: {\n tables: {\n internal_label: 'physical_table_name'\n }\n },\n api_base_url: 'auto' // will be automatically extracted below\n};\n\n/*\n automatic api base url extraction\n*/\nif ($input.item.json.api_base_url === 'auto') {\n const full = $('_REQUEST').item.json.webhookUrl;\n const marker = '/api/v';\n const pos = full.indexOf(marker);\n\n if (pos === -1)\n throw new Error(`No api base url for \"${marker}\" in \"${full}\"`);\n\n const base = full.slice(0, pos);\n const rest = full.slice(pos + marker.length);\n const version = rest.match(/^(\\d+)/)?.[1];\n\n $input.item.json.api_base_url = `${base}${marker}${version}`;\n}\nreturn $input.item;"
},
"typeVersion": 2
},
{
"id": "5ce6c0d8-0ce8-43a9-83e0-21ca7d609adc",
"name": "_REQUEST",
"type": "n8n-nodes-base.set",
"position": [
448,
-208
],
"parameters": {
"include": "except",
"options": {},
"assignments": {
"assignments": []
},
"excludeFields": "headers",
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "94fd5eb9-1a06-4bbd-988c-80bae085ae7e",
"name": "Respond to Webhook1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3520,
-592
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ $('_REQUEST').item.json }}"
},
"typeVersion": 1.5
},
{
"id": "aeb33496-b122-4a90-ae66-66ded2c135ae",
"name": "Invalid Route",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1488,
-80
],
"parameters": {
"options": {
"responseCode": "={{ $('_CFG').item.json.defaults.invalid_route.status_code }}"
},
"respondWith": "text",
"responseBody": "={{ $('_CFG').item.json.defaults.invalid_route.response }}"
},
"typeVersion": 1.5
},
{
"id": "6269dca9-e433-40a2-ae07-13e32f6e0dbf",
"name": "Clear JSON",
"type": "n8n-nodes-base.set",
"position": [
832,
-208
],
"parameters": {
"options": {}
},
"typeVersion": 3.4,
"alwaysOutputData": true
},
{
"id": "627ab5bb-bf94-4609-8fae-bb6a97904420",
"name": "Invalid Route1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
1872,
-80
],
"parameters": {
"options": {
"responseCode": "={{ $('_CFG').item.json.defaults.invalid_route.status_code }}"
},
"respondWith": "text",
"responseBody": "={{ $('_CFG').item.json.defaults.invalid_route.response }}"
},
"typeVersion": 1.5
},
{
"id": "0a4fc685-916b-4703-b6fd-be67d3663ba5",
"name": "Invalid Route2",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2256,
-336
],
"parameters": {
"options": {
"responseCode": "={{ $('_CFG').item.json.defaults.invalid_route.status_code }}"
},
"respondWith": "text",
"responseBody": "={{ $('_CFG').item.json.defaults.invalid_route.response }}"
},
"typeVersion": 1.5
},
{
"id": "c99025cd-cbcb-427c-a87c-5bc110ebd4a4",
"name": "Invalid Route3",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2256,
64
],
"parameters": {
"options": {
"responseCode": "={{ $('_CFG').item.json.defaults.invalid_route.status_code }}"
},
"respondWith": "text",
"responseBody": "={{ $('_CFG').item.json.defaults.invalid_route.response }}"
},
"typeVersion": 1.5
},
{
"id": "62b6dbef-116b-4949-8e6f-e70e676c0bcf",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3520,
-384
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ $('_REQUEST').item.json }}"
},
"typeVersion": 1.5
},
{
"id": "f6d82071-1a0a-457d-b09e-9a61120c07b4",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1200,
-720
],
"parameters": {
"color": 7,
"width": 1296,
"height": 928,
"content": "## Endpoint-based routing\nDuplicated fallback nodes to prevent visual clutter, all fallbacks can ofc also route to a centralized flow."
},
"typeVersion": 1
},
{
"id": "ec02dbe3-82e1-4398-98e1-111ce7d01b6b",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2656,
-720
],
"parameters": {
"color": 4,
"width": 1168,
"height": 544,
"content": "## Endpoint Implementation\nSubworkflows are used as a placeholder, implementation can ofc also just be inline.\n"
},
"typeVersion": 1
},
{
"id": "80e850ec-66c5-4537-8c26-5bd128bc8676",
"name": "Routing",
"type": "n8n-nodes-base.noOp",
"position": [
1296,
-208
],
"parameters": {},
"typeVersion": 1
},
{
"id": "2fc22f0a-df85-49d9-8e21-80de2c3c9a75",
"name": "Check baz status",
"type": "n8n-nodes-base.noOp",
"position": [
3136,
-592
],
"parameters": {},
"typeVersion": 1
},
{
"id": "90650048-1797-420e-b8bd-1032aec09742",
"name": "Create new baz",
"type": "n8n-nodes-base.noOp",
"position": [
3136,
-384
],
"parameters": {},
"typeVersion": 1
},
{
"id": "0279ee50-54df-4d2d-b1ed-7fdf6ebb652b",
"name": "Implementation",
"type": "n8n-nodes-base.executeWorkflow",
"onError": "continueRegularOutput",
"position": [
3328,
-592
],
"parameters": {
"source": "parameter",
"options": {
"waitForSubWorkflow": false
},
"workflowJson": "{}"
},
"typeVersion": 1.3
},
{
"id": "0050daa5-2edb-484b-abb7-c618cd442abc",
"name": "Implementation1",
"type": "n8n-nodes-base.executeWorkflow",
"onError": "continueRegularOutput",
"position": [
3328,
-384
],
"parameters": {
"source": "parameter",
"options": {
"waitForSubWorkflow": false
},
"workflowJson": "{}"
},
"typeVersion": 1.3
},
{
"id": "34b83843-804b-43f6-8475-623ecc63b89a",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-304,
320
],
"parameters": {
"color": 5,
"width": 1248,
"height": 1200,
"content": "## Example for $json-based vs. absolute $('_NODE') notation for data access\nNodes that don't pass through content, like DB nodes, require cumbersome and cluttersome branching -> merging to preserve the n8n default principle of continuous data flow via the $json object. \n\nAs an alternative, absolute node references can help tremendously to reduce visual clutter. Support for absolute references is very good:\n- when renaming a target node, any absolute call reference will automatically update to the new name\n- when copying a whole section of a workflow that includes absolute references AND the target node, absolute references will be updated to the new target copy\n\nIn order to be able to reference a node:\n- the target node must be on the path to the node you are trying to reference it from\n- the target node must have been executed (check method in example)\n"
},
"typeVersion": 1
},
{
"id": "b1fe6080-4edc-4d15-91f0-f56bb352abf2",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
560,
672
],
"parameters": {
"mode": "chooseBranch"
},
"typeVersion": 3.2
},
{
"id": "acbfccc8-be97-4000-96af-b57b634a9b8a",
"name": "/foo",
"type": "n8n-nodes-base.switch",
"position": [
1872,
-240
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "025bf7d8-484b-4457-898a-55a8a39b3933",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $('_REQUEST').item.json.params.lvl2 == 'bar' }}",
"rightValue": "bar"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "bcbcd98d-625a-47ce-b752-90500c92fdf1",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $('_REQUEST').item.json.params.lvl2 == 'qux'}}",
"rightValue": "qux"
}
]
}
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3.4
},
{
"id": "8c8a1559-4246-4711-80dd-2806f9f853e0",
"name": "api root",
"type": "n8n-nodes-base.switch",
"position": [
1488,
-208
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "025bf7d8-484b-4457-898a-55a8a39b3933",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $('_REQUEST').item.json.params.lvl1 == 'foo' }}",
"rightValue": "foo"
}
]
}
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3.4
},
{
"id": "be329dc0-6874-44d5-8989-f8728197623e",
"name": "/foo/bar/baz",
"type": "n8n-nodes-base.noOp",
"position": [
2752,
-480
],
"parameters": {},
"typeVersion": 1
},
{
"id": "bef1ea6a-2e91-4f39-99f1-81676b53dbe5",
"name": "/foo/bar",
"type": "n8n-nodes-base.switch",
"position": [
2256,
-464
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a9e83028-162c-4b75-8d3b-b747bff055a8",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $('_REQUEST').item.json.params.lvl3 == 'baz'}}",
"rightValue": "baz"
}
]
}
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3.4
},
{
"id": "7732d88e-bc8c-4d74-9c99-c26d90437c67",
"name": "/foo/qux",
"type": "n8n-nodes-base.switch",
"position": [
2256,
-64
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "",
"rightValue": ""
}
]
}
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3.4
},
{
"id": "ca1c3fd7-05bf-426b-8fb8-68044cc5cb9b",
"name": "baz METHOD",
"type": "n8n-nodes-base.switch",
"position": [
2944,
-480
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "GET",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a9e83028-162c-4b75-8d3b-b747bff055a8",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('_REQUEST').item.json.method }}",
"rightValue": "GET"
}
]
},
"renameOutput": true
},
{
"outputKey": "POST",
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "355515a7-d7ce-4c4b-a665-4dcaac5d401a",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('_REQUEST').item.json.method }}",
"rightValue": "POST"
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "none"
}
},
"typeVersion": 3.4
},
{
"id": "fdf361ac-b211-4051-a666-6e72f7a9070e",
"name": "regular Set node",
"type": "n8n-nodes-base.set",
"position": [
176,
656
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "4b98db71-2a59-411f-b28f-e484d414f096",
"name": "test",
"type": "string",
"value": "we need this value"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "f910dc32-f762-464b-a938-3536a97b3f8b",
"name": "non-passthrough node",
"type": "n8n-nodes-base.executeWorkflow",
"onError": "continueRegularOutput",
"position": [
368,
768
],
"parameters": {
"source": "parameter",
"options": {
"waitForSubWorkflow": false
},
"workflowJson": "{}"
},
"typeVersion": 1.3
},
{
"id": "4985acc4-ba09-4fd1-bb97-acd75b2ac7da",
"name": "data via $json",
"type": "n8n-nodes-base.set",
"position": [
752,
672
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a0218318-24e6-4312-a7e3-397f626bf695",
"name": "test",
"type": "string",
"value": "={{ $json.test }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "57eb16cd-ffb2-4894-92a0-805396778504",
"name": "Named node",
"type": "n8n-nodes-base.set",
"position": [
176,
992
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "c984797c-e667-4f38-811b-446fca3dac9b",
"name": "test",
"type": "string",
"value": "we need this value"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "04cf9504-4620-4f85-820c-b6fcbcb6d6f7",
"name": "non-passthrough node1",
"type": "n8n-nodes-base.executeWorkflow",
"onError": "continueRegularOutput",
"position": [
368,
992
],
"parameters": {
"source": "parameter",
"options": {
"waitForSubWorkflow": false
},
"workflowJson": "{}"
},
"typeVersion": 1.3
},
{
"id": "f11e1ff4-c857-48f2-bd1b-c883a54e6ff2",
"name": "data via $('NODE')",
"type": "n8n-nodes-base.set",
"position": [
752,
992
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a0218318-24e6-4312-a7e3-397f626bf695",
"name": "test",
"type": "string",
"value": "={{ $('Named node').item.json.test }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "fa0a2770-f870-47af-9028-faa3a33b5ae6",
"name": "example: default $json-based",
"type": "n8n-nodes-base.noOp",
"position": [
-16,
656
],
"parameters": {},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "9ebccd9d-2f38-4b02-a3ae-253a6ab86c99",
"name": "example: $('NODE') based",
"type": "n8n-nodes-base.noOp",
"position": [
-16,
992
],
"parameters": {},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "6455c350-2f78-446e-a0c7-fbf74edce36f",
"name": "example: check for execution",
"type": "n8n-nodes-base.noOp",
"position": [
-16,
1296
],
"parameters": {},
"typeVersion": 1,
"alwaysOutputData": true
},
{
"id": "c905835f-82fa-41f6-a270-742e6e855b2b",
"name": "run examples",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-208,
992
],
"parameters": {},
"typeVersion": 1
},
{
"id": "7bde2def-0994-4d53-b1b3-45ee11ade62c",
"name": "optional path",
"type": "n8n-nodes-base.set",
"position": [
368,
1200
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a622a46b-b7d2-47a2-a8fd-f4aaae4dd6de",
"name": "test",
"type": "string",
"value": "we need this value"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "3c111485-8699-47c6-8c16-90f570b498bd",
"name": "50:50 randomizer",
"type": "n8n-nodes-base.if",
"position": [
176,
1296
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "38fa5843-9499-479e-b6ed-7465c05f76ee",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ Math.random() >= 0.5 }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"id": "a61bdd62-e908-4063-896d-41b677c7628f",
"name": "non-passthrough node2",
"type": "n8n-nodes-base.executeWorkflow",
"onError": "continueRegularOutput",
"position": [
560,
1312
],
"parameters": {
"source": "parameter",
"options": {
"waitForSubWorkflow": false
},
"workflowJson": "{}"
},
"typeVersion": 1.3
},
{
"id": "0731df76-749d-4a65-9b55-c2041a39a074",
"name": "data with fallback",
"type": "n8n-nodes-base.set",
"position": [
752,
1312
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a0218318-24e6-4312-a7e3-397f626bf695",
"name": "test",
"type": "string",
"value": "={{ $('optional path').isExecuted ? $('optional path').item.json.test : 'node not executed' }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "829745fe-f822-429a-8fad-5b701ab91417",
"name": "API entry point",
"type": "n8n-nodes-base.noOp",
"position": [
256,
-208
],
"parameters": {},
"typeVersion": 1
}
],
"connections": {
"/foo": {
"main": [
[
{
"node": "/foo/bar",
"type": "main",
"index": 0
}
],
[
{
"node": "/foo/qux",
"type": "main",
"index": 0
}
],
[
{
"node": "Invalid Route1",
"type": "main",
"index": 0
}
]
]
},
"_CFG": {
"main": [
[
{
"node": "Clear JSON",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "data via $json",
"type": "main",
"index": 0
}
]
]
},
"-> GET": {
"main": [
[
{
"node": "API entry point",
"type": "main",
"index": 0
}
]
]
},
"-> PUT": {
"main": [
[
{
"node": "API entry point",
"type": "main",
"index": 0
}
]
]
},
"-> POST": {
"main": [
[
{
"node": "API entry point",
"type": "main",
"index": 0
}
]
]
},
"Routing": {
"main": [
[
{
"node": "api root",
"type": "main",
"index": 0
}
]
]
},
"v1/seg1": {
"main": [
[
{
"node": "-> GET",
"type": "main",
"index": 0
}
],
[
{
"node": "-> POST",
"type": "main",
"index": 0
}
],
[
{
"node": "-> PUT",
"type": "main",
"index": 0
}
],
[
{
"node": "-> DELETE",
"type": "main",
"index": 0
}
]
]
},
"v1/seg2": {
"main": [
[
{
"node": "-> GET",
"type": "main",
"index": 0
}
],
[
{
"node": "-> POST",
"type": "main",
"index": 0
}
],
[
{
"node": "-> PUT",
"type": "main",
"index": 0
}
],
[
{
"node": "-> DELETE",
"type": "main",
"index": 0
}
]
]
},
"v1/seg3": {
"main": [
[
{
"node": "-> GET",
"type": "main",
"index": 0
}
],
[
{
"node": "-> POST",
"type": "main",
"index": 0
}
],
[
{
"node": "-> PUT",
"type": "main",
"index": 0
}
],
[
{
"node": "-> DELETE",
"type": "main",
"index": 0
}
]
]
},
"/foo/bar": {
"main": [
[
{
"node": "/foo/bar/baz",
"type": "main",
"index": 0
}
],
[
{
"node": "Invalid Route2",
"type": "main",
"index": 0
}
]
]
},
"/foo/qux": {
"main": [
[
{
"node": "Invalid Route3",
"type": "main",
"index": 0
}
]
]
},
"_REQUEST": {
"main": [
[
{
"node": "_CFG",
"type": "main",
"index": 0
}
]
]
},
"api root": {
"main": [
[
{
"node": "/foo",
"type": "main",
"index": 0
}
],
[
{
"node": "Invalid Route",
"type": "main",
"index": 0
}
]
]
},
"-> DELETE": {
"main": [
[
{
"node": "API entry point",
"type": "main",
"index": 0
}
]
]
},
"Clear JSON": {
"main": [
[
{
"node": "Routing",
"type": "main",
"index": 0
}
]
]
},
"Named node": {
"main": [
[
{
"node": "non-passthrough node1",
"type": "main",
"index": 0
}
]
]
},
"baz METHOD": {
"main": [
[
{
"node": "Check baz status",
"type": "main",
"index": 0
}
],
[
{
"node": "Create new baz",
"type": "main",
"index": 0
}
]
]
},
"/foo/bar/baz": {
"main": [
[
{
"node": "baz METHOD",
"type": "main",
"index": 0
}
]
]
},
"run examples": {
"main": [
[
{
"node": "example: default $json-based",
"type": "main",
"index": 0
},
{
"node": "example: $('NODE') based",
"type": "main",
"index": 0
},
{
"node": "example: check for execution",
"type": "main",
"index": 0
}
]
]
},
"optional path": {
"main": [
[
{
"node": "non-passthrough node2",
"type": "main",
"index": 0
}
]
]
},
"Create new baz": {
"main": [
[
{
"node": "Implementation1",
"type": "main",
"index": 0
}
]
]
},
"Implementation": {
"main": [
[
{
"node": "Respond to Webhook1",
"type": "main",
"index": 0
}
]
]
},
"API entry point": {
"main": [
[
{
"node": "_REQUEST",
"type": "main",
"index": 0
}
]
]
},
"Implementation1": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"50:50 randomizer": {
"main": [
[
{
"node": "optional path",
"type": "main",
"index": 0
}
],
[
{
"node": "non-passthrough node2",
"type": "main",
"index": 0
}
]
]
},
"Check baz status": {
"main": [
[
{
"node": "Implementation",
"type": "main",
"index": 0
}
]
]
},
"regular Set node": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
},
{
"node": "non-passthrough node",
"type": "main",
"index": 0
}
]
]
},
"non-passthrough node": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"non-passthrough node1": {
"main": [
[
{
"node": "data via $('NODE')",
"type": "main",
"index": 0
}
]
]
},
"non-passthrough node2": {
"main": [
[
{
"node": "data with fallback",
"type": "main",
"index": 0
}
]
]
},
"example: $('NODE') based": {
"main": [
[
{
"node": "Named node",
"type": "main",
"index": 0
}
]
]
},
"example: check for execution": {
"main": [
[
{
"node": "50:50 randomizer",
"type": "main",
"index": 0
}
]
]
},
"example: default $json-based": {
"main": [
[
{
"node": "regular Set node",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
A clean, extensible REST-style API routing template for n8n webhooks with up to 3 path levels. Serves API routes via Webhooks with path variables Normalizes incoming requests into "global" REQUEST and CFG nodes Flexible routing with Switch-nodes based on path segments & request…
Source: https://n8n.io/workflows/12789/ — 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.
PUQ Docker NextCloud deploy. Uses respondToWebhook, stickyNote, httpRequest, ssh. Webhook trigger; 44 nodes.
puq-docker-immich-deploy. Uses respondToWebhook, ssh, stickyNote. Webhook trigger; 35 nodes.
Analyze_email_headers_for_IPs_and_spoofing__3. Uses stickyNote, respondToWebhook, itemLists, httpRequest. Webhook trigger; 35 nodes.
puq-docker-n8n-deploy. Uses respondToWebhook, ssh, stickyNote. Webhook trigger; 34 nodes.
puq-docker-influxdb-deploy. Uses respondToWebhook, ssh, stickyNote. Webhook trigger; 33 nodes.