Base URL
https://api.flowella.io/v1/messages. Use it even where the app shows an address ending in /api/v1, such as API base URL in the Developer hub.
Requests to the app host,
https://app.flowella.io/api/v1/..., are permanently redirected (308) to https://api.flowella.io/v1/.... Many HTTP clients drop the Authorization header when they follow a redirect to another host, so the redirected request can fail with 401. Call https://api.flowella.io/v1 directly.Authentication
Send a bearer token in theAuthorization header of every request:
Use an API key for your own scripts and integrations. Use an OAuth app when other Flowella organisations install your integration.
Check your credentials
Call the ping endpoint to confirm that a key or token works:200 OK response means you are authenticated. organizationId is your organisation’s numeric ID:
401 response has the code UNAUTHORIZED and one of these messages: Missing bearer token, Invalid or expired API key, Invalid or expired access token or Unsupported bearer token.
Scopes
Each endpoint needs a scope. API keys created in the app have every scope. OAuth access tokens have only the scopes granted at authorisation.GET /v1/ping and GET /v1/rate-limits need no scope. GET /v1/capabilities (scope account:read) lists the scopes your token has.
A request without the scope it needs returns 403 with the code INSUFFICIENT_SCOPE. details.required lists the missing scopes:
Errors
Errors use the same envelope.requestId identifies the request when you contact support, and details holds extra information, such as validation issues, when there is any:
The
error.code value is stable, so your code can rely on it. The error.message text is for people and may change.
Rate limits
Each API key and each OAuth access token has its own limit on requests per minute. Flowella counts requests in fixed one-minute windows that start on the minute (UTC). Responses to requests that pass the authentication and scope checks include these headers:
When you go over the limit, Flowella returns
429 with the code RATE_LIMITED and a Retry-After header with the number of seconds to wait. GET /v1/rate-limits returns your limit, remaining and reset values as JSON.
For large sends, use POST /v1/templates/send, which takes up to 50,000 recipients in one request. The request also accepts an optional throttlePerHour field, a whole number from 1 to 100,000, but it doesn’t pace sends at the moment, so don’t rely on it. To spread a large send over time, split the recipient list into smaller batches and send each batch separately.
Request IDs
Responses include anX-Request-Id header, and error bodies repeat it as error.requestId. POST /v1/templates/send is the exception: see Bulk template sends. To use your own ID, send an X-Request-Id header of up to 128 characters and Flowella reuses it.
Quote the request ID when you contact support. To look up a request yourself, call GET /v1/requests/{requestId} (scope account:read): it returns the logged request with the events, jobs and webhook deliveries linked to it. The Developer hub lists your recent requests and their IDs.
Idempotency
Idempotency keys let you retry a write request after a timeout or network error without doing the work twice.POST /v1/templates/send follows its own rules, described below.
Most write requests
POST, PATCH, PUT and DELETE requests accept an optional Idempotency-Key header:
- The key must be 8 to 255 characters. Other lengths return
400. - Flowella remembers each key for your organisation for 24 hours.
- A repeat with the same key, method, path and body returns the stored response without running the request again.
- A repeat with the same key but a different method, path or body returns
409 IDEMPOTENCY_KEY_CONFLICT. - A repeat sent while the first request is still running returns
409 IDEMPOTENCY_KEY_IN_FLIGHT. Wait and retry. - Responses echo the key in an
Idempotency-Keyheader.
Bulk template sends
Bulk template sends are asynchronous.POST /v1/templates/send validates the request, queues it durably and returns 202 Accepted at once:
Idempotency-Key header that identifies each batch:
- The key can be up to 200 characters. A longer key returns
400. - A repeat with the same key within 7 days returns the original
idand sends nothing, even if the body changed. - Without the header, Flowella uses a hash of the request body as the key. If you send a byte-identical body again within 7 days, you get the original
idback and nothing is sent. Use a new key for every batch you mean to send.
- Call it with an API key. OAuth access tokens are refused with
401. - Its responses do not include the
X-Request-Id,API-VersionorX-RateLimit-*headers. Its requests still count towards the key’s rate limit.
Versioning
You can pin the API version with theAPI-Version header:
2026-08-11 is the only supported version and the default when you leave the header out. Any other value, or a value that is not a YYYY-MM-DD date, returns 400 with the message Unsupported API-Version. Responses echo the version in the API-Version and X-Flowella-Api-Version headers.
Sandbox
The sandbox lets you test an integration without sending anything to WhatsApp. It works on your real organisation: there is no separate test account. You can use it in two ways:- A sandbox key, which affects only requests made with that key. See Sandbox keys.
- The organisation-wide API sandbox in the Developer hub, which an Owner or Admin can turn on. See API sandbox.
POST /v1/messages stores the message and returns "sandbox": true without contacting Meta, and template submission returns an instant mock decision. The sandbox test tools under /v1/test/ and /v1/sandbox need the sandbox:manage scope.
Pagination
List endpoints, such as/v1/conversations, /v1/contacts and /v1/templates, use cursor pagination:
- Pass
limit(1 to 100, default 25) and an optionalcursor. - The response contains
itemsand, when there are more results, anextCursor. - Pass
nextCursorback as thecursorparameter to fetch the next page. - When
nextCursoris missing ornull, you have reached the end.
Date and time
All timestamps are ISO 8601 strings in UTC, for example2025-01-15T14:30:00.000Z. Where the API accepts dates, both date-only (2025-01-15) and full ISO 8601 values work.
Phone numbers
Pass phone numbers in E.164 form (+15551234567) where possible. Flowella normalises common variations, but E.164 is safest.
Channels
Many endpoints accept awhatsappChannelId. If your organisation has a single channel and you omit it, Flowella uses your default channel. If you have several channels, pass the ID explicitly so you do not send from the wrong number.
For the full URL pattern and channel switching, see Multi-channel.
OpenAPI spec
The live, machine-readable specification is public:Developer resources
The app has more developer material. These pages are public, so you can open them without signing in:
The Developer hub in Settings brings these links together with your recent API requests and the API sandbox switch.

