API reference
Overview
Conventions of the REST API: address, versions, authentication, error format, pagination, identifiers and dates.
Updated November 12, 2026View as Markdown
The full reference is generated from the API's real OpenAPI specification: it cannot drift from it. Each operation comes with a sample call (curl, Node.js, Python, PHP) and the real response recorded from the API.
Address and version#
https://YOUR-HOST/api/v1The major version is in the address (/v1). Changes that don't break integrations (new fields, new routes, new events) are added to /v1: ignore unknown fields in your responses. A breaking change would ship as a new version. See the changelog.
Authentication#
Authorization: Bearer <token>. There are two kinds of tokens: the console session (ses_…) and the API key (pk_test_…, pk_live_…). See Authentication and keys. Each operation states which one it requires and the scope needed. Key-based routes also accept the console session, with an X-Environment-Id header.
Request and response format#
- JSON bodies (
Content-Type: application/json), in UTF-8. - Identifiers: UUIDs, except Meta identifiers (
wabaId,phoneNumberIdwhen connecting), which are strings of digits. - Dates: ISO 8601, in UTC (
2026-11-12T06:09:17.388Z). - Unknown fields in a request are rejected (
400 validation_error), so a typo is caught quickly. - Resources belonging to another account or another environment answer
404, as if they didn't exist.
Errors#
All errors have the same format, whatever their origin:
{
"error": {
"code": "validation_error",
"message": "Invalid request: see details",
"details": ["email must be an email"],
"requestId": "req_0a1b2c3d-…"
}
}| Field | Description |
|---|---|
code | Stable identifier, to use in your code. |
message | Human-readable explanation, in French by default (English with Accept-Language: en). Do not parse its text. |
details | (validation) The list of fields at fault. |
requestId | Give it to support. Identical to the response's X-Request-Id header. |
Full list: Error codes.
Pagination#
Long lists are paginated by cursor, from newest to oldest.
{ "data": [ … ], "nextCursor": "MjAyNi0xMS0xMlQw…" }As long as nextCursor is not null, pass it in ?cursor= to get the next page. ?limit= sets the page size (1 to 100; 1 to 200 for logs). Never build a cursor yourself.
Request ID#
Every response carries an X-Request-Id header. You can provide your own (8 to 64 characters: letters, digits, ., _, -) to correlate your logs with ours. It appears in the request log.
Idempotency#
POST /messages accepts an Idempotency-Key header. See Reliability.
Calls from a browser#
The API is meant to be called from your server. Calls from a browser (CORS) are not allowed: an API key placed in a web page would be public.