---
name: tawked
description: Integrate Tawked, the Saudi OTP verification and WhatsApp messaging API. Use when a project needs to send a one-time code to a Saudi mobile number and check it, or send WhatsApp template messages, and when reading or writing code that calls tawked.com/v1.
license: Proprietary. Free to use for building integrations with Tawked.
compatibility: Any agent that can make HTTPS requests. The interactive reference and MCP server are at https://docs.tawked.com.
metadata:
  vendor: Tawked
  docs: https://docs.tawked.com
  openapi: https://tawked.com/openapi.json
  mcp: https://docs.tawked.com/mcp
  llms-full: https://docs.tawked.com/llms-full.txt
---

# Tawked

Tawked verifies Saudi mobile numbers with a one-time code: one request sends the code, one request checks what the person typed. Approved applications can also send WhatsApp template messages through their own number. Prepaid credits, billed only per delivered code.

## Before writing code

1. Read the exact request and response shapes from the docs, never from memory. Fastest: the MCP server at `https://docs.tawked.com/mcp` (tools `search_tawked` and `query_docs_filesystem_tawked`), or fetch `https://docs.tawked.com/llms-full.txt`. Any page is Markdown with a `.md` suffix, for example `https://docs.tawked.com/errors.md`.
2. For generated clients, use the OpenAPI 3.1 document at `https://tawked.com/openapi.json`.
3. The API key comes from the Tawked dashboard (Applications, then Keys). Read it from an environment variable such as `TAWKED_KEY`. Never write a key into source, logs or client-side code.

## The two calls

Base URL `https://tawked.com`. Send the key as `Authorization: Bearer <key>` (or `x-api-key: <key>`). JSON in and out.

```http
POST /v1/verify/start
{ "to": "0551234567", "lang": "ar", "reference": "signup-8f1c2" }
-> 201 { "id": "...", "status": "pending", "expires_at": "..." }

POST /v1/verify/check
{ "id": "...", "code": "482913" }
-> 200 { "verified": true, "status": "verified" }
-> 200 { "verified": false, "status": "invalid_code", "attempts_remaining": 2 }
```

- `to` accepts any Saudi mobile format (`+9665…`, `9665…`, `009665…`, `05…`, `5…`). Anything else is `422 invalid_destination`.
- `lang` is Arabic unless it is exactly `en`.
- `check` answers `200` for every outcome. Branch on `verified` first, then on `status` (`verified`, `invalid_code`, `too_many_attempts`, `failed`, `expired`, `canceled`). Only an unknown id is `404 not_found`.
- The code is compared exactly as sent. Do not trim or normalise it on the server; do it in the input field.
- Also available on the same id: `GET /v1/verify/{id}` (state, no attempt consumed), `POST /v1/verify/{id}/resend` (new code, up to 3), `POST /v1/verify/{id}/cancel`.

## Rules that prevent bugs

- Send an `Idempotency-Key` header on every `start` (one key per business event, 1 to 128 printable ASCII). A replay returns the original `201` with `Idempotent-Replayed: true` and sends nothing. Retry a `502` or a network error with the same key.
- Match errors on the `error` string in the JSON body, never on the HTTP status alone. Two `429` codes (`too_many_requests` per key, `rate_limited` per destination) and several `403` codes mean different things. The full table is at `https://docs.tawked.com/errors`.
- Pass `client_ip` (the end user's address) on `start` so the per-IP protection guard can work. It is never inferred from the request.
- Use a `tk_test_` key until the application is approved. It sends real messages, only to numbers the account has proven it owns, with a `[TEST]` stamp, and is capped at 10 sends per application. There is no WhatsApp sandbox.
- Keep a `reference` (your order or session id, up to 64 characters) on `start`; it is echoed back and searchable in the dashboard.
- Rate limit: 120 requests per minute per key. Every response carries `X-Request-Id`; log it.

## Webhooks

Optional, configured per application: `verification.verified`, `verification.failed`, `verification.expired`, and `message.sent`, `message.delivered`, `message.read`, `message.failed` for WhatsApp. Verify `tawked-signature` as hex HMAC-SHA256 of `"{tawked-timestamp}.{raw body}"` with the webhook secret, over the raw body, before parsing. Answer `2xx` quickly; deliveries retry otherwise. Details: `https://docs.tawked.com/webhooks`.

## WhatsApp template messages

Only with a `tk_live_` key of an approved application that has connected its WhatsApp number in the dashboard. `GET /v1/whatsapp/templates` lists the templates and the placeholders each expects; `POST /v1/whatsapp/messages` with `to`, `template`, `lang`, `params` (and `header` or `buttons` when the template has them) answers `202` with an id; `GET /v1/whatsapp/messages/{id}` reads the status (`accepted`, `sent`, `delivered`, `read`, `failed`). One-time codes never go through this endpoint; authentication templates are refused. Details: `https://docs.tawked.com/whatsapp/messages`.

## Where things are

- Guides and interactive reference: `https://docs.tawked.com`
- Errors, every code: `https://docs.tawked.com/errors`
- OpenAPI: `https://tawked.com/openapi.json`
- Status: `https://tawked.com/en/status`
- Support: support@tawked.com
