Skip to content

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 example user_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.


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.

POST https://api.thebridge.dev/event-log

Body Parameters

ParameterTypeRequiredDescription
appIdstringRequiredYour application ID
eventNamestringRequiredFree-form event name, e.g. signup_completed
timestampstringRequiredISO-8601 timestamp of when the event occurred. Historical timestamps are accepted
parametersobjectRequiredArbitrary key-value payload. Use {} when there is nothing to attach
ingestIdstringOptionalOptional external ingest identifier, stored on the raw event
ingestSourcestringOptionalOptional label for the ingest origin, stored on the raw event

{ "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
POST https://api.thebridge.dev/event-log
Stored in session memory only. Never persisted.

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.

POST https://api.thebridge.dev/event-log/query

Body Parameters

ParameterTypeRequiredDescription
appIdstringRequiredYour application ID
eventNamestringRequiredThe event name to query
fromstringRequiredISO-8601 range start (inclusive)
tostringRequiredISO-8601 range end (inclusive)
filtersobjectOptionalExact-match filters on parameters, e.g. { "plan": "pro" }
groupBystringOptionalOne of hour, day, week, month, none. Omit or use none for a single total
sumFieldstringOptionalName of a numeric parameter to sum, e.g. seats
currencystringOptionalReserved. Currently unused by the query
limitnumberOptionalReserved. Currently unused by the query

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
POST https://api.thebridge.dev/event-log/query
Stored in session memory only. Never persisted.

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.

GET https://api.thebridge.dev/event-log/charts

Query Parameters

ParameterTypeRequiredDescription
appIdstringRequiredYour application ID
eventNamestringRequiredThe event name to chart
intervalstringRequiredBucket size: hour, day, week, or month
fromstringRequiredISO-8601 range start (inclusive, on bucket start)
tostringRequiredISO-8601 range end (inclusive, on bucket start)
limitnumberOptionalMaximum buckets returned. Defaults to 500

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
GET https://api.thebridge.dev/event-log/charts?appId=:APP_ID&eventName=:EVENT_NAME&interval=day&from=:FROM&to=:TO
Stored in session memory only. Never persisted.
Your application ID
The event name to chart
ISO-8601 range start
ISO-8601 range end

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.

GET https://api.thebridge.dev/event-log/entities/ENTITY_TYPE/ENTITY_VALUE

Path Parameters

ParameterTypeRequiredDescription
ENTITY_TYPEstringRequiredThe parameter key that identified the entity, e.g. user_id
ENTITY_VALUEstringRequiredThe entity's identifier value

Query Parameters

ParameterTypeRequiredDescription
appIdstringRequiredYour application ID

| 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
GET https://api.thebridge.dev/event-log/entities/:ENTITY_TYPE/:ENTITY_VALUE?appId=:APP_ID
Stored in session memory only. Never persisted.
The entity parameter name, e.g. user_id
The entity's value
Your application ID

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.

GET https://api.thebridge.dev/event-log/journeys/stats

Query Parameters

ParameterTypeRequiredDescription
appIdstringRequiredYour application ID
startEventstringRequiredThe funnel's first event name
endEventstringRequiredThe funnel's second event name
entityTypestringOptionalRestrict to one entity type, e.g. user_id
fromstringOptionalISO-8601 filter on when the end event occurred
tostringOptionalISO-8601 filter on when the end event occurred

| 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
GET https://api.thebridge.dev/event-log/journeys/stats?appId=:APP_ID&startEvent=:START_EVENT&endEvent=:END_EVENT&entityType=user_id
Stored in session memory only. Never persisted.
Your application ID
First event in the funnel
Final event in the funnel

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.

GET https://api.thebridge.dev/event-log/audit

Query Parameters

ParameterTypeRequiredDescription
appIdstringRequiredYour application ID
actionstringOptionalExact match on the extracted action field
actorstringOptionalExact match on the extracted actor field
targetstringOptionalExact match on the extracted target field
fromstringOptionalISO-8601 range start
tostringOptionalISO-8601 range end
limitnumberOptional1 to 500. Defaults to 100
offsetnumberOptionalPagination offset. Defaults to 0

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
GET https://api.thebridge.dev/event-log/audit?appId=:APP_ID&limit=50
Stored in session memory only. Never persisted.
Your application ID