n8n
Send and receive messages on every Zavu channel from an n8n workflow
The Zavu community node brings the whole messaging API into n8n: send on SMS, WhatsApp, Telegram, Email, Instagram, Messenger and Voice, run broadcasts, manage contacts and templates, and start workflows from inbound messages.
The package ships two nodes:
- Zavu sends messages and manages every resource in the API.
- Zavu Trigger starts a workflow when something happens: a message arrives, a delivery status changes, a conversation opens, a call ends.
Install
Open community nodes
In your self-hosted n8n, go to Settings → Community Nodes → Install.
Install the package
Enter
n8n-nodes-zavu, accept the risks prompt, and confirm.Restart if needed
n8n loads the nodes immediately. If they do not appear in the node panel, restart the instance.
Prefer the command line? From your n8n user folder (~/.n8n):
terminalnpm install n8n-nodes-zavu
n8n Cloud
n8n Cloud installs community nodes straight from the Nodes panel, but only those n8n has verified. This package is not verified yet, so today it needs self-hosted n8n. Until then, n8n Cloud can reach the same API through the HTTP Request node, which every operation here is a wrapper around: see the API reference.
Credentials
Create a Zavu API credential and paste a project API key from Dashboard → Settings → API Keys.
| Field | Notes |
|---|---|
| API Key | zv_live_… for production, zv_test_… for test mode |
| Base URL | https://api.zavu.dev. Leave the default. |
Click Test to confirm the key resolves to a project. A zv_test_ key
simulates sends against the WhatsApp sandbox instead of reaching the recipient,
and cannot place voice calls. Use a live key for anything that must be delivered.
What the Zavu node does
| Resource | Operations |
|---|---|
| Message | Send, Get, Get Many, Get Attachments, React, Show Typing Indicator |
| Conversation | Get, Get Many, Get Messages, Mark as Read |
| Contact | Create, Get, Get by Phone, Get Many, Update, Delete, Add Channel, Merge |
| Template | Create, Get, Get Many, Delete, Submit for Approval |
| Broadcast | Create, Add Contacts, Send, Get, Get Many, Get Progress, Cancel, Delete |
| Sender | Create, Get, Get Many, Update, Delete |
| Agent | Create, Get, Get Many, Update, Delete, Test, Connect Sender, Disconnect Sender |
| Voice Call | Create, Get, Get Many, Hang Up |
| Phone Number | Search Available, Purchase, Get, Get Many, Update, Release |
| Utility | Validate Phone, Validate Email, Submit URL, Get Balance, Get Account |
| Custom API Call | Any endpoint the node does not model, with the same credential |
Senders, templates, agents and phone numbers load as dropdowns, so you pick a name instead of pasting an ID. The sender dropdown also shows the channels each sender can actually send on, so a sender that is not ready yet is visible before you build the workflow around it.
Every list operation walks the API cursor, so Return All really does return all of them rather than stopping at the first page.
Sending
Channel defaults to Auto, which routes on the sender's capabilities and the
recipient. Any non-text message type is delivered over WhatsApp regardless.
To takes a phone number in E.164, an email address, a numeric chat ID for Telegram, Instagram or Messenger, or a WhatsApp business-scoped user ID.
The node builds every message type for you: text, image, video, audio, document, sticker, location, contact card, buttons, list, CTA URL, location request, contact info request, and template.
Broadcasts from a spreadsheet
Broadcast → Add Contacts can read one recipient per incoming item, which is the shape a Google Sheets or Postgres node already produces. Recipients are sent in batches of 1000, so a 5000 row sheet goes through in a single node.
Sending a broadcast needs no account verification. What it passes through is
content review. WhatsApp is the exception, because Meta's approval of the
template is the review; what is enforced there is that the template is approved.
Every other channel waits for the review, and a broadcast it refuses lands on
rejected. Creating and editing drafts requires nothing.
See Broadcasts and Sending limits.
Zavu Trigger
Pick a sender and the events to react to. On activation the node points that sender's webhook at n8n, and on deactivation it restores whatever was configured before.
Three things about Zavu webhooks shape how this node behaves.
Deliveries only go to HTTPS. A local n8n hands out
http://localhost:5678/…, which Zavu refuses. Expose n8n over HTTPS (a tunnel,
or WEBHOOK_URL set to your public address) before activating the workflow.
A sender has exactly one webhook URL. If it already points at your own backend, activation stops and tells you which URL is configured rather than silently taking it over. Turn on Replace Existing Webhook to repoint it; the previous URL is restored when you deactivate the trigger.
The webhook secret is revealed once. Zavu generates and returns a secret when it configures a webhook on a sender that had none. For a sender that already had one, the existing secret is kept and never shown again, so paste it into Webhook Secret to let the node verify signatures. When the node has no secret it says so on the first delivery instead of quietly accepting unsigned traffic.
Signature verification accepts both schemes Zavu emits and prefers the stronger one when a delivery carries both. See Webhook security.
If you would rather configure the webhook yourself in the dashboard, turn off Register Webhook Automatically and the node only listens.
Payload
The trigger emits the webhook payload as sent:
JSON{ "id": "evt_1736850000000_abc123", "type": "message.inbound", "timestamp": 1736850000000, "senderId": "jx7abc123def456", "projectId": "jx7xyz789ghi012", "data": { "messageId": "jd7x2k3m4n5p6q7r8s9t0", "from": "+56912345678", "to": "+13125551212", "channel": "whatsapp", "text": "Is my order shipped?" } }
Every event type is listed in Webhook events.
Example: auto-reply to inbound WhatsApp
Add the trigger
Zavu Trigger, your sender, event Message: Inbound.
Show that you are working on it
Zavu → Message → Show Typing Indicator, Message ID
{{ $json.data.messageId }}. Skip this if the reply is instant.Reply
Zavu → Message → Send, To
{{ $json.data.from }}, Channel WhatsApp. Under Options, set Sender to{{ $json.senderId }}so the answer leaves from the number the contact already knows.
Troubleshooting
Activation fails: Zavu only delivers webhooks to https:// URLs
Your n8n is handing out a local or plain HTTP address. Expose it over HTTPS
and set WEBHOOK_URL to that address, then activate again. To register the
webhook yourself instead, turn off Register Webhook Automatically.
Activation fails: the sender already sends its webhooks somewhere else
A sender has one webhook URL. Use a different sender, fan the events out from your existing receiver, or turn on Replace Existing Webhook to repoint it here.
Deliveries are rejected for a signature mismatch
The node is verifying with the wrong secret. If the sender already had a webhook when you activated the trigger, Zavu never revealed its secret: paste it into Webhook Secret. Regenerating the secret in the dashboard invalidates the old one immediately, which breaks any other receiver using it.
The workflow never fires
Confirm the sender's webhook is active and subscribed to the events you selected, under Senders → your sender → Webhook in the dashboard. Check the trigger's event list matches the events you expect: deliveries of other types are acknowledged and dropped.
A send fails with whatsapp_window_closed
Free-form WhatsApp messages need an open 24 hour window. Use a template to start the conversation.