This workflow follows the Executecommand → 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": "KP Case Agent Native n8n",
"nodes": [
{
"parameters": {},
"id": "72de32b5-fd49-4e2d-a283-b2908f611631",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
240,
360
]
},
{
"parameters": {
"mode": "manual",
"jsonOutput": "{\n \"pythonBin\": \"C:/Users/civ/Desktop/n8n/kp_sender_python/.venv/Scripts/python.exe\",\n \"prepareScriptPath\": \"C:/Users/civ/Desktop/n8n/kp_sender_python/src/n8n_prepare_rows.py\",\n \"renderScriptPath\": \"C:/Users/civ/Desktop/n8n/kp_sender_python/src/n8n_render_row.py\",\n \"startRow\": 1,\n \"endRow\": 5,\n \"outgoingStart\": 101,\n \"runId\": \"n8n-native-demo\",\n \"caseAgentMode\": \"auto_fix\",\n \"caseAgentModel\": \"gpt-4o-mini\",\n \"caseAgentAutoFixMinConfidence\": 0.9\n}"
},
"id": "a6d66782-7de4-4212-abca-bf31f45fb3fd",
"name": "Workflow Config",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
500,
360
]
},
{
"parameters": {
"jsCode": "const cfg = $input.first().json;\nconst quote = (value) => `\"${String(value).replaceAll('\"', '\\\\\"')}\"`;\nconst parts = [\n quote(cfg.pythonBin),\n quote(cfg.prepareScriptPath),\n '--start', String(cfg.startRow ?? 1),\n '--end', String(cfg.endRow ?? cfg.startRow ?? 1),\n '--outgoing-start', String(cfg.outgoingStart ?? 101),\n];\nreturn [{ json: { ...cfg, commandLine: parts.join(' ') } }];"
},
"id": "24144397-0269-4ebe-ba91-f65ec03e1dc4",
"name": "Build Prepare Command",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
760,
360
]
},
{
"parameters": {
"command": "={{ $json.commandLine }}"
},
"id": "7020cf25-7750-46a4-90f0-8161ddecc6f9",
"name": "Prepare Rows",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [
1020,
360
]
},
{
"parameters": {
"jsCode": "const raw = $json.stdout || '';\nconst parsed = JSON.parse(raw);\nif (!parsed.ok) {\n throw new Error(parsed.error || 'Prepare step failed');\n}\nreturn (parsed.items || []).map((item) => ({\n json: {\n ...item,\n workflowMeta: {\n xlsxPath: parsed.xlsx_path,\n selectedRange: parsed.selected_range,\n },\n },\n}));"
},
"id": "d0f6c9ca-4166-47ab-90f7-b9ff13e9e5c4",
"name": "Expand Rows",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1280,
360
]
},
{
"parameters": {
"jsCode": "const cfg = $('Workflow Config').first().json;\nconst payload = ($json.reviews || []).map((review) => ({\n field: review.field,\n source_value: review.source_value,\n generated_value: review.generated_value,\n target_case: review.target_case,\n context_sentence: review.context_sentence,\n slot_instruction: review.slot_instruction,\n slot_label: review.slot_label,\n}));\nconst prompt = [\n '\u0422\u044b \u0430\u0433\u0435\u043d\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0443\u0441\u0441\u043a\u0438\u0445 \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043e\u043a \u0432 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0445.',\n '\u0422\u0432\u043e\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435 \u0443\u0433\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u0434\u0435\u0436 \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043f\u043e\u043b\u044f, \u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0435\u043a\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0442\u043e\u044f\u0442\u044c \u0432 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 [SLOT] \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0444\u0440\u0430\u0437\u044b \u0448\u0430\u0431\u043b\u043e\u043d\u0430.',\n '\u0421\u043c\u043e\u0442\u0440\u0438 \u043d\u0430 \u0432\u0441\u044e \u0444\u0440\u0430\u0437\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0434\u043b\u044f [SLOT].',\n '\u041d\u0435 \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u0443\u0439\u0441\u044f \u043d\u0430 \u0441\u0442\u0430\u0440\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043a\u0430\u043a \u043d\u0430 \u044d\u0442\u0430\u043b\u043e\u043d.',\n '\u0415\u0441\u043b\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0435\u0441\u0442\u044c \u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u043e\u0435 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435, \u043d\u0435 \u0441\u043a\u043b\u043e\u043d\u044f\u0439 \u0435\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0431\u0435\u0437 \u044f\u0432\u043d\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438.',\n '\u0415\u0441\u043b\u0438 generated_value \u0443\u0436\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0434\u043b\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0438 [SLOT], \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0435\u0440\u043d\u0438 status=\"ok\".',\n '\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 status=\"fix\" \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 corrected_value \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 generated_value.',\n '\u0415\u0441\u043b\u0438 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u043f\u043e\u0440\u043d\u044b\u0439, \u0432\u0435\u0440\u043d\u0438 status=\"needs_review\".',\n '\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0435\u0440\u043d\u0438 confidence \u043e\u0442 0.0 \u0434\u043e 1.0.',\n '\u0412\u0435\u0440\u043d\u0438 \u0442\u043e\u043b\u044c\u043a\u043e JSON-\u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432\u0438\u0434\u0430 {\"field\":\"...\", \"status\":\"ok|fix|needs_review\", \"corrected_value\":\"...\", \"confidence\":0.0, \"comment\":\"...\"}.',\n '',\n '\u0414\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438:',\n JSON.stringify(payload, null, 2),\n].join('\\n');\nreturn [{\n json: {\n ...$json,\n openaiRequestBody: {\n model: cfg.caseAgentModel || 'gpt-4o-mini',\n response_format: { type: 'json_object' },\n messages: [\n {\n role: 'user',\n content: prompt,\n },\n ],\n },\n },\n}];"
},
"id": "5716d5ef-ca3d-4643-8100-59f1b09f8a07",
"name": "Build AI Request",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1540,
360
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.openai.com/v1/chat/completions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{$env.OPENAI_API_KEY}}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json.openaiRequestBody) }}",
"options": {}
},
"id": "74bc50d0-b68a-4d7e-8c7e-852e7a8ccdc2",
"name": "OpenAI Case Review",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1800,
360
]
},
{
"parameters": {
"jsCode": "const cfg = $('Workflow Config').first().json;\nconst reviews = $json.reviews || [];\nlet parsedItems = [];\nlet error = null;\ntry {\n const raw = $json.choices?.[0]?.message?.content || '{}';\n let parsed = JSON.parse(raw);\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n parsed = parsed.items || parsed.result || parsed.results || parsed;\n }\n parsedItems = Array.isArray(parsed) ? parsed : [];\n} catch (e) {\n error = e.message;\n}\nconst reviewMap = new Map(reviews.map((review) => [review.field, review]));\nconst normalized = [];\nconst seen = new Set();\nfor (const item of parsedItems) {\n const field = item?.field;\n if (!field || !reviewMap.has(field)) continue;\n const review = reviewMap.get(field);\n const generated = String(review.generated_value || '').trim();\n const corrected = String(item.corrected_value ?? generated).trim() || generated;\n let status = String(item.status || 'needs_review').toLowerCase();\n let confidence = Number(item.confidence ?? 0);\n if (!Number.isFinite(confidence)) confidence = 0;\n let comment = String(item.comment || '').trim();\n if (!['ok', 'fix', 'needs_review'].includes(status)) status = 'needs_review';\n if (corrected !== generated && status === 'ok') status = 'fix';\n if (corrected === generated && status === 'fix') {\n status = 'ok';\n if (!comment) comment = '\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0444\u043e\u0440\u043c\u0430 \u0443\u0436\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0430.';\n }\n if ((status === 'ok' || status === 'fix') && confidence <= 0) confidence = 0.8;\n normalized.push({\n field,\n source_value: review.source_value,\n generated_value: generated,\n status,\n corrected_value: corrected,\n confidence,\n comment,\n });\n seen.add(field);\n}\nfor (const review of reviews) {\n if (seen.has(review.field)) continue;\n normalized.push({\n field: review.field,\n source_value: review.source_value,\n generated_value: review.generated_value,\n status: 'needs_review',\n corrected_value: review.generated_value,\n confidence: 0,\n comment: error || '\u041f\u043e\u043b\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 AI-\u0430\u0433\u0435\u043d\u0442\u0430.',\n });\n}\nconst summary = {\n reviewed_fields_count: reviews.length,\n ok_count: normalized.filter((item) => item.status === 'ok').length,\n fix_count: normalized.filter((item) => item.status === 'fix').length,\n needs_review_count: normalized.filter((item) => item.status === 'needs_review').length,\n};\nreturn [{\n json: {\n ...$json,\n agent_result: {\n enabled: true,\n mode: cfg.caseAgentMode || 'auto_fix',\n error,\n items: normalized,\n summary,\n },\n },\n}];"
},
"id": "ec252dcb-46d8-4711-8d3c-7b82203a8817",
"name": "Normalize AI Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2060,
360
]
},
{
"parameters": {
"jsCode": "const cfg = $('Workflow Config').first().json;\nconst quote = (value) => `\"${String(value).replaceAll('\"', '\\\\\"')}\"`;\nconst payload = {\n row: $json.row,\n context: $json.context,\n agent_result: $json.agent_result,\n};\nconst payloadBase64 = Buffer.from(JSON.stringify(payload), 'utf8').toString('base64');\nconst parts = [\n quote(cfg.pythonBin),\n quote(cfg.renderScriptPath),\n '--payload-base64',\n quote(payloadBase64),\n];\nreturn [{ json: { ...$json, renderCommand: parts.join(' ') } }];"
},
"id": "0bc64182-6609-40f5-8d1d-d98c5ac1f14f",
"name": "Build Render Command",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2320,
360
]
},
{
"parameters": {
"command": "={{ $json.renderCommand }}"
},
"id": "b06f11cb-e934-4c7b-bc82-6d8e335d2462",
"name": "Render Documents",
"type": "n8n-nodes-base.executeCommand",
"typeVersion": 1,
"position": [
2580,
360
]
},
{
"parameters": {
"jsCode": "const parsed = JSON.parse($json.stdout || '{}');\nreturn [{ json: parsed }];"
},
"id": "23491955-60ec-48c2-a59c-992730e14519",
"name": "Parse Render Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2840,
360
]
},
{
"parameters": {
"mode": "runOnceForAllItems",
"jsCode": "const items = $input.all().map((entry) => entry.json);\nreturn [{\n json: {\n status: items.every((item) => item.ok !== false) ? 'success' : 'partial_or_failed',\n totalItems: items.length,\n folders: items.map((item) => ({\n mun_name: item.mun_name,\n output_folder: item.output_folder,\n review_path: item.review_path,\n case_agent_status: item.case_agent_status,\n case_agent_summary: item.case_agent_summary,\n })),\n },\n}];"
},
"id": "aaf3f56d-b0f8-4c65-8db4-18521d7029b1",
"name": "Final Summary",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3100,
360
]
}
],
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Workflow Config",
"type": "main",
"index": 0
}
]
]
},
"Workflow Config": {
"main": [
[
{
"node": "Build Prepare Command",
"type": "main",
"index": 0
}
]
]
},
"Build Prepare Command": {
"main": [
[
{
"node": "Prepare Rows",
"type": "main",
"index": 0
}
]
]
},
"Prepare Rows": {
"main": [
[
{
"node": "Expand Rows",
"type": "main",
"index": 0
}
]
]
},
"Expand Rows": {
"main": [
[
{
"node": "Build AI Request",
"type": "main",
"index": 0
}
]
]
},
"Build AI Request": {
"main": [
[
{
"node": "OpenAI Case Review",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Case Review": {
"main": [
[
{
"node": "Normalize AI Result",
"type": "main",
"index": 0
}
]
]
},
"Normalize AI Result": {
"main": [
[
{
"node": "Build Render Command",
"type": "main",
"index": 0
}
]
]
},
"Build Render Command": {
"main": [
[
{
"node": "Render Documents",
"type": "main",
"index": 0
}
]
]
},
"Render Documents": {
"main": [
[
{
"node": "Parse Render Result",
"type": "main",
"index": 0
}
]
]
},
"Parse Render Result": {
"main": [
[
{
"node": "Final Summary",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "28238eb1-fc0c-4f43-b544-fdd4d623c728",
"meta": {
"templateCredsSetupCompleted": true
},
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
KP Case Agent Native n8n. Uses executeCommand, httpRequest. Event-driven trigger; 12 nodes.
Source: https://github.com/Parallel-Solutions/mailing-agent/blob/1d802e2cbbe8dbebf6554acab69fd3ab8087a5e0/workflows/kp_case_agent_native_n8n.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.
Clara Pipeline A - Demo to v1. Uses executeCommand, httpRequest. Event-driven trigger; 8 nodes.
This workflow creates a multi-talented AI assistant named Simran that interacts with users via Telegram. It can handle text and voice messages, understand the user's intent, and perform various tasks.
RAG CHATBOT Main. Uses telegram, telegramTrigger, lmChatOpenAi, n8n-nodes-mcp. Event-driven trigger; 87 nodes.
Video-To-Hugo. Uses httpRequest, lmChatOllama, moveBinaryData, youTube. Event-driven trigger; 47 nodes.
Turbo Videogen. Uses lmChatOpenRouter, agent, httpRequest, formTrigger. Event-driven trigger; 41 nodes.