wuapi MCP server
OfficialAn MCP server for the wuapi WhatsApp API that lets MCP clients operate a wuapi account: link and manage numbers, send and read WhatsApp data, and administer groups, channels, webhooks, projects, invitations, branding, and usage.
Link and manage WhatsApp numbers/accounts: create accounts, get QR or pairing codes, reconnect, set presence, disappearing timers, reject calls, update, log out, or delete accounts.
Send and interact with messages: text, media/files, locations, contact cards, polls, buttons, replies, reactions, edits, deletes, cancels, forwards, stars, poll votes, and file uploads.
Read and manage chats, messages, contacts, and labels: list/get messages and chats, mark read, archive, pin, mute, delete chats, manage labels, lookup/check/save contacts, and manage block lists.
Manage profile and privacy: update profile, set/delete profile picture, get/reset contact link, manage favorite stickers, and privacy settings.
Manage groups and communities: create groups, add/remove/promote/demote participants, invite links, leave groups, group settings, join requests, and community linking/membership.
Manage channels: list/get/preview channels, read posts, create/follow/unfollow/mute/unmute, react, and mark posts viewed.
Post, read, and manage stories: view contacts' stories, list own stories, get viewers, react, reply, and delete stories.
Manage webhooks and incoming webhooks: create/update/delete/list/get event webhook endpoints and secret incoming webhook URLs without exposing secrets.
Manage organization-level resources: projects, project API key auditing/revocation, invitations and branding, and usage reports.
Exposes MCP resources for the OpenAPI spec, wuapi docs, and webhook event types, plus prompts for sending messages, setting up webhooks, inviting customers, and using Streams.
Supports local stdio and hosted HTTP connections, with optional read-only mode that registers only reading tools.
Provides tools for interacting with the WhatsApp API (wuapi) to send messages, manage chats, groups, contacts, media, and webhooks.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@wuapi MCP serversend a WhatsApp message to +15551234567 saying 'Hey, meeting moved to 3pm'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
wuapi MCP server
A Model Context Protocol server for wuapi, the WhatsApp API for developers. It lets Claude, Cursor, VS Code and other MCP clients use your wuapi account: send messages, link numbers, read conversations, manage groups, communities, channels, labels, profile and privacy, webhooks, projects and invitations.
Every tool is a call to the wuapi REST API with your own API key, through @wuapidev/sdk. The API decides what the key may do, rate limits it (600 requests per minute per key) and logs each call in your dashboard, exactly as for any other client.
Docs: wuapi.dev/docs/mcp.
How it works. wuapi links your own numbers as devices, the same way WhatsApp Web works. It does not use the WhatsApp Business Platform. WhatsApp can restrict numbers that behave like spam: send only to people who expect your messages.
Two ways to connect
Local (stdio) | Hosted (Streamable HTTP) | |
Runs | on your machine: | at |
Key | your |
|
Needs | Node 20 or later | a client that sends custom headers |
The quickest local setup uses the wuapi CLI: it logs you in from the browser, stores a key on your machine (~/.config/wuapi/credentials.json, readable only by you) and registers the server with your client, with no key in the client's config:
npx @wuapidev/cli login
npx @wuapidev/cli mcp add # Claude Code, Cursor or VS CodeThe local server uses WUAPI_API_KEY when the client sets it, and otherwise that stored login: the current profile, or the one WUAPI_PROFILE names (npx @wuapidev/cli profiles lists them). Or create an API key yourself at wuapi.dev/app/api-keys and pass it as below. A project key limits the server to one project.
Claude Code
# Local, with the key from `npx @wuapidev/cli login`
claude mcp add wuapi -- npx -y @wuapidev/mcp
# Local, with a key in the config
claude mcp add wuapi --env WUAPI_API_KEY=wu_live_... -- npx -y @wuapidev/mcp
# Hosted
claude mcp add --transport http wuapi https://wuapi.dev/api/mcp --header "Authorization: Bearer $WUAPI_API_KEY"Claude Desktop
Settings > Developer > Edit Config, then add to claude_desktop_config.json:
{
"mcpServers": {
"wuapi": {
"command": "npx",
"args": ["-y", "@wuapidev/mcp"],
"env": { "WUAPI_API_KEY": "wu_live_..." }
}
}
}Cursor
~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"wuapi": {
"command": "npx",
"args": ["-y", "@wuapidev/mcp"],
"env": { "WUAPI_API_KEY": "wu_live_..." }
}
}
}Or the hosted server:
{
"mcpServers": {
"wuapi": {
"url": "https://wuapi.dev/api/mcp",
"headers": { "Authorization": "Bearer wu_live_..." }
}
}
}VS Code
.vscode/mcp.json. VS Code asks for the key once and stores it outside the file:
{
"inputs": [{ "type": "promptString", "id": "wuapi-key", "description": "wuapi API key", "password": true }],
"servers": {
"wuapi": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@wuapidev/mcp"],
"env": { "WUAPI_API_KEY": "${input:wuapi-key}" }
}
}
}For the hosted server use "type": "http", "url": "https://wuapi.dev/api/mcp" and "headers": { "Authorization": "Bearer ${input:wuapi-key}" }.
Other clients
Any client that starts a local command works with npx -y @wuapidev/mcp, with WUAPI_API_KEY in its environment or after npx @wuapidev/cli login. Any client that connects to a remote server with a custom header works with the hosted endpoint. Clients that only connect to remote servers through OAuth, as some chat apps do, cannot use the hosted endpoint yet.
Related MCP server: WhatsApp MCP Stream
Configuration
Variable | |
| Your API key, |
| Which stored login to use ( |
| Act inside one project: its id or |
| API base URL. Default |
|
|
The hosted endpoint takes the same options as headers: Wuapi-Project: <id or ext:externalId> and Wuapi-Read-Only: true.
Tools
87 tools reach every operation of the REST API, except the two that return a secret and the two steps of an upload through an upload URL (see below). Tools that read are marked readOnlyHint. Tools that delete, revoke, reset, block or leave are marked destructiveHint and take confirm: true, which the model has to set on purpose and your client shows you before the call.
Area | Tools |
Context |
|
Accounts |
|
Messages |
|
Chats |
|
Contacts |
|
Profile |
|
Groups |
|
Channels |
|
Stories |
|
Webhooks |
|
Incoming webhooks |
|
Projects |
|
Invitations |
|
Usage |
|
Resources with many small operations are one tool with an action argument, so the list stays short enough for a model to pick from. The tool's description lists its actions, and each field says which actions use it. Only the destructive actions (marked below) need confirm: true.
Tool | Actions |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* needs confirm: true.
To post to a channel, use send_text or send_media with to set to the channel id. In read-only mode a tool that mixes reads and writes keeps only its reading actions (manage_channel keeps list, get, preview_invite and list_messages).
get_account_qr_code returns the QR code as an image your client can show. Projects, invitations, branding and usage need an organization key.
Not exposed: creating a project API key, rotating a webhook endpoint's signing secret and rotating an incoming webhook's URL. Both return a secret exactly once, and tool results never carry secrets, so a tool would create a key or secret nobody could read (and a rotation would break your server's signature check at once). Do both in the dashboard or with the SDK. Also not exposed: completing and reading an upload. They belong to the upload-URL flow, where the file's raw bytes are posted to a URL, which a tool cannot do; upload_file takes the bytes in its one call and returns the upload ready to send. Sending a test webhook event and reading request logs have no public API endpoint; they are in the dashboard.
src/operations.ts maps every API operation to the tools that call it; a test keeps it equal to the OpenAPI spec.
Resources and prompts
Resources: https://wuapi.dev/openapi.json (the OpenAPI 3.1 spec), https://wuapi.dev/llms-full.txt (the docs as Markdown), https://wuapi.dev/llms.txt (their index) and wuapi://webhook-events (every event type).
Prompts: send_message (to, message), setup_webhook (url, events), invite_customer (customer, externalId, email) and use_streams (project, language). use_streams helps you receive events with Streams, the live alternative to Webhooks for code with no public endpoint: with the SDK's events.stream in TypeScript and Rust, and the rules of a client in any other language.
Security
The key stays where you put it: in the client's configuration, a header, or the CLI's credentials file (mode 0600), which the server only reads. The server never logs it, never returns it, and never includes it in an error.
Tool results never contain secrets. A webhook endpoint's signing secret is returned by the API only once, when the endpoint is created;
create_webhookdrops it and tells you to reveal it in the dashboard instead. An incoming webhook's URL is a credential too: its tools drop it, and the user copies it from the dashboard. There is no tool that creates API keys.Scope the key: a project key reaches one project, and
WUAPI_MCP_READ_ONLY=trueremoves every tool that writes.Media is fetched by the wuapi API, never by this server. The API refuses private and internal addresses.
Every argument is validated against the tool's JSON schema before any request. A base URL that is not https is refused, so the key never travels in clear text.
Use it as a library
import { Wuapi } from "@wuapidev/sdk";
import { createWuapiMcpServer } from "@wuapidev/mcp";
import { createWuapiMcpHttpHandler } from "@wuapidev/mcp/http";
// One server per client connection, acting as this key.
const server = createWuapiMcpServer({ client: new Wuapi({ apiKey: process.env.WUAPI_API_KEY }) });
// Or a stateless Streamable HTTP handler: (Request) => Promise<Response>,
// authenticated with each caller's own key as a bearer token.
const handle = createWuapiMcpHttpHandler();License
MIT
Available Tools
87 toolsadd_group_participantsAdd people to a groupA
Add participants to a group the account administers. Each result says whether it worked; someone who cannot be added directly comes back with an invite code.
| Name | Required | Description | Default |
|---|---|---|---|
| groupId | Yes | The group id (`...@g.us`), from list_groups. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| contactIds | Yes | Contact ids: E.164 with + (`+584241112233`) or `lid:<digits>`. |
archive_chatArchive or unarchive a chatBIdempotent
Archive a chat on the linked devices, or unarchive it with archived: false.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). | |
| archived | No | Default true. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
cancel_invitationCancel an invitationADestructiveIdempotent
Cancel an invitation: its link stops working. Completed invitations cannot be cancelled.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. The invitation link stops working. Only set it after the user asked for this or agreed to it. | |
| invitationId | Yes | The invitation id. |
cancel_messageCancel a queued messageADestructiveIdempotent
Stop a message that is still queued from being sent. It ends failed with error code cancelled. Fails with not_queued when the message already left; use delete_message for those.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. The message will not be sent. Only set it after the user asked for this or agreed to it. | |
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). |
check_numbersCheck numbers on WhatsAppARead-onlyIdempotent
Which of these phone numbers have WhatsApp, with their contact id, business name and username when known. Check before sending to a new number.
| Name | Required | Description | Default |
|---|---|---|---|
| phones | Yes | 1 to 50 numbers, E.164 (`+584241112233`) or digits. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
create_accountConnect a new numberA
Start linking a new WhatsApp number. Pick proxyLocation with list_proxy_locations (near where the phone is). Then show the QR code with get_account_qr_code, or pass pairingPhone to link with an 8-character pairing code instead. A linked number is billable; a new organization links its first number with no card. To let someone else link their own number, use create_invitation.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | A name for the account, such as `Front desk`. | |
| projectId | No | Organization keys only: the project to create it in (id or `ext:<externalId>`). A project key always uses its own project. | |
| historySync | No | `recent` imports the chats the phone sends right after linking. Default `none`. | |
| pairingPhone | No | Link by pairing code instead of QR code: the number to link, E.164. | |
| proxyLocation | Yes | Where the number's residential proxy exits: a country and city pair from list_proxy_locations. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
create_groupCreate a groupA
Create a WhatsApp group with the account as owner, inside a community when communityId is given. Participants whose privacy settings refuse being added get an invite code instead (see the result).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The group name. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| communityId | No | Create the group inside this community: its group id (`...@g.us`), from list_groups (`community: true`). The account must administer it. | |
| participants | Yes | Contact ids to add: E.164 with + or `lid:<digits>`. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
create_incoming_webhookCreate an incoming webhookA
Create a secret URL that sends a WhatsApp message from one of the user's numbers to one fixed contact or group when something POSTs to it (JSON {text} or plain text, no API key). The URL is a credential, so it is not returned through this tool: the user copies it from the wuapi dashboard (Integrations, Incoming webhooks).
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The fixed destination: a contact (+584121234567 or lid:<digits>) or a group (...@g.us). | |
| name | Yes | A label, for example the system that will call it. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
create_invitationInvite someone to link their numberA
Create a branded page (url) where a customer links their own WhatsApp number to your project by QR code or pairing code, without an account on wuapi. Send them the url: it is returned only here. With inviteeEmail, wuapi can email it too.
| Name | Required | Description | Default |
|---|---|---|---|
| methods | No | How they may link. Default both. | |
| projectId | No | Organization keys only: the project to create it in (id or `ext:<externalId>`). A project key always uses its own project. | |
| returnUrl | No | Where the page sends them when done. | |
| accountName | No | Name of the account created when they finish. | |
| historySync | No | ||
| inviteeName | No | ||
| inviteeEmail | No | ||
| inviteePhone | No | E.164. | |
| expiresInDays | No | 1 to 30. Default 7. | |
| proxyLocation | No | Preset the proxy location. Without it the invitee picks the country and city. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. | |
| suggestedCountry | No | ISO country preselected on the page. |
create_projectCreate a projectA
Create a project for one of your customers. Set externalId to your own customer id so you can address it as ext:<externalId>. Then invite the customer to link their number with create_invitation. Organization keys only.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| metadata | No | Your own string values, stored with it. | |
| externalId | No | Your id for this customer: letters, digits and `. _ : @ -`. | |
| maxAccounts | No | How many numbers it may link. Omitted: no limit. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
create_webhookCreate a webhook endpointA
Register a public https URL to receive events as signed POST requests. The signing secret is not returned through this tool, to keep it out of the conversation: the user reveals it in the wuapi dashboard (Webhooks, rotate the endpoint's secret) and stores it with their server.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Public https URL that answers 2xx within 10 seconds. | |
| events | Yes | Event types to receive, such as `message.received`, `message.sent`, `message.failed`, `account.connected`, `account.disconnected`. | |
| projectId | No | Organization keys only: the project to create it in (id or `ext:<externalId>`). A project key always uses its own project. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
delete_chatDelete a chatADestructiveIdempotent
Delete a chat from the account's linked devices (the phone and WhatsApp Web). The messages wuapi stores are kept and still readable with list_messages. This cannot be undone on the devices.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). | |
| confirm | Yes | Must be true. The chat disappears from the phone. Only set it after the user asked for this or agreed to it. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| deleteMedia | No | Also delete the chat's media files from the devices. |
delete_incoming_webhookDelete an incoming webhookADestructiveIdempotent
Delete an incoming webhook. Its URL stops working at once, for whatever still calls it.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. Whatever calls the URL stops sending. Only set it after the user asked for this or agreed to it. | |
| incomingWebhookId | Yes | The incoming webhook id, from list_incoming_webhooks. |
delete_messageDelete a messageADestructiveIdempotent
Delete an outbound message for everyone (or only on the linked devices with forEveryone: false). A message still queued is cancelled instead and never sent. This cannot be undone.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. Deleting a message cannot be undone. Only set it after the user asked for this or agreed to it. | |
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). | |
| forEveryone | No | Default true: delete it for every participant. |
delete_webhookDelete a webhook endpointADestructiveIdempotent
Delete a webhook endpoint. Its events stop at once, including deliveries still retrying.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. The endpoint stops receiving events. Only set it after the user asked for this or agreed to it. | |
| webhookEndpointId | Yes | The webhook endpoint id, from list_webhooks. |
demote_group_participantsRemove admin rightsAIdempotent
Turn group admins back into regular members.
| Name | Required | Description | Default |
|---|---|---|---|
| groupId | Yes | The group id (`...@g.us`), from list_groups. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| contactIds | Yes | Contact ids: E.164 with + (`+584241112233`) or `lid:<digits>`. |
edit_messageEdit a sent text messageAIdempotent
Change the text of an outbound text message, within WhatsApp's edit window (about 15 minutes). A message still queued is sent with the new text.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The new text. | |
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). |
forward_messageForward a messageA
Forward a stored message (received or sent) to up to 5 chats of the same account, the way WhatsApp forwards: the recipients see it as forwarded and no file is uploaded again. Works for text, images, videos, audio, voice notes, documents, stickers, locations and contact cards; polls, calendar events, reactions, view-once and deleted messages answer not_forwardable, and so does a contact's story (only a story the account posted, which is a message, can be forwarded). A message that is forwardedManyTimes goes to one chat per call. Returns a list with one queued message per chat, in the order of to; check each with get_message. To label new content as forwarded, use a send tool with forwarded: true instead.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | The chats to forward to, each once: contact ids (E.164 or `lid:<digits>`) or group ids. At most 5; exactly 1 when the message is `forwardedManyTimes`. | |
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
get_accountGet an accountARead-onlyIdempotent
One account: status, linked phone number, profile name, proxy location, disconnect reason and last error. hasQrCode says a QR code is waiting to be scanned (get it with get_account_qr_code).
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
get_account_qr_codeGet the QR code to link a numberARead-onlyIdempotent
The QR code to scan in WhatsApp (Settings > Linked devices > Link a device), as an image. Waits a few seconds for one when the account is still starting. QR codes rotate about every 20 seconds: call again if it expired. Returns the status instead when the account is already linked, and the pairing code when it links by phone number.
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| waitSeconds | No | How long to wait for a QR code to appear. Default 15. |
get_chatGet a chatARead-onlyIdempotent
One conversation of an account: its name, its latest message in full, and WhatsApp's unread, pinned, archived and muted state (a field that is missing is not known yet, which is not the same as false). A chat wuapi stored no message of answers not_found.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
get_contactGet a contactARead-onlyIdempotent
One contact of an account's address book, by number or lid: id: its saved name, profile name, username and picture id as wuapi stored them. A number that is not saved on the phone answers not_found; lookup_contacts asks WhatsApp about any number.
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| contactId | Yes | A contact: E.164 with + (`+584241112233`) or `lid:<digits>`. |
get_current_keyWho am IARead-onlyIdempotent
The organization, API key (name and last 4 characters, never the key) and project this server acts as. Call it first when you are unsure whether the key is an organization key or a project key.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
get_groupGet a groupBRead-onlyIdempotent
A group's name, description, settings and participants with their roles (member, admin, owner).
| Name | Required | Description | Default |
|---|---|---|---|
| groupId | Yes | The group id (`...@g.us`), from list_groups. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
get_group_invite_linkGet a group's invite linkARead-onlyIdempotent
The group's https://chat.whatsapp.com/... invite link. The account must be an admin.
| Name | Required | Description | Default |
|---|---|---|---|
| groupId | Yes | The group id (`...@g.us`), from list_groups. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
get_incoming_webhookGet an incoming webhookARead-onlyIdempotent
One incoming webhook: its number, destination and whether it is enabled. Never its URL.
| Name | Required | Description | Default |
|---|---|---|---|
| incomingWebhookId | Yes | The incoming webhook id, from list_incoming_webhooks. |
get_invitationGet an invitationARead-onlyIdempotent
One invitation's status, and the linked accountId once completed.
| Name | Required | Description | Default |
|---|---|---|---|
| invitationId | Yes | The invitation id. |
get_messageGet a messageARead-onlyIdempotent
One message with its status (queued, sent, delivered, read, failed, or received for inbound), content, and error when it failed. Received media is on demand by default (media.downloaded: false): pass fetchMedia: true to download it once and get a direct mediaFile.url that needs no API key.
| Name | Required | Description | Default |
|---|---|---|---|
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). | |
| fetchMedia | No | Also download the message's media if needed and return its direct URL as `mediaFile`. |
get_projectGet a projectARead-onlyIdempotent
One project: name, external id, status, account limit and count. Organization keys only.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | The project id or `ext:<externalId>`. |
get_usageGet this month's usageARead-onlyIdempotent
The current month's bill so far: billable numbers, proxy traffic, and the total in cents (USD). Organization keys only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
get_usage_by_projectGet usage per projectARead-onlyIdempotent
Numbers, proxy traffic and messages sent and received per project for a month, for rebilling your customers. With projectId, that project only. Organization keys only.
| Name | Required | Description | Default |
|---|---|---|---|
| month | No | `YYYY-MM` in UTC. Default: the current month. | |
| projectId | No | One project: its id or `ext:<externalId>`. |
get_webhookGet a webhook endpointARead-onlyIdempotent
One webhook endpoint: its URL, events and whether it is active. Never its signing secret.
| Name | Required | Description | Default |
|---|---|---|---|
| webhookEndpointId | Yes | The webhook endpoint id, from list_webhooks. |
leave_groupLeave a groupADestructiveIdempotent
Make the account leave a group. To come back it has to be added or invited again.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. The account leaves the group. Only set it after the user asked for this or agreed to it. | |
| groupId | Yes | The group id (`...@g.us`), from list_groups. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
list_accountsList accountsARead-onlyIdempotent
List the linked WhatsApp numbers (accounts), newest first, with their status: ready can send; qr_ready waits for a QR scan; disconnected or failed need attention.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| projectId | No | Only this project: its id, `ext:<externalId>`, or `none` for resources in no project. Organization keys only; a project key always sees its own project. |
list_chatsList chatsARead-onlyIdempotent
An account's conversations, the one with the newest message first: each chat's name, picture id, latest message and WhatsApp's unread, pinned, archived and muted state. Only chats wuapi stored a message of. A state field that is missing (unread, unreadCount, pinned, pinnedAt, archived, muted) is not known to wuapi yet, which is not the same as false. Filter by archived, unread or type, or search names, numbers and recent text with q. Read a conversation with list_messages and the chat's id as chatId.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Search the contact or group name, the number, the username and recent message text. Results come best match first. | |
| type | No | Only chats with a contact, groups, or channels. | |
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| unread | No | true: only chats with unread messages or marked as unread. false: every other chat. | |
| archived | No | true: only chats WhatsApp reported as archived. false: every other chat, including those whose state is not known yet. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
list_contactsList contactsARead-onlyIdempotent
An account's address book as its phone synced it to wuapi, ordered by saved name: each contact's id, number, savedName, WhatsApp profile name, and the username and picture id seen so far. Only contacts the phone saved (or that have a business name); people the account just chatted with are in list_chats. Read from what wuapi stored, so about and deviceCount are not here: lookup_contacts asks WhatsApp for those. Search names, usernames and numbers with q.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Search the saved name, profile name, business name, username or number. Results come best match first. | |
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
list_groupsList groupsARead-onlyIdempotent
Every group the account is in, read live from WhatsApp, with the participant count. A group inside a community has that community's id as communityId (absent when it is in none), and default: true when it is the community's announcement group. Use get_group for the participants.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
list_incoming_webhooksList incoming webhooksARead-onlyIdempotent
The incoming webhooks: secret URLs that send a WhatsApp message from one of your numbers to one fixed contact or group. Shows the name, the number, the destination and whether each is enabled. Never the URLs themselves.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| projectId | No | Only this project: its id, `ext:<externalId>`, or `none` for resources in no project. Organization keys only; a project key always sees its own project. |
list_invitationsList invitationsBRead-onlyIdempotent
Invitations and their status: pending, in_progress, completed (with the new accountId), failed, cancelled or expired.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| status | No | ||
| projectId | No | Only this project: its id, `ext:<externalId>`, or `none` for resources in no project. Organization keys only; a project key always sees its own project. |
list_messagesList messagesARead-onlyIdempotent
Messages wuapi stored, newest first: sent and received. Filter by account, chat and direction to read a conversation. Use list_chats to see which conversations an account has.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. | |
| chatId | No | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). | |
| direction | No | ||
| projectId | No | Only this project: its id, `ext:<externalId>`, or `none` for resources in no project. Organization keys only; a project key always sees its own project. |
list_projectsList projectsBRead-onlyIdempotent
Projects: one per customer of a platform, each with its own numbers, keys, webhooks and usage. Organization keys only.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| status | No | ||
| externalId | No | Exact match on your own customer id. |
list_proxy_locationsList proxy locationsARead-onlyIdempotent
Countries and cities a new number's proxy can exit from, for create_account and create_invitation. Search with q (sao finds Sao Paulo) or filter by country.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | City or country name or code. | |
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| country | No | ISO 3166-1 alpha-2 country code. |
list_webhooksList webhook endpointsARead-onlyIdempotent
The webhook endpoints that receive events: URL, events and whether active. Signing secrets are never shown here.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. | |
| projectId | No | Only this project: its id, `ext:<externalId>`, or `none` for resources in no project. Organization keys only; a project key always sees its own project. |
lookup_contactsLook up contactsARead-onlyIdempotent
About text, picture id, WhatsApp username, business name and device count of 1 to 50 contacts, asked from WhatsApp (the saved names are in list_contacts). Usernames cannot be searched: WhatsApp does not let a linked device resolve an @username, so look contacts up by number or lid: id.
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| contactIds | Yes | 1 to 50 contact ids: E.164, digits or `lid:<digits>`. |
lookup_whatsapp_infoLook up WhatsApp detailsARead-onlyIdempotent
Read details from WhatsApp through a linked number: a contact's profile picture or business profile, who a contact QR link or business message link points to, WhatsApp's AI bot directory, and the sticker pack or catalog order a message refers to. Nothing is changed.
Actions:
contact_picture: The contact's profile picture URL, when the account can see it.business_profile: A business contact's address, email, categories, time zone and opening hours.resolve_link: Who a contact QR link or business message link points to, and its prefilled text. Fails withnot_supportedwhen WhatsApp does not offer it to the account.bots: WhatsApp's AI bot directory as the account sees it. Fails withnot_supportedwhere WhatsApp does not offer it.sticker_pack: A sticker pack and its stickers.order: The products, quantities and totals of a catalog order received as a message.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | The link, or its code. Required for `resolve_link`. | |
| kind | No | `contact` for a contact QR link, `business` for a business message link. Required for `resolve_link`. | |
| limit | No | Page size, 1 to 100. Default 20. Optional for `bots`. | |
| token | No | The order's token, from the same order message. Required for `order`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. Optional for `bots`. | |
| orderId | No | The order id, from an order message. Required for `order`. | |
| preview | No | A small preview instead of the full picture. Optional for `contact_picture`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| contactId | No | A contact: E.164 with + (`+584241112233`) or `lid:<digits>`. Required for `contact_picture`, `business_profile`. | |
| stickerPackId | No | The sticker pack id, from a sticker message. Required for `sticker_pack`. |
manage_block_listBlock or unblock contactsADestructiveIdempotent
The account's block list on WhatsApp: list blocked contacts, block a contact (it can no longer message or call the account) or unblock it.
Actions:
list: Blocked contacts, with their number andlid:id when known.block: Block a contact. Needsconfirm: true.unblock: Unblock a contact.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. Optional for `list`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. Optional for `list`. | |
| confirm | No | Must be true. The contact can no longer message or call the account. Only set it after the user asked for this or agreed to it. Required for `block`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| contactId | No | A contact: E.164 with + (`+584241112233`) or `lid:<digits>`. Required for `block`, `unblock`. |
manage_brandingManage invitation brandingAIdempotent
How the invitation page and email look to your customers: display name, logo, accent color, support link, and whether the "Powered by wuapi" footer shows. Organization keys only.
Actions:
get: The current branding.update: Change any of the fields. Returns the branding.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | What to do. See the list of actions in the tool description. | |
| logoUrl | No | https URL of your logo. null clears it. Optional for `update`. | |
| supportUrl | No | https URL where customers get help. null clears it. Optional for `update`. | |
| accentColor | No | `#RRGGBB`. null uses wuapi's. Optional for `update`. | |
| displayName | No | Your name as customers see it. Required the first time. Optional for `update`. | |
| hideWuapiBranding | No | Hide the "Powered by wuapi" footer. `true` needs the White label add-on (`addon_required` otherwise). Optional for `update`. |
manage_channelManage channelsA
WhatsApp channels (one-to-many broadcasts, ids end in @newsletter): list the ones the account follows or owns, read one and its posts, preview an invite, create a channel, follow, unfollow, mute and unmute, react to posts and count as a viewer. To post to a channel the account administers, use send_text or send_media with to set to the channel id.
Actions:
list: Channels the account follows or administers, with its role.get: One channel: name, description, subscriber count, the account's role and whether it is muted.preview_invite: The channel behind an invite code or link, without following it.list_messages: The channel's recent posts, newest first, with view and reaction counts.create: Create a channel with the account as owner. Returns it.follow: Follow the channel.unfollow: Stop following the channel.mute: Mute the channel's notifications.unmute: Unmute the channel.react: React to a post with an emoji, or remove the reaction with an empty string.mark_viewed: Count the account as a viewer of these posts.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | The invite code, or the full invite link (`https://chat.whatsapp.com/...`, `https://whatsapp.com/channel/...`). Required for `preview_invite`. | |
| name | No | The channel name. Required for `create`. | |
| emoji | No | One emoji. An empty string removes the reaction. Required for `react`. | |
| limit | No | Page size, 1 to 100. Default 20. Optional for `list`, `list_messages`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. Optional for `list`, `list_messages`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| channelId | No | The channel id (`...@newsletter`), from manage_channel `list`. Required for `get`, `list_messages`, `follow`, `unfollow`, `mute`, `unmute`, `react`, `mark_viewed`. | |
| description | No | The channel description. Optional for `create`. | |
| pictureBase64 | No | The channel picture as a base64 JPEG. Optional for `create`. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. Optional for `create`. | |
| channelMessageId | No | A post's id, from `list_messages`. Required for `react`. | |
| channelMessageIds | No | 1 to 100 post ids, from `list_messages`. Required for `mark_viewed`. |
manage_communityManage communitiesA
WhatsApp communities: a community is a group with community: true that links other groups. Create one, list its groups and members, and link or unlink groups (the account must admin both). get_group reads the community itself; send to it like a group. To create a new group inside a community, use create_group with communityId; list_groups shows each group's communityId.
Actions:
create: Create a community with the account as owner. Returns it.list_groups: The groups linked to the community, marking its default (announcement) group.list_members: Members across the community's linked groups.link_group: Link a group into the community.unlink_group: Unlink a group from the community. The group itself stays.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | The community name. Required for `create`. | |
| limit | No | Page size, 1 to 100. Default 20. Optional for `list_groups`, `list_members`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. Optional for `list_groups`, `list_members`. | |
| groupId | No | The group to link or unlink (`...@g.us`). Required for `link_group`, `unlink_group`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| communityId | No | The community's group id (`...@g.us`), from list_groups (`community: true`). Required for `list_groups`, `list_members`, `link_group`, `unlink_group`. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. Optional for `create`. |
manage_favorite_stickersManage favorite stickersAIdempotent
The account's favorite stickers: the star tab of WhatsApp's sticker picker, which WhatsApp keeps in sync with the phone. List them, get one's file, favorite a sticker from a message or an uploaded WebP file, or remove one. Adding and removing change the list on the phone too.
Actions:
list: The favorites, newest first, from what wuapi stored (no call to WhatsApp). Each hasmedia.urlandmedia.downloaded;animatedandemojisare null until its file was fetched.get_file: A direct URL to one favorite's file that needs no API key. Fetches the file from WhatsApp the first time, which needs the account ready.add: Favorite a sticker: passmessageIdoruploadId, one of them. A sticker that is a favorite already is returned as is.remove: Take a sticker out of the favorites. It can be favorited again.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size, 1 to 100. Default 20. Optional for `list`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. Optional for `list`. | |
| uploadId | No | A WebP file uploaded with upload_file (`mimeType: image/webp`, at most 2 MB) to favorite. Optional for `add`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| messageId | No | A sticker message of this account to favorite (from list_messages or a webhook). Optional for `add`. | |
| stickerId | No | A favorite sticker's id, from the `list` action. Required for `get_file`, `remove`. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. Optional for `add`. |
manage_group_joinsJoin groups and handle join requestsA
Joining groups: preview the group behind an invite link, join it, and, in a group that needs approval to join, list, approve or reject the pending requests (the account must be an admin).
Actions:
preview_invite: The group behind an invite code or link, without joining: name, description, size.join: Join a group with an invite code or link. Returns the group id; a group that needs approval makes it a pending request instead.list_requests: Pending requests to join the group.approve_requests: Let these people in. Each result says whether it worked.reject_requests: Turn these requests down. Each result says whether it worked.
| Name | Required | Description | Default |
|---|---|---|---|
| code | No | The invite code, or the full invite link (`https://chat.whatsapp.com/...`, `https://whatsapp.com/channel/...`). Required for `preview_invite`, `join`. | |
| limit | No | Page size, 1 to 100. Default 20. Optional for `list_requests`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. Optional for `list_requests`. | |
| groupId | No | The group id (`...@g.us`), from list_groups. Required for `list_requests`, `approve_requests`, `reject_requests`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| contactIds | No | 1 to 256 contact ids of people who asked to join. Required for `approve_requests`, `reject_requests`. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. Optional for `join`. |
manage_group_settingsChange a group's info and settingsADestructiveIdempotent
Change a group the account administers: its name, description and settings (who can send, who can edit the info, whether joining needs approval, who can add members), and its picture.
Actions:
update: Change any of name, description, announce, locked, joinApproval and memberAddMode. Returns the group.set_picture: Set the group picture from an https URL or base64 JPEG. Returns the picture.delete_picture: Remove the group picture. Needsconfirm: true.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | The group name. Optional for `update`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| locked | No | `true`: only admins can edit the group info. Optional for `update`. | |
| confirm | No | Must be true. The group picture is removed. Only set it after the user asked for this or agreed to it. Required for `delete_picture`. | |
| groupId | No | The group id (`...@g.us`), from list_groups. Required for every action. | |
| announce | No | `true`: only admins can send messages. Optional for `update`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| pictureUrl | No | The picture as a public https URL of a JPEG. wuapi downloads it. Pass this or `pictureBase64`. Optional for `set_picture`. | |
| description | No | The group description. An empty string clears it. Optional for `update`. | |
| joinApproval | No | `true`: new members need an admin's approval (see manage_group_joins). Optional for `update`. | |
| memberAddMode | No | Who can add members. Optional for `update`. | |
| pictureBase64 | No | The picture as a base64 JPEG. Pass this or `pictureUrl`. Optional for `set_picture`. |
manage_labelsManage labelsADestructiveIdempotent
WhatsApp Business labels on chats and messages: create or edit a label, delete it, and add it to or remove it from a chat or a message. WhatsApp Business accounts only; others answer not_supported. There is no endpoint that lists labels: they arrive in label.updated webhook events, and upsert creates one under an id you choose.
Actions:
upsert: Create the label with this id, or rename or recolor it. Returns the label.delete: Delete the label. Needsconfirm: true.label_chat: Add the label to a chat.unlabel_chat: Remove the label from a chat.label_message: Add the label to a message, as the account that sent or received it.unlabel_message: Remove the label from a message.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | The label name. Required for `upsert`. | |
| color | No | WhatsApp's label color index, 0 to 19. Default 0. Optional for `upsert`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| chatId | No | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). Required for `label_chat`, `unlabel_chat`. | |
| confirm | No | Must be true. The label is removed from every chat and message. Only set it after the user asked for this or agreed to it. Required for `delete`. | |
| labelId | No | The label id. `upsert` creates the label under this id when there is none. Required for every action. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for `upsert`, `delete`, `label_chat`, `unlabel_chat`. | |
| messageId | No | A wuapi message id (from list_messages, a send tool, or a webhook). Required for `label_message`, `unlabel_message`. |
manage_privacyManage privacy settingsAIdempotent
The account's WhatsApp privacy settings: who sees its last seen, profile picture, stories and online status, who may add it to groups or call it, and whether it sends read receipts.
Actions:
get: Every privacy setting.get_story_privacy: Who sees the account's stories: its contacts, all but some, or only some.update: Change one or more settings. Each setting is one change on WhatsApp. Returns every setting.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | What to do. See the list of actions in the tool description. | |
| online | No | Who sees it online. Optional for `update`. | |
| callAdd | No | Who can call it: everyone, or only known contacts. Optional for `update`. | |
| profile | No | Who sees its profile picture. Optional for `update`. | |
| stories | No | Who sees its stories. Optional for `update`. | |
| groupAdd | No | Who can add the account to groups. Optional for `update`. | |
| lastSeen | No | Who sees its last seen. Optional for `update`. | |
| messages | No | Who can message it. Optional for `update`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| readReceipts | No | `none` stops sending read receipts (and seeing others'). Optional for `update`. |
manage_profileManage the account's profileADestructive
The linked number's own WhatsApp profile: its display name and About text, its profile picture, and its contact QR link (a https://wa.me/qr/... link that opens a chat with it).
Actions:
update: Change the display name, the About text, or both.set_picture: Set the profile picture from an https URL or base64 JPEG. Returns the picture.delete_picture: Remove the profile picture. Needsconfirm: true.get_contact_link: The account's contact QR link.reset_contact_link: Revoke the contact QR link and return a new one. The old link stops working. Needsconfirm: true.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Display name, up to 25 characters. Optional for `update`. | |
| about | No | About text, up to 139 characters. Optional for `update`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| confirm | No | Must be true. This cannot be undone. Only set it after the user asked for this or agreed to it. Required for `delete_picture`, `reset_contact_link`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| pictureUrl | No | The picture as a public https URL of a JPEG. wuapi downloads it. Pass this or `pictureBase64`. Optional for `set_picture`. | |
| pictureBase64 | No | The picture as a base64 JPEG. Pass this or `pictureUrl`. Optional for `set_picture`. |
manage_projectUpdate, delete or audit a projectADestructiveIdempotent
Change a project (rename it, set its external id, metadata or account limit, suspend or resume it), delete it, and list or revoke its API keys. Suspending refuses every send and write in the project while reads and inbound messages keep working. Organization keys only. New project keys are created in the wuapi dashboard: no tool returns an API key.
Actions:
update: Change any of name, externalId, metadata, maxAccounts and status. Returns the project.delete: Delete the project: its keys stop working at once, and its numbers are logged out and deleted in the background with its webhook endpoints. Needsconfirm: true.list_keys: The project's API keys, revoked ones included: name, last 4 characters, last use. Never the key itself.revoke_key: Revoke one of the project's API keys. It stops working at once. Needsconfirm: true.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | The project name. Optional for `update`. | |
| limit | No | Page size, 1 to 100. Default 20. Optional for `list_keys`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. Optional for `list_keys`. | |
| status | No | `suspended` refuses sends and writes; `active` resumes. Optional for `update`. | |
| confirm | No | Must be true. This cannot be undone. Only set it after the user asked for this or agreed to it. Required for `delete`, `revoke_key`. | |
| apiKeyId | No | The API key id, from `list_keys`. Required for `revoke_key`. | |
| metadata | No | Your own string values. Replaces the whole metadata object. Optional for `update`. | |
| projectId | No | The project id or `ext:<externalId>`. Required for every action. | |
| externalId | No | Your id for this customer: letters, digits and `. _ : @ -`. null clears it. Optional for `update`. | |
| maxAccounts | No | How many numbers it may link. null removes the limit. Optional for `update`. |
manage_storiesRead and answer storiesADestructive
Stories (WhatsApp Status): read the ones the account's contacts posted in the last 24 hours, mark one as viewed, react or reply to it, and see or delete the ones the account posted (post with post_story). Reading stories tells the contact nothing; view does, so call it only when the user wants the contact to know. Contacts' stories arrive only for accounts with stories turned on.
Actions:
list: Contacts' stories, grouped by contact, the contact with the newest story first.list_own: The stories the account posted in the last 24 hours, with how many contacts saw each.get: One story. WithfetchMedia, also its file's direct URL.viewers: Who saw a story the account posted, with their reactions, the latest viewer first.view: Tell the contact the account saw their story: the account then shows in the story's viewers. Only when the user asked for it.authorNotified: falsein the answer means WhatsApp did not tell them (read receipts are off).react: React to a contact's story with an emoji, or remove the reaction with an empty string. Only the story's author sees it.reply: Reply to a contact's story with text: a message in the chat with its author, who sees it as a reply to their story.delete: Delete a story the account posted, for everyone. Needsconfirm: true.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | The reply. Required for `reply`. | |
| emoji | No | One emoji, such as a green heart. An empty string removes the reaction. Required for `react`. | |
| limit | No | Page size, 1 to 100. Default 20. Optional for `list`, `list_own`, `viewers`. | |
| action | Yes | What to do. See the list of actions in the tool description. | |
| cursor | No | `nextCursor` from the previous page, to get the next one. Optional for `list`, `list_own`, `viewers`. | |
| confirm | No | Must be true. The story is deleted for every contact and cannot be restored. Only set it after the user asked for this or agreed to it. Required for `delete`. | |
| storyId | No | A story id, from `list`, `list_own` or a webhook. A story the account posted has the id of its message. Required for `get`, `viewers`, `view`, `react`, `reply`, `delete`. | |
| unviewed | No | `true`: only the contacts with a story the account has not seen. Optional for `list`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| contactId | No | A contact id (E.164 with + or `lid:<digits>`): only this contact's stories. Optional for `list`. | |
| fetchMedia | No | Also download the story's file if needed and return its direct URL as `mediaFile`. Does not mark the story as viewed. Optional for `get`. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. Optional for `view`, `reply`. |
mark_chat_readMark a chat read or unreadAIdempotent
Clear (or set, with unread: true) the chat's unread badge on the linked devices. Sends no read receipts; use send_read_receipts for blue ticks.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). | |
| unread | No | Mark it unread instead. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
mute_chatMute or unmute a chatAIdempotent
Mute a chat's notifications for a while or until unmuted, or unmute it with muted: false.
| Name | Required | Description | Default |
|---|---|---|---|
| muted | No | Default true. | |
| chatId | Yes | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| durationSeconds | No | How long to mute. Omitted or 0: until unmuted. |
pin_chatPin or unpin a chatAIdempotent
Pin a chat to the top on the linked devices, or unpin it with pinned: false.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). | |
| pinned | No | Default true. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
post_storyPost a storyA
Post a story from the account: text on a colored background, or an image or video with an optional caption, from a public URL (mediaUrl) or a file uploaded with upload_file (uploadId).
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | The story text (required for `text`), or the caption. | |
| type | No | Default `text`. | |
| mediaUrl | No | Image or video: public http(s) URL of the file. | |
| uploadId | No | The id of an upload made with upload_file (or `POST /v1/uploads`): a file wuapi already stores. Usable for 24 hours, any number of times. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. | |
| backgroundColor | No | Text stories: `#RRGGBB`. |
promote_group_participantsMake participants adminsBIdempotent
Make participants admins of a group the account administers.
| Name | Required | Description | Default |
|---|---|---|---|
| groupId | Yes | The group id (`...@g.us`), from list_groups. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| contactIds | Yes | Contact ids: E.164 with + (`+584241112233`) or `lid:<digits>`. |
react_to_messageReact to a messageAIdempotent
React to a message with an emoji, as the account that received or sent it. An empty string removes the reaction.
| Name | Required | Description | Default |
|---|---|---|---|
| emoji | Yes | One emoji, such as a thumbs up. Empty removes the reaction. | |
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). |
reconnect_accountReconnect an accountAIdempotent
Restart the account's session. Use it when an account is disconnected; when the link is no longer valid it produces a fresh QR code.
| Name | Required | Description | Default |
|---|---|---|---|
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
reject_callReject an incoming callA
Reject a WhatsApp call ringing on the account, with the id and from of its call.received webhook event. To reject every call automatically, set rejectCalls with update_account.
| Name | Required | Description | Default |
|---|---|---|---|
| from | Yes | The caller: `data.object.from` of the same event. | |
| callId | Yes | The call id: `data.object.id` of the `call.received` event. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
remove_group_participantsRemove people from a groupADestructiveIdempotent
Remove participants from a group the account administers.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. Removed participants have to be added or invited again. Only set it after the user asked for this or agreed to it. | |
| groupId | Yes | The group id (`...@g.us`), from list_groups. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| contactIds | Yes | Contact ids: E.164 with + (`+584241112233`) or `lid:<digits>`. |
reply_to_messageReply to a messageA
Reply with text to a message, quoting it, in the same chat and from the same account. Works for messages in direct chats and groups.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The reply. | |
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
request_pairing_codeGet a pairing codeA
Link by phone number instead of QR code: returns an 8-character code the owner types in WhatsApp. It lives about 160 seconds. Fails with already_linked when the account is ready.
| Name | Required | Description | Default |
|---|---|---|---|
| phone | Yes | The number to link, E.164 (`+584121234567`) or digits. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
resend_invitationResend an invitationADestructive
Give an invitation a new link and expiry and email it again when it has an inviteeEmail. The previous url stops working; send the new one from the result. An account the invitee already started is kept, so they resume where they left off.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. The current invitation link stops working. Only set it after the user asked for this or agreed to it. | |
| invitationId | Yes | The invitation id. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
reset_group_invite_linkReset a group's invite linkADestructive
Revoke the group's invite link and return a new one. Anyone holding the old link can no longer join with it.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Must be true. The old invite link stops working. Only set it after the user asked for this or agreed to it. | |
| groupId | Yes | The group id (`...@g.us`), from list_groups. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). |
save_contactsSave contacts on the phoneAIdempotent
Save contacts on the linked phone, in WhatsApp and in the phone's own address book, as if they were saved on the phone. Any number can be saved. Saves are queued (also while the account reconnects): each contact's phoneSync says pending, then synced or failed (not_on_whatsapp, account_offline), and contact.updated fires; the phone shows the name about a minute later. Removing a contact is not supported. backfill_auto_save queues the contacts of the account's existing direct chats, named with its auto-save templates (update_account contactAutoSave), at most 200 a day.
Actions:
one: Save one contact undersavedName. Returns the contact with itsphoneSync.many: Save up to 500 contacts at once. Returns the batch id and each contact's status.backfill_auto_save: Queue the auto-save of the contacts of the account's existing direct chats.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | What to do. See the list of actions in the tool description. | |
| contacts | No | 1 to 500 contacts to save. Required for `many`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| contactId | No | A contact: E.164 with + (`+584241112233`) or `lid:<digits>`. Required for `one`. | |
| firstName | No | The short name the phone shows. Defaults to the first word of `savedName`. Optional for `one`. | |
| savedName | No | The name to save the contact under. Required for `one`. |
send_buttonsSend buttonsA
Send a message with 1 to 10 tappable buttons. A quick reply (id) answers as a message.received of type button with button.id; a link (url, HTTPS) opens when tapped. WhatsApp disables a quick reply in the sender's own view of the message; recipients can tap it. The body is text, with an optional footer.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient: a phone number in E.164 with + (`+584241112233`), `lid:<digits>`, the `@username` of a contact the account already chats with, a group id (`...@g.us`), or a channel id (`...@newsletter`) the account administers. | |
| text | Yes | The message body. | |
| footer | No | Small print under the buttons. | |
| buttons | Yes | 1 to 10 buttons: each one with an `id` (quick reply) or a `url` (link), not both. | |
| mentions | No | Contact ids to @mention (E.164 or `lid:<digits>`). | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. | |
| replyToMessageId | No | A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`). |
send_contactSend contact cardsC
Send one contact card, or up to 20 in one message.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient: a phone number in E.164 with + (`+584241112233`), `lid:<digits>`, the `@username` of a contact the account already chats with, a group id (`...@g.us`), or a channel id (`...@newsletter`) the account administers. | |
| contacts | Yes | ||
| mentions | No | Contact ids to @mention (E.164 or `lid:<digits>`). | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. | |
| replyToMessageId | No | A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`). |
send_locationSend a locationC
Send a map pin, with an optional place name and address.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient: a phone number in E.164 with + (`+584241112233`), `lid:<digits>`, the `@username` of a contact the account already chats with, a group id (`...@g.us`), or a channel id (`...@newsletter`) the account administers. | |
| name | No | Place name. | |
| address | No | ||
| latitude | Yes | ||
| mentions | No | Contact ids to @mention (E.164 or `lid:<digits>`). | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| longitude | Yes | ||
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. | |
| replyToMessageId | No | A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`). |
send_mediaSend an image, video, audio or documentA
Send a file: an image, video, audio, voice note (ogg/opus), document or sticker, with an optional caption. Give exactly one of url (a public URL wuapi downloads itself) or uploadId (a file uploaded before with upload_file). Images go out at the account's image quality (standard by default, as WhatsApp sends a photo); pass quality to change it for one image, or send the file as a document to deliver it untouched.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient: a phone number in E.164 with + (`+584241112233`), `lid:<digits>`, the `@username` of a contact the account already chats with, a group id (`...@g.us`), or a channel id (`...@newsletter`) the account administers. | |
| url | No | Public http(s) URL of the file. wuapi downloads it (up to 100 MB); private and internal addresses are refused. | |
| type | Yes | What kind of file it is. | |
| caption | No | Text shown with the file. | |
| quality | No | Images only: the quality of this image instead of the account's. `hd` is WhatsApp's HD photo; `original` sends the file without re-encoding it. | |
| filename | No | Documents: the file name the recipient sees. | |
| mentions | No | Contact ids to @mention (E.164 or `lid:<digits>`). | |
| mimeType | No | Guessed from the URL, or the upload's own type, when omitted. | |
| uploadId | No | The id of an upload made with upload_file (or `POST /v1/uploads`): a file wuapi already stores. Usable for 24 hours, any number of times. | |
| viewOnce | No | Images, videos, audio and voice: can be opened once. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. | |
| replyToMessageId | No | A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`). |
send_pollSend a pollA
Send a poll with 2 to 12 options. Votes arrive as poll.voted webhooks and in the message's poll tally (get_message).
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient: a phone number in E.164 with + (`+584241112233`), `lid:<digits>`, the `@username` of a contact the account already chats with, a group id (`...@g.us`), or a channel id (`...@newsletter`) the account administers. | |
| options | Yes | 2 to 12 unique options. | |
| mentions | No | Contact ids to @mention (E.164 or `lid:<digits>`). | |
| question | Yes | The poll question. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. | |
| selectableCount | No | How many options a voter may pick. 0 (default) means any number; 1 makes it single choice. | |
| replyToMessageId | No | A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`). |
send_read_receiptsSend read receiptsAIdempotent
Send read receipts (blue ticks) for inbound messages in a chat: the given ids, or every unread inbound message wuapi stores for it.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | Yes | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| messageIds | No | wuapi ids of inbound messages in this chat. Default: every unread one. |
send_textSend a text messageA
Send a text message from a linked number to a contact, group or channel. The message is queued and sent at the account's pace; the result has its id and queued status. Send only to people who expect it.
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient: a phone number in E.164 with + (`+584241112233`), `lid:<digits>`, the `@username` of a contact the account already chats with, a group id (`...@g.us`), or a channel id (`...@newsletter`) the account administers. | |
| text | Yes | The message, up to 4096 characters. WhatsApp formatting works: *bold*, _italic_. | |
| mentions | No | Contact ids to @mention (E.164 or `lid:<digits>`). | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. | |
| replyToMessageId | No | A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`). |
set_disappearing_timerSet disappearing messagesAIdempotent
Turn disappearing messages on or off: for one chat with chatId, or without it the account's default timer, which new chats start with. Messages already stored in wuapi are kept.
| Name | Required | Description | Default |
|---|---|---|---|
| chatId | No | The chat (a contact or group id). Omit it to set the account's default for new chats. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| durationSeconds | Yes | How long messages last: 86400 (24 hours), 604800 (7 days) or 7776000 (90 days). 0 turns disappearing messages off. |
set_presenceSet presence or typingAIdempotent
Presence as contacts see it: the account online or offline, typing or recording in a chat, and presence events from a contact. Typing shows until paused or the next message. With typing turned on in the account's pacing (update_account), sends show it on their own.
Actions:
online: Show the account as online to contacts.offline: Show the account as offline.typing: Show typing in a chat.recording: Show recording audio in a chat.paused: Clear the typing or recording indicator in a chat.subscribe: Receivecontact.presence_updatedwebhook events when the contact comes online, goes offline or types. Fails withnot_supportedwhen the account cannot receive presence events.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | What to do. See the list of actions in the tool description. | |
| chatId | No | The chat: a contact as E.164 with + (`+584241112233`) or `lid:<digits>`, or a group id (`...@g.us`). Required for `typing`, `recording`, `paused`. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. | |
| contactId | No | A contact: E.164 with + (`+584241112233`) or `lid:<digits>`. Required for `subscribe`. |
star_messageStar or unstar a messageAIdempotent
Star a message on the phone and the other linked devices, or unstar it with starred: false. Returns the message.
| Name | Required | Description | Default |
|---|---|---|---|
| starred | No | Default true. | |
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). |
unlink_accountLog out or delete an accountADestructiveIdempotent
Unlink a WhatsApp number from wuapi. Both actions log the number out on WhatsApp and stop billing for it. Use logout to keep the account and its stored messages (reconnect_account then shows a new QR code to link again); use delete to remove the account for good.
Actions:
logout: Unlink the phone and stop billing, keeping the account and its messages. Returns the account. Needsconfirm: true.delete: Log out, delete the account and stop billing for it. Cannot be undone; fires no event. Needsconfirm: true.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | What to do. See the list of actions in the tool description. | |
| confirm | No | Must be true. The number is logged out of WhatsApp. Only set it after the user asked for this or agreed to it. Required for every action. | |
| accountId | No | The wuapi account id of the linked number to act as (from list_accounts). Required for every action. |
update_accountUpdate an accountAIdempotent
Change an account's settings: rename it, reject incoming calls automatically, turn on and tune its pacing (the anti-ban protections, off by default), choose whether the next link imports recent chats, choose which received media is downloaded right away (the rest on demand), choose the quality its images are sent at, save the contacts of new chats on the phone automatically (contactAutoSave), or move its proxy location. Pacing applies from the next send. A proxy location change gives the number a new exit IP and reconnects it; it is refused within 10 minutes of the previous change. Returns the updated account with its pacing.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | A name for the account, such as `Front desk`. | |
| pacing | No | Anti-ban pacing, merged over the stored values: omitted fields keep theirs, null resets the whole pacing to the defaults (every protection off). Recommended for bulk, cold or marketing sends: `{"messagesPerMinute": 12, "firstContactPerMinute": 5, "typing": {"enabled": true}}`. | |
| accountId | Yes | The wuapi account id of the linked number to act as (from list_accounts). | |
| historySync | No | `recent` imports the chats the phone sends at the next link. A number that is already linked gets no new history. | |
| rejectCalls | No | Reject incoming calls automatically. | |
| imageQuality | No | What the account's images are re-encoded to before their upload through the number's proxy (proxy traffic). `standard` (default): longest side 1600 px, JPEG, as WhatsApp sends a photo. `hd`: up to 4096 px. `original`: the file as it is. | |
| proxyLocation | No | Move the number (`country` and `city` together), switch whether its city is exact (`strictCity`), or both. The session reconnects on a new exit IP. | |
| contactAutoSave | No | Contact auto-save: only direct chats with a number, never renaming a contact the phone already holds, each contact at most once, at most 200 a day. The given fields change. | |
| mediaAutoDownload | No | Which received media is downloaded right away through the number's proxy (proxy traffic). `none` (default for new accounts): on demand, when its media URL is first requested. `all`: every file. `{maxBytes, types}`: only those. | |
| rejectCallsMessage | No | Text sent to the caller after an automatic reject (not for group calls). |
update_incoming_webhookUpdate an incoming webhookAIdempotent
Rename an incoming webhook, or pause it (enabled: false) and resume it. The destination cannot change: create another one.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| enabled | No | ||
| incomingWebhookId | Yes | The incoming webhook id, from list_incoming_webhooks. |
update_webhookUpdate a webhook endpointAIdempotent
Change a webhook endpoint's URL or events, or pause it (active: false) and resume it.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | ||
| active | No | ||
| events | No | Event types to receive, such as `message.received`, `message.sent`, `message.failed`, `account.connected`, `account.disconnected`. | |
| webhookEndpointId | Yes | The webhook endpoint id, from list_webhooks. |
upload_fileUpload a file to sendA
Upload a file whose bytes you have (not a URL) so it can be sent: returns an upload whose id goes in uploadId of send_media or post_story. The file can be sent for 24 hours, to any number of chats. Up to 5 MB; the hosted server takes requests up to 1 MB, so about 700 KB of file there. For a file that is already at a public URL, skip this and pass the URL to send_media.
| Name | Required | Description | Default |
|---|---|---|---|
| base64 | Yes | The file's bytes in base64. | |
| filename | No | Documents: the file name the recipient sees. | |
| mimeType | Yes | The file's MIME type: `image/jpeg`, `application/pdf`, `audio/ogg; codecs=opus` for a voice note. | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
vote_in_pollVote in a pollAIdempotent
Vote in a poll message as the account that received or sent it, with the names of its options (get_message shows them). An empty list retracts the vote. Returns the poll with its tally.
| Name | Required | Description | Default |
|---|---|---|---|
| options | Yes | Option names exactly as in the poll. `[]` retracts the vote. | |
| messageId | Yes | A wuapi message id (from list_messages, a send tool, or a webhook). | |
| idempotencyKey | No | Optional. Reuse the same key when retrying this exact call: within 24 hours wuapi returns the first result instead of doing it twice. |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.16.0- Added
send_buttons
2 tool updates
v0.14.0- Added
save_contacts - Changed
update_account1 field changed- added
Input schema / properties / contactAutoSaveAdded value: +{ + "description": "Contact auto-save: only direct chats with a number, never renaming a contact the phone already holds, each contact at most once, at most 200 a day. The given fields change.", + "properties": { + "enabled": { + "description": "Save the contacts of new direct chats on the phone automatically.", + "type": "boolean" + }, + "fallbackName": { + "description": "Used when the template needs a profile name the contact has not set.", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "nameTemplate": { + "description": "The saved name: `{profileName}` (WhatsApp profile name) and `{phone}` (E.164).", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "trigger": { + "description": "`first_inbound`: the contact's first message in a new chat. `any_chat`: any new chat, whoever writes first.", + "enum": [ + "first_inbound", + "any_chat" + ], + "type": "string" + } + }, + "type": "object" +}
10 tool updates
v0.13.1- Added
create_incoming_webhook - Added
delete_incoming_webhook - Added
get_incoming_webhook - Added
list_incoming_webhooks - Changed
send_contact1 field changed- changed
Input schema / properties / replyToMessageId / descriptionPrevious value: -"A wuapi message id in the same chat to quote (reply to)."New value: +"A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`)."
- Changed
send_location1 field changed- changed
Input schema / properties / replyToMessageId / descriptionPrevious value: -"A wuapi message id in the same chat to quote (reply to)."New value: +"A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`)."
- Changed
send_media1 field changed- changed
Input schema / properties / replyToMessageId / descriptionPrevious value: -"A wuapi message id in the same chat to quote (reply to)."New value: +"A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`)."
- Changed
send_poll1 field changed- changed
Input schema / properties / replyToMessageId / descriptionPrevious value: -"A wuapi message id in the same chat to quote (reply to)."New value: +"A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`)."
- Changed
send_text1 field changed- changed
Input schema / properties / replyToMessageId / descriptionPrevious value: -"A wuapi message id in the same chat to quote (reply to)."New value: +"A wuapi message id in the same chat to quote (reply to). One exception, a private reply: a message someone else wrote in a group can be quoted in the direct chat with its author (`to` is that message's `from`)."
- Added
update_incoming_webhook
1 tool update
v0.12.0- Changed
create_group1 field changed- added
Input schema / properties / communityIdAdded value: +{ + "description": "Create the group inside this community: its group id (`...@g.us`), from list_groups (`community: true`). The account must administer it.", + "maxLength": 200, + "minLength": 1, + "type": "string" +}
5 tool updates
v0.10.0- Changed
create_webhook1 field changed- changed
Input schema / properties / events / items / enumPrevious value: -[ - "account.qr_code_issued", - "account.pairing_code_issued", - "account.connected", - "account.disconnected", - "account.failed", - "message.received", - "message.sent", - "message.delivered", - "message.read", - "message.failed", - "message.edited", - "message.deleted", - "message.media_downloaded", - "poll.voted", - "group.joined", - "group.updated", - "group.join_requested", - "group.join_request_revoked", - "chat.updated", - "chat.presence_updated", - "contact.presence_updated", - "contact.picture_updated", - "contact.updated", - "blocklist.updated", - "label.updated", - "call.received", - "call.ended", - "channel.message_received", - "channel.message_updated", - "channel.updated", - "history.synced", - "project.created", - "project.updated", - "project.deleted", - "invitation.status_changed" -]New value: +[ + "account.qr_code_issued", + "account.pairing_code_issued", + "account.connected", + "account.disconnected", + "account.failed", + "message.received", + "message.sent", + "message.delivered", + "message.read", + "message.failed", + "message.edited", + "message.deleted", + "message.media_downloaded", + "story.received", + "story.deleted", + "story.viewed", + "story.reacted", + "poll.voted", + "group.joined", + "group.updated", + "group.join_requested", + "group.join_request_revoked", + "chat.updated", + "chat.presence_updated", + "contact.presence_updated", + "contact.picture_updated", + "contact.updated", + "blocklist.updated", + "sticker.favorites_updated", + "label.updated", + "call.received", + "call.ended", + "channel.message_received", + "channel.message_updated", + "channel.updated", + "history.synced", + "project.created", + "project.updated", + "project.deleted", + "invitation.status_changed" +]
- Added
forward_message - Added
manage_favorite_stickers - Added
manage_stories - Changed
update_webhook1 field changed- changed
Input schema / properties / events / items / enumPrevious value: -[ - "account.qr_code_issued", - "account.pairing_code_issued", - "account.connected", - "account.disconnected", - "account.failed", - "message.received", - "message.sent", - "message.delivered", - "message.read", - "message.failed", - "message.edited", - "message.deleted", - "message.media_downloaded", - "poll.voted", - "group.joined", - "group.updated", - "group.join_requested", - "group.join_request_revoked", - "chat.updated", - "chat.presence_updated", - "contact.presence_updated", - "contact.picture_updated", - "contact.updated", - "blocklist.updated", - "label.updated", - "call.received", - "call.ended", - "channel.message_received", - "channel.message_updated", - "channel.updated", - "history.synced", - "project.created", - "project.updated", - "project.deleted", - "invitation.status_changed" -]New value: +[ + "account.qr_code_issued", + "account.pairing_code_issued", + "account.connected", + "account.disconnected", + "account.failed", + "message.received", + "message.sent", + "message.delivered", + "message.read", + "message.failed", + "message.edited", + "message.deleted", + "message.media_downloaded", + "story.received", + "story.deleted", + "story.viewed", + "story.reacted", + "poll.voted", + "group.joined", + "group.updated", + "group.join_requested", + "group.join_request_revoked", + "chat.updated", + "chat.presence_updated", + "contact.presence_updated", + "contact.picture_updated", + "contact.updated", + "blocklist.updated", + "sticker.favorites_updated", + "label.updated", + "call.received", + "call.ended", + "channel.message_received", + "channel.message_updated", + "channel.updated", + "history.synced", + "project.created", + "project.updated", + "project.deleted", + "invitation.status_changed" +]
11 tool updates
v0.9.0- Changed
create_webhook1 field changed- changed
Input schema / properties / events / items / enumPrevious value: -[ - "account.qr_code_issued", - "account.pairing_code_issued", - "account.connected", - "account.disconnected", - "account.failed", - "message.received", - "message.sent", - "message.delivered", - "message.read", - "message.failed", - "message.edited", - "message.deleted", - "poll.voted", - "group.joined", - "group.updated", - "group.join_requested", - "group.join_request_revoked", - "chat.updated", - "chat.presence_updated", - "contact.presence_updated", - "contact.picture_updated", - "contact.updated", - "blocklist.updated", - "label.updated", - "call.received", - "call.ended", - "channel.message_received", - "channel.message_updated", - "channel.updated", - "history.synced", - "project.created", - "project.updated", - "project.deleted", - "invitation.status_changed" -]New value: +[ + "account.qr_code_issued", + "account.pairing_code_issued", + "account.connected", + "account.disconnected", + "account.failed", + "message.received", + "message.sent", + "message.delivered", + "message.read", + "message.failed", + "message.edited", + "message.deleted", + "message.media_downloaded", + "poll.voted", + "group.joined", + "group.updated", + "group.join_requested", + "group.join_request_revoked", + "chat.updated", + "chat.presence_updated", + "contact.presence_updated", + "contact.picture_updated", + "contact.updated", + "blocklist.updated", + "label.updated", + "call.received", + "call.ended", + "channel.message_received", + "channel.message_updated", + "channel.updated", + "history.synced", + "project.created", + "project.updated", + "project.deleted", + "invitation.status_changed" +]
- Added
get_chat - Added
get_contact - Changed
get_message1 field changed- added
Input schema / properties / fetchMediaAdded value: +{ + "description": "Also download the message's media if needed and return its direct URL as `mediaFile`.", + "type": "boolean" +}
- Added
list_chats - Added
list_contacts - Changed
post_story1 field changed- added
Input schema / properties / uploadIdAdded value: +{ + "description": "The id of an upload made with upload_file (or `POST /v1/uploads`): a file wuapi already stores. Usable for 24 hours, any number of times.", + "maxLength": 64, + "minLength": 1, + "type": "string" +}
- Changed
send_media4 fields changed- changed
Input schema / properties / mimeType / descriptionPrevious value: -"Guessed from the URL when omitted."New value: +"Guessed from the URL, or the upload's own type, when omitted." - added
Input schema / properties / qualityAdded value: +{ + "description": "Images only: the quality of this image instead of the account's. `hd` is WhatsApp's HD photo; `original` sends the file without re-encoding it.", + "enum": [ + "standard", + "hd", + "original" + ], + "type": "string" +} - added
Input schema / properties / uploadIdAdded value: +{ + "description": "The id of an upload made with upload_file (or `POST /v1/uploads`): a file wuapi already stores. Usable for 24 hours, any number of times.", + "maxLength": 64, + "minLength": 1, + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "accountId", - "to", - "type", - "url" -]New value: +[ + "accountId", + "to", + "type" +]
- Changed
update_account2 fields changed- added
Input schema / properties / imageQualityAdded value: +{ + "description": "What the account's images are re-encoded to before their upload through the number's proxy (proxy traffic). `standard` (default): longest side 1600 px, JPEG, as WhatsApp sends a photo. `hd`: up to 4096 px. `original`: the file as it is.", + "enum": [ + "standard", + "hd", + "original" + ], + "type": "string" +} - added
Input schema / properties / mediaAutoDownloadAdded value: +{ + "anyOf": [ + { + "enum": [ + "none", + "all" + ], + "type": "string" + }, + { + "properties": { + "maxBytes": { + "description": "Largest file downloaded up front, in bytes.", + "maximum": 2000000000, + "minimum": 1, + "type": "integer" + }, + "types": { + "description": "Media types downloaded up front.", + "items": { + "enum": [ + "image", + "video", + "audio", + "document", + "sticker" + ], + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "maxBytes", + "types" + ], + "type": "object" + } + ], + "description": "Which received media is downloaded right away through the number's proxy (proxy traffic). `none` (default for new accounts): on demand, when its media URL is first requested. `all`: every file. `{maxBytes, types}`: only those." +}
- Changed
update_webhook1 field changed- changed
Input schema / properties / events / items / enumPrevious value: -[ - "account.qr_code_issued", - "account.pairing_code_issued", - "account.connected", - "account.disconnected", - "account.failed", - "message.received", - "message.sent", - "message.delivered", - "message.read", - "message.failed", - "message.edited", - "message.deleted", - "poll.voted", - "group.joined", - "group.updated", - "group.join_requested", - "group.join_request_revoked", - "chat.updated", - "chat.presence_updated", - "contact.presence_updated", - "contact.picture_updated", - "contact.updated", - "blocklist.updated", - "label.updated", - "call.received", - "call.ended", - "channel.message_received", - "channel.message_updated", - "channel.updated", - "history.synced", - "project.created", - "project.updated", - "project.deleted", - "invitation.status_changed" -]New value: +[ + "account.qr_code_issued", + "account.pairing_code_issued", + "account.connected", + "account.disconnected", + "account.failed", + "message.received", + "message.sent", + "message.delivered", + "message.read", + "message.failed", + "message.edited", + "message.deleted", + "message.media_downloaded", + "poll.voted", + "group.joined", + "group.updated", + "group.join_requested", + "group.join_request_revoked", + "chat.updated", + "chat.presence_updated", + "contact.presence_updated", + "contact.picture_updated", + "contact.updated", + "blocklist.updated", + "label.updated", + "call.received", + "call.ended", + "channel.message_received", + "channel.message_updated", + "channel.updated", + "history.synced", + "project.created", + "project.updated", + "project.deleted", + "invitation.status_changed" +]
- Added
upload_file
21 tool updates
v0.3.0- Added
delete_chat - Added
get_webhook - Added
lookup_whatsapp_info - Added
manage_block_list - Added
manage_branding - Added
manage_channel - Added
manage_community - Added
manage_group_joins - Added
manage_group_settings - Added
manage_labels - Added
manage_privacy - Added
manage_profile - Added
manage_project - Added
reject_call - Added
resend_invitation - Added
set_disappearing_timer - Added
set_presence - Added
star_message - Added
unlink_account - Added
update_account - Added
vote_in_poll
51 tool updates
v0.1.0- First observed
add_group_participants - First observed
archive_chat - First observed
cancel_invitation - First observed
cancel_message - First observed
check_numbers - First observed
create_account - First observed
create_group - First observed
create_invitation - First observed
create_project - First observed
create_webhook - First observed
delete_message - First observed
delete_webhook - First observed
demote_group_participants - First observed
edit_message - First observed
get_account - First observed
get_account_qr_code - First observed
get_current_key - First observed
get_group - First observed
get_group_invite_link - First observed
get_invitation - First observed
get_message - First observed
get_project - First observed
get_usage - First observed
get_usage_by_project - First observed
leave_group - First observed
list_accounts - First observed
list_groups - First observed
list_invitations - First observed
list_messages - First observed
list_projects - First observed
list_proxy_locations - First observed
list_webhooks - First observed
lookup_contacts - First observed
mark_chat_read - First observed
mute_chat - First observed
pin_chat - First observed
post_story - First observed
promote_group_participants - First observed
react_to_message - First observed
reconnect_account - First observed
remove_group_participants - First observed
reply_to_message - First observed
request_pairing_code - First observed
reset_group_invite_link - First observed
send_contact - First observed
send_location - First observed
send_media - First observed
send_poll - First observed
send_read_receipts - First observed
send_text - First observed
update_webhook
TDQS
Scored across 87 tools
The tools mostly target clearly distinct resources and actions, and the rich descriptions clarify overlaps like list_messages vs manage_channel.list_messages or get_contact vs lookup_contacts. A few umbrella tools (manage_labels, manage_channel, manage_stories) and similarly named contact/chat tools could still require careful reading, but genuine misselection is limited.
Names consistently use snake_case and mostly follow a verb_noun pattern (send_text, get_chat, create_group, manage_channel). The repeated manage_* convention for multi-action resources is predictable, and there are no style collisions such as camelCase or vague single-word tools.
Eighty-seven tools is very large even for a broad WhatsApp API surface, and many tools bundle multiple actions internally, making the external surface unusually heavy. The domain is extensive, but the set would benefit from consolidation or clearer grouping.
Coverage is exceptionally broad: accounts, messaging, media, chats, contacts, groups, communities, channels, stories, labels, privacy, webhooks, projects, invitations, billing, and more. The tool surface handles lifecycle operations and edge cases with few obvious dead ends.
Maintenance
Related MCP Connectors
WhatsMCP connects Claude and other MCP-compatible AI agents directly to WhatsApp. Send and receive text, images, documents, and voice notes; manage groups (create, add/remove members, promote admins); look up contacts and profiles; follow channels; and read call and message history — all through a standard MCP interface. For voice use cases, WhatsMCP offers SIP-based calling plans (inbound-only, or full inbound/outbound) so AI voice agents can answer and place WhatsApp calls, plus low-latency WebSocket integrations with voice agent providers like ElevenLabs. Multiple WhatsApp accounts can be paired and managed per workspace, with webhook support for real-time inbound message delivery to your own infrastructure.
Drive WhatsApp from any MCP client: pair devices, send text and media, manage contacts and groups.
WhatsApp (Web + Business API), SMS, contacts, and call records via 2Chat's MCP server.
Let Claude or ChatGPT search, read and send your WhatsApp messages over MCP. OAuth sign-in.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables sending messages, managing templates, uploading media, and configuring webhooks for WhatsApp Business via the MCP protocol.10 npm5MIT
- AlicenseNot gradedqualityCmaintenanceEnables programmatic WhatsApp automation through MCP, including sending messages, managing chats and contacts, searching conversation history, and exchanging media files.MIT
- FlicenseNot gradedqualityCmaintenanceEnables linking a WhatsApp number via QR code and then sending, reading, listing chats, and checking status through MCP tools, with per-account API key authentication.-
- AlicenseNot gradedqualityCmaintenanceEnables agents and MCP clients to read and send WhatsApp messages and media, search chats, and manage contacts and groups after a one-time QR pairing.37 npmMIT