REST API
Send events directly from any system that can make HTTP requests.
Base URL
https://api.flowalert.io/v1Authentication
All event requests require an API key in the X-Api-Key header:
X-Api-Key: fa_live_xxxxxxxxxxxxxxxxSend an event
POST /v1/eventscurl -X POST https://api.flowalert.io/v1/events \
-H "Content-Type: application/json" \
-H "X-Api-Key: <your-api-key>" \
-d '{
"event": "booking.created",
"title": "New Booking — Sarah Connor",
"body": "Sunset Cruise · 2 guests · 7 PM",
"priority": "NORMAL",
"detail": "Customer notes: wheelchair access required",
"data": {
"booking_id": "BK-5512",
"tour": "Sunset Cruise"
}
}'Response (201 Created):
{
"id": "evt_abc123",
"eventKey": "booking.created",
"title": "New Booking — Sarah Connor",
"createdAt": "2026-05-11T12:00:00.000Z"
}Payload fields
| Field | Type | Required | Description |
|---|---|---|---|
event | string | ✓ | Event key, e.g. booking.created |
title | string | ✓ | Push notification title (keep under 60 chars) |
body | string | ✓ | Notification body (max 2000 chars) |
priority | string | LOW · NORMAL · HIGH · URGENT | |
detail | string | Extended detail shown when the notification is opened in the app | |
data | object | Structured fields your routing rules match on — also listed in the in-app event detail (see below) | |
url | string | URL associated with the event | |
dedupeKey | string | Deduplicate identical events within a 10-minute window | |
requiresAck | boolean | Per-event override for acknowledgement requirement |
Event keys must follow resource.action format using lowercase letters, numbers, and underscores only (e.g. order.created, payment_v2.failed). The prefix flowalert. is reserved.
What shows where, and what data is for
It's worth being explicit about where each field surfaces:
| Field | Role | Where it shows up |
|---|---|---|
title, body | Display | The push notification itself — on the lock screen |
detail | Display | The "Additional detail" box when the alert is opened in the app |
data | Matching + reference | Used by routing rules and listed as fields in the in-app event detail |
The key nuance: data is not on the lock screen and is never interpolated into the title or body — there is no {{data.x}} templating. It's matched by routing rules, and it's shown as a read-only Details list when the recipient opens the alert.
So for the lock-screen headline, put it in title/body. To make it routable (and visible on open), put it in data. For a value you want in the push and as a filter — like the tour name below — include it in both:
{
"event": "booking.created",
"title": "New Booking — Sarah Connor",
"body": "Sunset Cruise · 2 guests · 7 PM",
"data": { "tour": "Sunset Cruise", "guests": 2, "booking_id": "BK-5512" }
}On the lock screen the staff member reads "Sunset Cruise · 2 guests · 7 PM"; opening the alert also lists Tour, Guests, and Booking id under Details; and a routing rule matches on data.tour and data.guests.
Using data in a routing rule
In the routing rule builder, add a condition that targets a data.* field by its dotted path:
| Condition | Effect |
|---|---|
data.tour equals Sunset Cruise | Send only this tour's bookings to the boat crew |
data.guests greater_than 6 | Escalate large-group bookings to a manager |
data.region one_of EU, UK | Route by region to the right team |
Available operators include equals, not_equals, contains, starts_with, ends_with, one_of, not_one_of, greater_than / less_than (and _or_equal), between, is_empty, is_not_empty, and matches_regex. You can also match on the top-level title, body, and priority.
After FlowAlert receives the first event of a given key, the rule builder remembers its data shape and lists those fields in the condition's field dropdown (data.tour, data.booking_id, … alongside title, body, and priority) — so send one test event first and pick the field from the menu, or choose Custom field… to type any path by hand.
Error responses
| Status | Meaning |
|---|---|
401 Unauthorized | Missing or invalid API key |
422 Unprocessable Entity | Missing required fields |
429 Too Many Requests | Rate limit exceeded |