Send a message
Sends one message from the given session. There is a **single** send endpoint for every kind of message; the discriminated `type` field in the request body chooses which one. **Supported in v1:** `text`, `poll`, `location`, and `contact`. **Not implemented yet:** the media types `image`, `video`, `audio`, `document`, and `sticker` return **501 `not_implemented`** before any WhatsApp call is made. ### Delivery mode (`?async`) - **Synchronous (default, `?async=false`):** the call blocks until WhatsApp acknowledges the send and returns **200** with the final `SendResult`. - **Asynchronous (`?async=true`):** the gateway persists the send to a queue and returns **202** immediately with a queued `SendResult`. The final delivery status arrives later as a `message.status` event on the event stream. ### Idempotency (`Idempotency-Key` header) Supply a stable key to make retries safe: replaying a send with a key already seen for your organization returns the **original** result and does not dispatch a second WhatsApp message. ### Preconditions & errors - Requires the **`send`** capability. - The session must exist, be owned by your organization, and be connected. - **400 `validation_error`** — malformed body or an unsupported/invalid field for the chosen `type`. - **404 `not_found`** — the session does not exist or is not owned by your organization. - **429 `rate_limited`** — over the per-session send rate limit. A synchronous send is rejected with 429; an async send stays queued instead of failing. - **501 `not_implemented`** — a media `type` that is not built yet.
Send Authorization: Bearer <token>. The router accepts two kinds of token and tries each in turn: a frontend-minted login JWT (verified against the frontend JWKS; the person's org + role are read from it), or an api-key for a script/service (carrying a fixed set of gateway permissions). The bearerFormat: JWT label describes the person-login case.
In: header
Path Parameters
The WhatsApp session id (a session is one attached WhatsApp number) that performs the send. Must be a session your organization owns and that is currently connected.
Query Parameters
Delivery mode. When false (the default) the call blocks until WhatsApp acknowledges the send and the response is 200 with the final SendResult. When true the gateway enqueues the send, returns immediately with 202 (status "queued"), and the final delivery status arrives later as a "message.status" event on the event stream. Async also changes rate-limit behavior: an over-limit synchronous send returns 429, whereas an async send stays queued instead of failing.
Header Parameters
Optional client-supplied idempotency token, scoped to your organization. If you retry a send with the same key, the gateway returns the result of the first send and does not dispatch a second message to WhatsApp. Use a fresh UUID per logical send and reuse it on retries. Omit it to send unconditionally.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
The contact card to share. Required for type contact.
Latitude of the shared location in decimal degrees. Required for type location.
doubleLongitude of the shared location in decimal degrees. Required for type location.
doubleThe media file to send (base64). Required for the media types (image/video/audio/document/sticker). Caption, replyTo, and mentions apply.
JIDs to @-mention in the message. Optional.
For a poll, the poll question; for a location, the place label. Required for poll; optional for location.
The poll's answer options. Required for type poll.
Id of the message this one quotes/replies to (a wa_message_id). Optional.
How many options a voter may pick in the poll (1 = single choice). Used for type poll.
int64The message text. Required for type text; ignored otherwise.
The recipient's JID: a user JID for a direct message (e.g. 6281234567890@s.whatsapp.net) or a group JID for a group (e.g. 120363021234567890@g.us). Required.
Which kind of message to send. Determines which other fields are required. text uses text (+ optional replyTo/mentions); poll uses name (question) + options + selectableCount; location uses latitude + longitude + optional name (label); contact uses contact. The media types image, video, audio, document, sticker use media (a base64 file + optional caption/filename, replyTo, mentions).
Value in
- "text"
- "poll"
- "location"
- "contact"
- "image"
- "video"
- "audio"
- "document"
- "sticker"
Response Body
application/json
application/json
curl -X POST "https://example.com/api/v1/sessions/01HZX.../messages" \ -H "Content-Type: application/json" \ -d '{ "to": "6281234567890@s.whatsapp.net", "type": "text" }'{ "mode": "string", "outboxId": "string", "replayed": true, "status": "string", "timestamp": 0, "waMessageId": "string"}{ "error": { "code": "not_found", "details": { "property1": null, "property2": null }, "message": "session not found" }}Join a group by invite POST
Joins the group named by the **invite** code (the code from a WhatsApp group invite link) and returns the joined group's JID in the shape `{ "groupJid": "...@g.us" }`. **Capability:** requires `send`. **Precondition (live action):** the session must be **connected**. If it is not the gateway responds **501 `not_implemented`**. **Success:** **200 OK** with the group's JID. Use that JID with the other group endpoints (e.g. `getGroup`, `listGroupMembers`). Joining a group the account already belongs to still returns the group's JID. **Errors:** - **400 `validation_error`** — missing or unparseable invite code/link, or the invite is invalid/expired. - **404 `not_found`** — no session with this id is owned by your organization. - **501 `not_implemented`** — the session is not connected.
Edit a sent text message PATCH
Replaces the text body of a message you already sent, identified by `mid` in the path and located by `chat` in the body. **Constraints:** - Only **text** messages can be edited; editing media or other kinds is not supported. - The message must have been sent by this session. This is a synchronous send to WhatsApp and returns **200** with a `SendResult`. ### Preconditions & errors - Requires the **`send`** capability. - **400 `validation_error`** — missing/empty `text` or a non-text message. - **404 `not_found`** — the session or message does not exist or is not owned by your organization.