Skip to main content
Glama

Server Details

WhatsApp for AI agents — your own number or the official Cloud API: messages, media, templates.

Ownership verified
Status
Healthy
Uptime
82.3% over 43 days
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
ChatGPT
–
Claude
–

TDQS

A3.7/5.0

Scored across 46 tools

Disambiguation4/5

The toolset is generally well partitioned by resource and action, and descriptions explicitly distinguish message-reading tools such as wa_get_chat, wa_list_messages, and wa_get_message. A few edges remain: wa_delete_group vs wa_leave_chat, wa_list_calls vs wa_ai_list_calls, and the webhook management tools could be confused at a glance, but the descriptions largely resolve them.

Naming Consistency4/5

Nearly all tools use a predictable wa_ + verb + noun pattern in snake_case, such as wa_send_message, wa_list_groups, and wa_update_group. Minor deviations include wa_ai_call_get, wa_ai_call_hangup, and wa_pair_status, which place the action after the object rather than following the dominant verb-first convention.

Tool Count2/5

With 46 tools, the surface is far beyond the well-scoped 3-15 range and feels overgrown for agent use. The count is made worse by several tools marked not usable in this workspace, especially the AI-call and webhook groups, which add noise without providing usable operations here.

Completeness4/5

Coverage is broad: accounts and pairing, messaging and media, contacts and blocking, groups, channels, templates, call history, webhooks, profile management, and reporting are all represented. Minor gaps remain, such as no single group-detail lookup or message search, and some advertised tools are plan-gated dead ends in this workspace.

Available Tools

46 tools
wa_ai_call_getGet an AI Voice-Agent CallA
Read-only
Inspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] Read an AI call started with wa_ai_call_start: status (dialing, in_progress, done, failed, no_answer, busy), and once it has ended the summary, whether the agent judged it successful, the data it collected, the transcript, and a recording_url valid for one hour.

NameRequiredDescriptionDefault
call_refYesfrom wa_ai_call_start

Output Schema

NameRequiredDescription
callNothe call; transcript, summary and data fill in once it has ended
nextNowhat to do next
refusalNopresent only when the request was declined
recording_urlNoMP3 of the call, valid for one hour; present once recording_state is saved

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and idempotentHint=false, but the description adds substantial context beyond them: the exact refusal mode (plan_required), where to check eligibility (wa_get_plan), the lifecycle status values, the fact that summary/transcript/collected data only appear after the call ends, and that recording_url expires in one hour. The expiry TTL and partial-result behavior are exactly what an agent needs and cannot get from the schema or annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The availability caveat is front-loaded and the payload sentence is dense but single-purpose with no filler. The second sentence is long — a status list, six return fields, and a TTL in one breath — which slightly hurts scanability but wastes no words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values did not need spelling out, yet naming them (plus the one-hour recording validity) is genuinely useful. Combined with the prerequisite, refusal mode and eligibility pointer, nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single parameter already documents 'from wa_ai_call_start'; the description restates the same origin rather than adding format or validation detail. With the schema doing the work, baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (read an AI call started with wa_ai_call_start) and enumerates exactly what comes back: status values, summary, success judgement, collected data, transcript, and recording_url. An agent can distinguish this from wa_ai_list_calls without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The prerequisite is clear (call_ref comes from wa_ai_call_start) and the caveat routes the agent to wa_get_plan for plan discovery. However, it never says when to prefer this over enumerating with wa_ai_list_calls, and the bracketed 'not usable in this workspace' note leaves the agent unsure whether to call it at all versus skipping straight to the sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_ai_call_hangupHang Up an AI Voice-Agent CallA
DestructiveIdempotent
Inspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] End a live AI voice-agent call — one you started with wa_ai_call_start, or an incoming call an agent answered. The call is hung up at once for both sides; its summary, transcript and recording then arrive as for any call (wa_ai_call_get). A call that has already ended is left alone (hung_up false).

NameRequiredDescriptionDefault
call_refYesthe call to end, from wa_ai_call_start or wa_ai_list_calls

Output Schema

NameRequiredDescription
nextNowhat to do next
statusNothe call's status as recorded when you asked; it settles to done within a minute of a hangup
hung_upYestrue when the call was live and has been ended; false when it had already ended
refusalNopresent only when the request was declined

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare a non-read-only, destructive, idempotent operation; the description adds real substance on top: the hangup is immediate for both parties, an already-ended call is left alone and returns hung_up false, and post-call artifacts (summary, transcript, recording) still arrive. It also discloses the plan_required refusal mode and points at wa_get_plan.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the availability caveat and then the core action, with no filler sentences. The bracketed workspace note is somewhat long but is high-value routing information, so it earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema and annotations exist, so return-shape explanation is unnecessary; everything else an agent needs — availability precondition, effects on both parties, idempotent no-op behavior, and follow-up read path — is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter, and schema description coverage is 100% — the schema already says call_ref comes from wa_ai_call_start or wa_ai_list_calls. The description repeats the same provenance without adding format or edge-case detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — end a live AI voice-agent call — and scopes it to both agent-started calls (wa_ai_call_start) and agent-answered incoming calls. It is clearly distinguishable from wa_ai_call_get (read results) and wa_ai_call_start (begin a call).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives the operative condition (there is a live call to end) and routes result-reading to wa_ai_call_get and plan-checking to wa_get_plan, plus a workspace availability caveat. It does not spell out an explicit 'do not use this if…' exclusion beyond the plan note, so it is a strong 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_ai_call_startStart an AI Voice-Agent CallAInspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] Have an AI voice agent call a WhatsApp number from one of your numbers, using a preset from wa_ai_list_presets. Pass per-call context in variables. Returns immediately with a call_ref; the call then rings and runs on its own. Poll wa_ai_call_get about every 30 seconds until status is done, failed, no_answer or busy — then it carries the summary, transcript, collected data and a recording link. One call at a time per number; a number that just finished a call must wait a moment. A call to a number that is not in the calling line's contacts is refused with reason recipient_not_contact so you do not cold-call a stranger by accident; set force=true to call anyway (this does not apply to Business/WABA lines).

NameRequiredDescriptionDefault
toYesthe WhatsApp number to call, international format, e.g. +447700900123
forceNoset true to call a number that is NOT in this line's contacts; without it such a call is refused with reason recipient_not_contact so you do not cold-call a stranger by accident. No effect when the calling line is a Business (WABA) number
presetYesthe preset name, from wa_ai_list_presets
variablesNoper-call context for the agent: flat string/number/boolean values, merged over the preset's defaults, e.g. {"customer_name":"Ann","order_id":"A-1042"}
first_messageNooverride what the agent says first on this call

Output Schema

NameRequiredDescription
nextNowhat to do next
statusNodialing once accepted
refusalNopresent only when the call was not placed
call_refNopass to wa_ai_call_get to follow the call

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare non-read-only, non-idempotent, non-destructive; the description adds substantially more: asynchronous immediate return with a call_ref, the poll cadence and terminal statuses, the result payload contents, one-call-at-a-time-per-number plus a post-call cooldown, and the recipient_not_contact guard with its force override and WABA exception. It also discloses the workspace-level plan_required refusal, which is the single most important behavior for an agent to know before invoking.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loading the 'not usable in this workspace' caveat is exactly right, and every sentence carries information: purpose, workflow, constraints, safety guard. The cost is a dense single paragraph of roughly 130 words with several semicolon-chained clauses, which could be broken into bullets for faster scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an asynchronous, side-effecting tool this is complete: it explains the immediate return, how to follow up, what the terminal statuses are, what the result contains, and the concurrency/cooldown limits. An output schema exists so return values need no further explanation, and the description covers everything an agent needs to call and then correctly follow up.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already fully documented, including the force guard and the variables example. The description reinforces the key ones ('Pass per-call context in variables', preset from wa_ai_list_presets) but adds little syntax or semantics the schema does not already carry. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: have an AI voice agent call a WhatsApp number from one of your numbers using a named preset. It distinguishes itself from the related siblings by naming wa_ai_list_presets (source of the preset), wa_ai_call_get (the polling counterpart) and wa_get_plan (the plan lookup). An agent can tell exactly what this tool is versus wa_ai_call_get or wa_ai_call_hangup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use and when-not-to-use: it first warns the tool returns a plan_required refusal in this workspace and points to wa_get_plan. It then spells out the full call lifecycle ('Returns immediately with a call_ref... Poll wa_ai_call_get about every 30 seconds until status is done, failed, no_answer or busy') and the alternatives for continuing the workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_ai_list_callsList AI Voice-Agent CallsA
Read-only
Inspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] List this workspace's AI voice-agent calls, newest first: outbound calls started with wa_ai_call_start and inbound WhatsApp calls answered by a preset whose answers_inbound is true (direction says which; from is the caller of an inbound call). Use a call_ref with wa_ai_call_get for the transcript and recording link.

NameRequiredDescriptionDefault
limitNohow many to return, 1-100; defaults to 25
beforeNoa call_ref from the previous page, to list older calls; omit for the newest

Output Schema

NameRequiredDescription
nextNopass as before for the next, older page; absent on the last page
callsYesAI calls, newest first — outbound ones you started and inbound ones an answering preset took; each call_ref works with wa_ai_call_get
refusalNopresent only when the request was declined

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint/idempotentHint, but the description adds substantial behavior: newest-first ordering, the direction/from semantics, that inbound calls depend on a preset's answers_inbound flag, and the plan_required refusal path via wa_get_plan. This is rich context beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The caveat is front-loaded and every sentence carries information, but the opening bracket about plan_required is verbose for what is a conditional prerequisite. Still dense and largely waste-free.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values needn't be explained, and the description still covers direction, from, call_ref handoff, pagination, and the plan limitation. An agent has everything needed to call correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both limit and before are fully documented in the schema. The description reinforces before as a call_ref-based pagination token but adds little beyond what the schema already states; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List this workspace's AI voice-agent calls') and scopes it to outbound calls started with wa_ai_call_start plus inbound calls answered by answers_inbound presets. This clearly distinguishes it from the sibling wa_list_calls (which handles non-AI calls).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: pairs a call_ref with wa_ai_call_get for transcript/recording, and warns to consult wa_get_plan for the plan_required refusal. It names alternatives but doesn't explicitly state when to prefer wa_list_calls over this one, leaving that inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_ai_list_presetsList AI Voice-Agent PresetsA
Read-only
Inspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] List the AI voice-agent presets of this workspace. A preset pairs a voice agent with one of your WhatsApp numbers (the line it calls from) and default variables. Use a preset's name with wa_ai_call_start; only presets with ready=true can call now (not_ready_reason says why otherwise). expected_variables are the variables the agent's prompt uses — pass them to wa_ai_call_start.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
presetsYesyour presets; call wa_ai_call_start with a preset whose ready is true
refusalNopresent only when the request was declined

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only profile, and the description adds real behavioral context the annotations cannot: calling it returns a plan_required refusal in this workspace, readiness is exposed via ready/not_ready_reason, and presets carry expected_variables. The opening caveat and the subsequent description of normal listing behavior pull in opposite directions, which costs a point on coherence even though the disclosure itself is valuable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core definition and the wa_ai_call_start routing are front-loaded and efficient, but the bracketed preamble is dense and delivers a mixed message before the reader knows what the tool is. Three of the four sentences earn their place; the caveat could be a single clear clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, yet the description still explains ready/not_ready_reason and expected_variables enough to act on. The only completeness gap is that it never resolves the tension between 'not usable in this workspace' and the normal listing instructions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description's discussion of ready and expected_variables refers to returned fields rather than inputs, so it neither helps nor hurts here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The core sentence is a specific verb+resource ('List the AI voice-agent presets') and it goes further by defining what a preset is (voice agent + WhatsApp line + default variables), which distinguishes it from wa_ai_list_calls. The bracketed preamble saying it is 'Not usable in this workspace' muddies the stated purpose and makes the agent wonder whether the tool is callable at all.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It routes clearly downstream: use the preset's name with wa_ai_call_start, pass expected_variables there too, and only presets with ready=true can call now. It also points to wa_get_plan for per-number plan information. What it lacks is an explicit statement of when to consult presets versus the sibling wa_ai_list_calls/wa_ai_call_get tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_block_contactBlock or Unblock ContactAInspect

Block a contact on one of your WhatsApp accounts, so they can no longer call or message it — or set unblock=true to unblock one. Reports who it acted on: their number, the name this account's address book has for them, and the country the number belongs to.

NameRequiredDescriptionDefault
jidYesthe contact — a phone number in international form or a full JID
unblockNotrue to unblock a previously blocked contact instead
account_idYesthe account, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
statusYesok (the operation succeeded) or refused (nothing was done)
blockedNoevery contact on the account's blocklist (wa_list_blocked only)
contactNothe contact that was blocked or unblocked (wa_block_contact only)
refusalNopresent only when status is refused

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and destructiveHint=false, and the description adds real behavioral context beyond them: the effect on the target ('can no longer call or message it') and exactly what the response reports (number, address-book name, country). It doesn't discuss reversibility nuances or whether a repeated block is a no-op, which is relevant given idempotentHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One front-loaded sentence that leads with the primary action and then the inverse flag. The trailing return-value clause is somewhat redundant given an output schema exists, but it is brief and harmless.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter mutation with full schema coverage, full annotation coverage, and an output schema, nothing an agent needs to invoke it correctly is absent. The account_id reference to wa_list_accounts is carried by the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all three parameters are already documented in the schema itself. The description's explanation of unblock largely restates the schema wording and adds no new format or edge-case detail, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Block a contact on one of your WhatsApp accounts') and covers the inverse mode explicitly ('set unblock=true to unblock one'). This is clearly distinguishable from the read-only sibling wa_list_blocked, which lists rather than mutates block state.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The dual-mode usage is spelled out: default blocks, and unblock=true reverses it. What's missing is guidance on prerequisites or when to prefer a sibling (e.g., wa_list_blocked to check current state first), so it stops short of full when/when-not coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_create_groupCreate GroupAInspect

Create a WhatsApp group with a name and initial members from one of your accounts. Returns the new group's JID (use it as wa_send_message's 'to') and an invite link.

NameRequiredDescriptionDefault
nameYesthe group name (max 25 characters)
membersNoinitial members — phone numbers (E.164) or JIDs, comma- or space-separated; do NOT include your own number
account_idYesthe account to create the group from, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false, so the mutation profile is covered. The description adds one genuinely useful behavioral note — that the returned JID feeds wa_send_message's 'to' — but says nothing about whether members are added immediately or invited, what happens on duplicate creation, or any permission/account prerequisites.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the action and followed by the return-value/routing hint. No filler and nothing that could be cut without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and full schema coverage, the description only needs to orient the agent, which it does, including the downstream JID usage. Slight gap: no mention of account pairing/prerequisite state or member-invitation behavior for a non-idempotent write.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% (E.164/JID formats, 25-char limit, 'do NOT include your own number', account_id from wa_list_accounts), so the schema carries all parameter meaning. The description only restates 'a name and initial members from one of your accounts' and adds nothing beyond it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create a WhatsApp group') plus the two inputs that define it (name, initial members, source account). The verb alone separates it from wa_update_group, wa_join_group, and wa_delete_group, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the verb — an agent knows to call this when it needs a new group rather than joining one — but there is no explicit when-to-use/when-not guidance and no mention of wa_join_group as the alternative for existing groups.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_create_templateCreate WhatsApp Business TemplateAInspect

Submit a new WhatsApp Business message template for Meta's review on one of your Business (Cloud API) numbers. Meta reviews it (usually minutes, sometimes longer); it can be sent with wa_send_message's template option only once wa_list_templates shows it APPROVED. Categories: MARKETING or UTILITY. Number body variables {{1}}, {{2}}, … in order and give one body_examples value per variable. Templates apply only to Business numbers.

NameRequiredDescriptionDefault
bodyYesthe message text, at most 1024 characters; variables are {{1}}, {{2}}, … numbered in order
nameYeslowercase letters, digits and underscores, e.g. order_update
footerNooptional footer, at most 60 characters, no variables
headerNooptional text header, at most 60 characters and one {{1}} variable
buttonsNooptional buttons: at most 10, of which at most 2 URL and 1 PHONE_NUMBER
categoryYesMARKETING or UTILITY
languageNolanguage code such as en_US (the default), en or pt_BR
account_idYesthe Business (Cloud API) account to create the template on, as returned by wa_list_accounts
body_examplesNoone example value per body variable, in order — Meta's reviewers read them
header_exampleNoexample value for the header's {{1}}, required when it has one
call_permissionNotrue asks the customer to allow the business to call them (WhatsApp's call permission request); MARKETING or UTILITY only, and no buttons

Output Schema

NameRequiredDescription
refusalNopresent only when the call was declined
templateNothe submitted template

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the read/write/idempotency profile; the description adds the missing behavioral context an agent needs — that submission triggers an asynchronous external review with variable latency, and that the template is unusable until approval. This is exactly the value-add beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and the review caveat, and every clause carries a constraint. The middle section is a fairly dense run-on stacking categories, variable ordering and number scoping, which slightly taxes scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 11-parameter mutation tool whose return values are covered by an output schema, the description supplies the lifecycle context (review, approval gating), the naming/variable conventions and the account scoping. Nothing essential for a correct call is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes further by explaining the coupling between body variables {{1}}, {{2}} and body_examples (one example per variable, in order, read by reviewers) and by restating the category enum. It doesn't cover header/header_example or call_permission constraints in prose, but the schema does.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('Submit a new WhatsApp Business message template') plus the scope constraint ('on one of your Business (Cloud API) numbers'), which separates it cleanly from siblings like wa_delete_template or wa_list_templates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the preconditions explicitly: templates can only be sent via wa_send_message's template option after wa_list_templates shows APPROVED, and it restricts applicability to Business numbers. Alternatives and their selection conditions are named, not implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_delete_groupDelete GroupA
Destructive
Inspect

Delete a WhatsApp group: remove every other member and then leave. The account must be a group admin. WhatsApp has no true group-delete, so this empties the group and exits it.

NameRequiredDescriptionDefault
group_jidYesthe group (…@g.us) JID to delete, as returned by wa_list_groups
account_idYesthe account, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, but the description adds genuinely non-obvious behavior: there is no true group-delete, so the call empties the group and exits, plus an admin authorization requirement. The main gap is failure semantics — nothing says what happens if a member removal fails mid-way or if the caller is not an admin.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, and the operative behavior is front-loaded before the caveat. The 'no true group-delete' clarification earns its place because it corrects a likely false assumption.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering destructiveness and an output schema covering return values, the description supplies the two things structure doesn't: the admin prerequisite and the real-world semantics. Only partial-failure behavior is left unaddressed for what is inherently a multi-step mutation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both group_jid and account_id documented including cross-references to wa_list_groups and wa_list_accounts. The description adds no parameter-level meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Delete a WhatsApp group') and immediately explains the mechanism: remove every other member, then leave. That composite definition implicitly distinguishes it from wa_leave_chat and wa_remove_participants, so an agent can tell which operation it is without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a real precondition ('the account must be a group admin') but never says when to prefer this over wa_leave_chat or wa_remove_participants, nor when not to use it. Usage is implied by the operation description rather than stated as routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_delete_messageDelete MessageA
Destructive
Inspect

Delete a WhatsApp message for everyone. WhatsApp has no true delete for a peer that already has the message locally — this revokes it, which every modern client honours.

NameRequiredDescriptionDefault
chatYesthe chat the message is in — a phone number or a group/channel JID
senderNogroup chats only, admin accounts: the phone number or JID of whoever sent the message being deleted; omit for your own message
account_idNothe account, as returned by wa_list_accounts; omit it when the workspace has only one account
message_idYesWhatsApp's id for the message, as returned by wa_send_message or seen in wa_list_messages

Output Schema

NameRequiredDescription
statusYesok (the operation succeeded) or refused (nothing was done)
refusalNopresent only when status is refused
new_message_idNoWhatsApp's id for the react/edit/revoke protocol message itself

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is set. The description adds real value beyond that by explaining the mechanism: this is a server-side revoke, not a local wipe, and modern clients honour it – important for setting expectations about what happens on the recipient's device. It stops short of saying the action is irreversible or that it can be refused by clients/old versions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the action and then the one nuance that matters. No filler, nothing buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, well-schema'd mutation with an output schema and destructive annotations, the description covers the essential what and how. The only gap is operational framing – reversibility, permission requirements, or failure modes – which an agent might want before issuing a destructive call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters including the group/admin nuance on `sender` and the account fallback on `account_id`. The description adds nothing parameter-specific, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource plus scope: 'Delete a WhatsApp message for everyone.' It doesn't explicitly name a sibling (e.g. wa_edit_message) as the alternative, but the intent is unmistakable and the 'for everyone' scope sets it apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated – an agent infers this is the tool for removing a message already sent. There is no explicit when/when-not guidance, no mention of the edit-vs-delete choice, and no note that deletion is usually for one's own message or requires admin rights (that only appears in the schema for `sender`).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_delete_templateDelete WhatsApp Business TemplateA
Destructive
Inspect

Delete a WhatsApp Business message template from one of your Business (Cloud API) numbers — one language, or every language of the name when language is omitted. Meta blocks reusing a deleted template's name for a while.

NameRequiredDescriptionDefault
nameYesthe template name
languageNodelete only this language, e.g. pt_BR; omit to delete every language of the name
account_idYesthe Business (Cloud API) account that owns the template

Output Schema

NameRequiredDescription
deletedNotrue when Meta deleted it
refusalNopresent only when the call was declined

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, readOnlyHint=false, so the safety profile is covered. The description adds meaningful context beyond that: the cascade behavior when `language` is omitted and the external side effect that Meta blocks name reuse for a period — both non-obvious consequences of deletion.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with zero filler, front-loading the action and scope, then appending the cascade rule and the Meta name-block caveat. Nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations carry the safety profile, so the description only needs to convey scope and consequences — which it does. It could go slightly further on irreversibility or confirmation expectations for a destructive bulk (all-language) deletion, but the essentials for correct invocation are present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters are already documented, including the omit-to-delete-all semantics for `language`. The description restates that semantics but adds no new syntax, format, or constraint detail beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Delete) and resource (WhatsApp Business message template) scoped to a Business (Cloud API) number, and immediately disambiguates cascade behavior (one language vs. all languages of the name). This clearly separates it from siblings like wa_create_template and wa_list_templates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for the key decision — omit `language` to delete every language of the name — and warns that Meta blocks reuse of the deleted name for a while, which helps an agent decide whether to call it now. It does not explicitly name alternatives (e.g., prefer this only when the template is truly unwanted vs. wa_create_template for a new one), so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_delete_webhookDelete WebhookA
Destructive
Inspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] Stop delivering inbound messages to the configured endpoint. Messages keep arriving and stay readable through wa_list_messages; only the push stops.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
noteNo
deletedYes
refusalNo

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true, but the description adds genuinely new behavioral facts: what survives the operation ('messages keep arriving and stay readable through wa_list_messages'), and that calls fail with a plan_required refusal in this workspace. That is exactly the kind of blast-radius and failure-mode context annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences plus a bracketed caveat, all of which earn their place, and the blocking caveat is front-loaded so the agent reads it before anything else. The bracket is dense and could be split, but nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, an output schema present, and destructive/read-only hints supplied by annotations, the description covers the only remaining unknowns: whether the tool is callable here, what failure looks like, and what data is preserved.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly avoids inventing parameter detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and effect: 'Stop delivering inbound messages to the configured endpoint,' which an agent can immediately map to the webhook resource. It does not explicitly name wa_enable_webhook / wa_set_webhook as the counterparts, but 'only the push stops' clearly separates it from message deletion.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The bracketed note is an unusually explicit when-NOT-to-use: it says the tool is unusable in this workspace, that calling it yields a plan_required refusal, and routes the agent to wa_get_plan for per-number plans. The only gap is that no positive 'use this when...' alternative (e.g. wa_set_webhook to repoint the endpoint) is offered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_edit_messageEdit MessageAInspect

Edit a WhatsApp message you sent. WhatsApp only accepts an edit within about 20 minutes of the original send.

NameRequiredDescriptionDefault
chatYesthe chat the message is in — a phone number or a group/channel JID
textYesthe replacement message body
account_idNothe account, as returned by wa_list_accounts; omit it when the workspace has only one account
message_idYesWhatsApp's id for the message, as returned by wa_send_message

Output Schema

NameRequiredDescription
statusYesok (the operation succeeded) or refused (nothing was done)
refusalNopresent only when status is refused
new_message_idNoWhatsApp's id for the react/edit/revoke protocol message itself

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds a genuine behavioral constraint the annotations do not carry: WhatsApp only accepts an edit within roughly 20 minutes of the original send. That tells the agent to expect a failure mode for old messages. It stops short of saying what the response or error looks like when the window has passed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero padding. The core action comes first and the constraint follows, so it is front-loaded and proportionate to a simple mutation tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the annotations cover the safety profile. The time-window caveat is the one thing an agent could not infer elsewhere. Only minor gap is silence on the failure behavior once the window lapses.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and every parameter is documented in-schema, so the schema does the work. The description adds no format or syntax detail about chat, message_id, or the replacement text. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Edit a WhatsApp message you sent" is a specific verb+resource and the ownership qualifier ("you sent") narrows scope usefully. It naturally separates from wa_send_message, wa_delete_message and wa_react in the sibling list, though it never names them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 20-minute window implies when the call will succeed, which is real guidance, but there is no explicit when-to-use/when-not and no fallback named for the expired case (e.g., send a new message, or the delete path). Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_enable_webhookPause or Resume WebhookA
Idempotent
Inspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] Pause or resume delivery to the configured webhook WITHOUT changing the endpoint or its signing secret. Use this to stop deliveries temporarily — deleting and re-creating the webhook would issue a new secret. Messages keep arriving while paused and stay readable with wa_list_messages.

NameRequiredDescriptionDefault
reasonNooptional note recorded with a pause, shown in the console
enabledYestrue resumes delivery, false pauses it; the endpoint and its signing secret are kept either way

Output Schema

NameRequiredDescription
noteNo
enabledYes
refusalNopresent only when the request was declined

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already say idempotent=true and destructive=false, but the description adds real behavior: the endpoint and signing secret survive a pause, and messages keep arriving and stay readable via wa_list_messages. It also discloses the plan_required refusal mode, which is behavior no annotation carries. Slightly short of 5 only because the refusal/workspace caveat is conveyed as a parenthetical rather than a clean precondition statement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The critical caveat is front-loaded and each sentence does work — non-destructive semantics, the delete/recreate alternative, and the paused-message behavior. The bracketed workspace note is long and em-dash dense, costing a bit of scannability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained. For a state-toggle tool the description covers availability preconditions, what is preserved, what happens to inbound messages, and the sibling alternative — everything needed to call it correctly or avoid calling it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters are already described there, including the true/false meaning of enabled and the optional note semantics. The description reinforces the non-destructive semantics of the toggle but adds no syntax or format detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb pair (pause/resume) and resource (webhook delivery) and immediately scopes it: 'WITHOUT changing the endpoint or its signing secret.' That contrast is exactly what separates it from wa_delete_webhook and wa_set_webhook in the sibling list, despite the enabling-sounding tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use-plus-alternative: use this to stop deliveries temporarily, because deleting and re-creating the webhook would issue a new secret. It also flags that the tool is unusable in the current workspace and routes the agent to wa_get_plan for per-number plan eligibility.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_follow_channelFollow ChannelBInspect

Follow a WhatsApp Channel from one of your accounts using its link.

NameRequiredDescriptionDefault
account_idYesthe account to follow from, as returned by wa_list_accounts
channel_linkYesthe channel link (https://whatsapp.com/channel/…) or bare invite key

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false, so the mutation profile is covered. The description adds only that it is account-scoped and link-driven, but says nothing about the practical consequence of the non-idempotent flag (what happens on a repeat follow) or any rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler and the action stated first. The phrase "from one of your accounts" slightly duplicates the account_id parameter, but overall it is tightly scoped.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and the two parameters are fully documented. What is missing for a non-idempotent mutation is the expected outcome when the follow is repeated or fails, which an agent would need before invoking.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters explain themselves, including the accepted link format and the cross-reference to wa_list_accounts. The description adds no meaning beyond that, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Follow) and resource (WhatsApp Channel) plus the key input (its link), so an agent can distinguish it from wa_join_group or wa_list_channels. It stops short of explicitly naming those siblings, which keeps it from a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"from one of your accounts using its link" implies the prerequisites, but the description never states when to use this versus wa_list_channels or wa_join_group, nor what to do if the channel is already followed. Usage is implied rather than guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_get_chatGet ChatA
Read-only
Inspect

Read the most recent messages for one account (WhatsApp or Telegram), oldest first — or, with chat, one conversation, including older history loaded with wa_load_history. Use this for context before replying; use wa_list_messages to page through everything new. Narrow with since/until (when sent; until is exclusive).

NameRequiredDescriptionDefault
chatNoread ONE conversation — a phone number or a group JID — including history loaded with wa_load_history; omit for the account's most recent messages across all chats
limitNohow many recent messages, 1-200; defaults to 50
sinceNoonly messages sent at or after this time: RFC3339 with a zone (2026-10-01T09:00:00+03:00) or a date (2026-10-01 = midnight UTC); omit for no lower bound
untilNoonly messages sent BEFORE this time — exclusive, so all of 1 October is since 2026-10-01 until 2026-10-02; same formats as since; omit for no upper bound
account_idNothe account whose conversation to read, from wa_list_accounts; omit it when the workspace has only one account
include_media_urlsNoalso return attachment.media_url on each available attachment — a time-limited (1h) signed URL to GET the bytes with plain HTTP instead of a wa_get_media call; off by default

Output Schema

NameRequiredDescription
accountNothe account this conversation was read from
refusalNopresent only when the request was declined
has_moreNotrue when older messages match than were returned; page them with wa_list_messages(account_id, chat, since, until, include_history=true)
messagesYesrecent messages for this account, oldest first
account_noticesNopresent when a number this read covers is not working: new messages are not arriving on it; says why and what to do

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and idempotentHint=false, so safety is covered structurally. The description adds genuine behavioral detail beyond that: results are ordered oldest-first, and one conversation's results include older history brought in by wa_load_history. It does not discuss result density or ordering caveats across chats, so it is useful but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The primary behavior and the 'chat' variant are front-loaded in the first clause, with guidance and filtering after. It is tight overall, though the em-dash stacking makes the opening sentence slower to parse than it needs to be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-shape explanation is unnecessary, and the description covers account scoping, conversation scoping, time bounds and the sibling alternative. Minor gaps (limit behavior, media URL opt-in) are fully handled by the schema, so nothing an agent needs is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter is already documented in detail, including the exclusive 'until' boundary and the 1h signed media URL. The description only reiterates that since/until refer to send time and that until is exclusive, which duplicates rather than extends the schema; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (read recent messages for one account) plus a clearly bounded variant (one conversation when 'chat' is supplied), including that history loaded via wa_load_history is visible. The scope distinction against wa_list_messages is made explicit, so an agent can choose without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an affirmative use case ("for context before replying") and names the alternative tool with its selecting condition ("use wa_list_messages to page through everything new"). It also states how to narrow results with since/until, leaving nothing to inference about which tool fits.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_get_mediaGet MediaA
Read-only
Inspect

Fetch the attachment (image/video/audio/document/sticker) a received message carried. A small attachment comes back as base64 in media_base64; a large one comes back as media_url, a time-limited link to GET the bytes. Use the message_id from wa_list_messages. 'refused' means no retrievable media for that id.

NameRequiredDescriptionDefault
account_idNothe account that received the message, from wa_list_accounts; omit it when the workspace has only one account
message_idYesthe message id whose attachment to fetch, from wa_list_messages (a WhatsApp message id, or on a Telegram account one of the form <chat>_<n>)

Output Schema

NameRequiredDescription
mimeNo
sizeNothe attachment size in bytes
statusYesok (media returned, inline or as a url) or refused
refusalNo
media_urlNoa time-limited (1h) URL to GET a large attachment's bytes, present instead of media_base64 when the attachment is over the inline cap
media_base64Nobase64 of the attachment, present for a small attachment

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnlyHint/idempotentHint annotations by disclosing the size-dependent return contract: small attachments arrive as base64 in media_base64, large ones as a time-limited media_url to GET separately. It also defines the 'refused' failure semantic, which is the kind of thing an agent otherwise discovers only by trial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences: what it fetches, how the payload varies by size, and the failure case. Front-loaded with the core action and free of repetition or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description need not document return fields, yet it still covers the branching payload shape and the refusal case. Combined with annotations and full schema coverage, an agent has everything needed to call it and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are already documented, including the account_id omission rule and the Telegram id format. The description reinforces that message_id comes from wa_list_messages but adds no syntax or format detail the schema lacks, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (fetch) and resource (the attachment a received message carried), and enumerates the media kinds covered, so an agent knows this is binary retrieval rather than message text. It never names the obvious sibling wa_get_message, leaving the attachment-vs-message-body distinction implicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete prerequisite chain by telling the agent to use the message_id from wa_list_messages, and pre-empts the most likely confusing outcome by defining what 'refused' means. No explicit when-not-to-use or named alternative is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_get_messageGet MessageA
Read-only
Inspect

Fetch ONE stored message from one of your accounts, by WhatsApp's message_id (as a webhook delivery or wa_list_messages gave it) or by its cursor. Use this to read the message a webhook told you about, or the one you are about to react to, edit or delete, without paging through history.

NameRequiredDescriptionDefault
cursorNothe message's cursor, as wa_list_messages returned it (a webhook delivery carries it as message_seq). Pass this or message_id
account_idNothe account the message belongs to, from wa_list_accounts; omit it when the workspace has only one account
message_idNoWhatsApp's id for the message — the message_id a webhook delivery, wa_list_messages or wa_send_message gave you. Pass this or cursor
include_media_urlsNoalso return attachment.media_url when the message carries an available attachment — a time-limited (1h) signed URL to GET the bytes with plain HTTP instead of a wa_get_media call; off by default

Output Schema

NameRequiredDescription
messageNothe message; absent when the request was declined
refusalNopresent only when the request was declined — including when no such message is stored
account_noticesNopresent when a number this read covers is not working: new messages are not arriving on it; says why and what to do

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and idempotentHint=false, so the safety profile is covered. The description adds useful framing: single-record retrieval rather than a scan, and the webhook-as-source workflow that motivates the call. It stops short of saying what happens if neither key is supplied or if the message is missing, which is the remaining behavioral gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the key constraint ('ONE', the two lookup keys) first, followed by a use case. No restatement of the name or title and no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a full output schema, 100% schema coverage, and read-only annotations, an agent has everything needed to invoke this correctly. The description supplies the workflow context the structured fields cannot, and nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the 'pass this or message_id/cursor' exclusivity and the one-hour media URL lifetime, so the schema does the heavy lifting. The description repeats the message_id provenance (webhook delivery or wa_list_messages) rather than adding new meaning, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Fetch ONE stored message') and pins down the two lookup keys (message_id or cursor). It explicitly contrasts itself with paging through history, i.e. wa_list_messages, so an agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names concrete trigger scenarios — reading the message a webhook reported, or the one about to be reacted to, edited, or deleted — and states the negative case (no paging through history). That is explicit when-to-use guidance with an implied alternative (wa_list_messages) for the bulk case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_get_planGet PlanA
Read-only
Inspect

Show a plan, its limits and current usage. Plans are per WhatsApp number: pass account_id to see ONE number's plan, limits and the tools it does not include (excluded_tools); omit it for the whole workspace — every number's plan and limits (lines), with excluded_tools listing only what NO active number can use, and plan "mixed" when the numbers are on different plans. A tool listed on this server may still be refused on a number whose plan leaves it out; a tool called WITHOUT account_id acts on every number, so it needs every active number's plan to include it. Call this to see why a tool answers plan_required on a given number, why wa_send_message might be refused, or how much headroom is left. It also reports this service's version (server_version, server_build_date).

NameRequiredDescriptionDefault
account_idNooptional: report one line's plan; omit to report every line

Output Schema

NameRequiredDescription
planYesthe plan's slug, e.g. free, starter, pro — an identifier; show display_name to a person
linesNoevery line's plan and limits, present only for the workspace view
refusalNopresent only when account_id names a line that cannot be used
voice_planYesthe SIP calls this plan allows, or null when it allows none — or, for a workspace whose numbers are on different plans, null: see each line's calls_inbound/calls_outbound
descriptionNowhat the plan includes, for a human
messages_1hYesthe hourly message-send limit and usage
display_nameYesthe plan's name as the customer sees it, e.g. Free, Pro
history_daysYeshow long messages are retained, in days; 0 means forever
messages_24hYesthe 24-hour message-send limit and usage
excluded_toolsNotools listed on this server that your plan does not include; calling one returns a plan_required refusal
server_versionYesthe version of this MCP service
accounts_pairedYesWhatsApp numbers currently paired
webhooks_enabledYeswhether this plan can register inbound webhooks
max_attachment_mbYeslargest attachment this plan can send, in MB; 0 means unlimited
server_build_dateYeswhen that version was built

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Well beyond the readOnlyHint annotation, it explains the non-obvious mechanics: excluded_tools lists only what no active number can use in workspace mode, plan becomes "mixed", and a tool invoked without account_id must be permitted on every active number. Those rules are exactly the failure modes an agent would otherwise misread.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then scope, then diagnostic use cases, with zero filler. Some sentences are long and clause-heavy (the excluded_tools and no-account_id rules), costing a little readability, but nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A one-parameter read-only tool with an output schema; the description still covers mode semantics, refusal implications, and the incidental server_version report. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, but the description adds the consequence of each mode — one number's plan and its excluded_tools versus the workspace intersection and "mixed" plans — which the schema's one-line parameter note does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Show a plan, its limits and current usage") and immediately scopes it to WhatsApp numbers vs. the whole workspace. No sibling tool deals with plans or limits, and the description makes that boundary obvious.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit trigger conditions: call it to diagnose plan_required errors, refusals of wa_send_message, or to check remaining headroom. It also spells out the choice between the two modes — pass account_id for one number, omit for the workspace — with no inference required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_get_profileGet ProfileA
Read-only
Inspect

Look up who a phone number is on WhatsApp, from one of your accounts: whether it is registered, its public name, about text, profile picture and — for a business — its categories, contact details and hours. An empty about or picture means the peer has not shared it with this account, not that it has none.

NameRequiredDescriptionDefault
phoneNothe number to look up, in international form (e.g. +447700900111)
account_idNowhich of your accounts to ask from, from wa_list_accounts; omit it when the workspace has only one account

Output Schema

NameRequiredDescription
jidNo
nameNothe best available public name
noteNo
aboutNothe peer's status text, when they let this account see it
phoneNo
refusalNopresent only when the request was declined
businessNopresent only for a business account
is_businessNotrue or false when known; ABSENT means the lookup could not establish it (see note) — absence is not a no
name_sourceNobusiness or none — a verified business name is vouched for by WhatsApp; "none" means nothing public is published
on_whatsappYesfalse means the number is not registered on WhatsApp at all
picture_urlNoa WhatsApp-hosted URL that expires; fetch it promptly

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover read-only safety, and the description adds real behavioral context the annotations cannot: results are account-relative, and an empty about/picture means the peer withheld it from this account rather than that it is unset. It does not cover failure behavior for unregistered numbers beyond the registered flag, so it falls short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences: the first front-loads what is returned, the second delivers a high-value caveat about empty fields. No repetition of the title or schema, nothing wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be restated, and the description covers scope and the main interpretive pitfall. It leaves implicit that phone is effectively the key input (the schema marks nothing required), a minor gap for a lookup tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, including phone format and the account_id lookup path, so the baseline is 3. The description adds only the soft notion of per-account visibility, not new semantics for either parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (look up) and resource (a phone number's WhatsApp identity) and enumerates exactly what comes back: registration status, public name, about text, picture, and business categories/contact/hours. This is clearly distinguishable from sibling list tools like wa_list_contacts and from wa_get_chat.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"From one of your accounts" implies the account_id scoping and the schema points to wa_list_accounts, but there is no explicit when-to-use/when-not guidance and no routing to alternatives such as wa_get_chat for numbers already in a chat. Usage is inferable rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_get_webhookGet WebhookA
Read-only
Inspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] Show the currently configured inbound webhook, including whether it is still enabled and why it was disabled if it was. The signing secret is never returned — it is shown only when the webhook is created.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
urlNo
eventsNo
enabledNo
configuredYes
webhook_idNo
disabled_byNowho paused delivery: owner, system (our delivery worker) or staff (support, and not resumable here)
disabled_reasonNo
last_delivery_atNo

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description discloses important behavior: the workspace-level plan_required refusal, the inclusion of disabled reason, and the crucial fact that the signing secret is never returned. These are meaningful operational details an agent could not infer from annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The critical workspace limitation is front-loaded in brackets, followed by two focused sentences covering return content and secret handling. Every sentence earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description need not explain the response shape. It still covers the key caveats an agent needs—plan refusal, disabled reason, and secret exclusion—making the definition complete for this read-only tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is nothing for the description to clarify beyond the schema. Baseline score of 4 is appropriate for a no-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'Show the currently configured inbound webhook,' and clarifies what is returned (enabled status, disabled reason). It is clearly distinct from sibling mutators like wa_set_webhook, wa_delete_webhook, and wa_enable_webhook.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states the tool is not usable in this workspace and that calling it returns a plan_required refusal, then routes the agent to wa_get_plan as the alternative. This is unambiguous when-not-to-use guidance with a named sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_join_groupJoin GroupBInspect

Join a WhatsApp group from one of your accounts using its invite link.

NameRequiredDescriptionDefault
account_idYesthe account to join from, as returned by wa_list_accounts
invite_linkYesthe group invite link (https://chat.whatsapp.com/…) or bare code

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this is a non-read-only, non-idempotent, non-destructive mutation. The description adds only that an invite link is used and that it operates from one of the user's accounts; it does not explain failure modes, already-member behavior, or whether the account must be paired first.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One front-loaded sentence with zero waste. It states the action, resource, and mechanism immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations cover mutation traits, so the definition is minimally callable. However, for a write operation it omits useful context such as whether the account must be paired, what happens if already a member, and what a successful join returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented with usage hints ('as returned by wa_list_accounts' and invite-link format). The description adds no meaning beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Join a WhatsApp group') and names the required mechanism ('using its invite link'). It is clear enough to distinguish from wa_create_group and wa_leave_chat, though it does not explicitly name those siblings or state that it is not group creation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives only the basic action, with no explicit when-to-use guidance, prerequisites (e.g., account must be paired), or alternatives such as wa_create_group or wa_get_group_invite_link. An agent gets implied usage from the invite-link mention but no routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_leave_chatLeave ChatA
Destructive
Inspect

Leave a group or unfollow a channel on one of your accounts, by its JID.

NameRequiredDescriptionDefault
jidYesthe group (…@g.us) or channel (…@newsletter) JID to leave, as returned by wa_list_groups / wa_list_channels
account_idYesthe account, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description clarifies *what* is being modified (group membership/channel subscription), which adds functional context. However, the primary behavioral safety (destructive nature) is handled by the annotations, limiting the description's added value in this category.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is maximally concise, providing the full scope of the tool's function in a single, highly efficient sentence. The structure is perfectly front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity of the input schema and the presence of strong annotations (destructive, not read-only), the description provides all necessary context for a successful initial tool call decision.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, setting a baseline of 3. The description reiterates that the JID and account_id are the necessary arguments, but adds no specific semantic nuance beyond the schema's provided definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses clear verbs ('leave', 'unfollow') and identifies the resource scope ('group' or 'channel'). It is highly specific about the tool's function and avoids ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The purpose itself serves as the primary guideline. By specifying 'leave' or 'unfollow', it naturally excludes the use of tools like 'join' or 'follow'. It is clear about when this operation is required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_accountsList WhatsApp AccountsA
Read-only
Inspect

List the WhatsApp accounts available to you. You need it only when no message row gives you the account_id — before a first message to a number you have no messages with, or to see why an account is not working; when replying, reuse the row's account_id. An account is only usable while its state is "connected" (status "live"); otherwise status and what_to_do say why and what to do.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
accountsYesthe accounts this API key can use — WhatsApp numbers and Telegram accounts; each says which in backend

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so safety is covered; the description instead adds the non-obvious usability rule that an account is only usable while state is 'connected' (status 'live') and that status/what_to_do carry the diagnosis. It does not address any rate limits or what an empty account list means, but the state gating is real behavioral context beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with purpose then immediately the usage rule. The middle sentence is dense with em-dashes but every clause carries a decision rule; nothing is redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be enumerated, and the description still names the salient fields an agent must act on (state, status, what_to_do). For a zero-parameter read tool, this is complete enough to call correctly on the first attempt.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the schema is closed (additionalProperties: false) and fully covered. Baseline 4 applies, with no parameter-level gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the WhatsApp accounts') plus scope ('available to you'), which cleanly separates it from the many wa_list_* siblings over messages, groups, contacts and templates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger ('only when no message row gives you the account_id'), two concrete scenarios (first message to an unknown number, diagnosing a broken account), and an explicit exclusion ('when replying, reuse the row's account_id'). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_blockedList Blocked ContactsA
Read-only
Inspect

List every contact one of your accounts has blocked. Each entry carries the contact's number, the name this account's address book has for them — absent for someone not saved on the phone — and the country the number belongs to. WhatsApp does not report when a contact was blocked, so no date is available.

NameRequiredDescriptionDefault
account_idYesthe account whose blocklist to read, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
statusYesok (the operation succeeded) or refused (nothing was done)
blockedNoevery contact on the account's blocklist (wa_list_blocked only)
contactNothe contact that was blocked or unblocked (wa_block_contact only)
refusalNopresent only when status is refused

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, and the description adds useful behavioral context: it explains the returned fields (number, address-book name with absence caveat, country) and discloses that WhatsApp does not report block dates.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loads the core purpose, then efficiently adds return-field semantics and the block-date limitation. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only listing tool with a complete input schema, existing output schema, and safety annotations, the description is complete: it covers purpose, returned fields, and the notable absence of block-date data.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the single account_id parameter is already well documented in the schema. The description does not add further semantics or formatting details beyond what the schema provides, matching the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: 'List every contact one of your accounts has blocked.' The scope ('blocked') clearly distinguishes it from sibling tools like wa_list_contacts and wa_block_contact.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the purpose—reading an account's blocklist—but the description does not explicitly state when to use this tool versus alternatives such as wa_list_contacts or wa_block_contact.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_callsList Call HistoryA
Read-only
Inspect

Read call history across your WhatsApp accounts, oldest first. Page with after_cursor: pass back the next_cursor you were given, and keep going until has_more is false to export the whole history. Each call says whether it was answered and how long it lasted. Narrow with since/until (until is exclusive).

NameRequiredDescriptionDefault
limitNohow many to return, 1-200; defaults to 50
sinceNoonly calls at or after this time: RFC3339 with a zone (2026-10-01T09:00:00+03:00) or a date (2026-10-01 = midnight UTC); omit for no lower bound
untilNoonly calls BEFORE this time — exclusive, so all of 1 October is since 2026-10-01 until 2026-10-02; same formats as since; omit for no upper bound
account_idNolimit to one account; omit for every account you have
after_cursorNoreturn calls after this cursor; omit to start from the oldest

Output Schema

NameRequiredDescription
callsYescalls in order, oldest first
refusalNopresent only when the request was declined
has_moreYestrue when the page was full and more may be waiting
next_cursorYespass this as after_cursor next time; page until has_more is false to export everything

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, idempotentHint=false), yet the description adds real behavior: oldest-first ordering, the explicit paging loop with next_cursor/has_more, and that each call reports answered status and duration. It omits account/auth prerequisites and rate-limit or result-size caveats.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, front-loaded with the resource and ordering, then paging, then record contents, then filtering. No sentence is redundant and every one carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and full parameter coverage, the description only needs to explain usage, which it does for paging, filtering, and ordering. The missing piece is disambiguation from wa_ai_list_calls, which matters given the dense sibling set.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter is already documented, including until being exclusive. The description reinforces the exclusive-until rule and the after_cursor paging contract but adds little syntax or interpretation beyond the schema; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read call history') plus scope ('across your WhatsApp accounts') and ordering ('oldest first'). It does not differentiate from the close sibling wa_ai_list_calls, so an agent cannot be certain which list tool to pick without opening both schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly explains operational usage: paginate with after_cursor/next_cursor until has_more is false to export the full history, and narrow with since/until. It stops short of when-not guidance or naming alternatives such as wa_ai_list_calls or wa_list_messages.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_channelsList ChannelsA
Read-only
Inspect

List the channels one of your accounts follows, with each channel's JID, name and subscriber count.

NameRequiredDescriptionDefault
account_idYesthe account whose channels to list, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true and idempotentHint=false, so the safety profile is covered. The description adds the returned fields, but it does not explain pagination, limits, or why the operation is marked non-idempotent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single front-loaded sentence with no wasted words. The scope and return fields are stated immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with an output schema and full parameter documentation, the description is nearly complete. It could mention pagination or result limits, but those gaps are minor given the structured metadata.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the single account_id parameter is already documented as the account whose channels to list. The description reinforces the account scoping but adds no syntax or format detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: list channels followed by one account. It also names the returned fields, so an agent can distinguish it from wa_follow_channel and other list tools without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage is implied by 'channels one of your accounts follows,' but there is no explicit when-to-use guidance, no exclusions, and no named alternative such as wa_follow_channel or wa_list_accounts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_contactsList ContactsA
Read-only
Inspect

List or search the address book of one of your accounts. On WhatsApp these are the contacts saved on the phone the account is linked to; use the returned phone numbers with wa_send_message. On Telegram they are the account's saved contacts and the people it has a chat with; use each row's jid as to or chat with every other tool. Pass query to find someone by name or number (on Telegram also by username); matching looks at saved names, the name the contact publishes, business names and the number. On WhatsApp, set include_pictures to also get each contact's profile picture URL; that looks the contacts up on WhatsApp, so it returns at most 10 per page and is slower.

NameRequiredDescriptionDefault
limitNohow many to return (default 500, max 2000; max 10 with include_pictures)
queryNooptional: only contacts whose name or number (on Telegram also the username) contains this; case-insensitive and ignores punctuation in numbers, so '+44 7700 900111' finds 447700900111. Omit to list everything
account_idYeswhich of your accounts to read, from wa_list_accounts
after_cursorNoreturn contacts after this cursor; omit to start from the beginning
include_picturesNoWhatsApp only: also return each contact's profile picture URL. This looks every contact on the page up on WhatsApp, so the page is capped at 10 and can take half a minute; leave it off for a fast listing

Output Schema

NameRequiredDescription
noteNo
totalYeshow many contacts matched in total, before the limit was applied
refusalNopresent only when the request was declined
contactsYes
has_moreNotrue when more contacts remain after this page
truncatedNotrue when more contacts exist than were returned
next_cursorNopass this as after_cursor to continue; page until has_more is false to read the whole address book

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so safety is covered. The description adds real behavioral context beyond that: include_pictures triggers per-contact lookups on WhatsApp, capping pages at 10 and making the call slow, and it recommends leaving it off for a fast listing. It does not describe pagination/cursor behavior explicitly, which is the remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each containing distinct information: channel semantics, identifier routing, query matching, and the picture-lookup cost. It is dense but front-loaded and free of filler; the picture caveat is partly redundant with the schema's own description, slightly diluting the tightness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description covers the channel-dependent meaning of the results and the cost tradeoff. For a read-only listing tool with four optional parameters this is close to complete; only explicit cursor/paging guidance is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds cross-channel meaning the schema does not: query matches on Telegram also by username, and include_pictures is WhatsApp-only with the page cap consequence restated in context. The after_cursor parameter is left entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List or search the address book of one of your accounts') and immediately differentiates what the resource means per channel (WhatsApp phone contacts vs Telegram saved contacts plus chat partners). An agent can tell this apart from siblings like wa_list_accounts or wa_list_blocked without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent downstream: use returned phone numbers with wa_send_message, use each row's jid as 'to'/'chat' with every other tool. It also gives the conditions for query and include_pictures. It does not say when to prefer this over adjacent listing tools such as wa_list_blocked, which keeps it short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_group_membersList Group MembersA
Read-only
Inspect

List a group's members. Each item is one participant with their JID, phone number (in 'name'), and an 'admin' flag.

NameRequiredDescriptionDefault
group_jidYesthe group (…@g.us) JID, as returned by wa_list_groups
account_idYesthe account, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true, so safety is covered. The description adds genuinely non-obvious return semantics: phone number surfaces in a field named 'name', and each item carries a JID and an 'admin' flag — a quirk an agent would otherwise get wrong. It says nothing about ordering, pagination, or behavior on large groups, which keeps it off a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, purpose first, then the return-shape detail. Every clause carries information an agent would not get from structured fields alone; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, two-required-param tool with a full output schema and complete schema coverage, the description covers purpose and the main return quirk. Minor omission: no mention of member ordering or what happens for very large groups, but nothing blocks a correct call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (group_jid, account_id) are already fully documented, including the @g.us format and cross-references to wa_list_groups / wa_list_accounts. The description adds nothing about parameters beyond 'group's members', so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List a group's members'), which is immediately distinguishable from wa_list_groups and from mutating siblings like wa_remove_participants or wa_update_participants. It stops short of explicitly naming a sibling to contrast against, so it sits just below the top band.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use or when-not guidance and no prerequisites. The only routing hint ('as returned by wa_list_groups') lives in the schema parameter description, not in the tool description itself.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_groupsList GroupsA
Read-only
Inspect

List the groups one of your accounts has joined, with each group's JID, name and member count.

NameRequiredDescriptionDefault
account_idYesthe account whose groups to list, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds scope ('groups one of your accounts has joined') and return fields, but does not explain idempotentHint=false, ordering, or freshness of the member count.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler. The core purpose and return fields are front-loaded, and every phrase contributes useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, has one fully documented parameter, read-only annotations, and an output schema. The description is sufficient to call it correctly, though it could be stronger by naming the sibling member-listing tool or clarifying ordering/freshness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the account_id description already explains that the value comes from wa_list_accounts. The tool description repeats the 'one of your accounts' idea but adds no further parameter semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: list groups for one account, including JID, name, and member count. It distinguishes listing groups from creating/updating/deleting them, but does not explicitly distinguish this from the sibling tool wa_list_group_members.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'one of your accounts has joined' and the account_id schema note pointing to wa_list_accounts. However, there is no explicit when-to-use guidance or mention of the alternative wa_list_group_members for member-level listing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_messagesList MessagesA
Read-only
Inspect

Read messages across all your accounts — WhatsApp and Telegram — oldest first. Page with after_cursor: pass back the next_cursor you were given to see only what has arrived since. Use this to catch up after being notified of a new message. Narrow with account_id, chat, and since/until (when the message was sent; until is exclusive). Add include_history to also read synced history. When a poll finds nothing new, wait about 30 seconds before the next one: calling again at once returns the same empty page.

NameRequiredDescriptionDefault
chatNoonly this conversation — a phone number or a group JID, or on a Telegram account the chat's Telegram id (<id>@telegram)
limitNohow many to return, 1-200; defaults to 50
sinceNoonly messages sent at or after this time: RFC3339 with a zone (2026-10-01T09:00:00+03:00) or a date (2026-10-01 = midnight UTC); omit for no lower bound
untilNoonly messages sent BEFORE this time — exclusive, so all of 1 October is since 2026-10-01 until 2026-10-02; same formats as since; omit for no upper bound
account_idNoonly this account's messages, from wa_list_accounts; omit for every account
after_cursorNoreturn messages after this cursor; omit or 0 to start from the beginning
include_historyNoalso return imported history (pairing sync and wa_load_history); off by default. With it on, a page is in storage order rather than time order — sort by at
include_media_urlsNoalso return attachment.media_url on each available attachment — a time-limited (1h) signed URL to GET the bytes with plain HTTP instead of a wa_get_media call; off by default

Output Schema

NameRequiredDescription
hintNopresent when the read found nothing new: wait before polling again
refusalNopresent only when the request was declined; next_cursor is then your after_cursor, unchanged
has_moreYestrue when the page was full and more may be waiting
messagesYesmessages in order, oldest first
next_cursorYespass this as after_cursor next time to get only newer messages
account_noticesNopresent when a number this read covers is not working: new messages are not arriving on it; says why and what to do

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint and non-idempotency; the description adds substantial behavior: chronological vs. storage ordering when include_history is on, how next_cursor/after_cursor paging works, that a repeat poll returns the same empty page, and that media URLs are 1-hour signed GET links. This is exactly the operational context an agent cannot infer from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with what the tool does and how to page, then narrowing filters, then polling advice — a sound information order with little waste. A few clauses echo the schema verbatim (e.g., 'until is exclusive'), which trims a point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an eight-parameter, all-optional read tool with an output schema covering return shape (including next_cursor), the description covers paging, filtering, ordering side effects, and polling cadence. Nothing material is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds cross-parameter meaning the schema lacks: passing back the prior next_cursor, and the caveat that include_history flips page ordering so results must be sorted by 'at'. It does restate some schema-level facts (until is exclusive), so it stops short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read messages'), the scope ('across all your accounts — WhatsApp and Telegram'), and the ordering ('oldest first'). An agent can immediately tell this apart from single-message siblings like wa_get_message or account-scoped siblings like wa_list_accounts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger ('Use this to catch up after being notified of a new message') and a polling discipline ('when a poll finds nothing new, wait about 30 seconds'). It also routes away from wa_get_media for attachment bytes via the include_media_urls parameter.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_list_templatesList WhatsApp Business TemplatesA
Read-only
Inspect

List the WhatsApp Business message templates of one of your Business (Cloud API) numbers, with each one's review status (APPROVED, PENDING, REJECTED — a rejected one carries Meta's rejected_reason). Use an APPROVED template's name and language with wa_send_message's template/template_language to start a conversation or message outside the 24-hour window, and supply its 'variables' count as template_variables, in order. Templates apply only to Business numbers, not personal linked-device numbers.

NameRequiredDescriptionDefault
account_idYesthe Business (Cloud API) account whose templates to list, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
refusalNopresent only when the call was declined
templatesNoevery message template with its review status; only APPROVED ones can be sent, with the name/language/variables to pass to wa_send_message

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds context annotations can't: the three possible review statuses, that rejected templates carry Meta's rejected_reason, and that templates only exist for Business numbers. It doesn't need to describe the return shape since an output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose and statuses before the workflow tip, and every sentence carries information. It is dense but slightly overpacked, folding status enumeration, send-workflow, and account-type caveat into one run-on block rather than separate scannable sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-param read tool with an output schema and readOnly annotations, the description covers scope, return semantics, downstream usage, and the personal-vs-business distinction. An agent has everything needed to call it and to know what to do with the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and account_id is already documented as coming from wa_list_accounts. The description reinforces the 'Business (Cloud API) number' meaning but adds no format or syntax beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (WhatsApp Business message templates) scoped to a Business (Cloud API) number, plus what each item carries (review status, rejected_reason). It explicitly distinguishes from personal linked-device numbers, which eliminates a real ambiguity an agent could hit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives the exact downstream workflow: use an APPROVED template's name and language with wa_send_message's template/template_language, and pass its variables count as template_variables in order. It also states the trigger condition (starting a conversation or messaging outside the 24-hour window) and the exclusion for personal numbers.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_load_historyLoad Older MessagesAInspect

Ask the account's phone for older messages in one conversation, before the oldest one stored here, and store them. The phone must be online; it usually answers within seconds. Read the result with wa_get_chat and the same chat. Loaded messages are history: they never trigger webhooks and appear in wa_list_messages only with include_history=true. They are kept for your plan's history window like any other message. A conversation needs at least one stored message to page back from.

NameRequiredDescriptionDefault
chatYesthe conversation to page back: a phone number for a direct chat, or a group JID (…@g.us)
countNohow many older messages to ask the phone for, 1-500; defaults to 50
account_idNothe account, as returned by wa_list_accounts; omit it when the workspace has only one account

Output Schema

NameRequiredDescription
statusYesok (the request reached the phone) or refused (nothing was asked)
refusalNopresent only when status is refused
answeredYesthe phone answered in time; false means it may still answer later (it must be online) — read the chat again in a minute
importedYesof those, how many were new here; 0 with answered=true usually means you reached the start of what the phone holds
receivedYesmessages the phone sent back

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: the phone must be online, latency is usually seconds, loaded messages never trigger webhooks, and retention follows the plan's history window. This explains the non-idempotent, mutating nature (remote fetch + local store) that readOnlyHint=false only implies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and its precondition, and every sentence carries information (latency, webhook suppression, retention, read path). Slightly dense at five sentences, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description covers the operational requirements (phone online), side effects (webhook suppression), retention, and the follow-up read call. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents chat, count (1-500, default 50), and account_id. The description only restates 'in one conversation' and 'older messages' without adding format or edge-case semantics, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: asks the account's phone for older messages in one conversation, before the oldest stored one, and stores them. This is clearly distinct from wa_list_messages and wa_get_chat, which are named explicitly as the read paths.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives the triggering condition (paging back before the oldest stored message) and the prerequisite (the conversation needs at least one stored message). It also routes the agent to the follow-up tool ('Read the result with wa_get_chat') and flags that wa_list_messages only shows loaded messages with include_history=true.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_pair_accountPair AccountAInspect

Begin linking a new WhatsApp account — or a Telegram account, with network set to telegram. For WhatsApp there are two ways to link and the right one depends on the user's devices, so ASK FIRST: if they can scan a QR code from another screen (a second phone, or this computer's screen) using the WhatsApp app on their phone, call this with no phone and show the returned QR PNG; if they only have the one phone that runs WhatsApp — it cannot scan its own screen — pass phone in international format to get an 8-character code they type on that phone instead. A Telegram account links by QR only, scanned from Telegram → Settings → Devices → Link Desktop Device; if it has two-step verification the state becomes password_needed and the user enters their cloud password on the console's pairing page (never through a tool). Then poll wa_pair_status with the returned pair_id: a QR re-arms about every 20 seconds (show the newest each time), a phone code lasts a few minutes, and either way the state turns "paired" once it is linked. Pass import_history to choose whether a WhatsApp pairing loads the phone's recent messages as history.

NameRequiredDescriptionDefault
phoneNolink by phone-number code instead of a QR: the number to link, in international format with its country code (for example +52 998 123 4567). WhatsApp on that phone is asked to accept an 8-character code, returned as pair_code. Use it when the user has only the one phone that runs WhatsApp and cannot scan a QR from another screen (WhatsApp only)
networkNothe messaging network of the account to link: whatsapp (the default) or telegram. A Telegram account links by QR only: the user scans it from Telegram → Settings → Devices → Link Desktop Device. Telegram accounts must be enabled for the workspace, or the call is refused
import_historyNoimport the phone's recent message history (about two months) as read-only history for this pairing; omit to use the workspace default (WhatsApp only)

Output Schema

NameRequiredDescription
stateYesstarting, qr, code, password_needed (a Telegram account with two-step verification: the user must enter their cloud password on the console's pairing page — never ask for it here), paired or failed
networkNothe messaging network the pairing links on: whatsapp or telegram
pair_idNopass this to wa_pair_status to follow the pairing
refusalNopresent only when pairing could not be started
pair_codeNothe 8-character code the user types on their phone (phone-number pairing only)
expires_atNowhen pair_code stops working, RFC 3339 (phone-number pairing only)
needs_planNotrue when the linked number has no plan yet and will not run until the user buys one in the console
instructionsNowhat to tell the user to do
qr_png_base64Noa PNG image of the QR code, base64 encoded — display this to the user

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say non-read-only, non-idempotent, non-destructive, which says almost nothing about this interactive flow. The description adds substantial operational detail beyond them: a re-arming QR every ~20 seconds, a phone code valid 'a few minutes', a password_needed state for Telegram two-step verification (with the password entered on the console page, never via a tool), and the transition to 'paired'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose and then the decision rule, and nearly every clause is decision-relevant. It is a single dense paragraph rather than clearly segmented branches, which costs a point on structure, but there is little pure filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, yet the description still tells the agent what comes back (QR PNG, pair_code, pair_id) and how to continue. Timing lifetimes, terminal state, and the password_needed exception complete the flow an agent needs to drive this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter already carries a rich description, so the description mostly restates the same rules (phone in international format, telegram enables QR-only, import_history for WhatsApp history). It adds marginal value by framing phone absence as the QR trigger, but not enough to exceed the baseline when the schema already does the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ('Begin linking a new WhatsApp account — or a Telegram account'), and the scope covers both networks in one sentence. It is plainly distinguishable from siblings like wa_pair_status and wa_unpair_account, which are named or implied elsewhere in the text.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to ASK FIRST, then branches on user device constraints: QR when another screen is available, phone code when the user has only the one phone ('it cannot scan its own screen'). Telegram is scoped to QR only and the polling handoff to wa_pair_status is stated outright.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_pair_statusCheck Pairing StatusA
Read-only
Inspect

Check a pairing started with wa_pair_account. While state is "qr" a new image is returned each time — show the latest to the user. While state is "code", show pair_code. A Telegram pairing may report "password_needed": the user enters their cloud password on the console's pairing page, never here. When state becomes "paired" the account is ready and appears in wa_list_accounts.

NameRequiredDescriptionDefault
pair_idYesthe pair_id returned by wa_pair_account

Output Schema

NameRequiredDescription
stateYesstarting, qr, code, password_needed (a Telegram account with two-step verification: the user must enter their cloud password on the console's pairing page — never ask for it here), paired or failed
networkNothe messaging network the pairing links on: whatsapp or telegram
pair_idNopass this to wa_pair_status to follow the pairing
refusalNopresent only when pairing could not be started
pair_codeNothe 8-character code the user types on their phone (phone-number pairing only)
expires_atNowhen pair_code stops working, RFC 3339 (phone-number pairing only)
needs_planNotrue when the linked number has no plan yet and will not run until the user buys one in the console
instructionsNowhat to tell the user to do
qr_png_base64Noa PNG image of the QR code, base64 encoded — display this to the user

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and idempotentHint=false; the description explains why the latter holds (a new image is returned each time while in "qr"), which is exactly the context annotations cannot convey. It further discloses the password_needed branch and the state transition to "paired", giving real behavioral guidance beyond the flags.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, each mapped to a distinct state or action, with the primary instruction (check the pairing) front-loaded. No redundant restatement of the title or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists so return values need not be re-explained, yet the description still enumerates every state the caller must handle and the correct user-facing action for each. Nothing an agent needs to poll correctly and act on the result is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single pair_id parameter is fully documented in the schema (100% coverage) as "the pair_id returned by wa_pair_account", and the description merely references the same origin. No additional format, lifetime, or reuse semantics are added, so the schema does the work and baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb and resource ("Check a pairing started with wa_pair_account") with an explicit link to the initiating sibling, which no other sibling tool covers. An agent can distinguish it from wa_list_accounts and wa_pair_account without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives per-state instructions for each value: for state "qr" show the latest image, for state "code" show pair_code, for "password_needed" the user acts on the console's pairing page. It also states an explicit exclusion ("never here") and the terminal condition ("paired" → visible in wa_list_accounts).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_reactReact to MessageAInspect

React to a WhatsApp message with an emoji. Pass an empty reaction to remove a reaction you previously sent.

NameRequiredDescriptionDefault
chatYesthe chat the message is in — a phone number or a group JID; reacting to a channel (@newsletter) message is not supported
senderNogroup chats only: the phone number or JID of whoever sent the original message; omit in a DM or for your own message
reactionYesthe emoji to react with; an empty string removes a reaction you previously sent
account_idNothe account, as returned by wa_list_accounts; omit it when the workspace has only one account
message_idYesWhatsApp's id for the message, as returned by wa_send_message or seen in wa_list_messages

Output Schema

NameRequiredDescription
statusYesok (the operation succeeded) or refused (nothing was done)
refusalNopresent only when status is refused
new_message_idNoWhatsApp's id for the react/edit/revoke protocol message itself

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare non-read-only, non-idempotent, non-destructive; the description adds real behavioral context beyond that — an empty string removes a reaction, and the phrasing 'a reaction you previously sent' scopes removal to your own reactions. It does not mention error behavior or the channel limitation, so it stops short of full disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero filler; the core action is front-loaded and the non-obvious removal trick follows immediately. Nothing here needs trimming or reordering.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations, an output schema, and 100% parameter coverage already in structured fields, the description only needs to frame the action and the removal case, which it does. The one gap is the unsupported-channel constraint, which an agent would only discover by reading the chat parameter description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters (including the non-obvious group-only sender and the account_id defaulting rule) are already documented in the schema. The description only restates the reaction/empty-string semantics that the schema also covers, adding no new parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (react) and resource (a WhatsApp message) plus the payload (an emoji), and adds the inverse operation (empty reaction removes). No sibling tool covers reactions, so an agent can route here without ambiguity against wa_send_message, wa_edit_message, or wa_delete_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The removal case is spelled out clearly, which is genuine usage guidance, but the description never names an alternative or states when not to use this tool. It also omits the channel restriction (reacting to @newsletter messages is unsupported), which lives only in the schema and is exactly the kind of routing constraint that belongs here.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_remove_participantsRemove ParticipantsA
Destructive
Inspect

Remove members from a WhatsApp group by phone number or JID. The account must be a group admin.

NameRequiredDescriptionDefault
membersYesmembers — phone numbers (E.164) or JIDs, comma- or space-separated
group_jidYesthe group (…@g.us) JID, as returned by wa_list_groups
account_idYesthe account, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructive=true, readOnly=false, idempotent=false; the description adds the admin-permission requirement, which is real behavioral context not encoded in structured fields. It leaves out what happens on partial failure or with non-member inputs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, the action and its scope front-loaded, prerequisite second. No filler and nothing redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists so return values need not be explained, and annotations carry the safety profile. With the admin prerequisite and identifier formats covered, the definition is nearly complete; only error/partial-failure behavior is unaddressed for this destructive operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter already carries a description (members format, group_jid source, account_id source). The description only restates that members may be phone numbers or JIDs, adding nothing beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Remove members from a WhatsApp group') and adds the accepted member identifiers (phone number or JID), so the action is unambiguous. It does not distinguish itself from the close sibling wa_update_participants, which would have earned a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States a concrete precondition — the account must be a group admin — which tells the agent when the call can succeed. It stops short of naming alternatives (e.g. wa_update_participants or wa_list_group_members for verification) or when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_reportReport to WhatsMCPAInspect

Send a bug report, feature request or feedback about WhatsMCP to the WhatsMCP team. Use it when the person asks to report a problem, suggest a feature or leave feedback — not to contact a WhatsApp user (that is wa_send_message). The report is emailed to the team with the workspace and the sender's address, so a reply reaches the person by email. Write it in the person's words; for a bug include what was done, what happened, what was expected and any error text. Never include passwords, API keys or message contents the person did not ask to share.

NameRequiredDescriptionDefault
typeYeswhat kind of report this is,enum=bug,enum=feature_request,enum=feedback
titleYesa one-line summary, at most 120 characters
messageYesthe report itself, at most 5000 characters: for a bug, what was done, what happened and what was expected, and which number it was on

Output Schema

NameRequiredDescription
statusYesok when the report was accepted for delivery, refused when it was not
messageNowhat happens next, for the person
refusalNopresent only when the report was not sent

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the annotations by disclosing the real side effect and its destination: the report is emailed to the team along with the workspace and the sender's address, so a reply reaches the person by email. It also adds a data-handling constraint (never include passwords, API keys or unshared message contents), which annotations do not express. It does not mention rate limits or duplicate-submission behavior, so it stops short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and the sibling exclusion are front-loaded in the first two sentences, and the later sentences each add non-redundant rules (email routing, bug template, privacy). It runs five sentences and could be tightened, but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter write tool that has an output schema, the description covers everything needed to call it correctly: trigger conditions, the sibling to avoid, where the report goes, what metadata is attached automatically, how to compose the body, and what must never be included.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description earns above that by telling the agent how to fill the message field for bugs (what was done, what happened, what was expected, error text) and by imposing a content exclusion rule that no schema constraint expresses. It adds writing guidance rather than restating field names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('send a bug report, feature request or feedback about WhatsMCP') and immediately distinguishes itself from the sibling that could be confused with it ('not to contact a WhatsApp user (that is wa_send_message)'). An agent can route between the two without inspecting either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the triggering conditions ('when the person asks to report a problem, suggest a feature or leave feedback') and names the excluded alternative with the condition that selects it. Both the when and the when-not are present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_send_messageSend WhatsApp MessageAInspect

Send a message from one of your accounts (WhatsApp, or Telegram for an account whose backend is telegram) — text, or an attachment: an image via image_base64 (JPEG/PNG, at most 5 MiB; text becomes the caption), a document via document_base64 (any file, at most 20 MiB; text becomes the caption), or audio via audio_base64 (at most 16 MiB; no caption). For a Business (WhatsApp Cloud API) number, set 'template' to send a pre-approved message template (e.g. hello_world) — the only way to start a conversation or to message that number outside the 24-hour window. A 1:1 message to a number that is NOT in this account's contacts is refused with reason recipient_not_contact so you do not message a stranger by accident; set force=true to send anyway (the gate does not apply to groups, channels, templates or Business numbers). Check the returned status: "sent" means delivered; "queued" means the message was accepted but not yet confirmed and may still arrive, so do NOT send it again; "refused" means nothing was sent and the reason explains whether retrying will help.

NameRequiredDescriptionDefault
toYesthe recipient. WhatsApp: a phone number in international form (digits only, e.g. 447700900123) for a 1:1 chat, or a full group/channel JID (…@g.us for a group, …@newsletter for a channel). Telegram (an account whose backend is telegram): the chat id exactly as wa_list_messages reports it (<id>@telegram; a group is -<id>@telegram, a channel or supergroup -100<id>@telegram) to reply, or to start a conversation an @username or a t.me/<name> link. A phone in +E.164 form works only if it is already in this account's Telegram contacts, and force does not change that. Never a bare number, which could be a phone or a user id
textNothe message body; when an image is attached this is its caption and may be empty. Either text or image_base64 is required
forceNoset true to send a 1:1 message to a number that is NOT in this account's contacts; without it such a send is refused with reason recipient_not_contact so you do not message a stranger by accident. No effect on groups, channels, templates, Business (WABA) numbers or Telegram accounts
templateNooptional: the name of a pre-approved message template to send (Business/WABA numbers only), e.g. hello_world. Use this to start a conversation or to message outside the 24-hour window; text and attachments are ignored when set
audio_pttNooptional: true to send as a voice note (push-to-talk) rather than a regular audio attachment
account_idNothe account to send from — the account_id on the message row you are replying to, or from wa_list_accounts; omit it when the workspace has only one account
audio_mimeNooptional: the audio's mime type, e.g. audio/ogg; codecs=opus
image_mimeNooptional: the image's mime type, image/jpeg or image/png
audio_base64Nooptional: base64-encoded audio to attach, at most 16 MiB decoded; audio has no caption
image_base64Nooptional: base64-encoded JPEG or PNG to attach, at most 5 MiB decoded; when set, text becomes the caption
audio_secondsNooptional: the audio's duration in seconds
document_mimeNooptional: the document's mime type, e.g. application/pdf
document_base64Nooptional: base64-encoded document/file to attach, at most 20 MiB decoded; when set, text is the caption
document_filenameNooptional: the filename shown to the recipient, e.g. report.pdf
template_languageNooptional: the template's language/locale code, e.g. en_US; defaults to en_US
template_variablesNooptional: values that fill the template body's positional {{1}}, {{2}}, … placeholders, in order

Output Schema

NameRequiredDescription
statusYessent (delivered), queued (accepted but unconfirmed - do NOT re-send), or refused (not attempted)
refusalNopresent only when status is refused
message_idNoWhatsApp's id for the message, present only when status is sent
request_idNocorrelation id; a queued message appears in wa_list_messages under this id once it settles

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses the recipient_not_contact refusal gate, the 24-hour Business window constraint, per-attachment size limits, caption behavior, and the meaning of each returned status including a warning against retrying queued sends (consistent with idempotentHint=false). This is exactly the extra context annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and dense enough that nearly every clause carries information; length is justified by 16 parameters. It suffers slightly from being one long run-on paragraph with repeated force/limit statements that also appear in the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter mutation tool with an output schema, the description covers everything an agent needs: recipient id conventions per backend, attachment constraints, the contact gate, template rules, and status interpretation. No meaningful gap remains for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real semantic grouping: the three mutually exclusive attachment types with their limits, template overriding text/attachments, and force having no effect on groups/channels/templates/Business/Telegram. Some of this duplicates schema text, but the cross-parameter interactions are new value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Send a message from one of your accounts') and immediately enumerates the media variants and Telegram backend case. It is clearly differentiable from siblings like wa_edit_message, wa_react, and wa_create_template.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete when-to-use conditions: templates for starting conversations or messaging outside the 24-hour window, force for non-contact recipients, and explicit 'do NOT send it again' on queued status. It names sibling tools (wa_list_accounts, wa_list_messages) for obtaining ids, though it does not route the agent away from this tool toward edit/react for modifying existing messages.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_set_presenceSet PresenceAInspect

Announce a typing state ("composing"/"paused") to a chat, or set one of your accounts online/offline ("available"/"unavailable"). Fire-and-forget: there is no delivery confirmation.

NameRequiredDescriptionDefault
chatNothe chat (a phone number or a group/channel JID) to announce a typing state to; required for composing/paused, ignored for available/unavailable
stateYescomposing (show "typing…"), paused (stop), available, or unavailable
account_idNothe account, as returned by wa_list_accounts; omit it when the workspace has only one account

Output Schema

NameRequiredDescription
statusYesok (queued to the bridge) or refused (nothing was sent)
refusalNopresent only when status is refused

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly=false, idempotent=false, destructive=false, and the description adds real context beyond them: 'fire-and-forget: there is no delivery confirmation,' which tells the agent not to retry or wait on a result. It does not mention rate limits or whether the recipient actually sees the state, so it falls short of fully rich behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the dual-mode capability first, then the fire-and-forget caveat. Every clause carries information an agent needs, with no repetition or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values needn't be described, and annotations cover the safety profile; the description covers both operational modes and the lack of delivery confirmation. Only minor gaps remain, such as how long a typing state persists and whether presence is visible to other participants.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% — the chat, state, and account_id parameters are each documented, including the conditional requirement of chat for composing/paused. The description largely restates what the schema already says about the two state modes and adds no syntax, format, or account_id resolution details, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb (announce/set) and two distinct resources (typing state in a chat, account online status), and enumerates the concrete state values for each mode. No sibling tool in the list deals with presence, so an agent can unambiguously attribute this capability here; the only missing element for a 5 is an explicit statement about how it relates to siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context for when each mode applies — typing announcements go to a chat, availability applies to your own account — and indirectly clarifies that no alternative tool exists for this. There is no explicit 'do not use this for X' guidance, but nothing about the intended usage is left ambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_set_profile_photoSet Profile PhotoA
DestructiveIdempotent
Inspect

Change the profile photo of one of your own WhatsApp accounts — the picture every contact sees. Pass image_base64 (JPEG, PNG or GIF, at most 5 MiB) to replace it: the image is center-cropped to a square and scaled to at most 640x640, as WhatsApp stores it. Or pass remove=true to delete the current photo. The previous photo cannot be restored afterwards. Contacts may keep seeing the old photo for a while until their app refreshes it.

NameRequiredDescriptionDefault
removeNotrue removes the account's current profile photo instead of replacing it; image_base64 must then be omitted
account_idYesthe account whose own profile photo to change, as returned by wa_list_accounts
image_base64Nothe new photo: base64-encoded JPEG, PNG or GIF, at most 5 MiB decoded. It is center-cropped to a square and scaled to at most 640x640. Omit it when remove is true

Output Schema

NameRequiredDescription
bytesNothe size of the JPEG that was uploaded; absent on a removal
widthNothe stored photo's side in pixels (it is always square); absent on a removal
statusYesok (WhatsApp accepted the change) or refused (nothing was done)
refusalNopresent only when status is refused
summaryNoa human-readable result
picture_idNothe id WhatsApp assigned the new photo; absent on a removal

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and idempotentHint=true, but the description adds genuinely new context: the previous photo cannot be restored, the image is center-cropped and capped at 640x640, and contacts may see a stale photo until their app refreshes. That irreversibility and eventual-consistency detail is exactly what an agent needs before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then mode selection, then consequences — a sensible ordering with no filler. It repeats some schema-level detail (5 MiB ceiling, 640x640 scaling), which is defensible for critical constraints but keeps it from being maximally tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and annotations cover the safety profile. The description completes the picture with irreversibility, image transforms, and caching behavior, leaving nothing an agent needs missing for a 3-parameter mutation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the parameter descriptions already state formats, size limits, cropping and the remove/image_base64 mutual exclusion. The description largely restates those facts, adding only the 'as WhatsApp stores it' framing, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Change the profile photo') scoped to 'one of your own WhatsApp accounts' and clarifies it is the picture contacts see. This cleanly separates it from read-only siblings like wa_get_profile and from contact-level operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly documents the two operating modes — supply image_base64 to replace, or remove=true to delete — which is the main decision an agent faces. It does not explicitly name a sibling alternative (e.g. wa_get_profile to inspect the current photo first), so it falls short of a full when/when-not rubric.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_set_webhookSet WebhookAInspect

[Not usable in this workspace: it acts on every number, and not every number's plan includes it — calling it returns a plan_required refusal; wa_get_plan lists each number's plan.] Register an HTTPS endpoint to receive WhatsApp events as they happen, so you do not have to poll wa_list_messages. By default it delivers inbound messages; pass events to also receive outbound messages (sent from your number), message delivery status (delivered/read/failed), account lifecycle events (connected, disconnected, unlinked, blocked), and call events (completed, missed). Returns a signing secret that is shown ONCE — store it immediately. Calling this again replaces the endpoint and issues a NEW secret.

NameRequiredDescriptionDefault
urlYesan https:// URL that will receive POSTed events; must be publicly reachable
eventsNowhich events to receive — any of message.inbound, message.outbound, message.status, account.connected, account.disconnected, account.unlinked, account.blocked, call.completed, call.missed; defaults to message.inbound

Output Schema

NameRequiredDescription
urlNo
eventsNo
secretNothe signing secret — shown ONCE; store it now, it cannot be retrieved later
refusalNopresent only when the request was declined
warningNo
webhook_idNo
verificationNo
test_deliveryNo

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses the plan_required refusal and workspace limitation, the one-time signing secret, and that re-calling replaces the endpoint and issues a NEW secret — the key consequence of idempotentHint=false. Default event scope (inbound only) is also disclosed. Minor tension with destructiveHint=false since existing config and secret are overwritten, but this is disclosed rather than contradicted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The workspace/plan caveat is front-loaded in brackets before the core behavior, which is the right priority, and every sentence carries information (default scope, event taxonomy, secret handling, replacement semantics). It is dense but not padded; the bracketed note is slightly long relative to the rest.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not detail return values, yet it still flags the one-time secret that matters operationally. Combined with the URL reachability requirement, event defaults, and plan limitation, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: it explains that omitting events yields inbound messages only and that each event category maps to outbound messages, delivery status, lifecycle, and call events. This lets an agent choose events without reverse-engineering the enum list.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: registers an HTTPS endpoint to receive WhatsApp events, explicitly framed as an alternative to polling wa_list_messages. The sibling set contains wa_get_webhook, wa_delete_webhook, and wa_enable_webhook, none of which are named or distinguished here, so an agent must infer how 'set' relates to 'enable'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear use case (receive events as they happen instead of polling) and a hard exclusion (returns plan_required in this workspace, check wa_get_plan). It does not address when to prefer wa_enable_webhook or what happens if a webhook already exists beyond 'calling this again replaces the endpoint'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_unpair_accountUnpair AccountA
Destructive
Inspect

Disconnect a WhatsApp or Telegram account from this service. The account stops sending and receiving immediately. Message history is kept. Re-connecting requires pairing again (scanning a new code), so ask the user before calling this.

NameRequiredDescriptionDefault
account_idYesthe account to disconnect, from wa_list_accounts

Output Schema

NameRequiredDescription
noteYeswhat happened, and what was kept
stateYeslogged_out once the account has been disconnected
refusalNopresent only when the request was declined
account_idYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (destructiveHint=true) by specifying the concrete consequence: sending and receiving stop immediately, message history is preserved, and reversal costs the user a re-pairing scan. That is exactly the pre-call context an agent needs before an irreversible-feeling action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the action and consequence, ending with the safety instruction. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A destructive mutation with a documented output schema and strong annotations; the description covers state change, data retention, reversibility, and the confirmation requirement. Nothing an agent needs is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents account_id including its source ('from wa_list_accounts'). The description adds only the account-type context (WhatsApp/Telegram) and nothing about the identifier's format, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Disconnect') and resource ('a WhatsApp or Telegram account'), plus the scope ('from this service'). The clause about re-connecting requiring pairing implicitly distinguishes it from wa_pair_account, so an agent can route correctly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit behavioral guidance: 'ask the user before calling this' because re-connection requires a new pairing code. It does not name the counterpart sibling (wa_pair_account) explicitly, but the scenario is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_update_groupUpdate GroupAInspect

Change a WhatsApp group's settings: its name, its description, whether only admins may change settings (locked), and whether only admins may post (announce). Pass only the fields to change; several can change in one call. If the group restricts settings to admins, the account must be one. WhatsApp applies each change separately, so on a refusal 'applied' lists the changes that took effect before it.

NameRequiredDescriptionDefault
nameNoa new group name (max 25 characters)
lockedNotrue lets only admins change the name, description and photo; false lets every member
announceNotrue lets only admins post (an announcement group); false lets every member post
group_jidYesthe group (…@g.us) JID, as returned by wa_list_groups
account_idYesthe account, as returned by wa_list_accounts
descriptionNoa new description; an empty string clears it

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: changes apply one-by-one, a refusal can leave a partial result, and the 'applied' field reports what took effect before the failure. It also discloses the admin-authority prerequisite when settings are restricted, which the readOnly/destructive hints alone do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the scope and the list of changeable fields, then patch semantics, then failure behavior. No sentence is redundant with the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return shape need not be spelled out, yet the description still explains the one non-obvious output detail ('applied' on partial failure). For a 6-parameter, fully documented mutation tool, nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description nonetheless adds behavioral meaning to the parameters by explaining that omitted fields are left unchanged and that multiple fields can be set in one call. It does not restate per-field constraints (e.g., the 25-character name limit), which the schema already handles.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Change') and resource ('a WhatsApp group's settings') and enumerates the four mutable fields. It is clearly distinguishable from siblings such as wa_create_group, wa_delete_group, and wa_update_participants, which handle lifecycle and membership rather than group settings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Pass only the fields to change; several can change in one call' gives explicit partial-update usage and multi-field batching guidance, and the admin precondition is stated inline. It stops short of naming sibling alternatives (e.g., wa_update_participants for membership), so it lands just below the top.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

wa_update_participantsUpdate ParticipantsAInspect

Add members to a WhatsApp group (action=add), make members admins (action=promote), or make admins ordinary members again (action=demote), by phone number or JID. Adding needs the account to be a member (and, for private groups, an admin); promote and demote need an admin. To remove members, use wa_remove_participants.

NameRequiredDescriptionDefault
actionYesadd (new members), promote (members to admin) or demote (admins to members); to remove members use wa_remove_participants
membersYesmembers — phone numbers (E.164) or JIDs, comma- or space-separated
group_jidYesthe group (…@g.us) JID, as returned by wa_list_groups
account_idYesthe account, as returned by wa_list_accounts

Output Schema

NameRequiredDescription
itemsNothe rows of a list operation
statusYesok (the operation succeeded) or refused (see refusal; for wa_update_group, applied lists the changes that took effect before it)
appliedNowa_update_group only: the settings that were changed, in order — on a refusal, the ones that took effect before it
refusalNopresent only when status is refused
summaryNoa human-readable result
group_jidNothe new group's JID (wa_create_group only) — use it as wa_send_message's 'to'
invite_linkNothe group's invite link (wa_create_group or wa_get_group_invite_link)

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly=false and destructive=false, so the description's main added value is the permission model, which it supplies clearly. It leaves gaps on multi-member behavior (partial failures, what happens when a listed member is already in the group or already an admin) and does not note that these operations are not idempotent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the action enumeration before prerequisites and the sibling pointer. No filler or restated title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, and permissions plus sibling routing are covered. The remaining shortfall is behavioral detail on bulk member operations (ordering, partial success, duplicate handling) for a four-required-parameter mutation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters including action values and the comma/space-separated member format. The description's 'by phone number or JID' restates the schema's member format rather than adding syntax or edge-case guidance, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (add/promote/demote participants in a WhatsApp group) and enumerates each action's effect in plain language. It explicitly distinguishes itself from the sibling wa_remove_participants, which handles removal.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives per-action prerequisites ('adding needs the account to be a member (and, for private groups, an admin); promote and demote need an admin') and names the alternative tool for the excluded case ('To remove members, use wa_remove_participants'). An agent can pick the right action and know whether it has permission without further reading.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updates
    • Changedwa_get_chat1 field changed
      • addedOutput schema / properties / messages / items / properties / sent_by
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "present on an outbound message an AI agent or an app sent through WhatsMCP: who asked for the send",
        +  "properties": {
        +    "id": {
        +      "description": "the agent's, the API key's or the OAuth app's id",
        +      "type": "string"
        +    },
        +    "kind": {
        +      "description": "agent (a hosted AI agent), api_key (an app on one of your API keys) or oauth_app (an app you connected over OAuth, such as Claude)",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "its name as it was when the message was sent",
        +      "type": "string"
        +    },
        +    "version": {
        +      "description": "an agent only: the number of the agent's version that wrote it",
        +      "type": "integer"
        +    },
        +    "via": {
        +      "description": "an app only: mcp or rest, the API it sent through",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "kind",
        +    "id"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
    • Changedwa_get_message1 field changed
      • addedOutput schema / properties / message / properties / sent_by
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "present on an outbound message an AI agent or an app sent through WhatsMCP: who asked for the send",
        +  "properties": {
        +    "id": {
        +      "description": "the agent's, the API key's or the OAuth app's id",
        +      "type": "string"
        +    },
        +    "kind": {
        +      "description": "agent (a hosted AI agent), api_key (an app on one of your API keys) or oauth_app (an app you connected over OAuth, such as Claude)",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "its name as it was when the message was sent",
        +      "type": "string"
        +    },
        +    "version": {
        +      "description": "an agent only: the number of the agent's version that wrote it",
        +      "type": "integer"
        +    },
        +    "via": {
        +      "description": "an app only: mcp or rest, the API it sent through",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "kind",
        +    "id"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
    • Changedwa_list_contacts5 fields changed
      • changedInput schema / properties / include_pictures / description
        Previous value: -"also return each contact's profile picture URL. This looks every contact on the page up on WhatsApp, so the page is capped at 10 and can take half a minute; leave it off for a fast listing"New value: +"WhatsApp only: also return each contact's profile picture URL. This looks every contact on the page up on WhatsApp, so the page is capped at 10 and can take half a minute; leave it off for a fast listing"
      • changedInput schema / properties / query / description
        Previous value: -"optional: only contacts whose name or number contains this; case-insensitive and ignores punctuation in numbers, so '+44 7700 900111' finds 447700900111. Omit to list everything"New value: +"optional: only contacts whose name or number (on Telegram also the username) contains this; case-insensitive and ignores punctuation in numbers, so '+44 7700 900111' finds 447700900111. Omit to list everything"
      • changedOutput schema / properties / contacts / items / properties / jid / description
        Previous value: -"WhatsApp's own identifier for this contact"New value: +"the network's own identifier for this contact; on a Telegram account pass this as to or chat to every other tool"
      • changedOutput schema / properties / contacts / items / properties / phone / description
        Previous value: -"the contact's number in international form — pass this to wa_send_message"New value: +"the contact's number in international form — on WhatsApp pass this to wa_send_message; on Telegram use jid instead"
      • addedOutput schema / properties / contacts / items / properties / username
        Added value: +{
        +  "description": "Telegram only: the contact's public username, without the @",
        +  "type": "string"
        +}
    • Changedwa_list_messages1 field changed
      • addedOutput schema / properties / messages / items / properties / sent_by
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "present on an outbound message an AI agent or an app sent through WhatsMCP: who asked for the send",
        +  "properties": {
        +    "id": {
        +      "description": "the agent's, the API key's or the OAuth app's id",
        +      "type": "string"
        +    },
        +    "kind": {
        +      "description": "agent (a hosted AI agent), api_key (an app on one of your API keys) or oauth_app (an app you connected over OAuth, such as Claude)",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "its name as it was when the message was sent",
        +      "type": "string"
        +    },
        +    "version": {
        +      "description": "an agent only: the number of the agent's version that wrote it",
        +      "type": "integer"
        +    },
        +    "via": {
        +      "description": "an app only: mcp or rest, the API it sent through",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "kind",
        +    "id"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
  2. 44 tool updates
    • Changedwa_ai_call_get1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_ai_call_hangup1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_ai_call_start1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_ai_list_calls1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_ai_list_presets1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_block_contact1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_create_group1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_create_template1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_delete_group1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_delete_message1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_delete_template1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_delete_webhook1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_edit_message1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_enable_webhook1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_follow_channel1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_get_chat2 fields changed
      • changedOutput schema / properties / account_notices / items / properties / status / description
        Previous value: -"why it is not live: starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"why it is not live: starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_get_group_invite_link1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_get_media1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_get_message2 fields changed
      • changedOutput schema / properties / account_notices / items / properties / status / description
        Previous value: -"why it is not live: starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"why it is not live: starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_get_plan1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_get_profile1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_join_group1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_leave_chat1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_blocked1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_calls1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_channels1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_contacts1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_group_members1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_groups1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_messages2 fields changed
      • changedOutput schema / properties / account_notices / items / properties / status / description
        Previous value: -"why it is not live: starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"why it is not live: starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_templates1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_load_history1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_pair_account1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_pair_status1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_react1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_remove_participants1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_report1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_send_message1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_set_presence1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_set_profile_photo1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_set_webhook1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_unpair_account1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_update_group1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_update_participants1 field changed
      • changedOutput schema / properties / refusal / properties / account_status / description
        Previous value: -"when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"when the number is not working: its status — starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
  3. 4 tool updates
    • Changedwa_get_chat1 field changed
      • changedOutput schema / properties / messages / items / properties / chat_kind / description
        Previous value: -"dm, group, channel or broadcast"New value: +"dm, group, channel or broadcast; a Telegram supergroup reads as channel"
    • Changedwa_get_message1 field changed
      • changedOutput schema / properties / message / properties / chat_kind / description
        Previous value: -"dm, group, channel or broadcast"New value: +"dm, group, channel or broadcast; a Telegram supergroup reads as channel"
    • Changedwa_list_messages1 field changed
      • changedOutput schema / properties / messages / items / properties / chat_kind / description
        Previous value: -"dm, group, channel or broadcast"New value: +"dm, group, channel or broadcast; a Telegram supergroup reads as channel"
    • Changedwa_send_message2 fields changed
      • changedInput schema / properties / force / description
        Previous value: -"set true to send a 1:1 message to a number that is NOT in this account's contacts; without it such a send is refused with reason recipient_not_contact so you do not message a stranger by accident. No effect on groups, channels, templates or Business (WABA) numbers"New value: +"set true to send a 1:1 message to a number that is NOT in this account's contacts; without it such a send is refused with reason recipient_not_contact so you do not message a stranger by accident. No effect on groups, channels, templates, Business (WABA) numbers or Telegram accounts"
      • changedInput schema / properties / to / description
        Previous value: -"the recipient. WhatsApp: a phone number in international form (digits only, e.g. 447700900123) for a 1:1 chat, or a full group/channel JID (…@g.us for a group, …@newsletter for a channel). Telegram (an account whose backend is telegram): the chat id exactly as wa_list_messages reports it (<id>@telegram; a group is -<id>@telegram, a channel or supergroup -100<id>@telegram) to reply, or to start a conversation an @username, a t.me/<name> link or a phone in +E.164 form — never a bare number, which could be a phone or a user id"New value: +"the recipient. WhatsApp: a phone number in international form (digits only, e.g. 447700900123) for a 1:1 chat, or a full group/channel JID (…@g.us for a group, …@newsletter for a channel). Telegram (an account whose backend is telegram): the chat id exactly as wa_list_messages reports it (<id>@telegram; a group is -<id>@telegram, a channel or supergroup -100<id>@telegram) to reply, or to start a conversation an @username or a t.me/<name> link. A phone in +E.164 form works only if it is already in this account's Telegram contacts, and force does not change that. Never a bare number, which could be a phone or a user id"
  4. 4 tool updates
    • Changedwa_ai_call_start1 field changed
      • addedInput schema / properties / force
        Added value: +{
        +  "description": "set true to call a number that is NOT in this line's contacts; without it such a call is refused with reason recipient_not_contact so you do not cold-call a stranger by accident. No effect when the calling line is a Business (WABA) number",
        +  "type": "boolean"
        +}
    • Changedwa_get_chat5 fields changed
      • changedOutput schema / properties / messages / items / properties / kind / description
        Previous value: -"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"New value: +"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media; a reaction carries its emoji as text and names its target message in reacted_to_message_id, while a reply carries quoted_message_id for the message it quotes"
      • addedOutput schema / properties / messages / items / properties / quoted_message_id
        Added value: +{
        +  "description": "present on a reply: the message_id of the message this one quotes; pass it to wa_get_message to read what was quoted",
        +  "type": "string"
        +}
      • addedOutput schema / properties / messages / items / properties / quoted_sender
        Added value: +{
        +  "description": "who wrote the quoted message: a phone number when known, otherwise a JID",
        +  "type": "string"
        +}
      • addedOutput schema / properties / messages / items / properties / reacted_to_message_id
        Added value: +{
        +  "description": "present on a kind=reaction message: the message_id this reaction is about; the emoji itself is in text",
        +  "type": "string"
        +}
      • changedOutput schema / properties / messages / items / properties / text / description
        Previous value: -"the message body"New value: +"the message body; for a kind=reaction message this is the emoji"
    • Changedwa_get_message5 fields changed
      • changedOutput schema / properties / message / properties / kind / description
        Previous value: -"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"New value: +"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media; a reaction carries its emoji as text and names its target message in reacted_to_message_id, while a reply carries quoted_message_id for the message it quotes"
      • addedOutput schema / properties / message / properties / quoted_message_id
        Added value: +{
        +  "description": "present on a reply: the message_id of the message this one quotes; pass it to wa_get_message to read what was quoted",
        +  "type": "string"
        +}
      • addedOutput schema / properties / message / properties / quoted_sender
        Added value: +{
        +  "description": "who wrote the quoted message: a phone number when known, otherwise a JID",
        +  "type": "string"
        +}
      • addedOutput schema / properties / message / properties / reacted_to_message_id
        Added value: +{
        +  "description": "present on a kind=reaction message: the message_id this reaction is about; the emoji itself is in text",
        +  "type": "string"
        +}
      • changedOutput schema / properties / message / properties / text / description
        Previous value: -"the message body"New value: +"the message body; for a kind=reaction message this is the emoji"
    • Changedwa_list_messages5 fields changed
      • changedOutput schema / properties / messages / items / properties / kind / description
        Previous value: -"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"New value: +"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media; a reaction carries its emoji as text and names its target message in reacted_to_message_id, while a reply carries quoted_message_id for the message it quotes"
      • addedOutput schema / properties / messages / items / properties / quoted_message_id
        Added value: +{
        +  "description": "present on a reply: the message_id of the message this one quotes; pass it to wa_get_message to read what was quoted",
        +  "type": "string"
        +}
      • addedOutput schema / properties / messages / items / properties / quoted_sender
        Added value: +{
        +  "description": "who wrote the quoted message: a phone number when known, otherwise a JID",
        +  "type": "string"
        +}
      • addedOutput schema / properties / messages / items / properties / reacted_to_message_id
        Added value: +{
        +  "description": "present on a kind=reaction message: the message_id this reaction is about; the emoji itself is in text",
        +  "type": "string"
        +}
      • changedOutput schema / properties / messages / items / properties / text / description
        Previous value: -"the message body"New value: +"the message body; for a kind=reaction message this is the emoji"
  5. 1 tool update
    • Changedwa_send_message1 field changed
      • addedInput schema / properties / force
        Added value: +{
        +  "description": "set true to send a 1:1 message to a number that is NOT in this account's contacts; without it such a send is refused with reason recipient_not_contact so you do not message a stranger by accident. No effect on groups, channels, templates or Business (WABA) numbers",
        +  "type": "boolean"
        +}
  6. 1 tool update
    • Changedwa_set_webhook2 fields changed
      • addedOutput schema / properties / test_delivery
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / warning
        Added value: +{
        +  "type": "string"
        +}
  7. 1 tool update
    • Changedwa_list_accounts1 field changed
      • addedOutput schema / properties / accounts / items / properties / last_inbound_at
        Added value: +{
        +  "description": "the time this number last received a live (non-history) message, across all chats, RFC3339; absent when none is stored. Read it alongside status: a live number that is receiving has a recent last_inbound_at, so an empty message window with a recent last_inbound_at is a quiet conversation, not a missed one",
        +  "type": "string"
        +}
  8. 44 tool updates
    • Changedwa_ai_call_get1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_ai_call_hangup1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_ai_call_start1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_ai_list_calls1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_ai_list_presets1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_block_contact1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_create_group1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_create_template1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_delete_group1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_delete_message3 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account, as returned by wa_list_accounts"New value: +"the account, as returned by wa_list_accounts; omit it when the workspace has only one account"
      • changedInput schema / required
        Previous value: -[
        -  "account_id",
        -  "chat",
        -  "message_id"
        -]New value: +[
        +  "chat",
        +  "message_id"
        +]
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_delete_template1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_delete_webhook1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_edit_message3 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account, as returned by wa_list_accounts"New value: +"the account, as returned by wa_list_accounts; omit it when the workspace has only one account"
      • changedInput schema / required
        Previous value: -[
        -  "account_id",
        -  "chat",
        -  "message_id",
        -  "text"
        -]New value: +[
        +  "chat",
        +  "message_id",
        +  "text"
        +]
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_enable_webhook1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_follow_channel1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_get_chat6 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account whose conversation to read, from wa_list_accounts"New value: +"the account whose conversation to read, from wa_list_accounts; omit it when the workspace has only one account"
      • addedInput schema / properties / include_media_urls
        Added value: +{
        +  "description": "also return attachment.media_url on each available attachment — a time-limited (1h) signed URL to GET the bytes with plain HTTP instead of a wa_get_media call; off by default",
        +  "type": "boolean"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "account_id"
        -]
      • changedOutput schema / properties / messages / items / properties / attachment / description
        Previous value: -"present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media"New value: +"present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media, or pass include_media_urls on the read to get a direct media_url"
      • addedOutput schema / properties / messages / items / properties / attachment / properties / media_url
        Added value: +{
        +  "description": "a time-limited (1h) signed URL to GET the attachment's bytes, present only when the read passed include_media_urls and the attachment is available; an expired link is refused — read again for a fresh one",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_get_group_invite_link1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_get_media3 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account that received the message, from wa_list_accounts"New value: +"the account that received the message, from wa_list_accounts; omit it when the workspace has only one account"
      • changedInput schema / required
        Previous value: -[
        -  "account_id",
        -  "message_id"
        -]New value: +[
        +  "message_id"
        +]
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_get_message6 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account the message belongs to, from wa_list_accounts"New value: +"the account the message belongs to, from wa_list_accounts; omit it when the workspace has only one account"
      • addedInput schema / properties / include_media_urls
        Added value: +{
        +  "description": "also return attachment.media_url when the message carries an available attachment — a time-limited (1h) signed URL to GET the bytes with plain HTTP instead of a wa_get_media call; off by default",
        +  "type": "boolean"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "account_id"
        -]
      • changedOutput schema / properties / message / properties / attachment / description
        Previous value: -"present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media"New value: +"present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media, or pass include_media_urls on the read to get a direct media_url"
      • addedOutput schema / properties / message / properties / attachment / properties / media_url
        Added value: +{
        +  "description": "a time-limited (1h) signed URL to GET the attachment's bytes, present only when the read passed include_media_urls and the attachment is available; an expired link is refused — read again for a fresh one",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_get_plan1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_get_profile3 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"which of your accounts to ask from, from wa_list_accounts"New value: +"which of your accounts to ask from, from wa_list_accounts; omit it when the workspace has only one account"
      • removedInput schema / required
        Removed value: -[
        -  "account_id"
        -]
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_join_group1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_leave_chat1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_list_blocked1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_list_calls1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_list_channels1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_list_contacts1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_list_group_members1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_list_groups1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_list_messages4 fields changed
      • addedInput schema / properties / include_media_urls
        Added value: +{
        +  "description": "also return attachment.media_url on each available attachment — a time-limited (1h) signed URL to GET the bytes with plain HTTP instead of a wa_get_media call; off by default",
        +  "type": "boolean"
        +}
      • changedOutput schema / properties / messages / items / properties / attachment / description
        Previous value: -"present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media"New value: +"present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media, or pass include_media_urls on the read to get a direct media_url"
      • addedOutput schema / properties / messages / items / properties / attachment / properties / media_url
        Added value: +{
        +  "description": "a time-limited (1h) signed URL to GET the attachment's bytes, present only when the read passed include_media_urls and the attachment is available; an expired link is refused — read again for a fresh one",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_list_templates1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_load_history3 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account, as returned by wa_list_accounts"New value: +"the account, as returned by wa_list_accounts; omit it when the workspace has only one account"
      • changedInput schema / required
        Previous value: -[
        -  "account_id",
        -  "chat"
        -]New value: +[
        +  "chat"
        +]
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_pair_account1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_pair_status1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_react3 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account, as returned by wa_list_accounts"New value: +"the account, as returned by wa_list_accounts; omit it when the workspace has only one account"
      • changedInput schema / required
        Previous value: -[
        -  "account_id",
        -  "chat",
        -  "message_id",
        -  "reaction"
        -]New value: +[
        +  "chat",
        +  "message_id",
        +  "reaction"
        +]
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_remove_participants1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_report1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_send_message3 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account to send from, as returned by wa_list_accounts"New value: +"the account to send from — the account_id on the message row you are replying to, or from wa_list_accounts; omit it when the workspace has only one account"
      • changedInput schema / required
        Previous value: -[
        -  "account_id",
        -  "to"
        -]New value: +[
        +  "to"
        +]
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_set_presence3 fields changed
      • changedInput schema / properties / account_id / description
        Previous value: -"the account, as returned by wa_list_accounts"New value: +"the account, as returned by wa_list_accounts; omit it when the workspace has only one account"
      • changedInput schema / required
        Previous value: -[
        -  "account_id",
        -  "state"
        -]New value: +[
        +  "state"
        +]
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_set_profile_photo1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_set_webhook1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_unpair_account1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_update_group1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
    • Changedwa_update_participants1 field changed
      • addedOutput schema / properties / refusal / properties / candidates
        Added value: +{
        +  "description": "on an account_ambiguous refusal: the accounts to choose from — retry with one of these as account_id",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the id to retry with as account_id",
        +        "type": "string"
        +      },
        +      "name": {
        +        "description": "the account's WhatsApp display name",
        +        "type": "string"
        +      },
        +      "phone": {
        +        "description": "the account's phone number, E.164",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "whether the number works right now — live, connecting, or why not, as wa_list_accounts reports it",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
  9. 8 tool updates
    • Changedwa_get_chat2 fields changed
      • changedOutput schema / properties / messages / items / properties / chat / description
        Previous value: -"the conversation JID; pass it to wa_send_message's 'to' to reply here — a group is …@g.us, a channel …@newsletter"New value: +"the conversation JID; pass it to wa_send_message's 'to' to reply here — a group is …@g.us, a channel …@newsletter; on a Telegram account a Telegram id: <id>@telegram for a user, -<id>@telegram for a basic group, -100<id>@telegram for a channel or supergroup"
      • changedOutput schema / properties / messages / items / properties / peer / description
        Previous value: -"the other party's phone number (for a group/channel this is the individual SENDER; use chat to reply)"New value: +"the other party's phone number (for a group/channel this is the individual SENDER; use chat to reply); on a Telegram account the other party's Telegram id, <id>@telegram"
    • Changedwa_get_media1 field changed
      • changedInput schema / properties / message_id / description
        Previous value: -"the WhatsApp message id whose attachment to fetch, from wa_list_messages"New value: +"the message id whose attachment to fetch, from wa_list_messages (a WhatsApp message id, or on a Telegram account one of the form <chat>_<n>)"
    • Changedwa_get_message2 fields changed
      • changedOutput schema / properties / message / properties / chat / description
        Previous value: -"the conversation JID; pass it to wa_send_message's 'to' to reply here — a group is …@g.us, a channel …@newsletter"New value: +"the conversation JID; pass it to wa_send_message's 'to' to reply here — a group is …@g.us, a channel …@newsletter; on a Telegram account a Telegram id: <id>@telegram for a user, -<id>@telegram for a basic group, -100<id>@telegram for a channel or supergroup"
      • changedOutput schema / properties / message / properties / peer / description
        Previous value: -"the other party's phone number (for a group/channel this is the individual SENDER; use chat to reply)"New value: +"the other party's phone number (for a group/channel this is the individual SENDER; use chat to reply); on a Telegram account the other party's Telegram id, <id>@telegram"
    • Changedwa_list_accounts4 fields changed
      • changedOutput schema / properties / accounts / description
        Previous value: -"the WhatsApp accounts this API key can use"New value: +"the accounts this API key can use — WhatsApp numbers and Telegram accounts; each says which in backend"
      • changedOutput schema / properties / accounts / items / properties / backend / description
        Previous value: -"the account's backend: official (WhatsApp Business API) or personal (a linked device)"New value: +"the account's backend: official (WhatsApp Business API), personal (a WhatsApp linked device) or telegram (a Telegram user account; its chats and senders are Telegram ids of the form <id>@telegram)"
      • changedOutput schema / properties / accounts / items / properties / push_name / description
        Previous value: -"the display name WhatsApp shows for this account"New value: +"the display name WhatsApp (or Telegram) shows for this account"
      • changedOutput schema / properties / accounts / items / properties / status / description
        Previous value: -"whether the number is actually working: live, connecting, starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked"New value: +"whether the number is actually working: live, connecting, starting, not_running, whatsapp_down (telegram_down for a Telegram account), suspended, pairing, unlinked or locked"
    • Changedwa_list_messages3 fields changed
      • changedInput schema / properties / chat / description
        Previous value: -"only this conversation — a phone number or a group JID"New value: +"only this conversation — a phone number or a group JID, or on a Telegram account the chat's Telegram id (<id>@telegram)"
      • changedOutput schema / properties / messages / items / properties / chat / description
        Previous value: -"the conversation JID; pass it to wa_send_message's 'to' to reply here — a group is …@g.us, a channel …@newsletter"New value: +"the conversation JID; pass it to wa_send_message's 'to' to reply here — a group is …@g.us, a channel …@newsletter; on a Telegram account a Telegram id: <id>@telegram for a user, -<id>@telegram for a basic group, -100<id>@telegram for a channel or supergroup"
      • changedOutput schema / properties / messages / items / properties / peer / description
        Previous value: -"the other party's phone number (for a group/channel this is the individual SENDER; use chat to reply)"New value: +"the other party's phone number (for a group/channel this is the individual SENDER; use chat to reply); on a Telegram account the other party's Telegram id, <id>@telegram"
    • Changedwa_pair_account5 fields changed
      • changedInput schema / properties / import_history / description
        Previous value: -"import the phone's recent message history (about two months) as read-only history for this pairing; omit to use the workspace default"New value: +"import the phone's recent message history (about two months) as read-only history for this pairing; omit to use the workspace default (WhatsApp only)"
      • addedInput schema / properties / network
        Added value: +{
        +  "description": "the messaging network of the account to link: whatsapp (the default) or telegram. A Telegram account links by QR only: the user scans it from Telegram → Settings → Devices → Link Desktop Device. Telegram accounts must be enabled for the workspace, or the call is refused",
        +  "type": "string"
        +}
      • changedInput schema / properties / phone / description
        Previous value: -"link by phone-number code instead of a QR: the number to link, in international format with its country code (for example +52 998 123 4567). WhatsApp on that phone is asked to accept an 8-character code, returned as pair_code. Use it when the user has only the one phone that runs WhatsApp and cannot scan a QR from another screen"New value: +"link by phone-number code instead of a QR: the number to link, in international format with its country code (for example +52 998 123 4567). WhatsApp on that phone is asked to accept an 8-character code, returned as pair_code. Use it when the user has only the one phone that runs WhatsApp and cannot scan a QR from another screen (WhatsApp only)"
      • addedOutput schema / properties / network
        Added value: +{
        +  "description": "the messaging network the pairing links on: whatsapp or telegram",
        +  "type": "string"
        +}
      • changedOutput schema / properties / state / description
        Previous value: -"starting, qr, code, paired or failed"New value: +"starting, qr, code, password_needed (a Telegram account with two-step verification: the user must enter their cloud password on the console's pairing page — never ask for it here), paired or failed"
    • Changedwa_pair_status2 fields changed
      • addedOutput schema / properties / network
        Added value: +{
        +  "description": "the messaging network the pairing links on: whatsapp or telegram",
        +  "type": "string"
        +}
      • changedOutput schema / properties / state / description
        Previous value: -"starting, qr, code, paired or failed"New value: +"starting, qr, code, password_needed (a Telegram account with two-step verification: the user must enter their cloud password on the console's pairing page — never ask for it here), paired or failed"
    • Changedwa_send_message1 field changed
      • changedInput schema / properties / to / description
        Previous value: -"the recipient: a phone number in international form (digits only, e.g. 447700900123) for a 1:1 chat, or a full group/channel JID (…@g.us for a group, …@newsletter for a channel)"New value: +"the recipient. WhatsApp: a phone number in international form (digits only, e.g. 447700900123) for a 1:1 chat, or a full group/channel JID (…@g.us for a group, …@newsletter for a channel). Telegram (an account whose backend is telegram): the chat id exactly as wa_list_messages reports it (<id>@telegram; a group is -<id>@telegram, a channel or supergroup -100<id>@telegram) to reply, or to start a conversation an @username, a t.me/<name> link or a phone in +E.164 form — never a bare number, which could be a phone or a user id"
  10. 1 tool update
    • Changedwa_list_messages1 field changed
      • addedOutput schema / properties / hint
        Added value: +{
        +  "description": "present when the read found nothing new: wait before polling again",
        +  "type": "string"
        +}
  11. 2 tool updates
    • Changedwa_get_media4 fields changed
      • changedOutput schema / properties / media_base64 / description
        Previous value: -"base64 of the attachment, present when status is ok"New value: +"base64 of the attachment, present for a small attachment"
      • addedOutput schema / properties / media_url
        Added value: +{
        +  "description": "a time-limited (1h) URL to GET a large attachment's bytes, present instead of media_base64 when the attachment is over the inline cap",
        +  "type": "string"
        +}
      • addedOutput schema / properties / size
        Added value: +{
        +  "description": "the attachment size in bytes",
        +  "type": "integer"
        +}
      • changedOutput schema / properties / status / description
        Previous value: -"ok (media returned) or refused"New value: +"ok (media returned, inline or as a url) or refused"
    • Changedwa_set_webhook1 field changed
      • changedInput schema / properties / events / description
        Previous value: -"which events to receive; defaults to message.inbound"New value: +"which events to receive — any of message.inbound, message.outbound, message.status, account.connected, account.disconnected, account.unlinked, account.blocked, call.completed, call.missed; defaults to message.inbound"
  12. 1 tool update
    • Changedwa_pair_account1 field changed
      • changedInput schema / properties / phone / description
        Previous value: -"link by phone-number code instead of a QR: the number to link, in international format with its country code (for example +52 998 123 4567). WhatsApp on that phone is asked to accept an 8-character code, returned as pair_code. Use it when the user has only that phone and cannot scan a QR"New value: +"link by phone-number code instead of a QR: the number to link, in international format with its country code (for example +52 998 123 4567). WhatsApp on that phone is asked to accept an 8-character code, returned as pair_code. Use it when the user has only the one phone that runs WhatsApp and cannot scan a QR from another screen"
  13. 3 tool updates
    • Changedwa_get_chat1 field changed
      • changedOutput schema / properties / messages / items / properties / kind / description
        Previous value: -"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite or template; other is a type this server does not classify. text carries a body, and so do image/video/document captions and template text; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"New value: +"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"
    • Changedwa_get_message1 field changed
      • changedOutput schema / properties / message / properties / kind / description
        Previous value: -"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite or template; other is a type this server does not classify. text carries a body, and so do image/video/document captions and template text; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"New value: +"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"
    • Changedwa_list_messages1 field changed
      • changedOutput schema / properties / messages / items / properties / kind / description
        Previous value: -"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite or template; other is a type this server does not classify. text carries a body, and so do image/video/document captions and template text; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"New value: +"what the message is: text, image, video, audio, document, sticker, reaction, location, live_location, contact, poll, poll_vote, video_note, album, event, comment, pin, group_invite, template or call_permission; other is a type this server does not classify. text carries a body, and so do image/video/document captions, template text and a call_permission request or answer; an image, video, audio, document or sticker attachment can be fetched with wa_get_media"
  14. 45 tool updates
    • Changedwa_ai_call_get3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_ai_call_hangup3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_ai_call_start3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_ai_list_calls3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_ai_list_presets3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_block_contact3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_create_group3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_create_template4 fields changed
      • addedInput schema / properties / call_permission
        Added value: +{
        +  "description": "true asks the customer to allow the business to call them (WhatsApp's call permission request); MARKETING or UTILITY only, and no buttons",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_delete_group3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_delete_message3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_delete_template3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_delete_webhook3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_edit_message3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_enable_webhook3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_follow_channel3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_get_chat4 fields changed
      • addedOutput schema / properties / account_notices
        Added value: +{
        +  "description": "present when a number this read covers is not working: new messages are not arriving on it; says why and what to do",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the account this notice is about",
        +        "type": "string"
        +      },
        +      "message": {
        +        "description": "what is wrong and what to do; tell the user",
        +        "type": "string"
        +      },
        +      "since": {
        +        "description": "when it stopped working, RFC3339, when known",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "why it is not live: starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +        "type": "string"
        +      },
        +      "status_reason": {
        +        "description": "the detail, e.g. no_egress, no_plan, stopped",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id",
        +      "status",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_get_group_invite_link3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_get_media3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_get_message4 fields changed
      • addedOutput schema / properties / account_notices
        Added value: +{
        +  "description": "present when a number this read covers is not working: new messages are not arriving on it; says why and what to do",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the account this notice is about",
        +        "type": "string"
        +      },
        +      "message": {
        +        "description": "what is wrong and what to do; tell the user",
        +        "type": "string"
        +      },
        +      "since": {
        +        "description": "when it stopped working, RFC3339, when known",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "why it is not live: starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +        "type": "string"
        +      },
        +      "status_reason": {
        +        "description": "the detail, e.g. no_egress, no_plan, stopped",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id",
        +      "status",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_get_plan3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_get_profile3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_join_group3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_leave_chat3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_list_accounts4 fields changed
      • addedOutput schema / properties / accounts / items / properties / status
        Added value: +{
        +  "description": "whether the number is actually working: live, connecting, starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / accounts / items / properties / status_reason
        Added value: +{
        +  "description": "the detail when it is not live, e.g. no_egress, no_plan, stopped",
        +  "type": "string"
        +}
      • addedOutput schema / properties / accounts / items / properties / status_since
        Added value: +{
        +  "description": "when it stopped working, RFC3339, when known",
        +  "type": "string"
        +}
      • addedOutput schema / properties / accounts / items / properties / what_to_do
        Added value: +{
        +  "description": "what is wrong and what to do, when it is not live; tell the user",
        +  "type": "string"
        +}
    • Changedwa_list_blocked3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_list_calls3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_list_channels3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_list_contacts3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_list_group_members3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_list_groups3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_list_messages4 fields changed
      • addedOutput schema / properties / account_notices
        Added value: +{
        +  "description": "present when a number this read covers is not working: new messages are not arriving on it; says why and what to do",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "account_id": {
        +        "description": "the account this notice is about",
        +        "type": "string"
        +      },
        +      "message": {
        +        "description": "what is wrong and what to do; tell the user",
        +        "type": "string"
        +      },
        +      "since": {
        +        "description": "when it stopped working, RFC3339, when known",
        +        "type": "string"
        +      },
        +      "status": {
        +        "description": "why it is not live: starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +        "type": "string"
        +      },
        +      "status_reason": {
        +        "description": "the detail, e.g. no_egress, no_plan, stopped",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "account_id",
        +      "status",
        +      "message"
        +    ],
        +    "type": "object"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_list_templates4 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
      • addedOutput schema / properties / templates / items / properties / call_permission
        Added value: +{
        +  "description": "true when the template asks the customer to allow the business to call them (WhatsApp's call permission request)",
        +  "type": "boolean"
        +}
    • Changedwa_load_history3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_pair_account7 fields changed
      • addedInput schema / properties / phone
        Added value: +{
        +  "description": "link by phone-number code instead of a QR: the number to link, in international format with its country code (for example +52 998 123 4567). WhatsApp on that phone is asked to accept an 8-character code, returned as pair_code. Use it when the user has only that phone and cannot scan a QR",
        +  "type": "string"
        +}
      • addedOutput schema / properties / expires_at
        Added value: +{
        +  "description": "when pair_code stops working, RFC 3339 (phone-number pairing only)",
        +  "type": "string"
        +}
      • addedOutput schema / properties / pair_code
        Added value: +{
        +  "description": "the 8-character code the user types on their phone (phone-number pairing only)",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
      • changedOutput schema / properties / state / description
        Previous value: -"starting, qr, paired or failed"New value: +"starting, qr, code, paired or failed"
    • Changedwa_pair_status6 fields changed
      • addedOutput schema / properties / expires_at
        Added value: +{
        +  "description": "when pair_code stops working, RFC 3339 (phone-number pairing only)",
        +  "type": "string"
        +}
      • addedOutput schema / properties / pair_code
        Added value: +{
        +  "description": "the 8-character code the user types on their phone (phone-number pairing only)",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
      • changedOutput schema / properties / state / description
        Previous value: -"starting, qr, paired or failed"New value: +"starting, qr, code, paired or failed"
    • Changedwa_react3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_remove_participants3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Addedwa_report
    • Changedwa_send_message3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_set_presence3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_set_profile_photo3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_set_webhook3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_unpair_account3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_update_group3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
    • Changedwa_update_participants3 fields changed
      • addedOutput schema / properties / refusal / properties / account_status
        Added value: +{
        +  "description": "when the number is not working: its status — starting, not_running, whatsapp_down, suspended, pairing, unlinked or locked",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / account_status_reason
        Added value: +{
        +  "description": "the detail of account_status, e.g. no_egress, stopped, no_plan",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal / properties / since
        Added value: +{
        +  "description": "when the number stopped working, RFC3339, when known",
        +  "type": "string"
        +}
  15. 3 tool updates
    • Changedwa_get_chat3 fields changed
      • addedInput schema / properties / since
        Added value: +{
        +  "description": "only messages sent at or after this time: RFC3339 with a zone (2026-10-01T09:00:00+03:00) or a date (2026-10-01 = midnight UTC); omit for no lower bound",
        +  "type": "string"
        +}
      • addedInput schema / properties / until
        Added value: +{
        +  "description": "only messages sent BEFORE this time — exclusive, so all of 1 October is since 2026-10-01 until 2026-10-02; same formats as since; omit for no upper bound",
        +  "type": "string"
        +}
      • addedOutput schema / properties / has_more
        Added value: +{
        +  "description": "true when older messages match than were returned; page them with wa_list_messages(account_id, chat, since, until, include_history=true)",
        +  "type": "boolean"
        +}
    • Changedwa_list_calls2 fields changed
      • addedInput schema / properties / since
        Added value: +{
        +  "description": "only calls at or after this time: RFC3339 with a zone (2026-10-01T09:00:00+03:00) or a date (2026-10-01 = midnight UTC); omit for no lower bound",
        +  "type": "string"
        +}
      • addedInput schema / properties / until
        Added value: +{
        +  "description": "only calls BEFORE this time — exclusive, so all of 1 October is since 2026-10-01 until 2026-10-02; same formats as since; omit for no upper bound",
        +  "type": "string"
        +}
    • Changedwa_list_messages6 fields changed
      • addedInput schema / properties / account_id
        Added value: +{
        +  "description": "only this account's messages, from wa_list_accounts; omit for every account",
        +  "type": "string"
        +}
      • addedInput schema / properties / chat
        Added value: +{
        +  "description": "only this conversation — a phone number or a group JID",
        +  "type": "string"
        +}
      • addedInput schema / properties / include_history
        Added value: +{
        +  "description": "also return imported history (pairing sync and wa_load_history); off by default. With it on, a page is in storage order rather than time order — sort by at",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / since
        Added value: +{
        +  "description": "only messages sent at or after this time: RFC3339 with a zone (2026-10-01T09:00:00+03:00) or a date (2026-10-01 = midnight UTC); omit for no lower bound",
        +  "type": "string"
        +}
      • addedInput schema / properties / until
        Added value: +{
        +  "description": "only messages sent BEFORE this time — exclusive, so all of 1 October is since 2026-10-01 until 2026-10-02; same formats as since; omit for no upper bound",
        +  "type": "string"
        +}
      • addedOutput schema / properties / refusal
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "present only when the request was declined; next_cursor is then your after_cursor, unchanged",
        +  "properties": {
        +    "message": {
        +      "description": "a human-readable explanation",
        +      "type": "string"
        +    },
        +    "reason": {
        +      "description": "why the call was declined",
        +      "type": "string"
        +    },
        +    "refused": {
        +      "description": "true when the call was declined rather than performed",
        +      "type": "boolean"
        +    },
        +    "retry_after_seconds": {
        +      "description": "seconds to wait before retrying; absent or 0 means retrying will not help",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "refused",
        +    "reason",
        +    "message"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
  16. 5 tool updates
    • Changedwa_get_chat3 fields changed
      • addedOutput schema / properties / account
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "the account this conversation was read from",
        +  "properties": {
        +    "account_id": {
        +      "description": "the id to pass to other wa_ tools",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "the account's WhatsApp display name",
        +      "type": "string"
        +    },
        +    "phone": {
        +      "description": "the account's phone number, E.164",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "account_id"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • addedOutput schema / properties / messages / items / properties / account_name
        Added value: +{
        +  "description": "the WhatsApp display name of that account",
        +  "type": "string"
        +}
      • addedOutput schema / properties / messages / items / properties / account_phone
        Added value: +{
        +  "description": "the phone number of your account this message was sent from or received on, E.164",
        +  "type": "string"
        +}
    • Changedwa_get_message2 fields changed
      • addedOutput schema / properties / message / properties / account_name
        Added value: +{
        +  "description": "the WhatsApp display name of that account",
        +  "type": "string"
        +}
      • addedOutput schema / properties / message / properties / account_phone
        Added value: +{
        +  "description": "the phone number of your account this message was sent from or received on, E.164",
        +  "type": "string"
        +}
    • Changedwa_list_calls2 fields changed
      • addedOutput schema / properties / calls / items / properties / account_name
        Added value: +{
        +  "description": "the WhatsApp display name of that account",
        +  "type": "string"
        +}
      • addedOutput schema / properties / calls / items / properties / account_phone
        Added value: +{
        +  "description": "the phone number of your account that placed or received this call, E.164",
        +  "type": "string"
        +}
    • Changedwa_list_messages2 fields changed
      • addedOutput schema / properties / messages / items / properties / account_name
        Added value: +{
        +  "description": "the WhatsApp display name of that account",
        +  "type": "string"
        +}
      • addedOutput schema / properties / messages / items / properties / account_phone
        Added value: +{
        +  "description": "the phone number of your account this message was sent from or received on, E.164",
        +  "type": "string"
        +}
    • Changedwa_list_templates4 fields changed
      • addedOutput schema / properties / templates / items / properties / body
        Added value: +{
        +  "description": "the template's body text as Meta holds it, with its {{n}} variables",
        +  "type": "string"
        +}
      • addedOutput schema / properties / templates / items / properties / buttons
        Added value: +{
        +  "description": "one line per button, e.g. 'Quick reply: Yes' or 'Link: Shop → https://…'",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": [
        +    "null",
        +    "array"
        +  ]
        +}
      • addedOutput schema / properties / templates / items / properties / footer
        Added value: +{
        +  "description": "the template's footer, if any",
        +  "type": "string"
        +}
      • addedOutput schema / properties / templates / items / properties / header
        Added value: +{
        +  "description": "the template's text header, if any",
        +  "type": "string"
        +}
  17. 1 tool update
    • Changedwa_list_templates2 fields changed
      • changedOutput schema / properties / templates / description
        Previous value: -"the approved message templates, with the name/language/variables to pass to wa_send_message"New value: +"every message template with its review status; only APPROVED ones can be sent, with the name/language/variables to pass to wa_send_message"
      • addedOutput schema / properties / templates / items / properties / rejected_reason
        Added value: +{
        +  "description": "for a REJECTED template, Meta's reason code (e.g. INVALID_FORMAT, TAG_CONTENT_MISMATCH); fix the template and create it again under a new name",
        +  "type": "string"
        +}
  18. 3 tool updates
    • Changedwa_get_chat3 fields changed
      • addedOutput schema / properties / messages / items / properties / attachment
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media",
        +  "properties": {
        +    "available": {
        +      "description": "true when the file should be fetchable with wa_get_media(account_id, message_id) — a live received attachment; false for history and for files you sent, which are not kept",
        +      "type": "boolean"
        +    },
        +    "file_name": {
        +      "description": "documents only: the file name the sender gave it",
        +      "type": "string"
        +    },
        +    "mime": {
        +      "description": "the attachment's mime type as the sender declared it, e.g. image/jpeg or application/pdf; empty for a message stored before this was recorded",
        +      "type": "string"
        +    },
        +    "size": {
        +      "description": "the attachment's size in bytes as the sender declared it; 0 when unknown",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "available"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • addedOutput schema / properties / messages / items / properties / received_at
        Added value: +{
        +  "description": "when this server received and stored the message, RFC3339; later than at for a message delivered late or loaded as history",
        +  "type": "string"
        +}
      • addedOutput schema / properties / messages / items / properties / sender_name
        Added value: +{
        +  "description": "who wrote the message, by name: for inbound the sender's name as saved in this account's contacts, or else the name they chose for themselves; for outbound this account's own WhatsApp name. Empty when no name is known",
        +  "type": "string"
        +}
    • Changedwa_get_message3 fields changed
      • addedOutput schema / properties / message / properties / attachment
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media",
        +  "properties": {
        +    "available": {
        +      "description": "true when the file should be fetchable with wa_get_media(account_id, message_id) — a live received attachment; false for history and for files you sent, which are not kept",
        +      "type": "boolean"
        +    },
        +    "file_name": {
        +      "description": "documents only: the file name the sender gave it",
        +      "type": "string"
        +    },
        +    "mime": {
        +      "description": "the attachment's mime type as the sender declared it, e.g. image/jpeg or application/pdf; empty for a message stored before this was recorded",
        +      "type": "string"
        +    },
        +    "size": {
        +      "description": "the attachment's size in bytes as the sender declared it; 0 when unknown",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "available"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • addedOutput schema / properties / message / properties / received_at
        Added value: +{
        +  "description": "when this server received and stored the message, RFC3339; later than at for a message delivered late or loaded as history",
        +  "type": "string"
        +}
      • addedOutput schema / properties / message / properties / sender_name
        Added value: +{
        +  "description": "who wrote the message, by name: for inbound the sender's name as saved in this account's contacts, or else the name they chose for themselves; for outbound this account's own WhatsApp name. Empty when no name is known",
        +  "type": "string"
        +}
    • Changedwa_list_messages3 fields changed
      • addedOutput schema / properties / messages / items / properties / attachment
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "present on an image, video, audio, document or sticker message: the file's mime type, size and name; fetch the bytes with wa_get_media",
        +  "properties": {
        +    "available": {
        +      "description": "true when the file should be fetchable with wa_get_media(account_id, message_id) — a live received attachment; false for history and for files you sent, which are not kept",
        +      "type": "boolean"
        +    },
        +    "file_name": {
        +      "description": "documents only: the file name the sender gave it",
        +      "type": "string"
        +    },
        +    "mime": {
        +      "description": "the attachment's mime type as the sender declared it, e.g. image/jpeg or application/pdf; empty for a message stored before this was recorded",
        +      "type": "string"
        +    },
        +    "size": {
        +      "description": "the attachment's size in bytes as the sender declared it; 0 when unknown",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "available"
        +  ],
        +  "type": [
        +    "null",
        +    "object"
        +  ]
        +}
      • addedOutput schema / properties / messages / items / properties / received_at
        Added value: +{
        +  "description": "when this server received and stored the message, RFC3339; later than at for a message delivered late or loaded as history",
        +  "type": "string"
        +}
      • addedOutput schema / properties / messages / items / properties / sender_name
        Added value: +{
        +  "description": "who wrote the message, by name: for inbound the sender's name as saved in this account's contacts, or else the name they chose for themselves; for outbound this account's own WhatsApp name. Empty when no name is known",
        +  "type": "string"
        +}

Publisher details

Operator
WhatMCP · Publisher source
Vendor relationship
First-party · Publisher source
Trust center
Unknown
Restrictions
Unknown

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Connects AI assistants to the official Meta WhatsApp Cloud API for managing conversations and sending various message types through natural language. It provides tools for media management, template messages, and real-time webhook processing without the risk of account bans.
    18
    12 npm
    25
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    WhatsApp for your AI agent, sent from your own number. Link by QR, then connect over MCP. Source-available (Elastic License 2.0).
    4
    24
    56,835 npm
    5
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    WhatsApp notifications and human-in-the-loop for AI agents. Text "join" to get an API key, then send messages, ask questions with tap-to-answer buttons, and read replies - no Meta account, no templates, no dashboard.
    5
    1
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources