Send a WhatsApp message (text or media)
Sends a message from one of the authorized connections. Supply either `text` (text message) or `media` (image, video, audio, document, voice note) — not both. Pass an `idempotencyKey` on text sends to make retries safe.
Sends a message from one of the authorized connections. Supply either text (text message) or media (image, video, audio, document, voice note) — not both. Pass an idempotencyKey on text sends to make retries safe.
The default way to authenticate. Create a key at https://developers.wasync.app/keys and send it as Authorization: Bearer wsk_live_….
The key is shown once at creation and stored only as a hash — lose it and you revoke it and create another. Each key carries its own scopes (whatsapp.read, whatsapp.send, whatsapp.events, whatsapp.manage) and an optional IP allowlist.
Errors: an unknown or revoked key returns 401 invalid_key; a key whose IP allowlist does not cover the calling address returns 403 ip_not_allowed (a distinct code on purpose — the key is fine, the address is not). Both carry a WWW-Authenticate: Bearer challenge. Scopes and the connection list are resolved live on every request, so revoking a key or narrowing it takes effect on the next call.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Send either a text message or a media message — supply exactly one of the two. Supplying both returns 400 text_or_media.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/messages" \ -H "Content-Type: application/json" \ -d '{ "connectionId": "conn_8f3a21", "to": "40700000000", "text": "Hi from WASync 👋", "idempotencyKey": "order-1234-confirm" }'{ "messageId": "cmqj3k2ab0001xyz", "waMessageId": "[email protected]_3EB0A1B2C3", "status": "sent"}List recent messages GET
Returns recent messages (newest first) scoped to the token's connections. Cursor-paginated.
Mark inbound messages as read (blue ticks) POST
Sends a WhatsApp **read receipt** so the customer sees the blue ticks on the messages they sent you. Call this the moment one of your operators opens the conversation in your own UI. If your agents read WhatsApp inside your CRM, nobody ever opens the chat in WhatsApp — the customer's messages stay on double grey ticks and the conversation feels ignored. **Scope is `whatsapp.send`, not `whatsapp.read`:** marking read TRANSMITS a receipt from your number to the customer's device, so it is an outbound action. Any client that can already send can mark read — no new scope, no re-consent. Supply `connectionId` plus at least one of `phone` / `messageId`. `messageId` is WASync's stable id (a cuid) of an INCOMING message — not `waMessageId`. When both are given, `messageId` wins. Idempotent by nature: re-marking an already-read conversation is a no-op, so no `idempotencyKey` is accepted and no rate limit applies. Retry freely. Connection differences: WAPP/QR connections mark the whole chat; WABA (official API) connections can only mark one specific message, so a `phone`-only request resolves your most recent inbound message from that number automatically.