WhatsApp Gateway
API referenceChannels

Create a channel (newsletter)

Create a WhatsApp **channel** (newsletter) owned by this session, returning its newly minted JID. **Not implemented in v1.** This endpoint is wired but the underlying WhatsApp operation is not yet built, so it **always responds `501` with `not_implemented`** — no channel is created and nothing is persisted. The request body shape below documents the eventual contract; today it is accepted but ignored. **Authorization:** requires the `send` capability; callers lacking it get `403` (`forbidden`). Requests without a valid principal get `401`. **When implemented**, this will be a write that creates a brand-new channel on the WhatsApp network; it is **not** idempotent (each successful call would create a distinct channel) and on success returns `201` with the channel's `jid`. **Errors:** `403` `forbidden` (missing `send`), `404` `not_found` (session unknown), `501` `not_implemented` (current behavior), and, once built, `400` `validation_error` for a missing/invalid `name`.

POST
/api/v1/sessions/{session}/channels

Authorization

AuthorizationBearer <token>

Send Authorization: Bearer <token>. The router accepts two kinds of token and tries each in turn: a frontend-minted login JWT (verified against the frontend JWKS; the person's org + role are read from it), or an api-key for a script/service (carrying a fixed set of gateway permissions). The bearerFormat: JWT label describes the person-login case.

In: header

Path Parameters

session*string

The WhatsApp session id — one attached WhatsApp number — that will own the new channel. The session must exist and be connected.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

description?string

Optional free-text description shown on the channel profile.

name?string

Display name of the channel (newsletter). Optional on the wire; the service validates it and returns a validation_error (400) if it is missing or invalid.

Response Body

application/json

application/json

curl -X POST "https://example.com/api/v1/sessions/01HX.../channels" \  -H "Content-Type: application/json" \  -d '{}'
{  "jid": "string"}
{  "error": {    "code": "not_found",    "details": {      "property1": null,      "property2": null    },    "message": "session not found"  }}

Stop a session POST

Disconnects a session from WhatsApp **without** unlinking the device. Requires the `manage` capability. The attached number stays paired, so you can `:start` it again later without re-pairing. To unlink the device entirely, use `:logout` instead. **Idempotency.** Stopping an already-stopped session is a harmless no-op. The response returns the refreshed session so you can see its new status. **Errors.** `not_found` (404) — no such session in your organization. `unauthorized` (401) / `forbidden` (403) — credential / capability failures. Returns **200** with the refreshed session.

List stored channel messages GET

Return a page of **stored** messages for the channel identified by `jid` on this session, newest-first. This reads from the gateway's own message store — it returns what the gateway has already received and persisted for the channel, not a live fetch from WhatsApp. A channel the session has never received posts from yields an empty page. **Pagination:** use `limit` (1–200, default 50) and `cursor`. Omit `cursor` for the first page; read `nextCursor` from the response and pass it back to fetch the next page. The cursor is opaque — do not parse it. An empty `nextCursor` means the last page has been reached. **Authorization:** requires the `send` capability (`403` `forbidden` otherwise; `401` without a valid principal). This is a safe, side-effect-free read. **Errors:** `403` `forbidden` (missing `send`), `404` `not_found` (session or channel unknown).