POST to the URL.
You can manage webhooks in the app under Settings → Webhooks (see Add and manage outbound webhooks) or with the webhooks API. This page is the reference for what Flowella sends.
Event types
Tick these events when you add a webhook, or pass them inevents when you create one with the API.
Contact events fire only for these single-contact API calls. They do not fire for
POST /v1/contacts/bulk-upsert, for contacts created by inbound messages, or for changes made in the app or synced from HubSpot.
Flowella also sends webhook.test when you select Send test event in the app or call POST /v1/webhooks/{id}/test. You cannot subscribe to it. Its data is { "test": true, "sentAt": "<ISO 8601 time>" }.
One outbound message can produce two
message.sent events: one when Flowella hands it to Meta, and one when Meta reports it as sent. The two have different top-level id values. Use data.messageId to link them to the same message.Request format
Flowella sends each event as an HTTPPOST with these headers:
Flowella sends no other custom headers. The event type and ID are in the body.
Body
Every webhook has a payload version, returned aspayloadVersion by the webhooks API. Version 1 is the default for every webhook, and there is no setting in the app or the API to change it. The two versions use these envelopes:
Flowella does not send an event whose
data is larger than 256 KB.
Verify signatures
Check the signature on every request before you trust it. Flowella computesX-Flowella-Signature like this:
- Algorithm: HMAC with SHA-256.
- Key: the signing secret as UTF-8 text, exactly as saved. A secret generated by the API includes its
whsec_prefix. - Message: the raw request body, byte for byte, as Flowella sent it. Nothing else is signed: there is no timestamp or URL in the signature.
- Output: lowercase hexadecimal, 64 characters, with no
sha256=prefix.
Responses, retries and timeouts
Flowella delivers several events at once, so they can arrive out of order. Use
created_at or occurred_at if order matters. Reply with a 2xx status as soon as the signature checks out, then process the event in the background. For how retries look in the app, see Retries and back-off.
Deduplicate events
Your endpoint can receive the same event more than once: a retry after your endpoint timed out but still processed the request, or a replay through the API. Deduplicate on the top-levelid:
- Store the
idof every event you process. - If an incoming
idis already stored, reply200and do nothing else. - Keep stored IDs at least as long as you might replay deliveries.
data.messageId. Different events about the same message, such as message.sent and message.delivered, share it.
Event feed
The event feed is a pull alternative to webhooks.GET /v1/events returns events from the last 7 days, including events that no webhook subscribes to. It needs the events:read scope. Filter with type (one type or a comma-separated list), occurredAfter and occurredBefore, and page with limit and cursor.
Each item has id, type, occurredAt, version, correlationId and data. The id matches the id in the webhook body, so you can use the feed to fill gaps after your endpoint was down.
Manage webhooks with the API
All webhook endpoints need an API key or OAuth access token with thewebhooks:manage scope. Keys created in the app have it. See the API introduction for authentication.
Webhook objects contain
id, name, url, events, isActive, consecutiveFailures, signingSecretPrefix (the first 8 characters of the current secret), payloadVersion, lastTriggeredAt, disabledAt, createdAt and updatedAt.
A few rules apply to webhooks managed through the API:
- You cannot choose the signing secret through the API.
POST /v1/webhooksgenerates one that starts withwhsec_and returns it once, assigningSecret. - Replays do not count towards or reset the failure count. Flowella delivers a replay only while the webhook is active and still subscribed to that event type.
- The URL must follow the same URL rules as in the app.
Rotate a signing secret
Rotate a secret when you think it has leaked, or on a regular schedule. Rotation works for any webhook that has a secret, including webhooks whose secret you typed in the app.1
Request a new secret
Call the rotate endpoint and store the
signingSecret from the response. Flowella returns it only once.2
Accept both secrets for 24 hours
New deliveries are signed with the new secret in
X-Flowella-Signature, and with the old secret in X-Flowella-Signature-Previous. A handler that still uses the old secret keeps working if it checks both headers, as in the example in Verify signatures.3
Switch to the new secret
Update your handler to the new secret within 24 hours. After that, Flowella stops sending
X-Flowella-Signature-Previous.Test locally
To receive webhooks on your own computer, expose your local server through a public tunnel, such as ngrok or Cloudflare Tunnel. Use the tunnel’s public URL as the endpoint. Then use Send test event to send requests whenever you need them. Flowella refuses local and private addresses, so alocalhost URL does not work.
Related
Manage webhooks in the app
Add endpoints, send test events and read the delivery log.
API introduction
Authentication, scopes, rate limits and errors.
API keys
Create the key you need for the webhooks API.
Developer hub
Recent API requests, quickstarts and the API sandbox.

