Message Types Reference
This page documents every message_type you may encounter in message.received and message.sent webhook events. Each type includes the exact payload structure, which platforms support it, and whether it's inbound-only, outbound-only, or bidirectional.
For the webhook envelope structure and event lifecycle, see Webhook Events Reference.
Direction Matrix
| message_type | Inbound | Outbound | Platforms |
|---|---|---|---|
text | ✅ | ✅ | All |
image | ✅ | ✅ | All |
video | ✅ | ✅ | All |
audio | ✅ | ✅ | All |
document | ✅ | ✅ | WhatsApp, Telegram (inbound); All (outbound) |
sticker | ✅ | ✅ | All (inbound); WhatsApp (outbound) |
location | ✅ | ❌ | |
contact (inbound) / contacts (outbound) | ✅ | ✅ | |
interactive | ✅ | ✅ | |
button | ✅ | ❌ | WhatsApp (template quick-reply buttons) |
reaction | ✅ | ❌ | |
template | ❌ | ✅ | |
carousel | ❌ | ✅ | WhatsApp, Messenger |
File-Based Attachments
Messages of type image, video, audio, document, and sticker include an attachments array with enriched download data:
{
"id": "att_abc123",
"type": "image",
"filename": "whatsapp_image_abc123.jpg",
"content_type": "image/jpeg",
"file_size": 245000,
"url": "https://api.sendseven.com/api/v1/attachments/att_abc123/download",
"signed_url": "https://storage.googleapis.com/...?X-Goog-Signature=..."
}
| Field | Description |
|---|---|
url | Stable API endpoint — requires authentication, never expires |
signed_url | Pre-signed GCS URL — no auth required, expires in 24 hours |
If SendSeven could not download the media from the platform, the raw platform data is passed through with "source": "platform" added to each attachment object. Check for this field to detect unprocessed attachments.
Inbound Message Types
text
The most common message type. Supported on all platforms.
{
"message_type": "text",
"text": "Hello, I need help with my order",
"attachments": null
}
image
Photo messages with optional caption. Includes Telegram GIFs/animations.
{
"message_type": "image",
"text": "Check out this photo",
"attachments": [
{
"id": "att_img_001",
"type": "image",
"filename": "whatsapp_image_abc123.jpg",
"content_type": "image/jpeg",
"file_size": 245000,
"url": "https://api.sendseven.com/api/v1/attachments/att_img_001/download",
"signed_url": "https://storage.googleapis.com/...?X-Goog-Signature=..."
}
]
}
text contains the caption if provided, otherwise "".
video
Video messages with optional caption. Includes Telegram round video notes.
{
"message_type": "video",
"text": "",
"attachments": [
{
"id": "att_vid_001",
"type": "video",
"filename": "video_message.mp4",
"content_type": "video/mp4",
"file_size": 5242880,
"url": "https://api.sendseven.com/api/v1/attachments/att_vid_001/download",
"signed_url": "https://storage.googleapis.com/...?X-Goog-Signature=..."
}
]
}
audio
Voice messages and audio files.
{
"message_type": "audio",
"text": "",
"attachments": [
{
"id": "att_aud_001",
"type": "audio",
"filename": "voice_note.ogg",
"content_type": "audio/ogg",
"file_size": 128000,
"url": "https://api.sendseven.com/api/v1/attachments/att_aud_001/download",
"signed_url": "https://storage.googleapis.com/...?X-Goog-Signature=..."
}
]
}
document
File attachments with optional caption. WhatsApp and Telegram inbound.
{
"message_type": "document",
"text": "Here's the contract",
"attachments": [
{
"id": "att_doc_001",
"type": "document",
"filename": "contract_2026.pdf",
"content_type": "application/pdf",
"file_size": 184320,
"url": "https://api.sendseven.com/api/v1/attachments/att_doc_001/download",
"signed_url": "https://storage.googleapis.com/...?X-Goog-Signature=..."
}
]
}
sticker
Sticker messages from all platforms. WhatsApp sets text to "[Sticker]", other platforms use "".
{
"message_type": "sticker",
"text": "[Sticker]",
"attachments": [
{
"id": "att_stk_001",
"type": "sticker",
"filename": "sticker.webp",
"content_type": "image/webp",
"file_size": 32000,
"url": "https://api.sendseven.com/api/v1/attachments/att_stk_001/download",
"signed_url": "https://storage.googleapis.com/...?X-Goog-Signature=..."
}
]
}
location
Location pins shared by contacts. WhatsApp only, inbound only.
{
"message_type": "location",
"text": "Location: Eiffel Tower",
"attachments": [
{
"type": "location",
"latitude": 48.8566,
"longitude": 2.3522,
"name": "Eiffel Tower",
"address": "Champ de Mars, 75007 Paris"
}
]
}
Location attachments are not file-based — they contain coordinate data directly. The name and address fields are optional and depend on what the contact shared.
contact
Contact cards shared via WhatsApp.
{
"message_type": "contact",
"text": "Shared contacts: John Doe, Jane Smith",
"attachments": [
{
"type": "contact",
"contacts": [
{
"name": {
"formatted_name": "John Doe",
"first_name": "John",
"last_name": "Doe"
},
"phones": [
{ "phone": "+491234567890", "type": "CELL" }
],
"emails": [
{ "email": "[email protected]", "type": "WORK" }
]
}
]
}
]
}
WhatsApp sends contact cards with the plural type contacts; SendSeven normalizes inbound messages to the singular contact (both message_type and the attachment type). Outbound contact-card sends use the plural contacts type (see contacts (outbound)). Contact card attachments are not file-based.
interactive — Button Reply
When a contact taps a button from a previously sent interactive message. WhatsApp only.
{
"message_type": "interactive",
"text": "Yes, confirm order",
"attachments": [
{
"type": "button_reply",
"button_id": "btn_confirm",
"button_title": "Yes, confirm order"
}
]
}
The text field contains the button title for convenience, and a meta.button object ({ id, payload, text }) is also included — see Button Clicks Across Channels.
interactive — List Reply
When a contact selects an item from a list menu. WhatsApp only.
{
"message_type": "interactive",
"text": "Express Shipping\n2-3 business days",
"attachments": [
{
"type": "list_reply",
"list_id": "shipping_express",
"list_title": "Express Shipping",
"list_description": "2-3 business days"
}
],
"meta": {
"button": {
"id": "shipping_express",
"payload": "shipping_express",
"text": "Express Shipping",
"list_title": "Express Shipping",
"list_description": "2-3 business days"
}
}
}
text mirrors what the contact sees in WhatsApp: the selected row's title, and — when the row has a description — the description on the next line ("{list_title}\n{list_description}"). The meta.button object carries { id, payload, text } (with text = the list title) plus list_title and list_description for list replies (these two extra keys are present only for list replies; a plain button reply's meta.button stays { id, payload, text }).
interactive — Flow Response (NFM Reply)
When a contact completes a WhatsApp Flow. WhatsApp only.
{
"message_type": "interactive",
"text": "Flow completed: Customer Survey\n\n**Satisfaction:**\n -> Very Happy\n\n**Comments:**\n Great service!",
"attachments": [
{
"type": "flow_response",
"flow_name": "Customer Survey",
"flow_token": "token_abc123",
"response_data": {
"screen_0_Satisfaction_0": "5_Very_Happy",
"screen_1_Comments_0": "Great service!",
"flow_token": "token_abc123"
}
}
]
}
The text field contains a human-readable formatted summary. The response_data contains the raw key-value pairs from the flow screens.
reaction
Emoji reactions to messages. WhatsApp only, inbound only.
{
"message_type": "reaction",
"text": "Reacted 👍 to message",
"attachments": [
{
"type": "reaction",
"emoji": "👍",
"message_id": "wamid.HBgNNDkx..."
}
]
}
The message_id references the WhatsApp message ID that was reacted to.
button
When a contact taps a quick-reply button on a WhatsApp template message (as opposed to a standalone interactive message), the click arrives as message_type: "button". WhatsApp only, inbound only.
{
"message_type": "button",
"text": "Yes, confirm",
"attachments": null,
"meta": {
"button": {
"id": "OPT_YES",
"payload": "OPT_YES",
"text": "Yes, confirm"
}
}
}
The clicked button caption populates the text field, and the structured meta.button object carries { id, payload, text }. For template quick-reply buttons, WhatsApp does not send a distinct button ID, so id and payload both contain the button payload.
This is distinct from interactive button replies. Template quick-reply buttons (attached to a template message) arrive as message_type: "button"; buttons on a standalone interactive message arrive as message_type: "interactive" with a button_reply attachment. Both populate text with the caption and include meta.button.
Button Clicks Across Channels
Every channel that supports buttons forwards the clicked caption in the message text field and populates a structured meta.button object so you can react to the click without parsing the caption:
"meta": {
"button": {
"id": "OPT_YES",
"payload": "OPT_YES",
"text": "Yes, confirm"
}
}
| Field | Type | Description |
|---|---|---|
id | string | Button/option identifier |
payload | string | Developer-defined payload sent back on click (equals id when the channel has no separate payload) |
text | string | The button caption the contact saw (also mirrored into the message text) |
This applies to:
| Channel | Button source | message_type |
|---|---|---|
| Template quick-reply button | button | |
Interactive button_reply | interactive | |
Interactive list_reply | interactive | |
| Telegram | Inline keyboard callback | text |
| Messenger | Postback button | text |
| Messenger | Quick reply | text |
| Postback button | text | |
| Quick reply | text | |
| Live Chat | Widget button | text |
The existing channel-specific attachment objects (button_reply, list_reply) are still included for WhatsApp interactive messages — meta.button is provided in addition to them. For WhatsApp list replies, meta.button also carries list_title and list_description (the row's title and description); text remains the list title.
Outbound Message Types
These appear in message.sent webhook events.
text
{
"message_type": "text",
"text": "Hi John! Let me look into your order right away.",
"attachments": null
}
image / video / audio / document
Same as inbound — includes enriched attachments array:
{
"message_type": "image",
"text": "Here's the receipt",
"attachments": [
{
"id": "att_out_001",
"type": "image",
"filename": "receipt.jpg",
"content_type": "image/jpeg",
"file_size": 245000,
"url": "https://api.sendseven.com/api/v1/attachments/att_out_001/download",
"signed_url": "https://storage.googleapis.com/...?X-Goog-Signature=..."
}
]
}
interactive (outbound)
Interactive messages with buttons or list menus. WhatsApp only. Metadata includes the full interactive structure:
{
"message_type": "interactive",
"text": "How would you like to proceed?",
"attachments": null,
"meta": {
"interactive_type": "buttons",
"body": "How would you like to proceed?",
"header": { "type": "text", "text": "Order #12345" },
"footer": "Reply within 24 hours",
"buttons": [
{ "id": "btn_confirm", "title": "Confirm" },
{ "id": "btn_cancel", "title": "Cancel" }
]
}
}
For list-type interactive messages:
{
"meta": {
"interactive_type": "list",
"body": "Choose a shipping option:",
"sections": [
{
"title": "Shipping",
"rows": [
{ "id": "ship_standard", "title": "Standard", "description": "5-7 days" },
{ "id": "ship_express", "title": "Express", "description": "2-3 days" }
]
}
]
}
}
template
WhatsApp template messages. Outbound only.
{
"message_type": "template",
"text": "Hi John, your order #12345 has shipped! Track it here: https://track.example.com/12345",
"attachments": null,
"meta": {
"whatsapp_template": true,
"template_id": "tmpl_abc123",
"template_name": "order_shipped",
"template_language": "en",
"header_type": "text",
"header_text": "Order Update",
"footer_text": "Thank you for your purchase",
"buttons": [
{ "type": "URL", "text": "Track Order", "url": "https://track.example.com/12345" }
]
}
}
The text field contains the template body with parameters already substituted.
contacts (outbound)
Contact cards sent via WhatsApp.
{
"message_type": "contacts",
"text": "[Contact Cards]",
"attachments": null,
"meta": {
"content_type": "contacts",
"contacts_count": 1,
"contacts_data": [
{
"name": { "formatted_name": "Support Team", "first_name": "Support" },
"phones": [{ "phone": "+491781660323", "type": "WORK" }]
}
]
}
}
sticker (outbound)
Sticker sent via WhatsApp.
{
"message_type": "sticker",
"text": "[Sticker]",
"attachments": null,
"meta": {
"content_type": "sticker",
"sticker_id": "whatsapp_media_id",
"sticker_url": "https://example.com/sticker.webp"
}
}
carousel
Rich card carousels. WhatsApp and Messenger.
WhatsApp carousel:
{
"message_type": "carousel",
"text": "[Carousel: product_showcase] 3 cards",
"attachments": null,
"meta": {
"content_type": "carousel",
"cards_count": 3,
"platform": "whatsapp",
"template_name": "product_showcase",
"language": "en"
}
}
Messenger carousel:
{
"message_type": "carousel",
"text": "[Carousel] Sneakers, Jacket, Backpack",
"attachments": null,
"meta": {
"content_type": "carousel",
"cards_count": 3,
"platform": "messenger",
"elements": [
{
"title": "Sneakers",
"subtitle": "Running shoes — $89",
"image_url": "https://shop.example.com/img/sneakers.jpg",
"buttons": [
{ "type": "web_url", "url": "https://shop.example.com/sneakers", "title": "View" }
]
}
]
}
}
Platform-Specific Notes
WhatsApp
- Supports all message types listed above.
contactsuses plural form (matching WhatsApp API convention).- Template quick-reply button clicks arrive as
message_type: "button"with the caption intextand ameta.buttonobject (see button). - Interactive replies (button, list, flow) arrive as
message_type: "interactive"— differentiate by checkingattachments[0].type. Button and list replies also populatemeta.buttonwith{ id, payload, text }. - Reactions are
message_type: "reaction"(not in the standard enum, but stored and delivered).
Telegram
- GIFs/animations arrive as
message_type: "image". - Round video notes arrive as
message_type: "video". - Both voice messages and audio files arrive as
message_type: "audio". - Inline button clicks arrive as
message_type: "text"withmeta.is_callback_query: trueandmeta.callback_query_id. The clicked caption is forwarded intextand ameta.buttonobject ({ id, payload, text }) is included.
Messenger
- Stickers are detected via
sticker_idand delivered asmessage_type: "sticker"(Facebook sends them as image type). - Postback buttons and quick replies arrive as
message_type: "text"with the payload inmeta.quick_reply. The clicked caption is forwarded intextand ameta.buttonobject ({ id, payload, text }) is included. - Deep link referrals (
m.melinks) create a syntheticmessage_type: "referral"withmeta.ref_parameter.
Instagram
- Supports text, image, video, audio, and sticker.
- Story replies include
meta.is_story_reply: trueandmeta.story_id. - Postback buttons and quick replies arrive as
message_type: "text"with the caption intextand ameta.buttonobject ({ id, payload, text }). - No profile data is included in
contact_info(Instagram webhook limitation).
Live Chat
- Widget button clicks arrive as
message_type: "text"with the caption intextand ameta.buttonobject ({ id, payload, text }).
Next Steps
- Webhook Events Reference — event types and full payload envelope
- Signature Verification — secure your webhook endpoint
- Send Media Messages — sending attachments via the API