The WhatsApp Cloud API, typed end to end.
Composable TypeScript packages for bots, webhooks, and the Graph API. Run the whole SDK in your browser — no credentials, no install, no network.
import { GraphClient, GraphRateLimitError, PhoneNumberClient } from "@wats/graph";
import { createMockTransport } from "@wats/graph/testing";
const mock = createMockTransport();
const graphClient = new GraphClient({
accessToken: "demo-token",
apiVersion: "v25.0",
baseUrl: "https://graph.facebook.com",
transport: mock.transport,
});
const phone = new PhoneNumberClient({ graphClient, phoneNumberId: "1234567890" });
try {
await phone.sendText({ to: "15550001111", text: "hello from WATS" });
} catch (err) {
if (err instanceof GraphRateLimitError) console.log(err.retryAfter);
}
console.log(JSON.stringify(mock.requests, null, 2));{
"method": "POST",
"url": "https://graph.facebook.com/v25.0/1234567890/messages",
"headers": {
"content-type": "application/json",
"authorization": "Bearer demo-token"
},
"body": {
"messaging_product": "whatsapp",
"to": "15550001111",
"type": "text",
"text": {
"body": "hello from WATS"
}
}
}Typed end to end
Discriminated unions for every message and webhook shape. Narrow Meta errors with instanceof, not string matching. Construction-time validation catches bad payloads before the wire.
Webhook runtime included
Signature verification, envelope normalization, a typed router with filters and listeners. One facade from inbound event to typed handler.
Groups API
Create groups, manage participants, send to groups — same typed client as everything else.
See exactly what hits the wire. Before anything does.
Every WATS client runs against a Transport seam. Swap in MockTransport and the SDK captures the exact Graph request — method, path, payload — without a network in sight. Develop a complete bot before you have credentials.
Alpha, in the useful sense.
The core paths — sending, webhooks, templates, errors — are tested and have carried real traffic. The wider endpoint surface is typed and tested against the wire contract. The parity page tracks the status of each endpoint, so you can check yours before you build on it.