n8n
Human-in-the-loop AI workflows with mobile approvals
Overview
n8n is a workflow automation tool. With Nod, your n8n workflows can pause to ask humans for approval, send status updates to their phone, and wait for decisions — then continue based on the response. All through simple HTTP Request nodes calling the Nod API.
Download template
This template is a complete webhook agent with three event handlers: user messages, decision responses, and scheduled tasks. Download it and import into n8n to get started.
Import into n8n: Settings → Import from File → select the downloaded JSON.
Setup
- Create an agent in the Nod app. Note the
agent IDandsecretshown after creation. - Import the template into n8n (Settings → Import from File).
- Set your OpenAI credential — n8n will prompt you to select or create one for the AI nodes.
- Set your credentials in one place — open the
Credentialsnode (the first node after the Webhook). Replace the placeholder values with your own:Field Replace with agentId Your Nod agent ID (e.g. agt_abc123) agentSecret Your Nod agent secret (e.g. nod_abc123...) serperApiKey Your Serper.dev API key All other nodes reference these values automatically — you only set them once.
- Activate the workflow and copy the production webhook URL from the Webhook node (not the test URL).
- Set the webhook URL on your agent in the Nod app (Agent Settings → Webhook URL).
- Send a message from the Nod app — the workflow will process it and respond.
The Webhook node must respond immediately
Response Mode: Immediately (the onReceived option). Do not change this to "Using Respond to Webhook Node" — that holds the HTTP connection open until the workflow finishes, which might exceed Nod's 30-second timeout and trigger duplicate deliveries.How the template works
Every Nod event (messages, approvals, tasks) arrives at the same webhook URL as a POST request. The workflow routes each event to the right handler based on body.type.
Architecture
Nod Webhook → Credentials (sets agent ID, secret, API keys — one place for all) → Is User Message? → [message handling pipeline] → Is Decision Resolved? → [approval handling pipeline] → Is Task Due? → [task execution pipeline]
The three If nodes evaluate in parallel. Only one matches per event, so only one pipeline runs.
1. User messages
When a user sends a message from the Nod app:
- Processing: Start — shows "Thinking..." in the app
- Fetch Conversation History — gets the last 20 messages for context
- Build Context — formats the history and latest message for the AI
- AI Agent (OpenAI) — processes the message. If it needs current information, it responds with
SEARCH: <query> - Needs Web Search? — checks if the AI response starts with SEARCH:
If no search needed: sends the AI reply directly, then processing_stop clears the indicator.
If search needed: sends an approval request to the user's phone, then processing_stop. The workflow ends here — when the user responds, a new decision_resolved event triggers the next pipeline.
2. Decision responses
When the user taps Approve or Reject on a pending request:
- Approved → a Research Agent runs with OpenAI and the Serper web search tool, then sends the result as a message
- Rejected → a fallback AI answers from its own knowledge (no search), then sends that instead
Both paths end with processing_stop to clear the indicator.
3. Scheduled tasks
When a scheduled task fires:
- Task: Processing Start — shows the task is running
- Task Agent — OpenAI with web search (no approval needed — tasks search freely)
- Complete Task Run — calls
POST /api/agent/tasks/runs/:run_id/completewith the agent's output as the summary - Task: Processing Stop — clears the indicator
Chat bubble is created automatically
API features used
| Feature | What it does |
|---|---|
| processing_start / processing_stop | Shows and clears the "Thinking..." indicator |
| decision (kind: approval) | Sends an approval request to the user's phone |
| message | Sends a reply back to the conversation |
| alert | Logs activity events (visible in the activity feed) |
| GET .../conversations/:id/messages | Fetches conversation history for AI context |
| POST .../tasks/runs/:id/complete | Marks a task run as done (auto-creates chat bubble) |
Extend and customize
This template is a starting point. Here are ideas for extending it:
Add more tools
- Connect databases, APIs, or file storage as additional AI tools
- Add a code interpreter tool for data analysis
- Integrate with Slack, email, or calendar for the final output
User preferences and memory
- Store user preferences in a database (language, timezone, response style)
- Fetch preferences at the start of each execution to personalize responses
- Auto-allow certain actions based on stored preferences instead of asking every time
Task enhancements
- Use the task context scratchpad to persist state across multi-step tasks that pause for user input
- Send requests during task execution to ask for user input mid-task (they appear in the Requests inbox with a "Task" badge)
- Add error handling: if the AI agent fails, mark the run as
failedwith a summary
Custom event routing
- Add a branch for
task_triggerevents from external webhooks - Route different task types to different AI models or tool sets
- Use
status_textonprocessing_startfor custom indicator labels ("Searching the web...", "Analyzing data...")