WhatsApp HTTP API v1

Overview

A multi-tenant WhatsApp gateway. Each client can register one or more devices (phone numbers). Messages, reactions, receipts, and other events are forwarded to a per-client webhook URL.

All requests must be authenticated. There are two key tiers:

Authentication

Pass your API key in every request as an HTTP header:

x-api-key: <your-key>
Client keys are only accepted on routes scoped to their own :clientId. Attempting to access another client's data returns 401.

Base URL

https://wa.tachles.dev

All endpoints are prefixed with /api. Responses are JSON in the shape:

{ "success": true,  "data": { ... } }           // ok
{ "success": false, "error": { "code": "...", "message": "..." } }  // error

Client Keys

POST/api/clients/:clientId/key

Issue a new API key. Requires master key. Returns plaintext once — store it immediately, it cannot be retrieved again. Optional body: {"ttlDays": 90} (max 365).

POST/api/clients/:clientId/key/rotate

Rotate the key. Supply the current client key (or master key) in x-api-key. Old key is invalidated immediately. Optional body: {"ttlDays": 90}.

DELETE/api/clients/:clientId/key

Revoke the key immediately. Requires master key.

Client Config

GET/api/clients/:clientId/config

Read current config (webhook URL, event toggles, device limit). Key hash is never exposed — response shows key.hasKey, key.expiresAt, key.lastUsedAt.

PUT/api/clients/:clientId/config

Partial update. Send only the fields you want to change. Null-able fields (webhookUrl, webhookApiKey) accept null to revert to the global default.

{
  "webhookUrl": "https://yourapp.com/hooks/whatsapp",
  "webhookApiKey": "secret",
  "events": { "receipts": false, "presenceUpdates": false },
  "maxDevices": 3
}
DELETE/api/clients/:clientId/config

Reset to defaults.

Devices

GET/api/clients/:clientId/devices

List all devices for a client with their current status.

POST/api/clients/:clientId/devices

Register a new device. Body: {"deviceId": "my-phone"}. Returns QR code to scan.

GET/api/clients/:clientId/devices/:deviceId/qr

Fetch the current QR code (base64 PNG) for a device in QR_READY state.

DELETE/api/clients/:clientId/devices/:deviceId

Disconnect and remove a device.

Messages

POST/api/clients/:clientId/devices/:deviceId/send/text

Send a text message. Body: {"to": "972501234567", "text": "Hello"}.

POST/api/clients/:clientId/devices/:deviceId/send/image

Send an image. Body: {"to": "...", "url": "https://...", "caption": "..."}.

POST/api/clients/:clientId/devices/:deviceId/send/document

Send a file. Body: {"to": "...", "url": "https://...", "fileName": "report.pdf"}.

POST/api/clients/:clientId/devices/:deviceId/send/reaction

React to a message. Body: {"to": "...", "messageId": "...", "emoji": "👍"}.

Webhook Events

When an event occurs, a POST is sent to the client's webhookUrl with x-api-key set to webhookApiKey. The payload is always:

{
  "event": "message" | "reaction" | "receipt" | "presence_update" | "group_update" | "group_participants_update" | "call",
  "clientId": "...",
  "deviceId": "...",
  "data": { /* event-specific fields */ }
}

Toggle individual event types per-client via PUT /configevents.

Contacts & Chats

GET/api/clients/:clientId/devices/:deviceId/contacts

List contacts.

GET/api/clients/:clientId/devices/:deviceId/chats

List recent chats.

GET/api/clients/:clientId/devices/:deviceId/chats/:chatId/messages

Retrieve message history for a chat.

Status & Admin

GET/api/status

Public health check — no auth required.

GET/admin

Live dashboard — device statuses, queue metrics, per-client view. Requires master key (prompted in browser). Open dashboard ↗