WhatsApp API reference
Every endpoint in the wasender.dev API, 56 in total. Send and receive WhatsApp messages over plain HTTP on a number you already own.
This page is the plain-text rendering of the specification, written for reading and for machines. The interactive reference has a request playground, and the OpenAPI 3.1 document and llms.txt are generated from the same source.
Send and receive WhatsApp messages over plain HTTP. Connect a number by scanning a QR code, then use the channel token that comes back to call any endpoint below.
Authentication
Every request is authenticated with a channel token — one token per connected WhatsApp number. Pass it either way:
Authorization: Bearer wsk_sg_xxxxxxxxxxxxxxxxxxxxxxxx GET /chats?token=wsk_sg_xxxxxxxxxxxxxxxxxxxxxxxx
The token encodes its region (wsk_sg_…, wsk_us_…, wsk_eu_…) but is otherwise opaque. Treat it as a password: it grants full control of the number it belongs to.
Regions
Sessions currently run in Singapore, serving customers worldwide. Sending a WhatsApp message is asynchronous — delivery goes through Meta's own global network, not ours — so the region affects only the latency of your API call, not how fast your recipients get messages.
A channel is pinned to its region at creation and stays there: moving a live session changes its outbound IP, which materially raises the risk of WhatsApp restricting the number. Additional regions will be added for data-residency requirements.
Compatibility
The endpoints below are request- and response-compatible with whapi.cloud, so migrating is a change of base URL and token. Endpoints outside this document return 501 with an error body naming the endpoint; open an issue if you need one.
Important
This service drives WhatsApp through an unofficial client, the same mechanism as WhatsApp Web. Meta does not sanction it. Use a dedicated number you can afford to lose, do not send first-contact messages to people who have not opted in, and keep a fallback channel for anything auth- or revenue-critical. For regulated workloads, use Meta's official Cloud API instead.
Channel
The connected WhatsApp number itself — health, settings, profile, logout.
Check channel health
GET/health
Reports whether the number is connected and ready to send. Safe to poll — it does not touch WhatsApp, only the gateway's view of the session.
A hibernated channel is healthy: it has simply been parked to save resources and will wake on the next request that needs the socket, taking a few seconds to do so.
wakeup(query): Wake a hibernated channel and wait for it to reconnect before answering.
Get channel settings
GET/settings
Update channel settings
PATCH/settings
Sets the webhook the channel delivers events to, and the automatic behaviours (read receipts, presence) applied to incoming messages.
Get the QR code to link this number
GET/users/login/image
Returns the QR code to scan from WhatsApp on the phone (Settings → Linked devices → Link a device).
QR codes rotate roughly every 20 seconds; re-request when one expires. Once scanned, credentials are stored and future reconnects need no scan.
wakeup(query)size(query): Image edge length in pixels.
Get this number's own profile
GET/users/profile
Update this number's own profile
PATCH/users/profile
Unlink this number
POST/users/logout
Logs the device out of WhatsApp and discards the stored credentials. The channel itself is kept — reconnecting means scanning a fresh QR code.
This does not cancel billing. Delete the channel from the dashboard or the management API to stop being charged for it.
Messages
Send, read, edit, react to and delete messages.
List messages across all chats
GET/messages/list
count(query): How many records to return.offset(query): How many records to skip.time_from(query): Only messages at or after this Unix timestamp (seconds).time_to(query): Only messages at or before this Unix timestamp (seconds).normal_types(query): Exclude system and protocol messages.
List messages in one chat
GET/messages/list/{ChatID}
ChatID(path, required): Chat id, e.g. `[email protected]` or `[email protected]`.count(query): How many records to return.offset(query): How many records to skip.time_from(query)time_to(query)
Send a text message
POST/messages/text
The workhorse endpoint.
to accepts a bare phone number in international format without + (61371989950) or a full chat id ([email protected], [email protected] for a group).
A first-ever message to someone who has never messaged you is the single most reliable way to get a number restricted. Send to people who expect to hear from you.
Send an image
POST/messages/image
Send a video
POST/messages/video
Send an audio file
POST/messages/audio
Send a voice note
POST/messages/voice
Renders as a push-to-play voice note rather than an audio attachment. WhatsApp expects Opus in an Ogg container; other formats are transcoded, which adds latency.
Send a document
POST/messages/document
Send a sticker
POST/messages/sticker
Send a location
POST/messages/location
Send a contact card
POST/messages/contact
Send a link with a rich preview
POST/messages/link_preview
Send a poll
POST/messages/poll
Get one message
GET/messages/{MessageID}
MessageID(path, required)
Mark a message as read
POST/messages/{MessageID}
MessageID(path, required)
Edit a message
PUT/messages/{MessageID}
WhatsApp only allows editing your own messages, within 15 minutes of sending.
MessageID(path, required)
Delete a message
DELETE/messages/{MessageID}
MessageID(path, required)
React to a message
PUT/messages/{MessageID}/reaction
MessageID(path, required)
Remove your reaction
DELETE/messages/{MessageID}/reaction
MessageID(path, required)
Star or unstar a message
PUT/messages/{MessageID}/star
Not supported. Returns 501. The underlying engine exposes no way to star a message, and silently accepting the call would drop the flag without telling you.
MessageID(path, required)
Get delivery and read receipts for a message
GET/statuses/{MessageID}
MessageID(path, required)
Chats
Conversations, whether one-to-one or group.
List chats
GET/chats
count(query): How many records to return.offset(query): How many records to skip.
Get one chat
GET/chats/{ChatID}
ChatID(path, required): Chat id, e.g. `[email protected]` or `[email protected]`.
Mark a chat as read
POST/chats/{ChatID}
ChatID(path, required): Chat id, e.g. `[email protected]` or `[email protected]`.
Archive, pin or mute a chat
PATCH/chats/{ChatID}
ChatID(path, required): Chat id, e.g. `[email protected]` or `[email protected]`.
Delete a chat
DELETE/chats/{ChatID}
ChatID(path, required): Chat id, e.g. `[email protected]` or `[email protected]`.
Contacts
Address book and WhatsApp-reachability checks.
List contacts
GET/contacts
count(query): How many records to return.offset(query): How many records to skip.
Check whether numbers are on WhatsApp
POST/contacts
Validates numbers before you message them. Cheap insurance: sending to numbers that are not on WhatsApp is a strong spam signal and a common cause of restriction.
Keep batches modest — a few hundred at a time, not tens of thousands.
Get one contact
GET/contacts/{ContactID}
ContactID(path, required)
Get a contact's public profile
GET/contacts/{ContactID}/profile
ContactID(path, required)
Groups
Create and administer groups.
List groups
GET/groups
count(query): How many records to return.offset(query): How many records to skip.
Create a group
POST/groups
Get one group
GET/groups/{GroupID}
GroupID(path, required)
Update a group's subject or description
PATCH/groups/{GroupID}
GroupID(path, required)
Leave a group
DELETE/groups/{GroupID}
GroupID(path, required)
Add participants
POST/groups/{GroupID}/participants
WhatsApp privacy settings let people refuse group adds. Participants who cannot be added directly are returned with an invite link to send them instead.
GroupID(path, required)
Remove participants
DELETE/groups/{GroupID}/participants
GroupID(path, required)
Promote participants to admin
PATCH/groups/{GroupID}/admins
GroupID(path, required)
Demote admins to member
DELETE/groups/{GroupID}/admins
GroupID(path, required)
Join a group with an invite code
POST/groups/link/{InviteCode}
Accepts the code from an invite link — the part after chat.whatsapp.com/.
InviteCode(path, required)
Get the group invite link
GET/groups/{GroupID}/invite
GroupID(path, required)
Revoke and regenerate the invite link
DELETE/groups/{GroupID}/invite
GroupID(path, required)
Media
Upload and retrieve files.
List uploaded media
GET/media
count(query): How many records to return.offset(query): How many records to skip.
Upload a file
POST/media
Upload once and reuse the returned id across many sends — much cheaper than re-uploading the same file per recipient.
Download a media file
GET/media/{MediaID}
MediaID(path, required)
Delete a media file
DELETE/media/{MediaID}
MediaID(path, required)
Presences
Online status and typing indicators.
Set your own online presence
PUT/presences/me
Subscribe to a contact's presence
POST/presences/{EntryID}
Not supported. Returns 501. Presence updates arrive through webhooks rather than per-contact subscriptions, so there is nothing to subscribe to.
EntryID(path, required)
Send a typing or recording indicator
PUT/presences/{EntryID}
EntryID(path, required): Chat or contact id the indicator is shown in.