Authentication and permissions
Every request to the API and every MCP session is authenticated with an API key. This page explains what a key is, what it can do, and the limits that apply to it.
API keys
Section titled “API keys”- Format:
ws_live_followed by 40 hexadecimal characters. - A key belongs to the workspace, not to a person. It is created in Settings, then API & MCP, by an owner or an admin.
- It is shown once, right after creation. WhatSetter only stores a fingerprint, so nobody can read it back later.
- You can revoke it at any time with Revoke, then Confirm?. The dashboard confirms: Key revoked. Effective within a minute. Revoking cuts the REST API and the MCP server at the same time.
Send the key
Section titled “Send the key”Pass the key as a Bearer token. The X-Api-Key header is accepted too.
curl https://app.whatsetter.com/api/v1/me \ -H "Authorization: Bearer ws_live_…"Without a key you get 401 missing_api_key. With an unknown or revoked key you get 401 invalid_api_key.
Scopes
Section titled “Scopes”When you create a key you choose its Permissions: Full access (every scope, including sending messages) or Custom (pick exactly what this key can do). A key without the right scope gets 403 insufficient_scope, and the message names the missing scope.
| Scope | What it unlocks | Endpoints |
|---|---|---|
leads:read |
Read leads and their notes | GET /leads, GET /leads/{id}, GET /leads/{id}/notes |
leads:write |
Update status, tags, owner, next action and deal outcome; hand a conversation to a human and give it back; add notes | PATCH /leads/{id}, POST /leads/{id}/handoff, POST /leads/{id}/resume, POST /leads/{id}/notes |
conversations:read |
Inbox and full message history | GET /conversations, GET /conversations/{leadId}/messages |
lists:read |
List your contact lists | GET /lists |
lists:write |
Create lists and import contacts | POST /lists, POST /lists/{id}/leads |
campaigns:read |
List campaigns | GET /campaigns |
campaigns:write |
Pause and resume campaigns | POST /campaigns/{id}/pause, POST /campaigns/{id}/resume |
messages:send |
Send a message to a contacted lead; add an opt-in lead to a campaign (this sends their first message) | POST /messages, POST /campaigns/{id}/leads |
bookings:read |
Meetings booked by the agent | GET /bookings |
groups:read |
Tracked WhatsApp groups: details, members, messages, join and leave events | GET /groups, GET /groups/{id}, GET /groups/{id}/members, GET /groups/{id}/messages, GET /groups/{id}/events |
webhooks:manage |
Create, list, test and delete webhook subscriptions | GET /webhooks, POST /webhooks, DELETE /webhooks/{id}, POST /webhooks/{id}/test |
blocklist:manage |
Read, add and remove blocked numbers and dial prefixes | GET /blocked-contacts, POST /blocked-contacts, DELETE /blocked-contacts/{id} |
team:read |
List the members of the workspace (id, name, role), to assign leads | GET /team/members |
links:read |
Read tracked links and their click stats | GET /links, GET /links/{id} |
GET /me needs no scope: any valid key can call it.
Least privilege
Section titled “Least privilege”- One key per integration (CRM, Zapier, a script, an AI assistant). Revoking one does not break the others, and the dashboard shows when each was last used.
- A dashboard or a report needs read scopes only. Grant
messages:sendonly to the integration that really sends messages. - Keys given to an AI assistant through the MCP server deserve the same care: the assistant can only do what the key allows.
Rotate a key
Section titled “Rotate a key”- In Settings, then API & MCP, click Create a key with the same scopes as the old one.
- Put the new key in your integration and check it with
GET /me. - Click Revoke on the old key, then Confirm?. It stops working within a minute.
Rotate right away if you suspect a leak: a key that was pasted in a chat, a ticket or a public repository.
One key for the API and the MCP server
Section titled “One key for the API and the MCP server”The MCP server does not have its own accounts. Every tool call is a call to the REST API with your key, so the scopes, the rate limits and the anti-ban rules below apply exactly the same way. Revoke the key and the assistant loses access too.
Rate limits
Section titled “Rate limits”Requests are counted per workspace, per minute, all keys combined. The limit depends on your plan:
| Plan | Requests per minute |
|---|---|
| Free | 60 |
| Starter | 120 |
| Business | 300 |
| Scale | 1000 |
Every response carries three headers:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Your plan’s limit for the current window. |
X-RateLimit-Remaining |
Requests left in the window. |
X-RateLimit-Reset |
When the window resets, ISO 8601. |
Past the limit you get 429 rate_limited with a Retry-After header in seconds. Wait that long, then retry.
Message sends have a separate daily quota per WhatsApp number, reported in the X-Quota-* headers. See Errors, limits and idempotency.
Workspace isolation
Section titled “Workspace isolation”A key only sees the workspace it belongs to. If you request an id that exists but belongs to another workspace, the API answers 404 not_found, the same as for an id that does not exist. It never answers 403, so a foreign id cannot be told apart from an unknown one.

