Skip to main content
Events are the core of product analytics. When a user signs up, views a page, or makes a purchase, Tell records it as an event with a name and properties. The analytics engine lets you count events, rank them, break them down by property values, and run aggregations like sum and average.

Quick start

# Total event count over 30 days
tell metrics events --range 30d

# Top 10 most frequent events
tell metrics events --top --range 30d --limit 10
Via the API:
curl "https://your-tell-server/api/v1/metrics/events?range=30d&granularity=daily" \
  -H "Authorization: Bearer $TOKEN"

Event counts

Count all events or filter to a specific event name:
# All events over time
tell metrics events --range 7d

# Just sign_up events
tell metrics events --range 7d --event sign_up
API:
# Count a specific event
curl "https://your-tell-server/api/v1/metrics/events?range=7d&event=sign_up" \
  -H "Authorization: Bearer $TOKEN"

Top events

See which events happen most often:
curl "https://your-tell-server/api/v1/metrics/events/top?range=30d&limit=10" \
  -H "Authorization: Bearer $TOKEN"
Returns event names ranked by count, so you can quickly see what’s driving volume.

Property breakdowns

Break down a specific event by its properties to understand the distribution:
# sign_up events broken down by plan property
curl "https://your-tell-server/api/v1/metrics/events/properties?range=30d&event=sign_up&property=properties.plan" \
  -H "Authorization: Bearer $TOKEN"
This returns time series data grouped by each property value (e.g., “free”, “pro”, “enterprise”). For top-level fields, use the field name directly (device_type, country). For custom properties stored in the JSON properties column, prefix with properties. (e.g., properties.plan, properties.amount).

Custom aggregations

Run sum, average, min, max, or count on numeric event properties:
# Average order amount for purchase events
curl "https://your-tell-server/api/v1/metrics/events/custom?\
event=purchase&property=properties.amount&metric=avg&range=30d" \
  -H "Authorization: Bearer $TOKEN"

# Total revenue
curl "https://your-tell-server/api/v1/metrics/events/custom?\
event=purchase&property=properties.amount&metric=sum&range=30d" \
  -H "Authorization: Bearer $TOKEN"
Supported aggregation functions: sum, avg, min, max, count.

First-time events

Count users who did an event for the first time within a period. This answers questions like “how many users signed up for the first time this week?” — distinct from total event counts, which include repeat actions.
curl "https://your-tell-server/api/v1/metrics/events/first-time?event=sign_up&range=30d&granularity=daily" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123"
Tell scans each user’s full event history to find their earliest occurrence, then counts only those whose first occurrence falls within the query range. The result is a time series of new user acquisition per period.

First-time vs first-match

Two modes control how filter conditions interact with the historical scan:
Modematch_modeBehavior
first_timefalse (default)Finds user’s first occurrence of the event, regardless of conditions. Conditions only filter the output range.
first_matchtrueFinds user’s first occurrence that matches ALL conditions. A user who did purchase before but never with amount > 100 counts as first-time for that condition.
first_time (default) — “How many users made their first purchase this month?”
curl "https://your-tell-server/api/v1/metrics/events/first-time?event=purchase&range=30d" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123"
first_match — “How many users made their first purchase over $100 this month?”
curl "https://your-tell-server/api/v1/metrics/events/first-time?\
event=purchase&match_mode=true&range=30d&\
conditions[0][field]=properties.amount&conditions[0][op]=gt&conditions[0][value]=100" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123"

Lookback window

By default, Tell scans the entire event history to find true first occurrences. For large datasets, limit the scan with lookback_days:
# Only scan the last 365 days of history
curl "https://your-tell-server/api/v1/metrics/events/first-time?\
event=sign_up&range=30d&lookback_days=365" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123"
This trades accuracy for speed — a user who first did the event 400 days ago would be miscounted as first-time if their next occurrence falls within the range. Use this when you know your product’s age or only care about recent cohorts. First-time events support breakdowns, comparison, and audience filtering. When combined with a breakdown, Tell captures the property value at the time of the first event using argMin. See the first-time events API reference for full endpoint documentation.

Per-actor metrics

Regular event counts tell you totals. Per-actor metrics tell you about user behavior — how many events does a typical user trigger? What does the 90th percentile look like? Tell computes this with a two-level aggregation: first per user, then across users.
# Average page views per user, daily over 30 days
curl "https://your-tell-server/api/v1/metrics/events/per-actor?\
event=page_view&metric=avg&range=30d&granularity=daily" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123"
This returns a time series where each point is the average number of page_view events per user for that day — not the total count, but the per-user average.

Aggregation functions

FunctionDescription
avgAverage per user (default)
median / p50Median per user (robust to outliers)
p7575th percentile
p9090th percentile — identifies power users
p9595th percentile
p9999th percentile — extreme behavior
minMinimum per-user value
maxMaximum per-user value

Property aggregation

By default, per-actor counts events. Add property to aggregate a numeric property instead:
# P90 revenue per user from purchase events
curl "https://your-tell-server/api/v1/metrics/events/per-actor?\
event=purchase&metric=p90&property=properties.amount&range=30d" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123"
Without property: inner aggregation is COUNT(*) per user (event count). With property: inner aggregation is SUM(property) per user (property total). The outer function (avg, p90, etc.) then operates on those per-user values.

How it differs from other metrics

  • Event counts — total events across all users. “50,000 purchases happened.”
  • Per-actor metrics — distribution across users. “The average user made 2.3 purchases. The p90 user made 8.”
  • Custom aggregations — single-level property aggregation. “Average purchase amount is $42.” (not per-user)
  • Grouped metrics — per-actor logic applied per group for treemap visualization
Per-actor metrics support breakdowns, all granularity levels, and audience filtering. See the per-actor API reference for full endpoint documentation.

Drill-down

Inspect raw event data when you need to see individual records:
curl "https://your-tell-server/api/v1/metrics/events/raw?range=7d&limit=50" \
  -H "Authorization: Bearer $TOKEN"
Returns rows with timestamp, event_name, device_id, and session_id. Add filter conditions to narrow down the results.

Formulas

Combine multiple metric series with math. Define series A, B, C (up to 26), then write an expression:
curl -X POST https://your-tell-server/api/v1/metrics/formula \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "series": [
      { "metric": "event:sign_up" },
      { "metric": "event:purchase" }
    ],
    "formula": "B / A * 100",
    "range": "30d",
    "granularity": "daily"
  }'
This computes the daily conversion rate from sign-up to purchase. Series A is sign-up count, series B is purchase count, and the formula B / A * 100 gives a percentage.

Series references

Each series maps to a letter: the first is A, the second is B, and so on up to Z. Reference them in your formula by letter. Available series metrics: dau, wau, mau, events, event:<name>, sessions, users, logs.

Operators

OperatorDescriptionExample
+AddA + B
-SubtractA - B
*MultiplyA * B
/DivideA / B
%ModuloA % B
**PowerA ** 2
- (unary)Negate-A
Standard math precedence applies. Use parentheses to override: (A + B) / C. Division by zero returns 0 instead of an error.

Evaluation modes

Formulas evaluate in two modes depending on context:
  • Time series — per-bucket evaluation, used for charts. Missing values default to 0.
  • Total — evaluates on aggregate totals, used for KPI number blocks on boards.

Formulas on boards

Add formulas to any metric block on a board. Define your series, write the expression, and the board evaluates it on every refresh. Use this for computed metrics like conversion rates, ratios, or derived KPIs. See the formula API reference for full endpoint documentation.

Grouped metrics

Grouped metrics show proportional composition — which countries, events, or plans make up your traffic, and how engaged each group is. The result powers treemap visualizations on boards. Each group has two values:
  • Size — determines area (event count, unique users, or sum of a property)
  • Intensity — determines color (average events per user, percentile, or average of a property)
curl -X POST https://your-tell-server/api/v1/metrics/grouped \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "group_by": "country",
    "size": { "type": "unique_actors" },
    "intensity": { "type": "avg_per_actor" },
    "range": "30d"
  }'
This returns groups ordered by size, each with a size value (user count) and intensity value (average events per user). The US might have 1,500 users averaging 3.2 events each, while Canada has 800 users averaging 2.8.

Size metrics

TypeDescription
countTotal event count per group
unique_actorsDistinct users per group
sumSum of a numeric property (requires property field, e.g., properties.revenue)

Intensity metrics

TypeDescription
avg_per_actorAverage events per user
percentile_per_actorPercentile of events per user (default: p90, set percentile to override)
unique_actorsDistinct users (useful when size is count)
avgAverage of a numeric property (requires property field)

Options

FieldDefaultDescription
group_by(required)Field to group by: country, event_name, device_type, or any properties.* field
event(all events)Filter to a specific event
max_groups20Maximum number of groups returned
range30dTime range
Unlike breakdowns, grouped metrics always return a snapshot (not a time series) and use two-level aggregation — first per user, then per group — to reveal engagement patterns, not just raw counts. See the grouped metrics API reference for full endpoint documentation.

Lifecycle

The lifecycle metric tracks how your active user base evolves over time. Each period, Tell classifies every active user into one of three states:
StateMeaning
newFirst ever activity falls within this period
returningActive in both this period and the previous one
resurrectedWas inactive in the previous period, came back
curl "https://your-tell-server/api/v1/metrics/lifecycle?range=30d&granularity=weekly" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-ID: ws_abc123"
Returns a time series with one point per state per period:
{
  "data": {
    "points": [
      {"date": "2025-02-03", "value": 150, "dimension": "new"},
      {"date": "2025-02-03", "value": 800, "dimension": "returning"},
      {"date": "2025-02-03", "value": 50, "dimension": "resurrected"},
      {"date": "2025-02-10", "value": 200, "dimension": "new"},
      {"date": "2025-02-10", "value": 750, "dimension": "returning"},
      {"date": "2025-02-10", "value": 80, "dimension": "resurrected"}
    ],
    "total": 2030
  }
}
A healthy product has a large returning base with steady new user inflow. If resurrected starts outpacing new, your acquisition may be slowing while re-engagement improves. If returning shrinks, users aren’t sticking around. The default granularity is weekly. Supports daily, monthly, and all other granularity levels. Add compare=previous for period-over-period comparison.
This is different from lifecycle segments. The lifecycle metric is a time series — it classifies users per period with relative lookback. Segments are a snapshot — they classify all users right now using fixed 7/30-day windows and include dormant and churned states.
See the lifecycle API reference for full endpoint documentation.

Breakdowns and comparison

Event metrics support the full filtering system — breakdowns by any field, period comparison, and all granularity levels.
# Event count by device type, compared to previous period
tell metrics events --range 30d --breakdown device_type --compare previous