Skip to content

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.

  • 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.

Pass the key as a Bearer token. The X-Api-Key header is accepted too.

Terminal window
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.

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.

  • 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:send only 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.
  1. In Settings, then API & MCP, click Create a key with the same scopes as the old one.
  2. Put the new key in your integration and check it with GET /me.
  3. 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.

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.

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.

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.