client.message.send also accepts a raw Proto.IMessage. Fill the field that names the content type — locationMessage, contactMessage, contactsArrayMessage, interactiveMessage, and so on — and the library encodes it verbatim.
Kinds that already have a typed builder — polls, reactions, edits, revokes, pins, keep-in-chat, view-once wrapping, and quotes / mentions / link previews — belong in Sending messages and Interactive messages. This page is for the raw-only kinds.
The full set of recognized Proto.IMessage fields (location, live location, contacts, group invite, product, order, …) is listed in the message types reference. Some examples below use enum values from the proto namespace:
How the stanza type is resolved
Whatever field you fill, zapo classifies the message before it goes on the wire: a<message> stanza carries a type (text or media), and a media stanza must also carry a mediatype. The server silently drops a media stanza with no mediatype — the send acks fine and nothing ever arrives — so a content type that falls through to the media default without one is invisibly lost.
Two details matter when you hand-build a payload:
- Wrappers are descended into.
deviceSentMessage,botForwardedMessage,groupStatusMessageV2andgroupStatusMessageall carry the real message in.message, so the inner content decides the type. A forwarded image staysmediawith itsmediatype; an image status wrapped ingroupStatusMessageV2no longer goes out astype="media"with nomediatype— a pairing no real client sends. - The AI rich-response family classifies as text.
richResponseMessageand a barebotForwardedMessagewrapper resolve totype="text". Before 1.9.0 they fell through to the media default and never delivered.
Locations
name and address are optional.
For a live-location message, use the liveLocationMessage field instead — it carries movement metadata (accuracyInMeters, speedInMps, sequenceNumber).
Contacts
A single contact card is acontactMessage with a vCard string:
waid=<digits> parameter on the TEL line is what lets the WhatsApp client link the card back to a WhatsApp account — use the recipient’s E.164 phone number without the +.
For multiple cards at once, use contactsArrayMessage:
Group invite
Buttons
Up to three quick-reply buttons. The header is aoneof — pick text, image, video, location, or document (pre-uploaded for media):
List menu
A single-select list of rows grouped into sections:A list to a group goes out with a different stanza shape than the same list in a direct chat: the group takes it only when
type=media, mediatype=list and the <biz><list> companion node travel together, while a direct send keeps the flat text shape. zapo picks the right one for you. Before 1.10.0 a group list was nacked with 479 while the identical message went through 1:1.Interactive native flow (cta_url)
The modern interactive surface — buttons whose params are JSON-encoded ad-hoc payloads:name and buttonParamsJson differ.
Product
Send a catalog product. The innerproductImage must already be uploaded:
Order
Order confirmation / inquiry:Newsletter admin invite
Invite a contact to co-admin one of your newsletters:Toggle disappearing messages (ephemeral setting)
Chat-wide toggle for disappearing messages — distinct from the per-messageexpirationSeconds send option (one message) and the ephemeralMessage wrapper (one message inheriting the chat timer). This one flips the timer for the whole chat.
Request a phone number
Payments (PIX & review-and-pay)
Send WhatsApp Business payment cards — static PIX (payment_info) and order checkout (review_and_pay) — as raw interactiveMessage / nativeFlowMessage payloads through client.message.send. There is no typed builder for them yet, so build the shape yourself the same way as the locations/contacts cards above. The library relays the interactive native-flow buttons; the WhatsApp clients render the card UI.
Amounts are integer minor units plus an offset divisor: { value: 1000, offset: 100 } renders as R$ 10,00. PIX key_type is one of EVP (chave aleatória), EMAIL, PHONE (E.164 preferred), CPF, CNPJ.
PIX card (payment_info)
Renders the PIX payment card (key / merchant). Use this for a static PIX key without an order card.
Review-and-pay card (review_and_pay)
Renders the order / cobrança card (reference number, items, total). Use this for a checkout-style summary.
buttonParamsJson must be a JSON string — build the object in code and stringify it. body / footer on interactiveMessage are optional. Don’t mix payment_info and review_and_pay expecting the same UI — they render different cards, and adding extra cta_copy / CTA buttons in the same nativeFlowMessage can render differently on mobile vs Web.
See also
- Sending messages — the base
client.message.sendAPI, options, and typed content variants. - Interactive messages — typed builders for polls, reactions, edits, revokes, pins, and keep-in-chat.
- Message types reference — every recognized
Proto.IMessagefield and its resolved type.
