How to add WhatsApp to n8n.
The end-to-end recipe for catching inbound WhatsApp messages inside an n8n workflow and sending outbound replies from the same workflow. No WhatsApp Business API. No business verification. No template approval. Your customer scans one QR, the line is live, n8n triggers. Total time: under 30 minutes if n8n is already familiar.
Build the n8n workflow with a Webhook trigger
We start on the n8n side because Mossmoon delivers events to a webhook URL you attach to the line when you create it, so the URL has to exist first. In n8n, click + New Workflow. Add the first node by clicking the canvas, search for Webhook, choose Webhook (the trigger, not the Webhook Response action).
Provision a Mossmoon WhatsApp line
Sign up at mossmoon.app/signup if you haven’t already. Grab an API key from Dashboard > API keys. Provision a line with one POST, passing the n8n production URL from step 1 as the line’s webhook_url:
curl -X POST https://mossmoon.app/api/v1/wa/lines \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "existing",
"webhook_url": "https://your-instance.app.n8n.cloud/webhook/mossmoon-inbound",
"agency_external_user_id": "my_first_line"
}'Mossmoon returns:
{
"line_id": "wa_8f3c2e1a",
"status": "pending_link",
"mode": "existing",
"monthly_price_cents": 1500,
"connect_url": "https://mossmoon.app/wa/connect/<token>",
"webhook_secret": "wsec_...",
"created_at": "2026-06-12T14:30:00Z"
}Save the webhook_secret; it’s shown exactly once and signs every webhook Mossmoon sends you (step 4 uses it). You don’t need to hard-code the line_id: we’ll pull it from the inbound webhook payload in n8n.
Scan the QR
Open the connect_url in a browser. On your phone, open WhatsApp, tap Settings > Linked Devices > Link a Device, scan the QR.
The line transitions to ready within seconds. Mossmoon fires a line.ready webhook at the n8n URL you wired in step 2. Billing starts: 7-day free trial on your first line, $15/mo thereafter.
Catch a test inbound in n8n
To let n8n learn the inbound JSON shape, text the connected WhatsApp number from another phone. The message hits the webhook, n8n receives it, and the Webhook node now has a sample payload in its output. The shape (abridged):
{
"event": "message.received",
"line_id": "wa_8f3c2e1a",
"agency_external_user_id": "my_first_line",
"ts": "2026-06-12T14:35:22.001Z",
"data": {
"message_id": "wamsg_a1b2c3d4e5f6",
"from_me": false,
"from": "+15551234567",
"from_name": "Sarah K",
"is_group": false,
"type": "chat",
"text": "Hi, is the 3pm tour still available?",
"media_url": null,
"message_ts": "2026-06-12T14:35:21.812Z"
}
}One n8n quirk to know: the Webhook node nests the POST body under a body key, so the message text is {{ $json.body.data.text }} and the line ID is {{ $json.body.line_id }}. The full envelope (group context, reply quotes, media fields, contact identity) is in the webhook reference.
Add the HTTP Request node to send the reply
After the trigger, add whatever middle nodes you want. For this tutorial we’ll add an OpenAI node that drafts a reply, then an HTTP Request node that sends it through Mossmoon.
- After the Webhook node, add an OpenAI > Message a Model node. Pass
{{ $json.body.data.text }}as the user message. Give the system prompt whatever persona you want. The node returns the generated reply text. - After OpenAI, add an HTTP Request node. That’s the outbound through Mossmoon.
{
"to": "{{ $('Webhook').item.json.body.data.from }}",
"text": "{{ $json.message.content }}"
}The $('Webhook') reference pulls from the original trigger output regardless of which node you’re currently in. $json is the current node’s input (the OpenAI response in this case). Mossmoon answers 202 Accepted with a message_id and "status": "queued", then fires message.delivered or message.failed webhooks as the send progresses.
Save and activate the workflow. Send another test message from your phone. n8n triggers, OpenAI generates a reply, the HTTP Request node sends it through Mossmoon, your phone receives the response.
Patterns to build out from here
The two-node skeleton (Webhook trigger + HTTP outbound) handles every WhatsApp use case. Common things teams add in between:
- CRM-routed inbound. Postgres / Airtable / HubSpot nodes that look up the inbound number against contacts and create or attach the message to a record.
- Multi-line routing. Running multiple lines (one per client, one per agent, one per brand)? Add a Switch node that branches on
line_idand runs a different downstream workflow per line. - Calendar booking inline. Cal.com or Google Calendar nodes that fetch available slots when the AI decides it’s booking time. Send the slot list as a WhatsApp message. Catch the user’s pick on a follow-up inbound, confirm the booking.
- Media handling. Inbound payloads include images, voice notes, documents. Pipe images into OpenAI Vision, voice notes into Whisper, documents into your DMS. All inside the same workflow.
- AI agent loop. n8n’s native AI Agent node makes it trivial to wire a multi-turn conversation that keeps state across messages, queries tools (calendar, CRM, knowledge base), and replies through Mossmoon.
Why this beats n8n's Business API integrations
n8n has a native WhatsApp Business Cloud node and several community nodes that wrap Meta’s WhatsApp Business API. Everything you build with them inherits the Business API rules: every customer onboarded through Meta business verification (days to weeks per account), template pre-approval for every outbound past the 24-hour customer service window, per-conversation pricing.
The pattern in this tutorial avoids all of that. Mossmoon connects through the customer’s actual WhatsApp on their phone, not through Meta’s server-side API. No business verification. No template approval. No 24-hour window. No per-conversation fees. For a deeper comparison of the two paths, see: WhatsApp Business API vs personal WhatsApp API.
Spin up your first line and run the workflow this afternoon.
First line free for 7 days. No Meta onboarding. One QR scan. n8n trigger fires immediately.
Related reading: Make.com tutorial · GoHighLevel tutorial · Business API vs personal API · API without verification