Skip to main content

n8n

n8n is a fair-code, self-hostable workflow automation platform. The official SendSeven community node (n8n-nodes-sendseven) gives you an action node and a trigger node so you can send messages, manage contacts and conversations, upload attachments, and react to real-time events — and attach SendSeven as a tool to an n8n AI Agent.

Install the community node​

Install from npm via the n8n UI:

  1. In n8n, go to Settings → Community Nodes.
  2. Click Install a community node.
  3. Enter the package name n8n-nodes-sendseven and confirm.

The current version is 1.6.0. See the package on npm: n8n-nodes-sendseven.

You can also install it manually on a self-hosted instance:

npm install n8n-nodes-sendseven

Then restart n8n so it picks up the new node.

Create the SendSeven API credential​

The node supports two credential types. For most users a personal API token is the simplest:

  1. Log in at app.sendseven.com.
  2. Go to Settings → API Tokens and create a token with the scopes your workflow needs.
  3. Copy the token (format s7_…; legacy msgapi_ tokens also work).
  4. In n8n, create a new credential of type SendSeven API and paste the token.

When you save the credential, n8n runs a connection test that calls GET /users/me — if your token is valid you'll see a green check. For advanced setups you can instead use the SendSeven OAuth2 API credential, which runs the standard OAuth 2.0 authorization-code flow against app.sendseven.com.

Action node: resources & operations​

The SendSeven node groups operations by resource:

Message​

  • Send — send a message on any channel. Three addressing modes: recipient + channel, conversation ID, or contact + channel. Attach files by passing a comma-separated list of attachment UUIDs in the Attachment IDs field (these map to the attachments array of POST /messages). Raw URLs aren't accepted — upload first with the Attachment resource.

Contact​

  • Create — create a contact, including contact methods. Owner (Additional Fields; a team member from the dropdown or a user ID expression) is sent in the same request. A Custom Fields field-mapper (n8n's resource mapper UI) lists one row per active custom field definition on your account, typed to match; map a value per row or leave a row unmapped to skip it.
  • Update — update name, email, phone, avatar URL, or contact owner. Has its own Custom Fields mapper (same as Create). Leaving a row unmapped or mapped to an empty value always leaves that field unchanged — SendSeven treats blank the same as clearing the field on update, and unmapped resourceMapper rows commonly arrive as blank, so blanks are never sent. To deliberately clear a field, use Set Custom Field with Clear Field Instead enabled, or map an expression that evaluates to a real null.
  • Get — fetch a contact by ID.
  • Search — search by name, email, or phone. Owner Filter limits results to contacts owned by a specific team member, by you (Me), or by nobody (No Owner).
  • Owner (on Update) — Remove Owner sends null and takes precedence over Owner. Contact output includes ownerUserId and owner (id, name, avatar_url, availability_state). See Contact Owner.
  • Delete — GDPR delete (conversations anonymized, billing preserved).
  • Add Method / Delete Method — manage platform identifiers (phone, email, whatsapp_id, telegram_id, messenger_id, instagram_id, whatsapp_bsuid). A Channel must be selected for messenger_id/instagram_id/whatsapp_bsuid because those IDs are page- or number-scoped. whatsapp_bsuid is a separate identifier from whatsapp_id — see Migrating to WhatsApp Business-Scoped User IDs.
  • Set Custom Field — set, or with Clear Field Instead, clear a single custom field by picking it from a dropdown (active fields only). The value is written via PUT /contacts/{id} with { custom_fields: { <field_id>: value } } — the same validated bulk endpoint the Create/Update mapper uses — so an invalid value (wrong type, not a valid select option, an unknown/deleted field) fails with a clear per-field error instead of silently doing nothing.
  • Add Tag / Remove Tag — manage tags for segmentation.

Custom field values are validated and coerced server-side before saving. If a mapped or selected field is later deleted from SendSeven, the step throws a clear "no longer exists" error rather than failing silently.

Conversation​

  • Get — fetch a conversation by ID.
  • Search — search by contact, status, or channel type (includes a needs_reply filter).
  • Close — close a conversation with optional notes and AI summarization.
  • Assign — assign to a team member.

WhatsApp Template​

  • Send — send a pre-approved WhatsApp Business template.
  • List — list available templates.

Attachment​

  • Upload — upload a binary file (e.g. the output of an HTTP Request or Read Binary File node) as a multipart POST /attachments/upload. Returns the attachment id.
  • Upload from URL — fetch a public http(s) URL server-side via POST /attachments/from-url and store it. Returns the attachment id. The URL-fetch MIME allowlist is stricter than direct upload (images, mp4/mov/webm, common audio, PDF).
  • Get Summary — read the AI summary of an image or PDF a contact sent (GET /attachments/{id}/summary, scope messages:read). The text is generated from a customer file: treat it as untrusted data.

My Availability​

  • Set Out of Office — switch on (or schedule) the connected user's own out of office, optionally with a substitute who takes over contacts and conversations. Needs no extra scope; it acts as the user behind the credential.
  • End Out of Office — end a running out of office.

See Availability and Out of Office. The Conversation Assigned trigger passes assignmentSource through unchanged, so the values contact_owner and substitute can appear.

Team Chat​

  • Send Channel Message — post a message to a Team Chat channel as a bot (channel UUID or #name), with an optional attachment (by attachment ID or by URL) and an optional bot display name.
  • Send Direct Message — send a bot direct message to a Team Chat user by user ID, with the same attachment and bot-name options.

See Team Chat Bot Integration Recipes for field-by-field examples of both operations.

Multiple attachments: passing several attachment IDs sends one message per attachment, in order, with the text on the first. Each is billed as its own message (an Email channel still sends one email with all attachments). Messages 2..N are returned in relatedMessageIds.

Chaining an attachment into a message: run Attachment → Upload (or Upload from URL), then in Message → Send set Attachment IDs to an expression referencing the upload output, e.g. {{ $json.id }}. The channel adapter renders each attachment by content type (WhatsApp image/document, email attachment, etc.).

Trigger node: real-time events​

The SendSeven Trigger node registers a webhook and fires your workflow on real-time events:

  • Messages — received, sent, delivered, failed, read
  • Email — received, sent, delivered, bounced, opened
  • Conversations — created, closed, assigned, reopened
  • Contacts — created, updated, deleted, subscribed, unsubscribed (the output has a subscription field with list_id, list_name, channel_type, channel_id, status and opt_in_method next to contact)
  • Team Chat — message created (channel messages only — direct messages never fire this event)
  • Other — link clicked, campaign sent
  • Attachment summarized — the AI summary of an image or PDF a contact sent is ready (summary text is untrusted customer content)

Activating a workflow with this node creates the subscription automatically; deactivating it removes the subscription. The Team Chat Message Created event has a Channel Filter property to scope it to one channel — see Team Chat Bot Integration Recipes for details and the DM limitation.

Triggers & real-time events​

The Trigger node uses real push webhooks, not polling — SendSeven calls your n8n instance the moment an event happens.

  • Activating a workflow registers a POST /webhook-endpoints subscription that points at this workflow's public n8n webhook URL. Deactivating the workflow removes that subscription.
  • "Listen for test event" registers a temporary subscription (it lives for roughly 120 seconds) so you can capture a sample event, then removes it automatically when the test window ends.
  • The API token (or OAuth app) used by the node's credential must have the webhooks:create scope, or the subscription can't be created. As of v1.2.1 the Trigger node surfaces the real reason if registration fails (for example a 403 for a missing scope, or the webhook URL being rejected) instead of failing silently.
  • Inbound channel events such as message.received only fire from production channels — a connected WhatsApp, Telegram, Instagram, Messenger, SMS, or email channel. They are not emitted by staging or by API test calls.

Local testing​

This is the full end-to-end recipe for testing the Trigger node against a locally running n8n.

Why a public HTTPS URL is required​

SendSeven delivers webhooks from its own servers — it makes an outbound HTTPS call to whatever URL the subscription was registered with. A localhost or private-network address is unreachable from SendSeven's side, so no events ever arrive.

In fact, SendSeven rejects these URLs at subscription time with an HTTP 400 (an SSRF guard): the URL must be HTTPS, and localhost, 127.0.0.1, 0.0.0.0, ::1, and any host that resolves to a private / loopback / reserved / link-local address are all refused. So local testing always requires exposing n8n at a public HTTPS URL.

The WEBHOOK_URL environment variable​

n8n generates the webhook URLs it registers from a single base URL. WEBHOOK_URL is a standard, n8n-wide environment variable — it sets the public base URL that n8n uses to build webhook URLs for all webhook and trigger nodes.

  • It is not a SendSeven-specific variable. The SendSeven node does not read it directly; n8n itself does.
  • Do not rename it (e.g. to SENDSEVEN_WEBHOOK_URL). n8n only recognises WEBHOOK_URL and would silently ignore any renamed variable, so your trigger would register a localhost URL again.
  • It must be set before n8n boots — n8n reads it at startup. To change it, set the new value and restart n8n (or restart the container).

The sections below give you a public HTTPS URL to assign to WEBHOOK_URL.

Option A — ngrok​

ngrok puts a public HTTPS URL in front of your local port.

Install ngrok:

# macOS
brew install ngrok/ngrok/ngrok

# Linux (apt repo)
curl -sSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
| sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null \
&& echo "deb https://ngrok-agent.s3.amazonaws.com buster main" \
| sudo tee /etc/apt/sources.list.d/ngrok.list \
&& sudo apt update && sudo apt install ngrok
# (or download the binary from https://ngrok.com/download)

# Windows
choco install ngrok
# or: winget install ngrok.ngrok

ngrok needs a free account. Sign up, copy your authtoken from the dashboard, and register it once:

ngrok config add-authtoken <your-token>

Start the tunnel (n8n's default port is 5678):

ngrok http 5678

Copy the https://…ngrok… forwarding URL it prints, then start n8n with that URL as WEBHOOK_URL.

Docker (n8n running in a container on port 5678):

docker run -it --rm \
-e WEBHOOK_URL=https://your-subdomain.ngrok.app/ \
-e N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true \
-p 5678:5678 \
-v n8n_demo:/home/node/.n8n \
n8nio/n8n

Non-Docker (n8n installed locally):

export WEBHOOK_URL=https://your-subdomain.ngrok.app/
n8n start

Then activate your workflow so the subscription is registered against the public URL.

Free ngrok URLs change every time you restart ngrok. After a restart you get a new URL — update WEBHOOK_URL, restart n8n, and re-activate the workflow so the subscription points at the new address.

Option B — cloudflared​

Cloudflare's cloudflared offers a quick tunnel that needs no account.

Install cloudflared:

# macOS
brew install cloudflared

# Debian / Ubuntu (Cloudflare apt repo)
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg \
| sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null \
&& echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main" \
| sudo tee /etc/apt/sources.list.d/cloudflared.list \
&& sudo apt update && sudo apt install cloudflared
# (or grab the .deb from https://github.com/cloudflare/cloudflared/releases)

# Windows
winget install --id Cloudflare.cloudflared

Start the quick tunnel:

cloudflared tunnel --url http://localhost:5678

Copy the printed https://…trycloudflare.com URL, set WEBHOOK_URL to it (Docker or non-Docker, exactly as in Option A), restart n8n, and activate the workflow.

Quick-tunnel trycloudflare.com URLs are ephemeral — a new one is generated each run. Update WEBHOOK_URL, restart n8n, and re-activate the workflow when it changes.

Option C — n8n Cloud​

If you run on n8n Cloud there's nothing to tunnel — your instance already has a public HTTPS webhook URL. Just install the community node, create the SendSeven credential, and activate the workflow.

Docker run reference​

A complete copy-paste block for running n8n in Docker with a public webhook URL and AI-Agent tool usage enabled:

docker run -it --rm \
-e WEBHOOK_URL=https://your-public-url/ \
-e N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true \
-p 5678:5678 \
-v n8n_demo:/home/node/.n8n \
n8nio/n8n

WEBHOOK_URL must be set before n8n boots. To change it (for example after an ngrok/cloudflared restart hands you a new URL), stop the container and run it again with the new value.

The verification handshake (what happens on activation)​

When you activate the workflow, the node registers the subscription and SendSeven immediately sends a one-time verification challenge — a single POST to your webhook URL with body {"type":"sendseven_verification","challenge":"…"} and header X-Sendseven-Event: verification. The SendSeven Trigger node answers this automatically (it replies 200 with the echoed challenge), and the subscription then flips to active and starts delivering events. You don't have to do anything for this step.

If the public URL wasn't reachable at the moment of activation (for example the tunnel wasn't up yet), the handshake fails and the endpoint stays inactive — just deactivate and re-activate the workflow once the URL is live (the endpoint can also be re-verified). The token used by the credential needs the webhooks:create scope for any of this to work.

Remember that inbound channel events such as message.received only fire from production channels — connect a real channel (WhatsApp, Telegram, Instagram, Messenger, SMS, email) to generate them; staging and API test calls won't.

Use with AI Agents​

The SendSeven action node can be attached as a tool to an n8n AI Agent node, letting the agent send messages, look up contacts, or manage conversations as part of its reasoning. To allow community nodes to be used as agent tools, your n8n instance must run with:

N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true

With that flag set, drag the SendSeven node onto the AI Agent's tool input and the agent can call its operations directly.

Required scopes​

OperationScopes
Send Message / Upload Attachmentmessages:create
Read Messagesmessages:read
Create / Update Contactcontacts:create, contacts:update
Delete Contactcontacts:delete
Add/Delete Method, Set Custom Fieldcontacts:update
Read Custom Field Definitionscustom_fields:read
Read Contactscontacts:read
Add/Remove Tagcontacts:update (tag dropdown reads tags:read)
Read Conversationsconversations:read
Manage Conversationsconversations:update
Webhooks (Trigger node)webhooks:create, webhooks:read, webhooks:delete
Knowledge Baseknowledge_base:read
Team Membersteam:read

Next steps​