This workflow follows the Datatable → HTTP Request 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 →
{
"name": "concept-comparison",
"nodes": [
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
0,
0
],
"id": "dd28341c-cb87-49a5-8562-4a809bc0915c",
"name": "When clicking \u2018Execute workflow\u2019"
},
{
"parameters": {
"jsCode": "// utils\n\nfunction indexBy(f, objs) {\n return objs.reduce((acc, c) => {\n acc[f(c)] = c;\n return acc;\n },\n {});\n}\n\nreturn [{\n json: {\n properties: $('Set properties').first().json,\n parameters: indexBy((c) => c.parameter, items.map(item => item.json))\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
560,
0
],
"id": "5e60a30a-9e0c-4207-bb56-4a1a14f53389",
"name": "Merge items"
},
{
"parameters": {
"jsCode": "// utils\nfunction toPerc(x) {\n return Math.round(x * 100) + '%'\n}\n// core\nconst perspective_aspects = \n $('AI-function: compare concepts').first().json.result.perspective_aspects;\n//console.log(perspective_aspects);\nlet features = perspective_aspects.reduce((acc, aspect) => \n [...acc, ...aspect.aspect_features.map(feature => \n ({\n LLM_model: $('Merge items').first().json.parameters.LLM_model.value,\n type: 'feature_score',\n ...feature,\n aspect_name: aspect.aspect_name,\n a_winner: feature.normalized_comparison > 0,\n a_score: feature.normalized_comparison >= 0 ? toPerc(feature.normalized_comparison) : 0,\n b_winner: feature.normalized_comparison < 0,\n b_score: feature.normalized_comparison <= 0 ? toPerc(-feature.normalized_comparison) : 0,\n message: `a_concept: ${$('Merge items').first().json.parameters.a_concept.value}, b_concept: ${$('Merge items').first().json.parameters.b_concept.value}`})\n )]\n , []);\nconst comparison_total = $('AI-function: compare concepts').first().json.result.comparison_total;\nconst a_winner_total = comparison_total > 0;\nconst b_winner_total = comparison_total < 0;\nfeatures = [{\n LLM_model: $('Merge items').first().json.parameters.LLM_model.value,\n type: 'model_total',\n aspect_name: '-',\n feature_name: '-',\n a_winner: a_winner_total,\n a_score: toPerc(comparison_total),\n b_winner: b_winner_total,\n b_score: toPerc(-comparison_total),\n message: `Winner concept: ${$('AI-function: compare concepts').first().json.result.comparison_winner}\\nOther_details:\\nperspective_observer_strategy: ${$('AI-function: compare concepts').first().json.result.perspective_observer_strategy}\\npoint_of_view: ${$('AI-function: compare concepts').first().json.result.point_of_view}\\nsuperordinate_concept: ${$('AI-function: compare concepts').first().json.result.superordinate_concept}`\n }, \n ... features];\nreturn features;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
992,
0
],
"id": "be2e3669-b8f9-4bf8-aeb0-e6b8f2443acc",
"name": "Split items"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "ad40503a-0154-401b-98cb-5151db0c93bd",
"name": "ai_functions_url",
"value": "http://127.0.0.1:5001",
"type": "string"
},
{
"id": "a0fb242a-270d-4343-afdd-2ea693c9e4b3",
"name": "ai_functions_api_token",
"value": "xxx",
"type": "string"
},
{
"id": "8d4b81b8-5f92-4ff9-97c4-5ebcbc54f66e",
"name": "extra_information_retrieval_strategy",
"value": "Only_unbiased_authorative_sources: true",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
208,
0
],
"id": "0765eb51-9878-4f11-b357-1796083b6386",
"name": "Set properties"
},
{
"parameters": {
"method": "PUT",
"url": "={{ $json.properties.ai_functions_url }}/ai-func/concept_aspect_comparison",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Api-Token",
"value": "={{ $json.properties.ai_functions_api_token }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"observer_context_description\": \"{{ $json.parameters.observer_context_description.value }}\", \"frame_of_reference\": \"{{ $json.parameters.frame_of_reference.value }}\",\n\"a_concept\": \"{{ $json.parameters.a_concept.value }}\",\n\"b_concept\": \"{{ $json.parameters.b_concept.value }}\", \"output_content_language\": \"{{ $json.parameters.output_content_language.value }}\",\n\"extra_information_retrieval_strategy\": \"{{ $json.properties.extra_information_retrieval_strategy }}\",\n\"meta\": {\"model\": \"{{ $json.parameters.LLM_model.value }}\"}} ",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.3,
"position": [
768,
0
],
"id": "86e2f6af-3efd-403d-bf95-8ea687b8e489",
"name": "AI-function: compare concepts"
},
{
"parameters": {
"operation": "get",
"dataTableId": {
"__rl": true,
"value": "Mc7cdh2eJFl2DB5Z",
"mode": "list",
"cachedResultName": "concept-comparison-input",
"cachedResultUrl": "/projects/QosD6QypqpaVnHlA/datatables/Mc7cdh2eJFl2DB5Z"
},
"returnAll": true
},
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1,
"position": [
384,
0
],
"id": "2e17c18c-142d-49b0-896f-e40207ae316b",
"name": "Read input table"
},
{
"parameters": {
"operation": "deleteRows",
"dataTableId": {
"__rl": true,
"value": "c9OXF8AX7G7DVI9n",
"mode": "list",
"cachedResultName": "concept-comparison-output",
"cachedResultUrl": "/projects/QosD6QypqpaVnHlA/datatables/c9OXF8AX7G7DVI9n"
},
"filters": {
"conditions": [
{
"condition": "isNotEmpty"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1,
"position": [
0,
192
],
"id": "7e18d02f-49e0-491b-abcc-8624c883dd98",
"name": "Clear output table",
"alwaysOutputData": true,
"disabled": true
},
{
"parameters": {
"dataTableId": {
"__rl": true,
"value": "c9OXF8AX7G7DVI9n",
"mode": "list",
"cachedResultName": "concept-comparison-output",
"cachedResultUrl": "/projects/QosD6QypqpaVnHlA/datatables/c9OXF8AX7G7DVI9n"
},
"columns": {
"mappingMode": "defineBelow",
"value": {
"a_concept_score": "={{ $json.a_score }}",
"b_concept_score": "={{ $json.b_score }}",
"aspect_feature": "={{ $json.feature_name || '-' }}",
"aspect_name": "={{ $json.aspect_name || '-' }}",
"a_concept_winner": "={{ $json.a_winner }}",
"b_concept_winner": "={{ $json.b_winner }}",
"type": "={{ $json.type }}",
"message": "={{ $json.message }}",
"LLM_model": "={{ $json.LLM_model }}"
},
"matchingColumns": [],
"schema": [
{
"id": "LLM_model",
"displayName": "LLM_model",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "type",
"displayName": "type",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "aspect_name",
"displayName": "aspect_name",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "aspect_feature",
"displayName": "aspect_feature",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "a_concept_winner",
"displayName": "a_concept_winner",
"required": false,
"defaultMatch": false,
"display": true,
"type": "boolean",
"readOnly": false,
"removed": false
},
{
"id": "a_concept_score",
"displayName": "a_concept_score",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "b_concept_winner",
"displayName": "b_concept_winner",
"required": false,
"defaultMatch": false,
"display": true,
"type": "boolean",
"readOnly": false,
"removed": false
},
{
"id": "b_concept_score",
"displayName": "b_concept_score",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
},
{
"id": "message",
"displayName": "message",
"required": false,
"defaultMatch": false,
"display": true,
"type": "string",
"readOnly": false,
"removed": false
}
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1,
"position": [
1184,
0
],
"id": "68406bab-5063-4cf3-ba64-c3b0e9dcf37b",
"name": "Update output table"
}
],
"connections": {
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Set properties",
"type": "main",
"index": 0
}
]
]
},
"Merge items": {
"main": [
[
{
"node": "AI-function: compare concepts",
"type": "main",
"index": 0
}
]
]
},
"Split items": {
"main": [
[
{
"node": "Update output table",
"type": "main",
"index": 0
}
]
]
},
"Set properties": {
"main": [
[
{
"node": "Read input table",
"type": "main",
"index": 0
}
]
]
},
"AI-function: compare concepts": {
"main": [
[
{
"node": "Split items",
"type": "main",
"index": 0
}
]
]
},
"Read input table": {
"main": [
[
{
"node": "Merge items",
"type": "main",
"index": 0
}
]
]
},
"Clear output table": {
"main": [
[]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "490c9a24-135e-4e10-94ff-27aaf44235c0",
"id": "Oa0L0tGz2uumQHDe",
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
concept-comparison. Uses httpRequest, dataTable. Event-driven trigger; 8 nodes.
Source: https://github.com/ady1981/core-kbt/blob/b9b4556b04515eca87ffa83a9c2966bf3c0cca5c/examples/n8n/concept-comparison.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.
This workflow automates the collection of public procurement data from TenderNed (the official Dutch tender platform). It: Fetches the latest tender publications from the TenderNed API Retrieves detai
This workflow automates the management of Zoom OAuth tokens and the creation of new Zoom users through the Zoom API.
How It Works This sub-workflow uploads files to Dropbox and returns a direct download link:
Fetch up to 100 of your latest Threads posts along with their insights (views, likes, replies, reposts, quotes), build a formatted HTML summary table, and send it to your inbox automatically.
This workflow collects a seed keyword via an n8n form, triggers Keupera keyword research, polls until the job completes, and stores the resulting keyword list (intent, volume, difficulty, CPC, and mor