Framework guides
How to add human approvals to n8n
Use HTTP Request and Wait nodes in n8n to pause workflows, route approvals through Contro1, and branch on the result.
n8n is often the fastest path to a working approval flow because you can compose the request, wait state, and branch logic with built-in nodes.
Use the integration skill
Copy this skill link into your code agent to add n8n and Contro1 to your system.
Key takeaways
- The five-node pattern - Trigger, Set, HTTP Request, Wait, Switch - covers 90% of approval workflows.
- An Error Trigger workflow turns any n8n execution failure into a Contro1 request for an on-call human.
- The callback-proxy script verifies the Contro1 signature before forwarding to the Wait node's resume URL.
- Keep execution_id in metadata so the Wait node only resumes the right execution.
When to reach for Contro1 with n8n
n8n is fantastic for ops automation but lacks a first-class "wait for a specific human to decide" node. Contro1 fills that gap - your workflow calls our API, pauses on Wait On Webhook Call, and resumes only when a verified operator decision comes back.
The typical setup is a single workflow with five nodes and a tiny callback proxy. Teams usually have it in production within an afternoon.
Installation
Basic integration
Case continuity
Set correlation_id to {{$execution.id}} so the approval request, Wait node resume, and follow-up audit records for the same n8n execution all appear in one case timeline.
Keep external_request_id unique per approval node. If the same execution has two approval points, they share correlation_id but use different idempotency keys.
Logging autonomous actions
Use POST /api/centcom/v1/audit-records from an HTTP Request node when the workflow performs an allowed action and only needs durable evidence.
For actions that happen after a Wait node resumes, include in_reply_to with the request id returned by the approval step.
Gate the tool before it executes
The tool function itself is the right place to require approval for irreversible actions. The first line of a destructive tool calls Contro1 and blocks until an operator decides. Nothing runs until the human says yes - no prompt engineering needed.
Place an HTTP Request node pointing to {{$env.CENTCOM_BASE_URL}}/requests, then a Wait node (On Webhook Call). Connect the Wait node's output to an IF node that branches on approved: true before the destructive action node runs.
Pause the agent on system error - orchestrator level
Create a second workflow of type "Error Trigger" that every production workflow routes to. On failure, it opens a Contro1 request describing which workflow died and where. An on-call engineer decides: retry the failed execution, mark it as skipped, or escalate.
Escalate tool errors to a human
If the real work happens in a custom service called by the n8n HTTP Request node (not inside n8n itself), wrap that service call so it can escalate on its own before returning an error to n8n.
Prompt engineering: force the agent to pause
If an LLM node in n8n authors the content that later triggers an approval, nail down behavior in its system prompt: the model must describe the proposed action in structured output (draft + target + scope) rather than acting on it.
See our GitHub integration repo
Reference implementation: request template + callback proxy + node-by-node wiring guide.
centcom-n8n on GitHub · request_payload.json - HTTP Request template · n8n_callback_proxy.py - signed-callback forwarder
Frequently asked questions
Can I use n8n for multi-step approvals?
Yes, but model it as explicit branches with clear timeout and escalation behavior rather than one ambiguous wait state. Chain Wait nodes with Switch nodes between them.
Why do I need a callback proxy - why not point Contro1 straight at the Wait resume URL?
The resume URL is not validated by n8n, so anyone with the URL could inject a fake decision. The proxy verifies the Contro1 HMAC signature first and only then forwards to n8n.
How do I handle timeouts?
Put a Switch node after the Wait with explicit branches for approved, rejected, and timed_out. Fail closed on timeout by default.
Does this work in n8n cloud?
Yes. Host the callback proxy wherever you like (Cloud Run, Vercel, Fly.io) - it just needs a public HTTPS URL and the CENTCOM_WEBHOOK_SECRET env var.