HTTP API
API overview · WhatsApp API reference · messaging REST API · OpenAPI messaging APIAuthentication, pagination, errors and versioning for the Unified Messaging API.
This reference documents every endpoint of the Flow Messaging HTTP API, generated from its OpenAPI 3.1 spec.
curl https://api.flow.engineer/v0/app \ -H "Authorization: Bearer fk_test_..." \ -H "Flow-Version: 2026-11-01"Basics
Section titled “Basics”| Base URL | https://api.flow.engineer |
| Authentication | Authorization: Bearer fk_test_... or fk_live_... (test and live mode); never in the query string. No key yet: POST /v0/sandbox/keys needs none and returns a test key (keys and sign-in). In a browser, the live stream takes the key as a WebSocket subprotocol (Events and webhooks) |
| Version | Paths start with /v0 (API V0; /v1 is kept for 1.0). Flow-Version: 2026-11-01 (versioning) |
| Bodies | JSON (Content-Type: application/json), except POST /v0/files (multipart) |
| Sends | One endpoint per message kind: POST /v0/conversations/{conversation_id}/basic, /buttons, /list, … Each page opens with the channels it works on (message kinds) |
| Retries | Idempotency-Key on every POST, one per call (idempotency) |
| Spec | openapi.yaml |
Errors
Section titled “Errors”Errors share one shape. Switch on error.type, a closed list; never parse message.
{ "error": { "type": "outside_window", "channel": "whatsapp", "message": "Last message from the contact was 31h ago; WhatsApp allows only templates now.", "hint": "Send a template instead: POST /v0/conversations/{conversation_id}/template.", "doc_url": "https://api.flow.engineer/docs/errors/outside_window", "conversation": "conv_01JB8ZC3K5M7P9R1T3V5X7Z9B1" }}| Status | type |
|---|---|
| 400 | invalid_request |
| 401 | authentication |
| 403 | permission |
| 404 | not_found |
| 409 | idempotency_conflict, outside_window |
| 422 | unsupported_content, file_blocked |
| 429 | new_contact_limit, sender_throttled, rate_limited |
| 501 | not_implemented |
| 502 | channel_error |
| 500, 503 | api_error |
Every error carries hint, one sentence saying what to change; for a 422 unsupported_content it says what to send instead, param names what was refused and channel the conversation’s channel. Errors that clear by themselves carry retry_after in seconds; every error carries request_id; quote it when asking for help.
Pagination
Section titled “Pagination”Lists take limit (1 to 100, default 20) and after or before, set to the ID of an item you already have, and answer { "data": [...], "has_more": true }. The event log (GET /v0/events) is oldest first, so after moves forward in time; every other list is newest first.
Events
Section titled “Events”The reference lists GET /v0/events, the live stream (GET /v0/stream, a WebSocket) and the webhook delivery Flow sends to your endpoint. See Events and webhooks.
Thanks, we read every comment.