Base URL
/api/v1. HTTPS only.
Keys
Two ways to prove who you are, depending on the endpoint.Token in the path
/api/v1/responses/{token} carries its own key. Send no Authorization header. It expires after 45 minutes.Bearer key
Everything else takes
Authorization: Bearer mac_live_…. One key per chatbot, and it never expires. Writing Pages also needs Pages write turned on for the key.Endpoints
Messages
Files
Pages
Reads see every Page in the workspace. Writes only touch Pages owned by the key’s own bot.
Rules
- JSON in, JSON out. Send
Content-Type: application/json, except on the file upload endpoints, which takemultipart/form-data. - snake_case everywhere.
- Times are ISO 8601 in UTC (
2026-07-17T03:15:12.398Z). - Ids are plain strings. Do not try to read meaning into them.
- Success includes
"ok": true. Failure includes"ok": falseand anerrorobject. TheGEThistory endpoint is the one exception: it returns the data directly. - Error codes on the Pages endpoints are always UPPER_SNAKE (
INVALID_API_KEY,RATE_LIMITED). The messages and files endpoints mix cases (invalid_api_key,PAYLOAD_TOO_LARGE). Match on the exact string.
Errors
One shape everywhere:issues list that points at each problem:
Rate limits
A
429 tells you how long to wait: retry_after on the messages and files endpoints, retry_after_seconds on the Pages endpoints.
Sizes
Safe retries
Give a message amid, and sending it again updates instead of duplicating. Build the mid from the event’s event_id, and your whole integration becomes safe to retry. That matters, because Make, n8n, and Zapier all retry.
See Updating messages.
Pages are retry-safe by design: PUT /pages/by-slug/{slug} creates on the first call and updates after that, and content identical to the current version is skipped rather than stored twice.
