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": "agent-approval-gate (reference)",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "agent-proposal",
"options": {}
},
"name": "Webhook: ProposedAction in",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
240,
300
]
},
{
"parameters": {
"functionCode": "const a = $json.body || $json;\nconst required = ['proposal_id','agent','action_type','payload','created_at','tenant'];\nfor (const k of required) {\n if (!(k in a)) throw new Error('ProposedAction missing field: ' + k);\n}\nconst allowed = ['email.send','crm.update_record','ticket.create','db.update_row','api.call','n8n.trigger_workflow'];\nif (!allowed.includes(a.action_type)) throw new Error('Unknown action_type: ' + a.action_type);\nif (a.expires_at && new Date(a.expires_at) < new Date()) throw new Error('Proposal already expired');\nreturn [{json: a}];"
},
"name": "Validate against schema",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
460,
300
]
},
{
"parameters": {
"chatId": "={{$env.TG_APPROVER_CHAT_ID}}",
"text": "=*Proposed action:* `{{$json.action_type}}`\n*Tenant:* `{{$json.tenant}}`\n*Agent:* `{{$json.agent.name}}` v{{$json.agent.version}}\n*Risk:* {{$json.risk || 'unspecified'}}\n*Expires:* {{$json.expires_at || 'never'}}\n\n*Rationale:*\n{{$json.rationale}}\n\n*Payload:*\n```\n{{JSON.stringify($json.payload, null, 2)}}\n```\n\nReply `approve {{$json.proposal_id}}` or `reject {{$json.proposal_id}}` to decide.",
"additionalFields": {
"parse_mode": "Markdown"
}
},
"name": "Send to approver (Telegram)",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
680,
300
]
},
{
"parameters": {
"functionCode": "const proposal = $json;\nconst record = {\n event: 'proposed',\n proposal_id: proposal.proposal_id,\n tenant: proposal.tenant,\n action_type: proposal.action_type,\n agent: proposal.agent,\n payload: proposal.payload,\n rationale: proposal.rationale,\n created_at: proposal.created_at,\n logged_at: new Date().toISOString()\n};\nreturn [{json: record}];"
},
"name": "Append to audit log",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
900,
300
]
}
],
"connections": {
"Webhook: ProposedAction in": {
"main": [
[
{
"node": "Validate against schema",
"type": "main",
"index": 0
}
]
]
},
"Validate against schema": {
"main": [
[
{
"node": "Send to approver (Telegram)",
"type": "main",
"index": 0
}
]
]
},
"Send to approver (Telegram)": {
"main": [
[
{
"node": "Append to audit log",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"tags": [
"agent-approval-gate",
"ai-automation"
]
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
agent-approval-gate (reference). Uses telegram. Webhook trigger; 4 nodes.
Source: https://github.com/renezander030/agent-approval-gate/blob/37ce0fc7af206536afd04b2d591614f76dbf9517/examples/n8n-approval-workflow.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.
All-in-One Telegram/Baserow AI Assistant 🤖🧠 Voice/Photo/Save Notes/Long Term Mem. Uses telegram, baserowTool, baserow. Webhook trigger; 48 nodes.
🤖 Telegram Messaging Agent for Text/Audio/Images. Uses telegram, httpRequest. Webhook trigger; 39 nodes.
AI Phone Agent with RetellAI. Uses telegram, googleCalendar, httpRequest, googleDrive. Webhook trigger; 36 nodes.
Trato Hecho - Chat Agent. Uses httpRequest, telegram, gmail. Webhook trigger; 26 nodes.
Trato Hecho - Chat Agent. Uses httpRequest, telegram, gmail. Webhook trigger; 26 nodes.