Skip to main content
Version: v0.23.1

n8n Node Reference

Exact field-level reference for the two nodes in the @rmyndharis/n8n-nodes-openwa package (v0.9.1): OpenWA (an action node) and OpenWA Trigger (a webhook trigger node). Use it to look up every resource, operation, field, and event, plus the HMAC signature the trigger verifies.

For installation and a first workflow, see the n8n integration guide. For the underlying HTTP API each operation calls, see the API Reference.

Package overview

Noden8n typeDirectionPurpose
OpenWAopenWaActionSend messages and manage sessions, chats, contacts, groups, labels, templates, status, channels, keys, and webhooks
OpenWA TriggeropenWaTriggerTriggerStart a workflow when a subscribed event arrives

Both nodes use the openWaApi credential and call your OpenWA server's /api endpoints.

Credential: OpenWA API

Both nodes require an OpenWA API credential with two fields.

FieldRequiredDescription
Server URLYesBase URL with no trailing slash and no /api suffix, for example http://localhost:2785 or https://wa.example.com. The node appends /api/... itself.
API KeyYesSent as the X-API-Key header on every request. Get it from your OpenWA dashboard.

The credential test issues an authenticated GET /api/sessions, so an invalid key fails at save time. To create the key, see Authentication.

OpenWA (action node)

Package 0.9.0 extended the action node from four resources to the fifteen below. Select a Resource, then an Operation; the visible fields change with each operation.

Most operations take a Session Name or ID. It is a dropdown: the node calls GET /api/sessions with your credential and lists each session as name (id), storing the session's UUID. The stored value is a plain string, so an expression can supply an id instead of picking one. The same pattern backs the Chat, Contact, Group, Label, Template, Channel, and Webhook ID fields, each loading from its own listing endpoint once a session is chosen, and the API Key field, which is not session-scoped. The session, chat, contact, and group loaders fetch one page of up to 1000 entries — beyond that, set the field from an expression.

The Observability and API Key resources have no Session ID at all; on System it appears only for Get Session Stats, and on Webhook it is hidden for List All and Get Delivery Failures.

ResourceOperationMethod + path
SessionCreatePOST /api/sessions
SessionStartPOST /api/sessions/{sessionId}/start
SessionStopPOST /api/sessions/{sessionId}/stop
SessionForce KillPOST /api/sessions/{sessionId}/force-kill
SessionDeleteDELETE /api/sessions/{sessionId}
SessionGet QRGET /api/sessions/{sessionId}/qr
SessionRequest Pairing CodePOST /api/sessions/{sessionId}/pairing-code
SessionGet StatusGET /api/sessions/{sessionId}
SessionList AllGET /api/sessions
SessionGet Stats OverviewGET /api/sessions/stats/overview
MessageSend TextPOST /api/sessions/{sessionId}/messages/send-text
MessageSend ImagePOST /api/sessions/{sessionId}/messages/send-image
MessageSend VideoPOST /api/sessions/{sessionId}/messages/send-video
MessageSend AudioPOST /api/sessions/{sessionId}/messages/send-audio
MessageSend DocumentPOST /api/sessions/{sessionId}/messages/send-document
MessageSend StickerPOST /api/sessions/{sessionId}/messages/send-sticker
MessageSend LocationPOST /api/sessions/{sessionId}/messages/send-location
MessageSend ContactPOST /api/sessions/{sessionId}/messages/send-contact
MessageSend PollPOST /api/sessions/{sessionId}/messages/send-poll
MessageSend TemplatePOST /api/sessions/{sessionId}/messages/send-template
MessageSend BulkPOST /api/sessions/{sessionId}/messages/send-bulk
MessageGet Batch StatusGET /api/sessions/{sessionId}/messages/batch/{batchId}
MessageCancel BatchPOST /api/sessions/{sessionId}/messages/batch/{batchId}/cancel
MessageReplyPOST /api/sessions/{sessionId}/messages/reply
MessageReactPOST /api/sessions/{sessionId}/messages/react
MessageEditPOST /api/sessions/{sessionId}/messages/edit
MessageDeletePOST /api/sessions/{sessionId}/messages/delete
MessageForwardPOST /api/sessions/{sessionId}/messages/forward
MessageListGET /api/sessions/{sessionId}/messages
MessageGet HistoryGET /api/sessions/{sessionId}/messages/{chatId}/history
MessageGet ReactionsGET /api/sessions/{sessionId}/messages/{chatId}/{messageId}/reactions
ContactCheck ExistsGET /api/sessions/{sessionId}/contacts/check/{phoneNumber}
ContactGet InfoGET /api/sessions/{sessionId}/contacts/{contactId}
ContactGet PhoneGET /api/sessions/{sessionId}/contacts/{contactId}/phone
ContactGet Profile PictureGET /api/sessions/{sessionId}/contacts/{contactId}/profile-picture
ContactGet Profile PicturesGET /api/sessions/{sessionId}/contacts/profile-pictures?ids=
ContactListGET /api/sessions/{sessionId}/contacts
ContactBlockPOST /api/sessions/{sessionId}/contacts/{contactId}/block
ContactUnblockDELETE /api/sessions/{sessionId}/contacts/{contactId}/block
ChatListGET /api/sessions/{sessionId}/chats
ChatMark ReadPOST /api/sessions/{sessionId}/chats/read
ChatMark UnreadPOST /api/sessions/{sessionId}/chats/unread
ChatDeletePOST /api/sessions/{sessionId}/chats/delete
ChatSet StatePOST /api/sessions/{sessionId}/chats/typing
GroupListGET /api/sessions/{sessionId}/groups
GroupCreatePOST /api/sessions/{sessionId}/groups
GroupJoinPOST /api/sessions/{sessionId}/groups/join
GroupGetGET /api/sessions/{sessionId}/groups/{groupId}
GroupLeavePOST /api/sessions/{sessionId}/groups/{groupId}/leave
GroupAdd ParticipantsPOST /api/sessions/{sessionId}/groups/{groupId}/participants
GroupRemove ParticipantsDELETE /api/sessions/{sessionId}/groups/{groupId}/participants
GroupPromote ParticipantsPOST /api/sessions/{sessionId}/groups/{groupId}/participants/promote
GroupDemote ParticipantsPOST /api/sessions/{sessionId}/groups/{groupId}/participants/demote
GroupUpdate SubjectPUT /api/sessions/{sessionId}/groups/{groupId}/subject
GroupUpdate DescriptionPUT /api/sessions/{sessionId}/groups/{groupId}/description
GroupGet SettingsGET /api/sessions/{sessionId}/groups/{groupId}/settings
GroupUpdate SettingsPUT /api/sessions/{sessionId}/groups/{groupId}/settings
GroupGet Invite CodeGET /api/sessions/{sessionId}/groups/{groupId}/invite-code
GroupRevoke Invite CodePOST /api/sessions/{sessionId}/groups/{groupId}/invite-code/revoke
ProfileSet NamePUT /api/sessions/{sessionId}/profile/name
ProfileSet StatusPUT /api/sessions/{sessionId}/profile/status
ProfileSet PicturePUT /api/sessions/{sessionId}/profile/picture
LabelListGET /api/sessions/{sessionId}/labels
LabelGetGET /api/sessions/{sessionId}/labels/{labelId}
LabelGet for ChatGET /api/sessions/{sessionId}/labels/chat/{chatId}
LabelAdd to ChatPOST /api/sessions/{sessionId}/labels/chat/{chatId}
LabelRemove From ChatDELETE /api/sessions/{sessionId}/labels/chat/{chatId}/{labelId}
StatusListGET /api/sessions/{sessionId}/status
StatusGet by ContactGET /api/sessions/{sessionId}/status/{contactId}
StatusGet MediaGET /api/sessions/{sessionId}/status/{statusId}/media
StatusDeleteDELETE /api/sessions/{sessionId}/status/{statusId}
StatusSend TextPOST /api/sessions/{sessionId}/status/send-text
StatusSend ImagePOST /api/sessions/{sessionId}/status/send-image
StatusSend VideoPOST /api/sessions/{sessionId}/status/send-video
TemplateListGET /api/sessions/{sessionId}/templates
TemplateCreatePOST /api/sessions/{sessionId}/templates
TemplateGetGET /api/sessions/{sessionId}/templates/{templateId}
TemplateUpdatePUT /api/sessions/{sessionId}/templates/{templateId}
TemplateDeleteDELETE /api/sessions/{sessionId}/templates/{templateId}
ChannelListGET /api/sessions/{sessionId}/channels
ChannelGetGET /api/sessions/{sessionId}/channels/{channelId}
ChannelGet MessagesGET /api/sessions/{sessionId}/channels/{channelId}/messages
ChannelSubscribePOST /api/sessions/{sessionId}/channels/subscribe
ChannelUnsubscribeDELETE /api/sessions/{sessionId}/channels/{channelId}
CallRejectPOST /api/sessions/{sessionId}/calls/{callId}/reject
ObservabilityCheckGET /api/health
ObservabilityCheck LivenessGET /api/health/live
ObservabilityCheck ReadinessGET /api/health/ready
SystemGet SettingsGET /api/settings
SystemGet Stats OverviewGET /api/stats/overview
SystemGet Message StatsGET /api/stats/messages
SystemGet Session StatsGET /api/stats/sessions/{sessionId}
SystemGet Audit LogGET /api/audit
SystemSearchGET /api/search
API KeyListGET /api/auth/api-keys
API KeyCreatePOST /api/auth/api-keys
API KeyGetGET /api/auth/api-keys/{keyId}
API KeyUpdatePUT /api/auth/api-keys/{keyId}
API KeyRevokePOST /api/auth/api-keys/{keyId}/revoke
API KeyDeleteDELETE /api/auth/api-keys/{keyId}
API KeyValidatePOST /api/auth/validate
WebhookCreatePOST /api/sessions/{sessionId}/webhooks
WebhookGetGET /api/sessions/{sessionId}/webhooks/{webhookId}
WebhookListGET /api/sessions/{sessionId}/webhooks
WebhookUpdatePUT /api/sessions/{sessionId}/webhooks/{webhookId}
WebhookDeleteDELETE /api/sessions/{sessionId}/webhooks/{webhookId}
WebhookTestPOST /api/sessions/{sessionId}/webhooks/{webhookId}/test
WebhookList AllGET /api/webhooks
WebhookGet Delivery FailuresGET /api/webhooks/delivery-failures

Values that land in a URL path — Session ID, Batch ID, Webhook ID, Label ID, Status ID, Template ID, Call ID, API key ID — are sanitized before use: they cannot be empty and cannot contain .., /, or \. A value that violates this fails the item with a clear error rather than building a malformed URL. WhatsApp JIDs (chat, contact, group, channel) legitimately contain @ and ., so they are checked for emptiness and URL-encoded instead.

Not offered, because the server cannot serve them

Send Catalog and PUT /api/settings were removed from the server in v0.19.0 — both had answered 501 since they shipped. Catalog reads and Send Product are Baileys-only on the server and have no operations here either — call them with n8n's HTTP Request node against a Baileys session if you need them. Settings are environment-derived and read-only at runtime, so System exposes only a read; and /api/metrics authenticates with its own bearer token rather than the X-API-Key this credential carries. Presence subscription (POST /api/sessions/{sessionId}/presence/subscribe) also has no operation — call it with n8n's HTTP Request node if you want presence.update events.

Media source model

Every operation that carries media — Send Image, Send Video, Send Audio, Send Document, Send Sticker, Profile → Set Picture, and Status → Send Image / Send Video — shares one source model. A Source field offers Binary Data, URL, and Base64 (default URL), and the remaining fields follow from it:

SourceExtra fieldsRequest fields sent
Binary DataBinary Property (default data)base64 (the buffer encoded) and mimetype, read from the binary metadata
URL(the media URL field)url
Base64Base64 Data, MIME Typebase64 and mimetype (the MIME Type field)

When a binary item carries no MIME type of its own, the node falls back to a per-kind default: application/octet-stream for images, video, and documents, audio/ogg; codecs=opus for audio, image/webp for stickers, image/jpeg for profile and status images, and video/mp4 for status video.

Base64 needs a MIME type

OpenWA rejects base64 media without a mimetype. The Binary Data source fills it in from the binary metadata and the URL source needs nothing extra, but the Base64 source requires you to set the MIME Type field.

List fields

Several fields take a list: Mentions, Participants, Recipients, Contact IDs, poll Options, Allowed IPs, and Allowed Sessions. Each is a plain string field rather than a fixed set of rows, so it accepts three shapes: a comma- or newline-separated list typed by hand, a pasted JSON array, or an expression resolving to an array. Blank entries are dropped.

Session resource

Session operations address a session by its UUID. Create, List All, and Get Stats Overview take no Session ID.

OperationFieldsNotes
CreateSession Name, Session Config (JSON)Session Name is required: 3–50 characters, letters, numbers, and hyphens only. Session Config is an optional JSON object, for example {"autoReconnect":true} — a non-object value fails the item. Returns the new session's UUID.
StartSession Name or IDStarts the session and connects to WhatsApp.
StopSession Name or IDStops the session and disconnects.
Force KillSession Name or IDForce-kills a stuck session's engine.
DeleteSession Name or IDDeletes the session.
Get QRSession Name or IDReturns the QR code for scanning authentication.
Request Pairing CodeSession Name or ID, Phone NumberPhone Number is 6–15 digits in international format (for example 628123456789); the node strips +, spaces, -, and () before validating. Returns an 8-character phone-linking code.
Get StatusSession Name or IDReturns the status of one session.
List AllOptions: Limit, OffsetReturns every session, paginated.
Get Stats Overview(none)Overview statistics across all sessions.

Message resource

The twenty-one message operations share a required Session Name or ID. All of them except Send Bulk, Get Batch Status, Cancel Batch, Forward, and List also require a Chat Name or ID — the batch routes are not addressed to one chat, Forward names a source and a target chat of its own, and List takes an optional chat filter in its options collection.

FieldTypeRequiredDescription
Session Name or IDoptionsYesThe session to act through.
Chat Name or IDoptionsYes (all except Send Bulk, Get Batch Status, Cancel Batch, Forward, List)Recipient, for example 628123456789@c.us for a person or ...@g.us for a group. Empty values fail the item.

The operation-specific fields follow.

Send Text — request body { chatId, text }.

FieldTypeRequiredMaps to
MessagestringYestext

Send Image — the media source model, plus an optional caption. Request body { chatId } plus the source fields, and caption when set.

FieldTypeRequiredNotes
Image Sourceoptions: Binary Data, URL, Base64YesDefault URL.
Binary PropertystringYes (binary)Default data.
Image URLstringYes (url)Public URL of the image.
Base64 DatastringYes (base64)Base64-encoded image bytes.
MIME TypestringYes (base64)For example image/png. Default image/jpeg.
CaptionstringNoSent as caption.

Send Video — same shape as Send Image, with the Video Source field and a video/mp4 default MIME type.

Send Audio — same source model, plus a voice-note toggle. Request body { chatId } plus the source fields, and ptt: true when the toggle is on.

FieldTypeRequiredNotes
Audio Sourceoptions: Binary Data, URL, Base64YesDefault URL.
Binary PropertystringYes (binary)Default data.
Audio URLstringYes (url)Public URL of the audio.
Base64 DatastringYes (base64)Base64-encoded audio bytes.
MIME TypestringYes (base64)Default audio/ogg; codecs=opus. For a plain audio file set its real type (for example audio/mpeg).
Send as Voice NotebooleanNoDefault off. When on, the clip is delivered as a true WhatsApp voice note (PTT — the microphone bubble with a waveform) instead of a plain audio file. Requires OGG/Opus audio (audio/ogg; codecs=opus).

Send Document — same source model, with a filename. Request body { chatId, filename } plus the source fields, and caption when set.

FieldTypeRequiredNotes
Document Sourceoptions: Binary Data, URL, Base64YesDefault URL.
Binary PropertystringYes (binary)Default data.
Document URLstringYes (url)Public URL of the document.
Base64 DatastringYes (base64)Base64-encoded document bytes.
MIME TypestringYes (base64)For example application/pdf. Default application/pdf.
FilenamestringNoSent as filename. Default document.pdf.
CaptionstringNoSent as caption when set.

Send Sticker — same source model. WhatsApp expects a WebP sticker, ideally 512×512.

FieldTypeRequiredNotes
Sticker Sourceoptions: Binary Data, URL, Base64YesDefault URL.
Binary PropertystringYes (binary)Default data.
Sticker URLstringYes (url)Public URL of the sticker (WhatsApp expects a WebP image).
Base64 DatastringYes (base64)Base64-encoded sticker bytes.
MIME TypestringYes (base64)Default image/webp; WhatsApp requires WebP.
Mentions

Send Text, Send Image, Send Video, and Send Document accept an optional Mentions field — a list of WhatsApp ids to @mention (for example 628123456789@c.us), in any of the shapes described under List fields. The message text or caption must also contain the matching @628123456789 token for the mention to render. The field is guarded by operation, so a mentions value can never ride along on an operation whose DTO would reject it.

Send Location — request body { chatId, latitude, longitude }.

FieldTypeRequiredMaps to
LatitudenumberYeslatitude
LongitudenumberYeslongitude
Location NamestringNoSent as description (OpenWA's field for the location label) when set.

Send Contact — request body { chatId, contactName, contactNumber }.

FieldTypeRequiredMaps to
Contact NamestringYescontactName — display name for the shared contact card.
Contact NumberstringYescontactNumber — phone number including the country code (it is not auto-prefixed), for example +628123456789.

Send Poll — request body { chatId, name, options }, plus allowMultipleAnswers when on.

FieldTypeRequiredNotes
QuestionstringYesSent as name. Maximum 255 characters.
Optionsstring listYesThe answers to vote on. Between 2 and 12 — anything outside that range fails the item.
Allow Multiple AnswersbooleanNoDefault off. When on, voters may pick several options instead of exactly one.

Send Template — renders a stored template and sends the result. Request body { chatId } plus either templateId or templateName, and vars when set.

FieldTypeRequiredNotes
Template Name or IDoptionsYes (or Template Name)Id of the template to render. When both this and Template Name are set, the id wins.
Template NamestringYes (or Template Name or ID)Used only when the id is empty. Providing neither fails the item.
Variables (JSON)jsonNoValues substituted into the template's {{placeholder}} tokens, as a JSON object such as {"name":"Alice"}. A non-object value fails the item.

Send Bulk — sends up to 100 messages as a tracked batch. Request body { messages }, plus batchId and options when set. No Chat ID — each item carries its own chatId.

FieldTypeRequiredNotes
Messages (JSON)jsonYesArray of 1–100 items — an empty array or more than 100 items fails the item. A text item is { "chatId": "628123456789@c.us", "type": "text", "content": { "text": "Hello" } }. A media item nests the media object under the type key (image/video/audio/document) and puts caption alongside it on content: { "chatId": "628123456789@c.us", "type": "image", "content": { "image": { "url": "https://example.com/a.jpg" }, "caption": "Hi" } }. Media uses url or base64 (add mimetype for base64) — there is no binary source in bulk.
Batch IDstringNoCustom batch id; must be unique per session. Leave empty to let the server generate one.
OptionscollectionNoLeft empty, the server applies its own defaults (delay 3000 ms, randomize on, stop-on-error off).

The Options collection offers:

OptionTypeDefaultNotes
Delay Between Messages (Ms)number3000Milliseconds to wait between sends, 1000–60000.
Randomize DelaybooleanonAdds a random 0–2000 ms on top of the delay.
Stop on ErrorbooleanoffAborts the batch on the first failed send.

Send Bulk returns a batchId immediately and sends in the background. Poll Get Batch Status until the status is completed, cancelled, or failed, or stop the batch early with Cancel Batch.

Get Batch Status / Cancel Batch — read a batch's progress or cancel it. Each takes one field:

FieldTypeRequiredNotes
Batch IDstringYesThe batch id returned by Send Bulk.

Reply — request body { chatId, quotedMessageId, text }.

FieldTypeRequiredNotes
Quoted Message IDstringYesFull serialized id of the message to quote (for example true_628123456789@c.us_3EB0…), as returned by send operations or delivered by the Trigger.
MessagestringYesThe reply text, sent as text.

React — request body { chatId, messageId, emoji }.

FieldTypeRequiredNotes
Message IDstringYesFull serialized id of the target message.
EmojistringNoThe emoji to react with. Leave empty to remove your existing reaction — the empty value is sent deliberately.

Edit — request body { chatId, messageId, body }.

FieldTypeRequiredNotes
Message IDstringYesFull serialized id of the message to edit.
MessagestringYesThe replacement body, maximum 4096 characters.

Delete — request body { chatId, messageId, forEveryone }.

FieldTypeRequiredNotes
Message IDstringYesFull serialized id of the message to delete.
Delete for EveryonebooleanNoDefault on — revokes the message for everyone. Turn off to remove only your own local copy.

Forward — request body { fromChatId, toChatId, messageId }. Takes no shared Chat ID.

FieldTypeRequiredNotes
From Chat Name or IDoptionsYesThe chat the message currently lives in.
To Chat Name or IDoptionsYesThe chat to forward it to.
Message IDstringYesFull serialized id of the message to forward.

List — reads stored messages. Takes no shared Chat ID; every filter lives in its Options collection and is sent as a query parameter.

OptionTypeDefaultNotes
Chat Name or IDoptionsOnly return messages from this chat.
FromstringOnly return messages from this sender.
Limitnumber50Max number of results to return.
Offsetnumber0Records to skip before collecting the result set.

Get History — reads a chat's history. Requires a Chat ID; the Options collection offers:

OptionTypeDefaultNotes
DeepbooleanoffPull older messages from the device instead of only what the server has stored.
Include MediabooleanoffInclude media payloads in the returned messages.
Limitnumber50Max number of results to return.

Get Reactions — reads the reactions on one message.

FieldTypeRequiredNotes
Chat Name or IDoptionsYesThe chat the message lives in.
Message IDstringYesFull serialized id of the message.

Contact resource

Check Exists takes a Phone Number, Get Profile Pictures takes a list of ids, List takes only pagination, and every other contact operation takes a Contact Name or ID (a WhatsApp JID such as 628123456789@c.us).

OperationFieldTypeRequiredNotes
Check ExistsPhone NumberstringYesDigits only, for example 628123456789. The node strips +, spaces, -, and (); a value with any non-digit left over fails the item.
Get InfoContact Name or IDoptionsYesFor example 628123456789@c.us. Empty values fail the item.
Get PhoneContact Name or IDoptionsYesResolves the contact's phone number.
Get Profile PictureContact Name or IDoptionsYesReturns the contact's profile-photo URL.
Get Profile PicturesContact IDsstring listYesPictures for many contacts at once, sent as ?ids=. At most 50 — a longer list fails the item rather than being silently truncated by the server.
ListOptions: Limit, OffsetcollectionNoReturns the session's contacts, paginated.
BlockContact Name or IDoptionsYesBlocks the contact.
UnblockContact Name or IDoptionsYesUnblocks the contact (DELETE on the block endpoint).

Check Exists returns whatsappId, the engine-canonical chat id. It can differ from the number you sent (for example an @lid id), so read the recipient id from the response rather than reconstructing it.

Chat resource

Chat operations act on a conversation rather than the session. Every operation except List posts the target chat in the request body.

OperationFieldsNotes
ListOptions: Limit (default 50), Offset (default 0)Returns the session's chats, paginated.
Mark ReadChat Name or IDBody { chatId }.
Mark UnreadChat Name or IDBody { chatId }.
DeleteChat Name or IDBody { chatId }. A POST, not a DELETE — the server takes the chat id in the body here.
Set StateChat Name or ID, StateBody { chatId, state }. State is Typing, Recording, or Paused (default Typing); Typing and Recording show the indicator in the chat, Paused clears it.

Group resource

List, Create, and Join are session-level; every other operation takes a Group Name or ID (a JID such as 120363021234567890@g.us).

OperationFieldsNotes
ListOptions: Limit (1–1000), OffsetLeft empty, the server applies its own defaults (limit 1000, offset 0).
CreateGroup Name, ParticipantsName is required and capped at 100 characters; Participants is required and capped at 256. Baileys engine only since server v0.16.0 — whatsapp-web.js, the server default, answers 501 Operation not supported by the active engine: createGroup. See Groups.
JoinInvite CodeThe part after https://chat.whatsapp.com/. A full invite link is accepted and reduced to the code. Maximum 128 characters.
GetGroup Name or IDGroup info including participants.
LeaveGroup Name or IDLeaves the group.
Add / Remove / Promote / Demote ParticipantsGroup Name or ID, ParticipantsBody { participants }, capped at 256. Remove Participants is a DELETE that carries a JSON body — the API takes the list there rather than in the query string.
Update SubjectGroup Name or ID, SubjectRequired, maximum 100 characters.
Update DescriptionGroup Name or ID, DescriptionMaximum 1024 characters. An empty value is sent as-is and clears the description.
Get SettingsGroup Name or IDReads announce, locked, and the disappearing-message timer.
Update SettingsGroup Name or ID, SettingsPartial — settings you leave out stay untouched, and at least one is required.
Get Invite CodeGroup Name or IDThe invite code and link.
Revoke Invite CodeGroup Name or IDRevokes the code and generates a new one.

The Settings collection offers:

OptionTypeDefaultNotes
AnnouncebooleanoffOnly admins can send messages to the group.
LockedbooleanoffOnly admins can edit the group info.
Disappearing Messages (Seconds)number604800Disappearing-message timer; 0 disables it. Baileys engine only — whatsapp-web.js returns 501.

Add, Remove, Promote, and Demote report a per-participant outcome in results[], and a partial refusal does not fail the batch — check results[].success rather than the top-level success.

Profile resource

Changes the session's own WhatsApp profile.

OperationFieldsNotes
Set NameNameRequired, maximum 25 characters.
Set StatusStatusMaximum 139 characters. An empty value is sent as-is and clears the about text.
Set PicturePicture Source, and the matching Binary Property / Picture URL / Base64 Data + MIME TypeThe media source model; base64 defaults to image/jpeg. The resolved media fields form the whole request body.

Label resource

WhatsApp Business labels — the catalogue on the account, and the labels attached to one chat.

OperationFieldsNotes
List(none)Every label on the account.
GetLabel Name or IDOne label.
Get for ChatChat Name or IDThe labels attached to a chat.
Add to ChatChat Name or ID, Label Name or IDBody { labelId }.
Remove From ChatChat Name or ID, Label Name or IDBoth ids go in the path.

Status resource

Reads the Status (Stories) feed and posts new updates.

OperationFieldsNotes
List(none)The status feed.
Get by ContactContact Name or IDOne contact's status updates.
Get MediaStatus ID, Put Output in FieldStreams the stored image or video bytes. The response is attached as a binary property named by Put Output in Field (default data), not as JSON.
DeleteStatus IDDeletes one of your own status updates.
Send TextText, Background Color, Font, RecipientsBody { text } plus backgroundColor, font, and recipients when set. Text is required, maximum 4096 characters.
Send ImageImage Source (+ source fields), Caption, RecipientsThe media object nests under image rather than sitting flat on the body.
Send VideoVideo Source (+ source fields), Caption, RecipientsThe media object nests under video.
FieldTypeNotes
Background ColorcolorSent as backgroundColor. Leave empty for the server default.
FontoptionsFont index from the WhatsApp status font set: Default (0), Font 1, Font 2, Bold (6), Font 7, Font 8, Font 9, Font 10, and Server Default (the node's default), which omits the field entirely.
CaptionstringMaximum 1024 characters.
Recipientsstring listWho may see this status: at most 256 @c.us or @lid ids, never a group. Required on the Baileys engine; leave empty on whatsapp-web.js to post to all contacts.

Template resource

Reusable message bodies with {{variable}} placeholders, stored per session and rendered by Message → Send Template.

OperationFieldsNotes
List(none)Every template in the session.
CreateName, Body, Header, FooterName (max 100) and Body (max 4096) are required; Header and Footer are optional, max 1024 each.
GetTemplate Name or IDOne template.
UpdateTemplate Name or ID, Update FieldsPartial: the collection offers Body, Footer, Header, and Name, with the same limits. At least one is required.
DeleteTemplate Name or IDDeletes the template.

Channel resource

WhatsApp Channels (newsletters) the session follows.

OperationFieldsNotes
List(none)Followed channels.
GetChannel Name or IDOne channel.
Get MessagesChannel Name or ID, Options: LimitA channel's messages.
SubscribeInvite CodeThe part after https://whatsapp.com/channel/. A full link is accepted and reduced to the code.
UnsubscribeChannel Name or IDA DELETE on the channel — it unfollows rather than deletes.

Call resource

OperationFieldsNotes
RejectSession Name or ID, Call IDThe call id as delivered by the Trigger's call events. Rejection is the only call action the API exposes — pair it with call.received to auto-decline.

Observability resource

Server health, for alerting from inside a workflow. None of these are scoped to a session, so the resource has no Session ID and no other fields.

OperationNotes
CheckGET /api/health — the server's health JSON as-is.
Check LivenessThe liveness probe.
Check ReadinessThe readiness probe. This is the one that also probes the database connections, so it reports a server that is running but not yet able to serve.

System resource

Server-wide reporting. Settings are read-only here on purpose: the server derives them from its environment; the PUT /api/settings route was removed in v0.19.0 after always answering 501.

OperationFieldsNotes
Get Settings(none)The server settings document. ADMIN key.
Get Stats Overview(none)Overview statistics.
Get Message Stats(none)Message statistics.
Get Session StatsSession Name or IDStatistics for one session.
Get Audit LogFiltersThe audit log. ADMIN key.
SearchQuery, FiltersCross-session message search; q is the only required parameter.

The Search filters:

FilterTypeNotes
Chat IDstringOnly search within this chat. Deliberately free text, not a dropdown — Search spans every session, so there is no single session whose chats could be listed.
Date From / Date TodateTimeBounds on the message time. The UI supplies ISO-8601 and the node converts each to the epoch-milliseconds number the API binds; an unparseable value fails the item.
DirectionoptionsIncoming or Outgoing.
FromstringOnly return messages from this sender.
Limit / OffsetnumberPagination, defaults 50 and 0.
Session Name or IDoptionsOnly search within this session.
TypestringOnly return messages of this type, for example text or image.

The Get Audit Log filters:

FilterTypeNotes
ActionstringOnly entries for this action.
API Key Name or IDoptionsOnly entries recorded for this key. Sent to the API as apiKeyId.
Limit / OffsetnumberPagination, defaults 50 and 0.
Session Name or IDoptionsOnly entries for this session.
SeveritystringOnly entries of this severity.

API Key resource

API-key administration. Every operation except Validate needs the credential itself to carry the ADMIN role. Create returns the new key's plaintext exactly once — capture it in the same execution, because it cannot be read back afterwards.

OperationFieldsNotes
List(none)Every key.
CreateName, FieldsName is required; the Fields collection carries the optional restrictions below.
GetAPI Key Name or IDOne key. The id, not the key itself.
UpdateAPI Key Name or ID, FieldsPartial — only the fields you set are changed, and an empty list never clears an existing whitelist. At least one field is required.
RevokeAPI Key Name or IDDeactivates the key.
DeleteAPI Key Name or IDRemoves the key.
Validate(none)Validates the credential this node is already authenticating with. Works with any valid key.

The Fields collection offers:

OptionTypeDefaultNotes
NamestringA friendly name for the key.
RoleoptionsViewerAdmin, Operator, or Viewer.
Expires AtdateTimeWhen the key stops working.
Allowed IPsstring listRestrict the key to these IP addresses.
Allowed Sessionsstring listRestrict the key to these session ids.

Webhook resource

Use these to register, update, or inspect a webhook from a workflow. For an event-driven workflow, prefer the Trigger node, which registers and removes its own webhook automatically.

Create — request body { url, events }, plus secret when set.

FieldTypeRequiredNotes
Webhook URLstringYesDestination that receives event deliveries.
EventsmultiOptionsYesOne or more events. At least one must be selected.
Webhook Secretstring (password)NoIf set, OpenWA signs each delivery with X-OpenWA-Signature (HMAC-SHA256); 16+ characters required since v0.20.0. Sent as secret.

Update — partial update (PUT): only the fields you set in Update Fields are changed; everything else keeps its current value.

FieldTypeRequiredNotes
Webhook Name or IDoptionsYesThe webhook to update. The dropdown lists a session's webhooks by delivery URL.
Update FieldscollectionNoThe changes to apply — see the options below.

The Update Fields collection offers:

OptionTypeNotes
URLstringNew delivery URL.
EventsmultiOptionsReplaces the full set of subscribed events (not merged). When set, at least one event must be selected.
ActivebooleanWhether the webhook is enabled.
Retry CountnumberMaximum delivery attempts, 0–5.
Secretstring (password)A non-empty value rotates the HMAC-SHA256 signing secret; an empty value is ignored. To disable signing, recreate the webhook without a secret.
Headers (JSON)jsonCustom delivery headers as a flat JSON object of string values, for example {"X-Team":"ops"}. Headers are non-nullable server-side — clear them by sending {}.
Filters (JSON)jsonAdvanced delivery filters as a JSON object, for example {"conditions":[...]}. Enter null to clear existing filters.

Get / List / Delete / Test — read, remove, or probe a webhook.

OperationFieldsNotes
GetSession Name or ID, Webhook Name or IDOne webhook.
ListSession Name or IDThe session's webhooks.
DeleteSession Name or ID, Webhook Name or IDRemoves it.
TestSession Name or ID, Webhook Name or IDSends a test delivery.

List All and Get Delivery Failures span every session, so neither shows a Session ID field.

OperationOptionsNotes
List AllLimit, OffsetWebhooks across all sessions. GET /api/webhooks binds only limit and offset, so no session filter is offered — one there would be accepted by the UI and then ignored by the server.
Get Delivery FailuresLimit, Offset, Session Name or IDFailed deliveries; this route is the one that does accept a session filter. ADMIN key.

Output and error handling

On success, each input item produces one output item containing the OpenWA JSON response. A DELETE that answers 204 No Content surfaces as { "success": true } so downstream nodes receive a readable item instead of an empty one. Status → Get Media is the exception: it returns raw bytes, which the node attaches as a binary property rather than putting on json.

The node fails the workflow on the first error unless Continue On Fail is enabled, in which case the failing item's output is { "error": "<message>" } and processing continues. Validation problems (empty chat id, non-digit phone number, no event selected, malformed session id, a poll outside 2–12 options, an oversized participant list) surface as node errors carrying the offending item's index; HTTP failures from OpenWA surface as API errors carrying the server's status and message.

OpenWA Trigger (node)

The trigger node registers a webhook with OpenWA when the workflow activates and starts the workflow each time a subscribed event arrives. It has no input; its single output emits one item per delivery.

Fields

FieldTypeRequiredNotes
Session Name or IDoptionsYesSession to receive events from, chosen from the same dropdown the action node uses. Sanitized like the action node (no empty, .., /, or \).
EventsmultiOptionsYesEvents to subscribe to. Default ['message.received']. At least one is required.
Webhook Secretstring (password)NoShared secret for signature verification. See Signature verification.
Deduplicate DeliveriesbooleanNoDefault off. Drops a repeated delivery of the same deliveryId, remembering the 500 most recent ids in workflow static data. Best-effort: two deliveries arriving at the same moment can both pass, and a retry whose first run failed is also dropped — enable it only when downstream actions are not idempotent and failed runs are rare.

The delivery path is scoped to the session (…/webhook/openwa-<sessionId>), so several active workflows can each run a Trigger on one n8n instance without colliding on a shared path.

Webhook lifecycle

The node manages its own OpenWA webhook across activation and deactivation. It stores the returned webhook id — along with the session it was registered on and a hash of the registration configuration — in workflow static data, and reuses them on later checks.

  • On activate, the node compares a hash of the delivery URL, events, secret, and session against the stored one. A mismatch means the registration is stale: it is deleted from the session it was registered on and recreated with the current configuration. Otherwise the node confirms the webhook still exists with GET /api/sessions/{sessionId}/webhooks/{webhookId}, and creates one with POST /api/sessions/{sessionId}/webhooks if it does not.
  • On deactivate, the node issues DELETE /api/sessions/{sessionId}/webhooks/{webhookId}. A 404 is treated as already deleted; any other error propagates so activation fails loudly rather than orphaning a registration that would keep delivering.
Re-registering after a configuration change

Changing the secret, the events, or the session takes effect on the next activation — deactivate and reactivate the workflow, and the node re-registers automatically. No manual cleanup on the server is needed.

Events

The Events field offers the same list in both the trigger and the action node's Webhook → Create and Update operations, mirroring core's own event catalog. Package 0.9.1 offers all twenty-two events the gateway dispatches.

EventFires when
message.receivedA new message is received.
message.sentA message is sent successfully.
message.ackA message delivery or read acknowledgement occurs.
message.failedA message fails to send.
message.revokedA message is deleted for everyone.
message.editedA message's text or media is edited.
message.reactionA reaction is added to or removed from a message.
status.receivedA contact's Status (Story) is received.
session.statusAny session status change.
session.qrA new QR code is generated.
session.authenticatedThe session is authenticated.
session.disconnectedThe session loses connection.
session.reconnect_loopA session is stuck in a reconnect loop — once per 5 consecutive attempts.
session.restrictionWhatsApp places or lifts a restriction on the account.
presence.updateA subscribed chat's presence changes. Baileys only, and silent until the chat is subscribed with POST /api/sessions/{sessionId}/presence/subscribe; whatsapp-web.js answers that route with 501.
group.joinA participant joins a group the session belongs to.
group.leaveA participant leaves a group the session belongs to.
group.updateA group's metadata or participant roster changes.
call.receivedAn incoming WhatsApp call is detected. Both engines.
call.acceptedAn incoming call is answered. Baileys only.
call.rejectedAn incoming call is declined, including by auto-reject. Baileys only.
call.missedAn incoming call goes unanswered. Baileys only.
The call outcomes fire on one engine only

whatsapp-web.js hooks the call collection's insert and sees no status at all, so it can report the ring but never how the call ended. A workflow triggered on call.accepted, call.rejected, or call.missed simply never runs on a whatsapp-web.js session. call.received fires on both engines.

Every event above exists on every server this package supports, so no per-event version floor discriminates between them any more — the ≥ 0.14.0 package floor covers the whole catalog. See Compatibility.

Output shape

Each delivery is an envelope. The node passes the parsed JSON body straight through, so $json is the envelope and the event-specific payload is under data.

FieldDescription
eventThe event name, for example message.received.
timestampISO 8601 time the event was emitted, for example 2024-01-15T10:30:00Z.
sessionIdSession the event belongs to.
idempotencyKeyStable key for the logical event.
deliveryIdPer-delivery id. Repeated across retries of the same delivery.
dataThe event payload. Read message fields from here.
{
"event": "message.received",
"timestamp": "2024-01-15T10:30:00Z",
"sessionId": "default",
"idempotencyKey": "a1b2c3d4-...",
"deliveryId": "e5f6a7b8-...",
"data": {
"id": "3EB0F5A2B4C...",
"chatId": "628123456789@c.us",
"from": "628123456789@c.us",
"body": "Hello!",
"type": "text",
"timestamp": 1705312200
}
}

Reading the output:

  • Reference payload fields through data, for example {{ $json.data.body }} and {{ $json.data.chatId }}.
  • Read the message identifier from data.id. Incoming payloads use id, not messageId.
  • OpenWA retries failed deliveries with the same deliveryId. De-duplicate on it if your downstream actions are not idempotent — either with the node's Deduplicate Deliveries toggle or a Remove Duplicates node.
  • Message type is engine-neutral: voice notes are voice, shared contacts are contact, and plain chats are text.
  • Some payloads carry extra fields under data: type: "masked" marks a withheld business message, and a message.revoked event carries revokedId, the id of the revoked message.

If the request body is missing or not an object, the node emits no items for that delivery rather than failing.

Signature verification

When Webhook Secret is set, OpenWA signs each delivery and the node verifies it before running the workflow. The signature scheme:

  • OpenWA computes HMAC-SHA256(secret, rawBody) over the exact bytes it transmits and sends the result as X-OpenWA-Signature: sha256=<hex>.
  • The node reads the raw request body — it does not re-serialize the parsed JSON, which could reorder keys or change whitespace and reject a valid delivery — then recomputes the expected sha256=<hex> and compares.
  • Comparison uses a constant-time check (timingSafeEqual). A length mismatch is treated as a non-match before the comparison runs.
  • Verification returns false when either the secret or the signature header is absent. With a secret configured, a delivery whose signature is missing or wrong is rejected with HTTP 401 and produces no workflow run.
  • If the running n8n cannot supply the raw body at all, the node logs a warning and rejects the delivery with 401 rather than silently re-serializing and dropping valid deliveries at random.

Leave Webhook Secret empty to skip verification and accept unsigned deliveries. For end-to-end webhook setup and the same signature scheme used outside n8n, see Webhooks.

Common errors

SymptomCauseFix
Credential test fails on saveAPI key rejected by GET /api/sessionsUse a valid key from the dashboard; see Authentication.
Session ID contains invalid charactersSession id has .., /, or \Pick the session from the dropdown, or supply its UUID from an expression.
Chat ID cannot be emptyMessage sent with no Chat IDProvide a chat id like 628123456789@c.us.
Phone number must contain only digitsCheck Exists got non-digit input that survived strippingPass digits only, for example 628123456789.
Base64 image or document rejected by OpenWAMissing MIME type on a base64 payloadSet the MIME Type field, or use the Binary Data or URL source.
400 when creating a webhookThe server does not know one of the selected eventssession.restriction, presence.update, call.accepted, call.rejected, and call.missed need OpenWA ≥ 0.14.0. Upgrade the gateway, or deselect the events it does not know.
404 on one operation while the rest workThe route postdates the serverThe action node's routes top out at v0.10.9; see Compatibility.
A call-outcome trigger never runsThe session runs whatsapp-web.jscall.accepted, call.rejected, and call.missed are Baileys-only. Use call.received, which fires on both engines.
Trigger fires once and then goes quietThe webhook was registered against n8n's test URL, which stops after one deliveryActivate the workflow so the trigger registers its production URL.
Trigger subscribed to a group event never runsThe session isn't a member of any group, or no group activity has occurredConfirm the session has joined a group and that group activity (joins/leaves/roster changes) is happening. group.join, group.leave, and group.update are emitted by both engines.
401 Unauthorized on every deliverySignature mismatch between server and node secretsUse the same Webhook Secret on both sides; reactivate the workflow after changing it.
403 on an operation that used to workThe credential's role is too lowWrites need an OPERATOR key; the API Key resource, System → Get Settings, System → Get Audit Log, and Webhook → Get Delivery Failures need an ADMIN key.

Compatibility

This package targets a self-hosted OpenWA server ≥ 0.14.0, verified against v0.23.1. Two things set that floor independently.

The routes the action node calls top out at v0.10.9: the profile writes, groups/join, groups/{id}/settings, messages/edit, and calls/{id}/reject arrived in v0.10.3, the bulk contact profile-pictures route in v0.10.1, and the stored-status media download in v0.10.9. Against an older server those specific operations answer 404 and the rest keep working.

The event catalog is what actually sets 0.14.0. session.restriction, presence.update, call.accepted, call.rejected, and call.missed do not exist in core before v0.14.0 — a v0.10.9 server knows 17 events, not 22 — and the server validates a webhook registration against its own event list, so a Trigger subscribing to any of the five is refused at registration rather than degrading quietly. That is a harder failure than a 404 on one operation, which is why it, and not the routes, is the supported floor.

Next steps