Skip to main content
The Flowella REST API lets you send WhatsApp messages, manage contacts and opt-outs, work with templates and Flows, and read analytics from your own code. This page covers what you need to know before you call an endpoint. The Endpoints section of this API reference documents individual requests. For the complete, current list, use the live OpenAPI document or the interactive API docs in the app.

Base URL

Every endpoint lives under this base, for example 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 the Authorization header of every request:
Flowella accepts two kinds of token. Both act on one organisation only. Use an API key for your own scripts and integrations. Use an OAuth app when other Flowella organisations install your integration.
Treat keys and tokens like passwords. Never commit them to source control or paste them into chat or shared documents. Revoke a key you no longer need in API keys.

Check your credentials

Call the ping endpoint to confirm that a key or token works:
A 200 OK response means you are authenticated. organizationId is your organisation’s numeric ID:
A 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 an X-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-Key header.
Requests without the header run normally, with no protection against duplicates.

Bulk template sends

Bulk template sends are asynchronous. POST /v1/templates/send validates the request, queues it durably and returns 202 Accepted at once:
Flowella delivers the batch in the background and retries temporary WhatsApp errors automatically. Recipients are processed individually, so one invalid number does not block the rest of the batch. Follow delivery progress on the template’s Statistics tab in the app. Pass an Idempotency-Key header that identifies each batch:
This endpoint handles keys differently from other write requests:
  • 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 id and 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 id back and nothing is sent. Use a new key for every batch you mean to send.
Some other behaviour also differs for this endpoint:
  • Call it with an API key. OAuth access tokens are refused with 401.
  • Its responses do not include the X-Request-Id, API-Version or X-RateLimit-* headers. Its requests still count towards the key’s rate limit.

Versioning

You can pin the API version with the API-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.
While the sandbox applies, 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 optional cursor.
  • The response contains items and, when there are more results, a nextCursor.
  • Pass nextCursor back as the cursor parameter to fetch the next page.
  • When nextCursor is missing or null, you have reached the end.

Date and time

All timestamps are ISO 8601 strings in UTC, for example 2025-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 a whatsappChannelId. 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:
Import it into Postman, Insomnia or a code generator. It describes both API key and OAuth authentication.

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.
Pair this page with the webhooks reference to react to events instead of polling for changes.
Last modified on October 30, 2026