Event Log
The Event Log is Bridge’s lightweight product-analytics store. You POST named events with arbitrary parameters; Bridge keeps the raw events and maintains three derived views on write:
- Time-series aggregates: per-event counts (plus per-parameter value counts and numeric sums) bucketed by hour, day, week, and month. Read them via charts or query.
- Entity journeys: any parameter whose key ends in
id,Id, or_id(for exampleuser_id,tenantId) is treated as an entity identifier. For each entity, Bridge records the first occurrence of every event name and the durations between event pairs. Read them via entity journeys and journey stats. - Audit log: events that carry entity identifiers or allowlisted fields (
email,plan,billingSource,origin) also land in a filterable audit trail.
Events are scoped to your app, not to a single workspace (a workspace, also called a tenant, is one customer account in your app; you can browse these charts in Control Center, Bridge’s admin dashboard). Every request carries your appId explicitly, as a body field or query parameter. Send your app’s x-api-key header with every request, the same way Bridge’s own dashboard does.
Ingestion is asynchronous: a successful POST means the event is queued, and the derived views update moments later. Timestamps are supplied by you, so you can backfill historical events.
Ingest an event
Section titled “Ingest an event”Enqueue one event. The event name is free-form; parameters are an arbitrary JSON object. String and boolean parameters feed per-value counters, numeric parameters feed sums, and *id-suffixed parameters create entity journey entries.
HTTP Request
Section titled “HTTP Request”POST https://api.thebridge.dev/event-log
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
appId | string | Required | Your application ID |
eventName | string | Required | Free-form event name, e.g. signup_completed |
timestamp | string | Required | ISO-8601 timestamp of when the event occurred. Historical timestamps are accepted |
parameters | object | Required | Arbitrary key-value payload. Use {} when there is nothing to attach |
ingestId | string | Optional | Optional external ingest identifier, stored on the raw event |
ingestSource | string | Optional | Optional label for the ingest origin, stored on the raw event |
Response HTTP 201
Section titled “Response HTTP 201”{ "queued": true } when the event was placed on the ingest queue (queued: false means it was processed inline; both are success).
Request example
curl --request POST 'https://api.thebridge.dev/event-log' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"appId": "YOUR_APP_ID",
"eventName": "signup_completed",
"timestamp": "2026-07-07T09:30:00.000Z",
"parameters": {
"user_id": "63d2ab029e23f80afb0daf97",
"plan": "pro",
"seats": 5
}
}'Response example:
{
"queued": true
}
POST Try it out
https://api.thebridge.dev/event-logQuery events
Section titled “Query events”Count events (and optionally sum a numeric parameter) over a time range, filtered by exact parameter values, either as a single total or grouped into time buckets.
HTTP Request
Section titled “HTTP Request”POST https://api.thebridge.dev/event-log/query
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
appId | string | Required | Your application ID |
eventName | string | Required | The event name to query |
from | string | Required | ISO-8601 range start (inclusive) |
to | string | Required | ISO-8601 range end (inclusive) |
filters | object | Optional | Exact-match filters on parameters, e.g. { "plan": "pro" } |
groupBy | string | Optional | One of hour, day, week, month, none. Omit or use none for a single total |
sumField | string | Optional | Name of a numeric parameter to sum, e.g. seats |
currency | string | Optional | Reserved. Currently unused by the query |
limit | number | Optional | Reserved. Currently unused by the query |
Response HTTP 200
Section titled “Response HTTP 200”Without groupBy (or with groupBy: "none"):
| Field | Type | Description |
|---|---|---|
| totalCount | number | How many events matched |
| totalSum | number? | Sum of sumField across matches. Only present when sumField was sent |
With groupBy, the response adds a buckets array of { bucketStart, count, total? }, where total is the per-bucket sum of sumField.
Request example
curl --request POST 'https://api.thebridge.dev/event-log/query' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data-raw '{
"appId": "YOUR_APP_ID",
"eventName": "signup_completed",
"filters": { "plan": "pro" },
"groupBy": "day",
"sumField": "seats",
"from": "2026-07-01T00:00:00.000Z",
"to": "2026-07-07T23:59:59.999Z"
}'Response example (grouped):
{
"totalCount": 42,
"totalSum": 180,
"buckets": [
{ "bucketStart": "2026-07-01T00:00:00.000Z", "count": 8, "total": 31 },
{ "bucketStart": "2026-07-02T00:00:00.000Z", "count": 11, "total": 52 }
]
}
POST Try it out
https://api.thebridge.dev/event-log/queryGet chart buckets
Section titled “Get chart buckets”Read the precomputed time-series aggregates for one event name at a fixed interval. Unlike query, this reads the write-time aggregates directly (no scan of raw events) and includes per-parameter breakdowns: value counts for string/boolean parameters and running sums for numeric parameters.
HTTP Request
Section titled “HTTP Request”GET https://api.thebridge.dev/event-log/charts
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
appId | string | Required | Your application ID |
eventName | string | Required | The event name to chart |
interval | string | Required | Bucket size: hour, day, week, or month |
from | string | Required | ISO-8601 range start (inclusive, on bucket start) |
to | string | Required | ISO-8601 range end (inclusive, on bucket start) |
limit | number | Optional | Maximum buckets returned. Defaults to 500 |
Response HTTP 200
Section titled “Response HTTP 200”An array of buckets, oldest first:
| Field | Type | Description |
|---|---|---|
| bucketStart | string | Start of the bucket |
| count | number | Events in the bucket |
| parameterCounts | object | Per-parameter value counts: { <param>: { <value>: count } } for string/boolean parameters |
| parameterSums | object | Per-parameter sums for numeric parameters |
Request example
curl --request GET 'https://api.thebridge.dev/event-log/charts?appId=YOUR_APP_ID&eventName=signup_completed&interval=day&from=2026-07-01T00:00:00.000Z&to=2026-07-07T23:59:59.999Z' \
--header 'x-api-key: YOUR_API_KEY'Response example:
[
{
"bucketStart": "2026-07-01T00:00:00.000Z",
"count": 8,
"parameterCounts": {
"plan": { "pro": 6, "free": 2 }
},
"parameterSums": {
"seats": 31
}
}
]
GET Try it out
https://api.thebridge.dev/event-log/charts?appId=:APP_ID&eventName=:EVENT_NAME&interval=day&from=:FROM&to=:TOGet an entity’s journey
Section titled “Get an entity’s journey”Everything Bridge has recorded for one entity (a user, workspace, or any other *id-suffixed parameter you send): the timestamp of the first occurrence of each event name, plus the millisecond durations between each event pair.
HTTP Request
Section titled “HTTP Request”GET https://api.thebridge.dev/event-log/entities/ENTITY_TYPE/ENTITY_VALUE
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ENTITY_TYPE | string | Required | The parameter key that identified the entity, e.g. user_id |
ENTITY_VALUE | string | Required | The entity's identifier value |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
appId | string | Required | Your application ID |
Response HTTP 200
Section titled “Response HTTP 200”| Field | Type | Description |
|---|---|---|
| events | object | { <eventName>: <ISO timestamp of first occurrence> } |
| durations | object | { "<eventA>_to_<eventB>": <milliseconds> } between first occurrences |
Returns HTTP 404 when the entity has no recorded events.
Request example
curl --request GET 'https://api.thebridge.dev/event-log/entities/user_id/63d2ab029e23f80afb0daf97?appId=YOUR_APP_ID' \
--header 'x-api-key: YOUR_API_KEY'Response example:
{
"events": {
"signup_completed": "2026-07-01T09:30:00.000Z",
"first_project_created": "2026-07-01T09:42:12.000Z",
"plan_upgraded": "2026-07-05T14:02:44.000Z"
},
"durations": {
"signup_completed_to_first_project_created": 732000,
"signup_completed_to_plan_upgraded": 361364000
}
}
GET Try it out
https://api.thebridge.dev/event-log/entities/:ENTITY_TYPE/:ENTITY_VALUE?appId=:APP_IDGet journey funnel stats
Section titled “Get journey funnel stats”Aggregate duration statistics for a two-step funnel across all entities that completed it: how many entities went from startEvent to endEvent, and how long it took them.
HTTP Request
Section titled “HTTP Request”GET https://api.thebridge.dev/event-log/journeys/stats
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
appId | string | Required | Your application ID |
startEvent | string | Required | The funnel's first event name |
endEvent | string | Required | The funnel's second event name |
entityType | string | Optional | Restrict to one entity type, e.g. user_id |
from | string | Optional | ISO-8601 filter on when the end event occurred |
to | string | Optional | ISO-8601 filter on when the end event occurred |
Response HTTP 200
Section titled “Response HTTP 200”| Field | Type | Description |
|---|---|---|
| count | number | Entities that completed the funnel |
| average_ms | number | Mean duration in milliseconds |
| median_ms | number | Median duration in milliseconds |
| min_ms | number | Fastest completion |
| max_ms | number | Slowest completion |
All values are 0 when no entity has completed the funnel.
Request example
curl --request GET 'https://api.thebridge.dev/event-log/journeys/stats?appId=YOUR_APP_ID&startEvent=signup_completed&endEvent=plan_upgraded&entityType=user_id' \
--header 'x-api-key: YOUR_API_KEY'Response example:
{
"count": 128,
"average_ms": 259200000,
"median_ms": 172800000,
"min_ms": 3600000,
"max_ms": 1209600000
}
GET Try it out
https://api.thebridge.dev/event-log/journeys/stats?appId=:APP_ID&startEvent=:START_EVENT&endEvent=:END_EVENT&entityType=user_idQuery the audit log
Section titled “Query the audit log”Read the audit trail: events that carried entity identifiers or allowlisted audit fields (email, plan, billingSource, origin). Filterable by action, actor, and target when your events include parameters with those names.
HTTP Request
Section titled “HTTP Request”GET https://api.thebridge.dev/event-log/audit
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
appId | string | Required | Your application ID |
action | string | Optional | Exact match on the extracted action field |
actor | string | Optional | Exact match on the extracted actor field |
target | string | Optional | Exact match on the extracted target field |
from | string | Optional | ISO-8601 range start |
to | string | Optional | ISO-8601 range end |
limit | number | Optional | 1 to 500. Defaults to 100 |
offset | number | Optional | Pagination offset. Defaults to 0 |
Response HTTP 200
Section titled “Response HTTP 200”An array of audit entries, newest first:
| Field | Type | Description |
|---|---|---|
| timestamp | string | When the event occurred |
| eventName | string | The originating event name |
| extracted | object | The identifier and allowlisted fields captured from the event’s parameters |
| rawEventId | string | ID of the underlying raw event |
Request example
curl --request GET 'https://api.thebridge.dev/event-log/audit?appId=YOUR_APP_ID&limit=50' \
--header 'x-api-key: YOUR_API_KEY'Response example:
[
{
"timestamp": "2026-07-05T14:02:44.000Z",
"eventName": "plan_upgraded",
"extracted": {
"user_id": "63d2ab029e23f80afb0daf97",
"plan": "pro",
"email": "john@example.com"
},
"rawEventId": "665f2c9e6d1b4f4e9d1a6a20"
}
]
GET Try it out
https://api.thebridge.dev/event-log/audit?appId=:APP_ID&limit=50