Contact
Overview
WhatSetter API 2026-07
Section titled “WhatSetter API 2026-07”The WhatSetter public API lets you connect your CRM and tools to your
WhatSetter workspace: push leads into lists, read leads and conversations,
send WhatsApp messages through the anti-ban engine, manage campaigns,
and receive signed webhooks. An MCP server is also available for AI
agents at mcp.whatsetter.com. It uses the same API keys.
Authentication
Every request needs an API key, created from your WhatSetter dashboard (Settings → API) or by your account manager. Pass it as a Bearer token:
Authorization: Bearer ws_live_xxxxxxxxxxxxxxxxxxxx
A key belongs to one workspace (team) and carries scopes. Keep it secret. It is shown once at creation and can be revoked at any time.
Errors
All errors use one envelope:
{ "error": { "code": "validation_error", "message": "…" } }
| HTTP | code | meaning |
|---|---|---|
| 400 | validation_error | malformed URL encoding in the path (e.g. /leads/%ZZ) |
| 401 | missing_api_key / invalid_api_key | key absent, unknown or revoked |
| 403 | insufficient_scope | key lacks the required scope |
| 404 | not_found | resource doesn’t exist (or belongs to another workspace) |
| 422 | validation_error | bad parameter or body |
| 429 | rate_limited / quota_exceeded | slow down / a daily or per-workspace quota is reached |
| 500 | internal_error | our fault (or a feature not configured on this deployment), retry later |
| 502 | upstream_error / send_failed | a downstream engine (workflow, WhatsApp) refused or timed out |
| 503 | agent_disconnected | the campaign’s WhatsApp number is not available |
Endpoint-specific codes (lead_not_contacted, request_in_flight,
invalid_state, already_blocked, plan_limit_reached) are listed on
each operation.
Rate limits
Requests are limited per workspace (all keys combined), by plan:
| Plan | Requests / minute |
|---|---|
| Free | 60 |
| Starter | 120 |
| Business | 300 |
| Scale | 1000 |
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and
X-RateLimit-Reset. On 429 rate_limited, honor the Retry-After header.
(WhatsApp sending has its own separate daily anti-ban quota: see
POST /messages.)
Idempotency
POST /messages is retry-safe: pass an Idempotency-Key header (any unique
string ≤200 chars, e.g. a UUID per send intent). A key that already produced
a response replays it (with X-Idempotent-Replay: true) instead of sending
a second WhatsApp message. A retry fired while the first is still processing
gets 409 request_in_flight. If a send times out (502), retrying with the
SAME key is safe (it will never double-deliver); retrying WITHOUT a key may.
Always use an Idempotency-Key when sending.
Pagination
List endpoints return pagination.has_more and pagination.next_cursor.
Pass cursor=<next_cursor> to fetch the next page. limit is 1–100
(default 25). An invalid or expired cursor (its row was deleted) answers
422 validation_error on every paginated endpoint.
Authentication
Section titled “Authentication”bearerAuth
Section titled “bearerAuth”Authorization: Bearer ws_live_… is the recommended form. The same
key is also accepted in an X-Api-Key: ws_live_… header (for tools
that cannot set Authorization).
A key carries scopes; each endpoint names the one it needs. A key
missing the scope answers 403 insufficient_scope.
| Scope | Grants |
|---|---|
leads:read |
read leads and their notes |
leads:write |
update leads (status, tags, owner, next action, outcome), add notes, handoff / resume |
conversations:read |
inbox + message transcripts |
lists:read / lists:write |
contact lists + imports |
campaigns:read / campaigns:write |
campaign directory + pause / resume |
messages:send |
send a WhatsApp message, add an opt-in lead to a campaign |
bookings:read |
calls booked by the AI |
groups:read |
tracked WhatsApp groups |
webhooks:manage |
webhook subscriptions |
blocklist:manage |
read, add and remove blocked numbers / dial prefixes |
team:read |
list team members (id, name, role) to assign leads |
links:read |
read tracked links and their click stats |
Security scheme type: http
Bearer format: ws_live_…

