The six safety classes, the prepare and confirm pattern, idempotency, approvals, and audit behaviour.
Safety and Approvals
Summary
The six safety classes, the prepare and confirm pattern, idempotency, approvals, and audit behaviour.
Prerequisites
- A Whats91 account
- A generated public API token
Related documentation
Every Whats91 MCP tool declares a safety class. The class is not decorative: it sets the tool annotations, audit severity, rate-limit class, and the default confirmation, preview, and approval behaviour. A client can read all of it from tools/list before deciding to call anything.
Safety Classes
The Approval and Preview columns below are the defaults a class implies. Individual tools override them in both directions, so treat the class as a guide and the per-tool metadata as the authority.
| Class | Tools | Approval | Preview | Retry policy | Audit |
|---|---|---|---|---|---|
| READ_ONLY | 69 | No | No | SAFE | INFO |
| DRAFT_WRITE | 17 | No | No | IDEMPOTENCY_REQUIRED | NOTICE |
| REVERSIBLE_WRITE | 23 | No | No | IDEMPOTENCY_REQUIRED | NOTICE |
| DESTRUCTIVE_WRITE | 15 | Yes | Yes | NO_AUTOMATIC_RETRY | WARNING |
| EXTERNAL_SIDE_EFFECT | 14 | Yes | Yes | PROVIDER_AWARE | WARNING |
| HIGH_IMPACT_EXECUTION | 13 | Yes | Yes | NO_AUTOMATIC_RETRY | CRITICAL |
| Class | Means |
|---|---|
| READ_ONLY | Reads data. Safe to call and safe to retry. |
| DRAFT_WRITE | Creates or edits a draft that has no external effect until it is published or sent. |
| REVERSIBLE_WRITE | Changes stored data in a way you can undo through another tool or the dashboard. |
| DESTRUCTIVE_WRITE | Removes or overwrites data in a way that is not trivially reversible. |
| EXTERNAL_SIDE_EFFECT | Reaches an external system such as Meta. The effect leaves Whats91 and cannot be recalled. |
| HIGH_IMPACT_EXECUTION | Both destructive and externally visible, typically at audience scale. The most restricted class. |
Note
A tool with no declared safety class is treated as HIGH_IMPACT_EXECUTION rather than as read-only. The platform fails closed.
Never Infer Approval From the Class
A tool can require approval that its class would not imply, and can waive approval that its class would imply. Read whats91/approvalRequired from the tool _meta returned by tools/list, and branch on that value rather than on the safety class.
| Tool | Class | Actual behaviour |
|---|---|---|
| whats91_blacklist_bulk_add_confirm | REVERSIBLE_WRITE | Requires approval and preview even though the class does not imply them. |
| whats91_chatbot_delete | DESTRUCTIVE_WRITE | Does not require approval; the guarded path is the separate prepare and confirm pair. |
| whats91_media_upload_prepare | EXTERNAL_SIDE_EFFECT | Does not require approval; it opens an upload session rather than publishing anything. |
| whats91_media_upload_bytes | EXTERNAL_SIDE_EFFECT | Does not require approval; bytes are staged until the upload is completed. |
| whats91_media_upload_complete | EXTERNAL_SIDE_EFFECT | Does not require approval; it finalises an already-authorised upload session. |
Prepare and Confirm
High-risk operations are split into two calls. Prepare computes the effect server-side and returns a one-time confirmation token; the second call executes exactly that computed effect. The model never gets to describe an effect in its own words and then have that description executed.
- Call the prepare tool with an idempotency key. It validates the target, computes a server-side preview, and returns a confirmation token.
- Show the preview to the person responsible for the action.
- Call the matching confirm tool with the token to execute the previewed effect.
- If the underlying draft changed between prepare and confirm, the token no longer matches and confirm is rejected.
{
"jsonrpc": "2.0",
"id": 10,
"method": "tools/call",
"params": {
"name": "whats91_campaign_execution_prepare",
"arguments": {
"setup_uid": "setup_abc12345",
"campaign_uid": "cmp_abc123",
"idempotency_key": "acme-campaign-2026-08-12-001"
}
}
}Warning
Never treat a prepare result as the action having happened. Prepare has no external effect. Only the second call executes.
Most pairs are named _prepare and _confirm. Two flows use a different second step, so match on the prepare tool rather than assuming the suffix.
| Prepare tool | Second step | Notes |
|---|---|---|
| whats91_<operation>_prepare | whats91_<operation>_confirm | The standard pair, used by 20 of the 22 prepare tools. |
| whats91_contact_book_archive_prepare | whats91_contact_book_archive | The executing tool keeps the plain name. |
| whats91_media_upload_prepare | whats91_media_upload_bytes, then whats91_media_upload_complete | A three-step upload: open a session, stage bytes, then finalise. Poll whats91_media_upload_status_get for progress. |
Idempotency
Every non-read class expects idempotency. Write tools take an idempotency_key: a caller-generated stable key, 8 to 200 characters from letters, digits, dot, underscore, colon, and hyphen. Replaying the same key replays the same result rather than performing the operation twice.
- Derive the key from something stable in your own system, not from a timestamp or random value regenerated on retry.
- SAFE retry policy means the tool can be retried freely.
- IDEMPOTENCY_REQUIRED means retry only with the same idempotency key.
- PROVIDER_AWARE means the outcome depends on an external provider; reconcile before retrying.
- NO_AUTOMATIC_RETRY means never retry automatically. Surface the failure to a human.
Approvals
Approval-required tools are gated by the customer approval path in addition to OAuth scope. Before executing, the platform checks operational readiness and reports whether the approval path is available. When approvals are not configured, an approval-required tool reports that it cannot be attempted instead of silently running.
{
"operational_capability": {
"can_attempt": true,
"approval_required": true
}
}Note
Message sending has its own customer policy. When the policy is set to require approval, message-sending tools are only attemptable while the approval path is available.
Entitlements and Consent
Tools also declare the Whats91 entitlements they need, such as mcp_platform, campaign_builder, or campaign_send, and whether customer consent is required. A scope grant does not bypass a missing subscription, an expired plan, or an inactive add-on.
| Error code | Meaning |
|---|---|
| MCP_FEATURE_DISABLED | The capability is not enabled for the account. |
| MCP_SUBSCRIPTION_REQUIRED | An active Whats91 subscription is required. |
| MCP_SUBSCRIPTION_EXPIRED | The subscription has expired. Renew before retrying. |
| MCP_ADDON_ACCESS_REQUIRED | The required add-on is not active for the account. |
Rate Limits
| Limit | Default | Counted by |
|---|---|---|
| MCP server requests | 120 / 60 seconds | Connection |
| MCP runtime per user | 120 / 60 seconds | Tenant |
| Authorization endpoint | 10 / 60 seconds | Client IP |
| Token and revoke endpoints | 60 / 60 seconds | Client and IP |
| Per tool class (READ, WRITE, BULK_WRITE, EXTERNAL_SIDE_EFFECT, HIGH_IMPACT) | 120 / 60 seconds each | Tenant and class |
Note
Tool class limits are configured independently, so a burst of reads cannot exhaust the budget for high-impact executions. All values are operator-configurable defaults.
Related Documentation
MCP
Connect an AI assistant to Whats91 through the Model Context Protocol and give it safe, scoped access to your WhatsApp workspace.
Connect and Authorize
Register an OAuth 2.1 client, complete the PKCE authorization flow, and obtain a scoped Whats91 MCP access token.
Protocol
The JSON-RPC methods the Whats91 MCP endpoint implements, protocol negotiation, and transport rules.
Scopes
Every Whats91 MCP OAuth scope, what it unlocks, and how to choose a minimal set.