Events API
An event is a behavioral signal reported from your application — purchase, cart_abandoned, price_drop_watch, anything. Events are the trigger source for event-triggered automations, and they populate each subscriber's activity timeline in the dashboard. The browser and mobile SDKs report events for you on the client; from your own backend you report them with the single endpoint below.
From a Node backend, use the Server SDK (
@reachbell/node) instead of calling this endpoint directly — it wraps event reporting with typed helpers and error handling. The raw REST below is for other languages and for endpoints the SDK doesn't wrap yet.
Reporting events authenticates with x-api-key (server-to-server). The project is resolved from the key, so you never pass a projectId. The endpoint is rate-limited to 120 requests per minute per IP.
Report an event
POST /events
Report a single behavioral event for the project.
curl -X POST https://api.reachbell.com/events \
-H "x-api-key: rb_live_yourkey" \
-H "Content-Type: application/json" \
-d '{
"name": "purchase",
"externalId": "user_42",
"properties": { "orderId": "A123", "value": 79.0, "currency": "USD" }
}'Body fields:
name— the event name. Required. Normalized at ingest: trimmed, lowercased, and any run of characters outsidea-z 0-9 _ . -is collapsed to_(soCart Abandoned!becomescart_abandoned_). Capped at 64 characters. An empty name after normalization returns400.externalId— the user ID you set via identify. Used to resolve which subscriber the event belongs to. Optional, but see identity resolution below.subscriberId— the ReachBell subscriber ID, if you have it. Takes precedence overexternalIdwhen both are present.properties— a free-form JSON object (order value, product ID, …). Optional. Must be an object — arrays and scalars are ignored and stored as{}. The serialized payload is capped at 4 KB; a larger payload returns400.source—"sdk"or"api". Optional; defaults to"api". Any value other than"sdk"is recorded as"api".
Success:
{
"id": "evt_01HX6...",
"name": "purchase",
"resolved": true
}id— the stored event's ID.name— the normalized event name (so you can see exactly what was recorded).resolved—trueif the event was matched to a known subscriber. See below.
Identity resolution
ReachBell resolves the event to a subscriber so it can enroll them into matching automations and place the event on their timeline:
- If
subscriberIdis supplied and is a valid ID belonging to this project, that subscriber is used. - Otherwise, if
externalIdis supplied, the most recently active subscriber with thatexternalIdon the project is used. - If neither resolves, the event is still stored (with whatever identity you sent) and
resolvedcomes backfalse.
A resolution miss is not an error. The event is persisted either way, so a later identify still leaves a usable trail — but automations can only enroll a subscriber that resolved. If your automations aren't firing, check that
resolvedistrue: the usual cause is reporting an event before the user has been identified.
When an event resolves, ReachBell enrolls the subscriber into any automation whose trigger is event with a matching name — this is the primary way to drive automated flows from your own backend.
Batch reporting
To report several events in one request, send an events array instead of a single event. Each element has the same shape as a single event. A top-level source applies to every event in the batch.
curl -X POST https://api.reachbell.com/events \
-H "x-api-key: rb_live_yourkey" \
-H "Content-Type: application/json" \
-d '{
"events": [
{ "name": "product_view", "externalId": "user_42", "properties": { "sku": "SHOE-1" } },
{ "name": "add_to_cart", "externalId": "user_42", "properties": { "sku": "SHOE-1", "qty": 1 } }
]
}'A batch is capped at 25 events per call — any beyond the first 25 are silently dropped, so keep each call at or under the cap. Events are processed independently: one bad event doesn't fail the rest.
Success:
{
"accepted": 2,
"results": [
{ "id": "evt_01HX6...", "name": "product_view", "resolved": true },
{ "id": "evt_01HX7...", "name": "add_to_cart", "resolved": true }
]
}accepted— how many events were processed (after the 25-event cap).results— one entry per processed event, in order. A successful entry is the same{ id, name, resolved }object as a single report; an entry that failed (for example a too-largepropertiespayload) is{ "error": "<message>" }instead. Inspect each entry — a200 OKon the batch does not mean every event succeeded.
What's next?
- Trigger a flow from your events with an event-triggered Automation.
- Identify users first so events resolve — see the Subscribers API.
- Send a one-off message with the Transactional API.