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 →
{
"name": "[DEV] eval / testing-framework-data-table-api",
"description": null,
"active": true,
"nodes": [
{
"id": "webhook-requirements",
"name": "Webhook Requirements",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
0,
0
],
"parameters": {
"path": "testing-requirements",
"httpMethod": "POST",
"responseMode": "responseNode",
"options": {},
"authentication": "headerAuth"
}
},
{
"id": "code-router",
"name": "Parse Request",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
220,
0
],
"parameters": {
"jsCode": "const body = $input.first().json.body || {};\nconst query = $input.first().json.query || {};\n\nreturn [{\n json: {\n operation: body.operation || 'get',\n data: body.data || {},\n id: body.id || query.id,\n limit: parseInt(query.limit) || 50,\n offset: parseInt(query.offset) || 0\n }\n}];"
}
},
{
"id": "switch-operation",
"name": "Route by Operation",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
440,
0
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "insert",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "insert"
},
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "update",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "update"
},
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "delete",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "delete"
}
]
},
"fallbackOutput": "extra",
"options": {}
}
},
{
"id": "dt-req-insert",
"name": "Insert Requirement",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
-200
],
"parameters": {
"resource": "row",
"operation": "insert",
"dataTableId": {
"mode": "name",
"value": "testing-requirements"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"requirement_id": "={{ $json.data.requirement_id }}",
"user_intent": "={{ $json.data.user_intent }}",
"verbatim_quote": "={{ $json.data.verbatim_quote }}",
"captured_at": "={{ $json.data.captured_at }}",
"status": "={{ $json.data.status }}",
"source": "={{ $json.data.source }}",
"linked_tests": "={{ JSON.stringify($json.data.linked_tests || []) }}",
"tags": "={{ JSON.stringify($json.data.tags || []) }}"
}
}
}
},
{
"id": "dt-req-update",
"name": "Update Requirement",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
-100
],
"parameters": {
"resource": "row",
"operation": "update",
"dataTableId": {
"mode": "name",
"value": "testing-requirements"
},
"filters": {
"conditions": [
{
"keyName": "requirement_id",
"condition": "eq",
"keyValue": "={{ $json.id }}"
}
]
},
"columns": {
"mappingMode": "autoMapInputData",
"value": {}
}
}
},
{
"id": "dt-req-delete",
"name": "Delete Requirement",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
0
],
"parameters": {
"resource": "row",
"operation": "deleteRows",
"dataTableId": {
"mode": "name",
"value": "testing-requirements"
},
"filters": {
"conditions": [
{
"keyName": "requirement_id",
"condition": "eq",
"keyValue": "={{ $json.id }}"
}
]
}
}
},
{
"id": "dt-req-get",
"name": "Get Requirements",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
100
],
"parameters": {
"resource": "row",
"operation": "get",
"dataTableId": {
"mode": "name",
"value": "testing-requirements"
},
"returnAll": true
}
},
{
"id": "respond-success",
"name": "Respond Success",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
880,
0
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ { success: true, data: $json } }}"
}
},
{
"id": "webhook-cases",
"name": "Webhook Cases",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
0,
400
],
"parameters": {
"path": "testing-cases",
"httpMethod": "POST",
"responseMode": "responseNode",
"options": {},
"authentication": "headerAuth"
}
},
{
"id": "code-cases",
"name": "Parse Cases",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
220,
400
],
"parameters": {
"jsCode": "const body = $input.first().json.body || {};\nconst query = $input.first().json.query || {};\nreturn [{ json: { operation: body.operation || 'get', data: body.data || {}, id: body.id || query.id } }];"
}
},
{
"id": "switch-cases",
"name": "Route Cases Op",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
440,
400
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "insert",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "insert"
},
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "update",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "update"
},
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "delete",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "delete"
}
]
},
"fallbackOutput": "extra",
"options": {}
}
},
{
"id": "dt-cases-insert",
"name": "Insert Case",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
300
],
"parameters": {
"resource": "row",
"operation": "insert",
"dataTableId": {
"mode": "name",
"value": "testing-cases"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"test_id": "={{ $json.data.test_id }}",
"type": "={{ $json.data.type }}",
"requirement_id": "={{ $json.data.requirement_id }}",
"name": "={{ $json.data.name }}",
"description": "={{ $json.data.description }}",
"input": "={{ JSON.stringify($json.data.input || {}) }}",
"expected_output": "={{ JSON.stringify($json.data.expected_output || {}) }}",
"tags": "={{ JSON.stringify($json.data.tags || []) }}",
"enabled": "={{ $json.data.enabled }}",
"created_at": "={{ $json.data.created_at }}",
"updated_at": "={{ $json.data.updated_at }}"
}
}
}
},
{
"id": "dt-cases-update",
"name": "Update Case",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
400
],
"parameters": {
"resource": "row",
"operation": "update",
"dataTableId": {
"mode": "name",
"value": "testing-cases"
},
"filters": {
"conditions": [
{
"keyName": "test_id",
"condition": "eq",
"keyValue": "={{ $json.id }}"
}
]
},
"columns": {
"mappingMode": "autoMapInputData",
"value": {}
}
}
},
{
"id": "dt-cases-delete",
"name": "Delete Case",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
480
],
"parameters": {
"resource": "row",
"operation": "deleteRows",
"dataTableId": {
"mode": "name",
"value": "testing-cases"
},
"filters": {
"conditions": [
{
"keyName": "test_id",
"condition": "eq",
"keyValue": "={{ $json.id }}"
}
]
}
}
},
{
"id": "dt-cases-get",
"name": "Get Cases",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
550
],
"parameters": {
"resource": "row",
"operation": "get",
"dataTableId": {
"mode": "name",
"value": "testing-cases"
},
"returnAll": true
}
},
{
"id": "respond-cases",
"name": "Respond Cases",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
880,
400
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ { success: true, data: $json } }}"
}
},
{
"id": "webhook-results",
"name": "Webhook Results",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
0,
800
],
"parameters": {
"path": "testing-results",
"httpMethod": "POST",
"responseMode": "responseNode",
"options": {},
"authentication": "headerAuth"
}
},
{
"id": "code-results",
"name": "Parse Results",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
220,
800
],
"parameters": {
"jsCode": "const body = $input.first().json.body || {};\nconst query = $input.first().json.query || {};\nreturn [{ json: { operation: body.operation || 'get', data: body.data || {}, id: body.id || query.id, execution_id: query.execution_id } }];"
}
},
{
"id": "switch-results",
"name": "Route Results Op",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
440,
800
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "insert",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "insert"
}
]
},
"fallbackOutput": "extra",
"options": {}
}
},
{
"id": "dt-results-insert",
"name": "Insert Result",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
750
],
"parameters": {
"resource": "row",
"operation": "insert",
"dataTableId": {
"mode": "name",
"value": "testing-results"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"result_id": "={{ $json.data.result_id }}",
"test_id": "={{ $json.data.test_id }}",
"execution_id": "={{ $json.data.execution_id }}",
"requirement_id": "={{ $json.data.requirement_id }}",
"status": "={{ $json.data.status }}",
"actual_output": "={{ JSON.stringify($json.data.actual_output || {}) }}",
"latency_ms": "={{ $json.data.latency_ms }}",
"error_message": "={{ $json.data.error_message }}",
"executed_at": "={{ $json.data.executed_at }}",
"assertions_passed": "={{ $json.data.assertions_passed }}",
"assertions_failed": "={{ $json.data.assertions_failed }}"
}
}
}
},
{
"id": "dt-results-get",
"name": "Get Results",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
900
],
"parameters": {
"resource": "row",
"operation": "get",
"dataTableId": {
"mode": "name",
"value": "testing-results"
},
"returnAll": true
}
},
{
"id": "respond-results",
"name": "Respond Results",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
880,
800
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ { success: true, data: $json } }}"
}
},
{
"id": "webhook-runs",
"name": "Webhook Runs",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
0,
1200
],
"parameters": {
"path": "testing-runs",
"httpMethod": "POST",
"responseMode": "responseNode",
"options": {},
"authentication": "headerAuth"
}
},
{
"id": "code-runs",
"name": "Parse Runs",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
220,
1200
],
"parameters": {
"jsCode": "const body = $input.first().json.body || {};\nconst query = $input.first().json.query || {};\nreturn [{ json: { operation: body.operation || 'get', data: body.data || {}, id: body.id || query.id } }];"
}
},
{
"id": "switch-runs",
"name": "Route Runs Op",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
440,
1200
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "insert",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "insert"
},
{
"conditions": {
"options": {
"version": 2,
"combinator": "and"
},
"conditions": [
{
"leftValue": "={{ $json.operation }}",
"rightValue": "update",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "update"
}
]
},
"fallbackOutput": "extra",
"options": {}
}
},
{
"id": "dt-runs-insert",
"name": "Insert Run",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
1100
],
"parameters": {
"resource": "row",
"operation": "insert",
"dataTableId": {
"mode": "name",
"value": "testing-runs"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"execution_id": "={{ $json.data.execution_id }}",
"started_at": "={{ $json.data.started_at }}",
"completed_at": "={{ $json.data.completed_at }}",
"triggered_by": "={{ $json.data.triggered_by }}",
"trigger_source": "={{ $json.data.trigger_source }}",
"total_tests": "={{ $json.data.total_tests }}",
"passed": "={{ $json.data.passed }}",
"failed": "={{ $json.data.failed }}",
"errors": "={{ $json.data.errors }}",
"skipped": "={{ $json.data.skipped }}",
"pass_rate": "={{ $json.data.pass_rate }}",
"avg_latency_ms": "={{ $json.data.avg_latency_ms }}"
}
}
}
},
{
"id": "dt-runs-update",
"name": "Update Run",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
1200
],
"parameters": {
"resource": "row",
"operation": "update",
"dataTableId": {
"mode": "name",
"value": "testing-runs"
},
"filters": {
"conditions": [
{
"keyName": "execution_id",
"condition": "eq",
"keyValue": "={{ $json.id }}"
}
]
},
"columns": {
"mappingMode": "autoMapInputData",
"value": {}
}
}
},
{
"id": "dt-runs-get",
"name": "Get Runs",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [
660,
1300
],
"parameters": {
"resource": "row",
"operation": "get",
"dataTableId": {
"mode": "name",
"value": "testing-runs"
},
"returnAll": true
}
},
{
"id": "respond-runs",
"name": "Respond Runs",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [
880,
1200
],
"parameters": {
"respondWith": "json",
"responseBody": "={{ { success: true, data: $json } }}"
}
}
],
"connections": {
"Webhook Requirements": {
"main": [
[
{
"node": "Parse Request",
"type": "main",
"index": 0
}
]
]
},
"Parse Request": {
"main": [
[
{
"node": "Route by Operation",
"type": "main",
"index": 0
}
]
]
},
"Route by Operation": {
"main": [
[
{
"node": "Insert Requirement",
"type": "main",
"index": 0
}
],
[
{
"node": "Update Requirement",
"type": "main",
"index": 0
}
],
[
{
"node": "Delete Requirement",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Requirements",
"type": "main",
"index": 0
}
]
]
},
"Insert Requirement": {
"main": [
[
{
"node": "Respond Success",
"type": "main",
"index": 0
}
]
]
},
"Update Requirement": {
"main": [
[
{
"node": "Respond Success",
"type": "main",
"index": 0
}
]
]
},
"Delete Requirement": {
"main": [
[
{
"node": "Respond Success",
"type": "main",
"index": 0
}
]
]
},
"Get Requirements": {
"main": [
[
{
"node": "Respond Success",
"type": "main",
"index": 0
}
]
]
},
"Webhook Cases": {
"main": [
[
{
"node": "Parse Cases",
"type": "main",
"index": 0
}
]
]
},
"Parse Cases": {
"main": [
[
{
"node": "Route Cases Op",
"type": "main",
"index": 0
}
]
]
},
"Route Cases Op": {
"main": [
[
{
"node": "Insert Case",
"type": "main",
"index": 0
}
],
[
{
"node": "Update Case",
"type": "main",
"index": 0
}
],
[
{
"node": "Delete Case",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Cases",
"type": "main",
"index": 0
}
]
]
},
"Insert Case": {
"main": [
[
{
"node": "Respond Cases",
"type": "main",
"index": 0
}
]
]
},
"Update Case": {
"main": [
[
{
"node": "Respond Cases",
"type": "main",
"index": 0
}
]
]
},
"Delete Case": {
"main": [
[
{
"node": "Respond Cases",
"type": "main",
"index": 0
}
]
]
},
"Get Cases": {
"main": [
[
{
"node": "Respond Cases",
"type": "main",
"index": 0
}
]
]
},
"Webhook Results": {
"main": [
[
{
"node": "Parse Results",
"type": "main",
"index": 0
}
]
]
},
"Parse Results": {
"main": [
[
{
"node": "Route Results Op",
"type": "main",
"index": 0
}
]
]
},
"Route Results Op": {
"main": [
[
{
"node": "Insert Result",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Results",
"type": "main",
"index": 0
}
]
]
},
"Insert Result": {
"main": [
[
{
"node": "Respond Results",
"type": "main",
"index": 0
}
]
]
},
"Get Results": {
"main": [
[
{
"node": "Respond Results",
"type": "main",
"index": 0
}
]
]
},
"Webhook Runs": {
"main": [
[
{
"node": "Parse Runs",
"type": "main",
"index": 0
}
]
]
},
"Parse Runs": {
"main": [
[
{
"node": "Route Runs Op",
"type": "main",
"index": 0
}
]
]
},
"Route Runs Op": {
"main": [
[
{
"node": "Insert Run",
"type": "main",
"index": 0
}
],
[
{
"node": "Update Run",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Runs",
"type": "main",
"index": 0
}
]
]
},
"Insert Run": {
"main": [
[
{
"node": "Respond Runs",
"type": "main",
"index": 0
}
]
]
},
"Update Run": {
"main": [
[
{
"node": "Respond Runs",
"type": "main",
"index": 0
}
]
]
},
"Get Runs": {
"main": [
[
{
"node": "Respond Runs",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"availableInMCP": false
},
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
[DEV] eval / testing-framework-data-table-api. Uses dataTable. Webhook trigger; 29 nodes.
Source: https://github.com/wranngle/n8n_showcase/blob/main/workflows/eval/testing-framework-data-table-api.json — 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.
A production-ready authentication workflow implementing secure user registration, login, token verification, and refresh token mechanisms. Perfect for adding authentication to any application without
[PROD] elevenlabs-cicd. Uses dataTable. Webhook trigger; 12 nodes.