n8n node

The PrivacyFlow n8n community node — install it, send and poll encrypted messages from visual workflows, and preserve routing fields when replying.

The PrivacyFlow n8n community node is an n8n node package that exposes two nodes: Send (an Action node) and Poll Trigger (a Trigger node). Both call the public API using a credential you store in n8n’s encrypted credential store.

Install

In your n8n instance:

  1. Open Settings → Community Nodes.
  2. Install n8n-nodes-privacyflow from npm.
  3. Restart n8n if prompted.

You need n8n 1.x or newer and Node 22+. The package has no runtime dependencies beyond n8n-workflow (vendored by n8n).

Dev install (for contributors):

git clone https://github.com/privacyflow-app/n8n-nodes-privacyflow
cd n8n-nodes-privacyflow
npm install
npm run dev   # links into your local n8n community-nodes directory

Configure the credential

Create a new PrivacyFlow API credential in n8n:

FieldValue
API Keypf_live_… — your key from the dashboard Credentials section.
Base URLhttps://privacyflow.app (the default). Override only for self-hosted instances.

The credential stores apiKey and baseUrl. The node sends the key as Authorization: Bearer <apiKey> on every call. Click Test in the credential editor — it pings GET /api/v1/auth/verify and asserts valid === true. See verify.

Note

Older n8n-nodes-privacyflow releases ship with https://api.privacyflow.app as the Base URL preset. The canonical host is https://privacyflow.apptype it in explicitly as the Base URL value, until a future node release updates the preset.

The Send node (Action)

PrivacyFlow → Send a text message in the node menu. Required and optional fields per message:

FieldRequiredNotes
appIdyesMust be one of the appIds the credential’s key can access.
contactIdyesRecipient in the messenger’s native format. See contact formats.
messengeryessignal, simplex, or session.
messageyes1–10,000 characters.
groupIdnoSet when replying to a group message (matches the inbound’s groupId).

The node validates inputs locally with the same rules as the API (see send). On success it returns the same {successfulMessages, failedMessages, totalAccepted, totalFailed} envelope so downstream nodes can branch on per-message failure.

Send one

A single-trigger-to-action workflow:

[Schedule Trigger] → [PrivacyFlow Send]

In the Send node, fill appId, contactId, messenger, message. Run. The node returns:

{
  "successfulMessages": [/* … */],
  "failedMessages": [],
  "totalAccepted": 1,
  "totalFailed": 0
}

Send a batch

PrivacyFlow accepts up to 50 messages per call. Build the batch with a Code node:

[Manual Trigger] → [Code] → [PrivacyFlow Send]

In the Code node, return an array of objects shaped like { appId, contactId, messenger, message }:

return [
  { appId: "app_123", contactId: "+12025550104", messenger: "signal", message: "Your order shipped." },
  { appId: "app_123", contactId: "+12025550105", messenger: "signal", message: "Your order shipped." },
  { appId: "app_123", contactId: "+12025550106", messenger: "signal", message: "Your order shipped." }
];

In the Send node, set the messages field to {{ $json }} (or use the node’s “Many” mode if available) so the array posts to POST /api/v1/messages/send as one batch. One request, three messages, three units off your send rate budget.

The Poll Trigger node

PrivacyFlow Trigger in the node menu. Emits one n8n item per inbound message. One field:

FieldDefaultRange
Message Limit501–50

The trigger polls GET /api/v1/messages/poll?limit=N on the schedule n8n assigns to the trigger (configure the polling interval in n8n’s trigger settings; 3–5 seconds is reasonable for chat, 30–60 for batch processing). Each polled item becomes an n8n item with the PolledMessage shape.

Preserving routing fields when replying

The single most important rule when building a Poll → Reply workflow: copy appId, contactId, messenger, and groupId from the polled item into the Send node’s fields. Getting any of them wrong produces a per-message failure in failedMessages or lands the reply in the wrong thread.

The trigger node surfaces this in its UI:

⚠ When sending a reply, preserve appId, contactId, messenger, and (if present) groupId from the polled message. Changing the messenger or contactId will route the reply to the wrong recipient or fail.

A correct Poll → Reply loop:

[PrivacyFlow Trigger (limit: 50)] → [n8n Set/Code: extract appId, contactId, messenger, groupId, content] → [PrivacyFlow Send: pass those fields through]

In the Send node, bind each field to the trigger’s output:

  • appId = {{ $json.appId }}
  • contactId = {{ $json.contactId }}
  • messenger = {{ $json.messenger }}
  • groupId = {{ $json.groupId }} (only present on group messages; leave blank when not)
  • message = your reply text, however you generate it.

Why batch matters

The free-tier send limit is 600 messages per minute, not 600 requests. A 50-message batch consumes 50 units of the same budget that a 1-message request consumes 1 unit of — but the overhead of 50 separate requests is far higher than one batched one. For broadcasts, always batch. See rate limiting and the broadcast prompt on the MCP server for the same idea from the agent side.

Warning

The Poll trigger is a destructive read. Each trigger run pops the message off your queue. If n8n re-runs the workflow (a manual re-execution, a failed downstream node), the message is already gone — there is no replay. Design your workflow to be idempotent or to persist the polled item before doing work.

Both nodes use the same four endpoints behind the scenes:

Node actionEndpoint
Credential testGET /api/v1/auth/verify
Poll triggerGET /api/v1/messages/poll?limit=N
Send nodePOST /api/v1/messages/send
(Health check)GET /api/v1/health (not used by the node, but available for monitoring)

See the API Reference for full request/response schemas.

Last updated: