---
title: "Kaption for developers"
canonical: "https://kaptionai.com/developers/"
lang: "en"
---

# Kaption for developers

Canonical: https://kaptionai.com/developers/

Kaption exposes WhatsApp to AI apps and agents through one MCP server.

## Endpoint

- MCP (Streamable HTTP, JSON-RPC 2.0): https://mcp.kaptionai.com/mcp
- SSE, for older clients: https://mcp.kaptionai.com/sse
- The tools run in the Kaption extension (WhatsApp Web in Chrome or Edge) or the Kaption desktop app on the user's own computer. They only work while Kaption is open.

## Authentication

- OAuth 2.1, PKCE (S256), dynamic client registration.
- One scope: `kaption:access`.
- Users sign in with their phone number and a code sent to them on WhatsApp, then choose how long the connection lasts (while in use, ending after 90 days idle; 1 year; or until they disconnect).
- Access tokens expire after one hour.
- Every call, including `initialize` and `tools/list`, needs a bearer token. Without one the server returns HTTP 401 with `WWW-Authenticate: Bearer resource_metadata="https://mcp.kaptionai.com/.well-known/oauth-protected-resource/mcp", scope="kaption:access"`.

## Machine-readable documents

- Protected resource metadata (RFC 9728): https://mcp.kaptionai.com/.well-known/oauth-protected-resource/mcp
- Authorization server metadata: https://mcp.kaptionai.com/.well-known/oauth-authorization-server
- OpenAPI 3.1: https://kaptionai.com/openapi.json
- MCP server card (MCP Registry server.json format): https://kaptionai.com/.well-known/mcp.json
- API catalog (RFC 9727): https://kaptionai.com/.well-known/api-catalog
- Site guide for agents: https://kaptionai.com/llms.txt
- Any page on kaptionai.com returns Markdown when requested with `Accept: text/markdown`.

## Tools (cloud server)

query, list_contacts, get_contact, get_contact_groups, list_groups, get_group, export_contacts, download_media, get_analytics, summarize_conversation, manage_chat, manage_reminders, manage_lists, manage_labels, manage_notes, manage_scheduled_messages, send_message, call_recordings.

`call_recordings` reads call recordings and transcripts made with the Kaption extension in Chrome or Edge. Recordings made in the desktop app are not included yet.

From Kaption 0.94, `send_message` works unless the user has turned off "Let assistants send messages from this computer" in Kaption for that WhatsApp account; an assistant cannot change that setting, and it should still confirm the text and the recipient with the user. It queues a message, with at most one attachment of 8 MiB, to an existing person chat or eligible group for the earliest permitted delivery, and "queued" is not proof of delivery. Sending from the computer is limited to 8 messages an hour and 20 a day, plus group limits and delays, and the computer and WhatsApp must stay open. With the setting off, the AI can leave a draft, or schedule one message (up to 800 characters) to one person. Chats the user locked in WhatsApp are never visible.

## Local server

For clients that run local MCP servers (Node.js 18 or newer):

```bash
npx -y @kaptionai/mcp-extension@latest
```

Claude Code:

```bash
claude mcp add whatsapp -- npx -y @kaptionai/mcp-extension@latest
```

## Errors

Every error the server shapes itself is an RFC 9457 problem document (`Content-Type: application/problem+json`). Branch on `code`; `detail` is for people. Errors are never HTML.

```json
{
  "type": "https://kaptionai.com/developers/#errors-rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Too many requests. Try again later.",
  "code": "rate_limited",
  "policy": "otp-send-account",
  "retry_after": 1800
}
```

Inside the MCP transport (`/mcp` and `/sse`), protocol errors are JSON-RPC error objects, as the MCP specification requires, and a failed tool call is a result with `isError: true`. The 401 for a missing or bad token is a problem document that keeps the RFC 6750 `error` and `resource_metadata` fields, with the `WWW-Authenticate` header above.

| Status | Codes |
|---|---|
| 400 | `bad_request`, `invalid_json`, `invalid_input`, `invalid_content_type`, `invalid_phone`, `missing_credentials`, `missing_parameters`, `invalid_account_id`, `invalid_connection_id`, `invalid_authorization_request`, `invalid_oauth_state`, `invalid_session`, `otp_invalid`, `otp_expired`, `otp_attempts_exceeded`, `verification_expired`, `connect_code_malformed`, `connect_code_expired` |
| 401 | `unauthorized`, `authentication_required`, `invalid_token`, `missing_bearer_token`, `invalid_credentials` |
| 403 | `forbidden` |
| 404 | `not_found`, `not_configured`, `reviewer_not_configured` |
| 405 | `method_not_allowed` |
| 406 | `not_acceptable` |
| 409 | `conflict` |
| 410 | `gone` |
| 413 | `payload_too_large` |
| 415 | `unsupported_media_type` |
| 422 | `unprocessable_content` |
| 426 | `upgrade_required` |
| 429 | `rate_limited` |
| 500 | `internal_error`, `otp_send_failed`, `authorization_failed` |
| 501 | `not_implemented` |
| 502 | `bad_gateway`, `upstream_error`, `handshake_unavailable` |
| 503 | `service_unavailable` |
| 504 | `gateway_timeout` |

## Rate limits

Throttled requests get `429` with `Retry-After` (seconds) and `code: "rate_limited"`. Counted responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds) for the policy closest to running out; `RateLimit-Policy` lists every policy that applies, e.g. `50;w=3600, 100;w=3600`.

| Policy | Limit | Window | Counted on |
|---|---|---|---|
| `otp-send-account` | 50 | 60 min (fixed) | /authorize/send-otp, /ext-auth/send-otp |
| `otp-send-ip` | 100 | 60 min (fixed) | /authorize/send-otp, /ext-auth/send-otp, /authorize/resend-otp |
| `otp-resend-account` | 3 | 10 min (fixed) | /authorize/resend-otp |
| `connect-code-redeem-ip` | 20 | 10 min (restarts on each attempt) | /connect/remember, /authorize/connect-code |
| `connect-code-start-account` | 10 | 60 min (restarts on each attempt) | /ext/connect-code/start |
| `reviewer-login-ip` | 10 | 15 min (restarts on each attempt) | /authorize/reviewer-login |

Tool calls use credits from a monthly allowance set by the Kaption plan (calendar month, UTC): unlimited for the first 60 days; after that a plan is needed: Lifetime local AI 50; Pro 250; Business 500 for its 2 numbers plus 250 per extra number; Business Agent included with fair use (https://kaptionai.com/pricing/). A call uses 0 to 5 credits by tool and action, and a failed call gives them back. Once they are used up, the call is answered with an error that links to pricing; the connection stays open, and it is not an HTTP 429. Listing tools, connecting and failed calls do not count. Bulk or unsolicited messaging is still against the terms, and access can be suspended to protect the service.

## Deprecation and sunset policy

- Breaking changes to the MCP endpoint, its HTTP contract or a tool are announced on this page at least 90 days before they take effect.
- Affected responses then carry a `Deprecation` header (RFC 9745), a `Sunset` header (RFC 8594) with the date it stops working, and a `Link` with `rel="deprecation"` to the migration notes.
- Adding tools, optional fields or error codes is not a breaking change.

## Source and security

- Relay source code (BUSL-1.1): https://github.com/Kaption-AI/mcp-extension-remote. Every deploy is signed and recorded in a public log.
- npm package: https://www.npmjs.com/package/@kaptionai/mcp-extension
- Rate limits are listed above. Bulk or unsolicited messaging is against the terms: https://kaptionai.com/terms/
- Report vulnerabilities privately to security@kaptionai.com.
