Envelope
Headers: Content-Type: application/json, Authorization: Bearer <webhookToken>, User-Agent: Meowsapp-WhatsApp/1, X-SN-Event: <type>. Delivery rules are in the Receiving messages guide.
{
"event": "message.received",
"type": "text",
"clientId": "acmemain",
"orgId": "acme",
"timestamp": "2026-08-28T05:22:55Z",
"chatRoomId": "acmemain-60111111111111-123456789012345",
"myLid": "60111111111111",
"clientLid": "123456789012345",
"remoteJid": "123456789012345@lid",
"remoteName": "Jane Lim",
"remotePhone": "60123456789",
"remoteUsername": "janelim",
"avatarUrl": "https://files.meowsapp.com/…/avatars/123456789012345/1965117713.jpg",
"pushName": "Jane",
"fromMe": false,
"isGroup": false,
"messageId": "3EB0A1B2C3D4E5F6",
"body": "Hello there",
"quoted": { "messageId": "3EB0…", "participant": "6011…", "body": "Earlier text", "type": "text" },
"mentions": ["60111111111111"],
"isForwarded": false,
"meta": { "fromAI": true, "userId": "u_42", "sender": "Ops bot", "raw": { "campaign": "aug" } },
"media": { "…": "type = image | video | audio | document | sticker" },
"poll": { "…": "type = poll_creation" },
"pollVote": { "…": "type = vote_update" },
"interactive": { "…": "type = interactive_reply" },
"contact": { "…": "type = contact" },
"location": { "…": "type = location" },
"reaction": { "…": "type = reaction" },
"edit": { "…": "type = edit" },
"revoke": { "…": "type = revoke" },
"group": { "…": "only when isGroup = true" }
}textText message
A plain text message. body holds the text.
- Replies carry
quoted; @-mentions carrymentions; forwarded messages setisForwarded: true.
imagevideoaudiodocumentstickerMedia message
A file was sent. The bytes are not included; media.download lets you fetch and decrypt it, or use the hosted inbox to have it stored for you.
{
"mimeType": "image/jpeg",
"mediaType": "image",
"fileName": "photo.jpg",
"fileSize": 102400,
"caption": "Here you go",
"download": {
"directPath": "/v/t62.7118-24/…",
"mediaKey": "base64…",
"fileSha256": "base64…",
"fileEncSha256": "base64…",
"fileLength": 102400
}
}mediaKeydecrypts the file — treat it as a secret.- Stickers are WebP with
mediaType: "sticker". Voice notes arrive asaudiowithmimeType: "audio/ogg; codecs=opus". - See the Media guide for downloading, or point
webhookUrlat the hosted inbox and readdownloadUrlfrom history instead.
poll_creationPoll created
Someone sent a poll.
{ "name": "Lunch?", "options": ["Pizza", "Sushi"], "selectableCount": 1 }- Store
optionsagainstmessageId— you need them to resolve votes (or configurepollLookupUrl).
vote_updatePoll vote
Someone voted on a poll.
{
"pollMessageId": "3EB0…",
"selectedNames": ["Pizza"],
"selectedHashes": ["a1b2…"],
"resolved": true
}resolved: truewithselectedNameswhen we could look up the poll (hosted inbox, or yourpollLookupUrl).- Otherwise
resolved: falseandselectedHashes= hex SHA-256 of each chosen option name; match against your stored options.
interactive_replyButton tapped
A quick-reply button from /send-interactive-message was tapped.
{ "selectedId": "yes", "selectedDisplayText": "Yes" }contactContact card shared
One or more vCards were shared.
{ "contacts": [ { "displayName": "Jane Lim", "phones": ["+60123456789"], "vcard": "BEGIN:VCARD…" } ] }bodyis a readable rendering:Contact shared\nName: …\nNumber: ….
locationLocation
A pinned or live location.
{ "latitude": 3.139, "longitude": 101.6869, "name": "KLCC", "address": "Kuala Lumpur", "url": "", "isLive": false }reactionReaction
An emoji reaction to an earlier message. Not a new message — update targetId.
{ "targetId": "3EB0…", "emoji": "👍" }emoji: ""means the reaction was removed.
editMessage edited
The sender edited an earlier message. Replace the body of targetId.
{ "targetId": "3EB0…", "body": "Corrected text" }revokeMessage deleted for everyone
The sender deleted an earlier message. Mark targetId as deleted.
{ "targetId": "3EB0…" }Group messages
Delivered only when the session has group receiving enabled. Any of the types above can arrive with isGroup: true and this object:
{
"jid": "120363012345678901@g.us",
"subject": "Launch team",
"participant": "123456789012345",
"participantPhone": "60123456789",
"participantUsername": "janelim"
}Note
chatRoomId for a group is <clientId>-<myLid>-<groupId> and remoteJid ends in @g.us. Reply in the group with to: group.jid, or privately with to: group.participant.