Send Messages

Send messages from a connected device using the API.

Endpoint

Method Path Description
POST /devices/{device_id}/messages Send a message via the connected device.
  • Headers: Authorization: Bearer <token>, Content-Type: application/json
  • Required: to (MSISDN or full JID: @s.whatsapp.net/@lid/@g.us), type (text/image/video/audio/document/sticker/contact/location).
  • Device state: must be connected; otherwise you receive a device-not-connected error.

Large Group Behavior

  • Large groups/community chats: sends to big @g.us groups can take materially longer than direct chats or small groups because WhatsApp may need extra prekey/encryption work before accepting the message.
  • Client timeout: use a longer HTTP timeout for POST /devices/{device_id}/messages. Recommended minimum: 70-90s for production clients that send to large groups.
  • Retryable errors: treat group_prekey_timeout and upstream_timeout as retryable with backoff.
  • Non-retryable restriction: treat group_posting_restricted as a final failure until group settings/admin rights change.
{
  "error": {
    "code": "group_prekey_timeout",
    "message": "Timed out while preparing encryption for a large WhatsApp group. Retry later or reduce fan-out."
  },
  "request_id": "..."
}

Text

  • Fields: to, type: "text", text.
{
  "to": "6281234567890",
  "type": "text",
  "text": "Hello from wa-server"
}

Example (via LID):

{
  "to": "1234567890987654321@lid",
  "type": "text",
  "text": "Hello using LID"
}

Image

  • Fields: to, type: "image", mime_type, data_base64 or url, optional caption.
  • Caption: When you send an image with caption, the caption will appear in the webhook's text field when the message is received.
{
  "to": "6281234567890",
  "type": "image",
  "mime_type": "image/jpeg",
  "caption": "Sample image with caption",
  "data_base64": "<base64>"
}

Note: When receiving messages with caption via webhook, the text field will contain the caption text.

Video

  • Fields: to, type: "video", mime_type, data_base64 or url, optional caption.
  • Caption: Video captions will appear in webhook's text field when received.
  • Supported formats: MP4, QuickTime (mov), and other video formats supported by WhatsApp.
  • MIME types: video/mp4, video/quicktime, video/3gpp, etc.

Example: Video with Caption (Individual)

{
  "to": "6281234567890",
  "type": "video",
  "mime_type": "video/mp4",
  "caption": "Check out this amazing video",
  "data_base64": "<base64 encoded video data>"
}

Example: Video with Caption (Group)

{
  "to": "120363012345678901@g.us",
  "type": "video",
  "mime_type": "video/mp4",
  "caption": "Video for the team meeting",
  "data_base64": "<base64 encoded video data>"
}

Example: Video using URL (Individual)

{
  "to": "6281234567890",
  "type": "video",
  "mime_type": "video/mp4",
  "caption": "Watch this video from our server",
  "url": "https://example.com/videos/sample-video.mp4"
}

Example: Video without Caption (Individual)

{
  "to": "6281234567890",
  "type": "video",
  "mime_type": "video/mp4",
  "data_base64": "<base64 encoded video data>"
}

Example: Video using LID

{
  "to": "1234567890987654321@lid",
  "type": "video",
  "mime_type": "video/mp4",
  "caption": "Video sent via LID",
  "data_base64": "<base64 encoded video data>"
}

Note: When receiving video messages via webhook, the text field will contain the caption text (if present). The webhook includes media_mime_type, media_size, media_path for downloaded videos, and is_view_once flag.

Audio

  • Fields: to, type: "audio", mime_type, data_base64 or url, optional ptt.
  • PTT (Push-to-Talk): Set ptt: true for voice notes (short recordings sent in real-time). Set ptt: false or omit for regular audio files (music, podcasts, etc.).
  • Supported formats: MP3, OGG (Opus), AAC, M4A, and other audio formats supported by WhatsApp.
  • MIME types: audio/mpeg (MP3), audio/ogg or audio/ogg; codecs=opus (OGG/Opus), audio/aac, audio/mp4, etc.

Example: Voice Note (PTT) - Individual

{
  "to": "6281234567890",
  "type": "audio",
  "mime_type": "audio/ogg; codecs=opus",
  "ptt": true,
  "data_base64": "<base64 encoded audio data>"
}

Voice note: Use ptt: true for voice notes. These are typically shorter recordings (up to several minutes). WhatsApp often uses OGG/Opus format for voice notes.

Example: Regular Audio File - Individual

{
  "to": "6281234567890",
  "type": "audio",
  "mime_type": "audio/mpeg",
  "ptt": false,
  "data_base64": "<base64 encoded audio data>"
}

Regular audio: Use ptt: false or omit the ptt field for regular audio files like music or podcasts. MP3 is the most common format.

Example: Voice Note (PTT) - Group

{
  "to": "120363012345678901@g.us",
  "type": "audio",
  "mime_type": "audio/ogg; codecs=opus",
  "ptt": true,
  "data_base64": "<base64 encoded audio data>"
}

Example: Regular Audio File using URL - Individual

{
  "to": "6281234567890",
  "type": "audio",
  "mime_type": "audio/mpeg",
  "ptt": false,
  "url": "https://example.com/audio/music.mp3"
}

Example: Audio using LID

{
  "to": "1234567890987654321@lid",
  "type": "audio",
  "mime_type": "audio/mpeg",
  "ptt": false,
  "data_base64": "<base64 encoded audio data>"
}

Note: Voice notes (PTT) are typically displayed differently in WhatsApp (as playable voice messages), while regular audio files are sent as standard audio attachments. The choice of format and PTT setting affects how the audio is displayed and played in WhatsApp.

Document

  • Fields: to, type: "document", mime_type, file_name, data_base64 or url, optional caption.
  • Caption: Document captions will appear in webhook's text field when received.
  • Supported formats: PDF, Word (.doc, .docx), Excel (.xls, .xlsx), PowerPoint (.ppt, .pptx), text files (.txt), ZIP archives, and other document formats.
  • MIME types: application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document (.docx), application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (.xlsx), application/msword (.doc), application/vnd.ms-excel (.xls), text/plain (.txt), application/zip, etc.

Example: Document with Caption (Individual)

{
  "to": "6281234567890",
  "type": "document",
  "mime_type": "application/pdf",
  "file_name": "report.pdf",
  "caption": "Please review this document",
  "data_base64": "<base64 encoded PDF data>"
}

Example: Document without Caption (Individual)

{
  "to": "6281234567890",
  "type": "document",
  "mime_type": "application/pdf",
  "file_name": "invoice.pdf",
  "data_base64": "<base64 encoded PDF data>"
}

Example: Excel Document with Caption (Group)

{
  "to": "120363012345678901@g.us",
  "type": "document",
  "mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  "file_name": "budget_2026.xlsx",
  "caption": "Monthly budget spreadsheet",
  "data_base64": "<base64 encoded Excel data>"
}

Example: Document using URL (Individual)

{
  "to": "6281234567890",
  "type": "document",
  "mime_type": "application/pdf",
  "file_name": "manual.pdf",
  "caption": "User manual",
  "url": "https://example.com/documents/manual.pdf"
}

Example: Word Document using LID

{
  "to": "1234567890987654321@lid",
  "type": "document",
  "mime_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  "file_name": "proposal.docx",
  "caption": "Project proposal",
  "data_base64": "<base64 encoded Word document data>"
}

Note: The file_name field is required for document messages. The filename helps users identify the document type and should include the file extension (e.g., report.pdf, invoice.xlsx). Documents can optionally include captions to provide context.

Sticker

  • Fields: to, type: "sticker", mime_type: "image/webp", data_base64 or url.
  • Format: WhatsApp stickers use WebP format. They can be static or animated (animated WebP).
  • Size: Stickers are typically small files (under 100KB). WhatsApp optimizes sticker sizes automatically.
  • Caption: Stickers do not support captions. The caption field is ignored if provided.
  • MIME type: Always image/webp for WhatsApp stickers.

Example: Sticker (Individual)

{
  "to": "6281234567890",
  "type": "sticker",
  "mime_type": "image/webp",
  "data_base64": "<base64 encoded WebP sticker data>"
}

Example: Sticker (Group)

{
  "to": "120363012345678901@g.us",
  "type": "sticker",
  "mime_type": "image/webp",
  "data_base64": "<base64 encoded WebP sticker data>"
}

Example: Sticker using URL (Individual)

{
  "to": "6281234567890",
  "type": "sticker",
  "mime_type": "image/webp",
  "url": "https://example.com/stickers/happy.webp"
}

Example: Sticker using LID

{
  "to": "1234567890987654321@lid",
  "type": "sticker",
  "mime_type": "image/webp",
  "data_base64": "<base64 encoded WebP sticker data>"
}

Note: Stickers must be in WebP format. If you have an image in another format (PNG, JPG, GIF), you'll need to convert it to WebP first. Animated stickers use animated WebP format. Stickers are displayed larger than regular images in WhatsApp chats.

Contact

  • Fields: to, type: "contact", contact_name, vcard.
  • vCard format: Standard vCard 3.0 format. Can contain multiple phone numbers (TEL fields).
  • Auto-farming: When a contact message is received, the system automatically extracts all phone numbers from the vCard and fetches their profile data.

Example: Single Phone Number

{
  "to": "6281234567890",
  "type": "contact",
  "contact_name": "John Doe",
  "vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nTEL;TYPE=CELL:+6281234567890\nEND:VCARD"
}

Example: Multiple Phone Numbers

{
  "to": "6281234567890",
  "type": "contact",
  "contact_name": "John Doe",
  "vcard": "BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nTEL;TYPE=CELL:+6281234567890\nTEL;TYPE=WORK:+6289876543210\nTEL;TYPE=HOME:+6281111111111\nEMAIL:john@example.com\nEND:VCARD"
}

Note: When a contact message with multiple phone numbers is received, the system will automatically extract and farm profile data for all phone numbers found in the vCard.

Location

  • Fields: to, type: "location", latitude, longitude, optional address.
  • Coordinates: latitude must be between -90 and 90, longitude must be between -180 and 180 (decimal degrees).
  • Address: Optional location name or address (e.g., "National Monument", "123 Main St, City"). This will be displayed in the webhook as location_name or location_address.

Example: Location with Address (Individual)

{
  "to": "6281234567890",
  "type": "location",
  "latitude": -6.175392,
  "longitude": 106.827153,
  "address": "National Monument, Jakarta, Indonesia"
}

Example: Location with Address (Group)

{
  "to": "120363012345678901@g.us",
  "type": "location",
  "latitude": -6.2088,
  "longitude": 106.8456,
  "address": "Restaurant ABC, Jl. Sudirman No. 123, Jakarta"
}

Example: Location without Address (Individual)

{
  "to": "6281234567890",
  "type": "location",
  "latitude": -6.175392,
  "longitude": 106.827153
}

Coordinates only: You can send a location with just coordinates. The address field is optional. If omitted, the webhook will only include latitude and longitude.

Example: Location using LID

{
  "to": "1234567890987654321@lid",
  "type": "location",
  "latitude": -6.175392,
  "longitude": 106.827153,
  "address": "National Monument, Jakarta"
}

Note: When receiving location messages via webhook, the text field will contain the location name if available (e.g., "📍 Location: National Monument"), otherwise it will display "📍 Location". The webhook includes latitude, longitude, and optionally location_name and location_address fields.

Live Location Sharing: The current implementation supports sending static location messages only. For live location sharing (where location updates automatically), users must share manually through the WhatsApp app. When someone shares live location with your device, each location update will be received as a separate location message through the webhook. See Live Location Documentation for more details on receiving and tracking live location updates.

Integration Notes

  • Provide media as base64 or HTTPS URL; enforce MIME allowlist and size limits.
  • Keep payloads concise; avoid sending unnecessary metadata.
  • Use webhooks for receipts/presence instead of polling.