Documentation Index
Fetch the complete documentation index at: https://docs.tell.rs/llms.txt
Use this file to discover all available pages before exploring further.
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:
| Mode | match_mode | Behavior |
|---|
| first_time | false (default) | Finds user’s first occurrence of the event, regardless of conditions. Conditions only filter the output range. |
| first_match | true | Finds 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
| Function | Description |
|---|
avg | Average per user (default) |
median / p50 | Median per user (robust to outliers) |
p75 | 75th percentile |
p90 | 90th percentile — identifies power users |
p95 | 95th percentile |
p99 | 99th percentile — extreme behavior |
min | Minimum per-user value |
max | Maximum 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.
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
| Operator | Description | Example |
|---|
+ | Add | A + B |
- | Subtract | A - B |
* | Multiply | A * B |
/ | Divide | A / B |
% | Modulo | A % B |
** | Power | A ** 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.
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
| Type | Description |
|---|
count | Total event count per group |
unique_actors | Distinct users per group |
sum | Sum of a numeric property (requires property field, e.g., properties.revenue) |
Intensity metrics
| Type | Description |
|---|
avg_per_actor | Average events per user |
percentile_per_actor | Percentile of events per user (default: p90, set percentile to override) |
unique_actors | Distinct users (useful when size is count) |
avg | Average of a numeric property (requires property field) |
Options
| Field | Default | Description |
|---|
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_groups | 20 | Maximum number of groups returned |
range | 30d | Time 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:
| State | Meaning |
|---|
| new | First ever activity falls within this period |
| returning | Active in both this period and the previous one |
| resurrected | Was 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