Skip to main content
This reference is generated from the query compiler schema. Use the RQL guide for limits and examples.

Tables and fields

events

AI event records (user message + agent response), with signals, properties, tool calls, errors, token usage, and user context. Recent reprojections can temporarily expose multiple physical versions until background merges settle.
  • project_id (string): Owning project id — selectable and filterable inside the server-injected read scope
  • event_id (string): Internal Raindrop database event id — accepted by get_event; use for exact counts and correlating separate event/trace queries
  • timestamp (datetime): Event time (UTC)
  • event_name (string): Instrumented event name (e.g. chat_message)
  • user_id (string): End-user id
  • convo_id (string): Conversation id
  • custom_event_id (string): Caller-supplied public event id — shown as id by get_event when present
  • ai_input (string): User input text
  • ai_output (string): AI response text
  • ai_model (string): Model that produced the response
  • ai_input_language (string): Detected language of the user input
  • signals (array(string)): Signal ids attached to this event — use has(signals, ’…’) or arrayJoin(signals)
  • properties (map(string)): Custom event properties — access with properties.my_key
  • user_traits (map(string)): User traits at event time — access with user_traits.plan
  • feature_flags (map(string)): Feature flags at event time — access with feature_flags.my_flag
  • user_plan (string): User plan at event time
  • user_created_at (datetime): When the user was first seen
  • is_internal (boolean): Marked as internal traffic
  • is_excluded_user (boolean): User is on the exclusion list
  • input_words (number): Word count of ai_input
  • output_words (number): Word count of ai_output
  • tool_calls (array(json)): Tool calls made during the event (JSON), newest 500 only
  • tool_names (array(string)): Names of tools called during the event. Stored list keeps only the newest 500 calls; for giant events use the traces table
  • tool_call_count (number): Number of tool calls in the event, from a stored list that keeps only the newest 500. A value of 500 may be a floor: count TOOL_CALL spans in the traces table for the full total
  • error_spans (array(json)): Error spans recorded on the event (JSON)
  • error_names (array(string)): Span names that errored during the event
  • error_count (number): Number of error spans on the event
  • has_errors (boolean): Event has at least one error span
  • token_usage (array(json)): Per-span token usage (JSON)
  • input_tokens (number): Total input tokens across the event’s LLM calls
  • output_tokens (number): Total output tokens across the event’s LLM calls
  • total_tokens (number): Total tokens (input + output) across the event’s LLM calls

traces

OTel span records — LLM calls, tool executions, and agent steps. Correlate with events using event_id in separate queries; RQL does not support JOIN. Recent reprojections can temporarily expose multiple physical versions until background merges settle.
  • project_id (string): Owning project id — selectable and filterable inside the server-injected read scope
  • event_id (string): Owning event id
  • trace_id (string): OTel trace id
  • span_id (string): OTel span id
  • parent_span_id (string): Parent span id
  • span_type (string): Span type: LLM_GENERATION, LLM_GENERATION_STREAM, TOOL_CALL, or INTERNAL — filter LLM calls with span_type LIKE ‘LLM%’
  • span_name (string): Span name
  • status (string): Span status (OK / ERROR)
  • timestamp (datetime): Span start time (UTC)
  • end_timestamp (datetime): Span end time (UTC)
  • duration_ms (number): Span duration in milliseconds
  • input_payload (string): Span input payload
  • output_payload (string): Span output payload
  • input_tokens (number): Input tokens (LLM spans)
  • output_tokens (number): Output tokens (LLM spans)
  • provider (string): LLM provider (e.g. openai.chat)
  • model (string): LLM model id
  • user_id (string): End-user id (from the owning event when the span doesn’t carry one)
  • convo_id (string): Conversation id (from the owning event when the span doesn’t carry one)
  • attributes (map(string)): String span attributes — access with attributes.my_attr
  • attributes_num (map(number)): Numeric span attributes — access with attributes_num.my_attr. LLM spans carry their USD cost as attributes_num.raindrop.pricing.cost_usd (absent when the call could not be priced or was ingested before cost stamping)

users

One row per project and end-user from the maintained user-activity rollup — activity, plan, traits, and signals.
  • project_id (string): Owning project id
  • user_id (string): End-user id
  • event_count (number): Approximate distinct events from this user
  • first_seen (datetime): First event time
  • last_seen (datetime): Most recent event time
  • active_days (number): Distinct days with activity
  • plan (string): Latest known plan
  • traits (map(string)): Latest user traits — access with traits.my_trait
  • signals (array(string)): All signal ids seen across the user’s events

user_days

One row per project, end-user, and UTC day from the maintained user-activity rollup — daily per-user event counts. The query time range bounds day unless WHERE filters day.
  • project_id (string): Owning project id
  • user_id (string): End-user id
  • day (datetime): UTC day (date)
  • event_count (number): Approximate distinct events from this user on that day

conversations

One row per project and conversation from the maintained conversation rollup — anchor event, user, activity window, message count, and signals.
  • project_id (string): Owning project id
  • convo_id (string): Conversation id
  • event_id (string): Most recent event id, used as the conversation’s clickable anchor
  • user_id (string): User id on the most recent event
  • start_ts (datetime): First event time
  • end_ts (datetime): Most recent event time
  • message_count (number): Rollup event rows; use uniqExact(event_id) on events for an exact distinct count
  • duration_seconds (number): Seconds between the first and most recent event
  • signals (array(string)): All materialized signal ids seen in the conversation

Functions

  • count() (aggregate): Number of rows
  • countIf(cond) (aggregate): Rows matching a condition
  • countDistinct(x) (aggregate): Exact distinct count (alias of uniqExact)
  • uniq(x) (aggregate): Approximate distinct count
  • uniqIf(x, cond) (aggregate): Approximate distinct count for rows matching a condition
  • uniqExact(x) (aggregate): Exact distinct count
  • uniqExactIf(x, cond) (aggregate): Exact distinct count for rows matching a condition
  • sum(x) (aggregate): Sum
  • sumIf(x, cond) (aggregate): Conditional sum
  • avg(x) (aggregate): Average
  • avgIf(x, cond) (aggregate): Conditional average
  • min(x) (aggregate): Minimum
  • minIf(x, cond) (aggregate): Conditional minimum
  • max(x) (aggregate): Maximum
  • maxIf(x, cond) (aggregate): Conditional maximum
  • median(x) (aggregate): Approximate median
  • quantile(0.95)(x) (aggregate): Approximate quantile
  • quantiles(0.5, 0.9, 0.99)(x) (aggregate): Multiple quantiles
  • any(x) (aggregate): Any value in the group
  • anyIf(x, cond) (aggregate): Any value among matching rows
  • argMin(x, order) (aggregate): x at the minimum of order
  • argMax(x, order) (aggregate): x at the maximum of order
  • groupArray(x) (aggregate): Collect values into an array
  • groupUniqArray(x) (aggregate): Collect distinct values into an array
  • groupArrayIf(x, cond) (aggregate): Collect matching values into an array
  • groupUniqArrayIf(x, cond) (aggregate): Collect distinct matching values into an array
  • argMinIf(x, order, cond) (aggregate): x at the minimum of order among matching rows
  • argMaxIf(x, order, cond) (aggregate): x at the maximum of order among matching rows
  • quantileIf(0.95)(x, cond) (aggregate): Approximate quantile over matching rows
  • topK(10)(x) (aggregate): Approximate top-K most frequent values
  • windowFunnel(3600)(toDateTime(timestamp), cond1, cond2, ...) (aggregate): Deepest step reached in order within the window (seconds) per group, 0 to N; wrap traces timestamps in toDateTime()
  • retention(cond1, cond2, ...) (aggregate): Array of 0/1 per condition: cond1 met, and each later condition met along with cond1, per group
  • sequenceMatch('(?1).*(?2)')(toDateTime(timestamp), cond1, cond2) (aggregate): 1 when the group’s rows match the step pattern in time order; wrap traces timestamps in toDateTime()
  • sequenceCount('(?1).*(?2)')(toDateTime(timestamp), cond1, cond2) (aggregate): Number of non-overlapping pattern matches in time order; wrap traces timestamps in toDateTime()
  • toStartOfMinute(t) (date): Truncate to minute
  • toStartOfFiveMinutes(t) (date): Truncate to 5-minute bucket
  • toStartOfFifteenMinutes(t) (date): Truncate to 15-minute bucket
  • toStartOfInterval(t, INTERVAL 30 MINUTE) (date): Truncate to an interval
  • toStartOfHour(t) (date): Truncate to hour
  • toStartOfDay(t) (date): Truncate to day
  • toStartOfWeek(t) (date): Truncate to week
  • toStartOfMonth(t) (date): Truncate to month
  • toDate(t) (date): Cast to date
  • toDateTime('2026-01-31 00:00:00', 'UTC') (date): Cast a value to a whole-second UTC datetime; direct datetime-column string comparisons are converted automatically
  • toDateTime64('2026-01-31 00:00:00.123', 3, 'UTC') (date): Cast a value to a UTC datetime with fractional-second precision
  • toHour(t) (date): Hour of day (0-23)
  • toDayOfWeek(t) (date): Day of week (1=Mon)
  • now() (date): Current timestamp
  • today() (date): Current date
  • yesterday() (date): Yesterday’s date
  • dateDiff('hour', a, b) (date): Difference between two datetimes
  • dateAdd('day', 1, t) (date): Add an interval — or just use t + INTERVAL 1 DAY
  • dateSub('day', 1, t) (date): Subtract an interval — or just use t - INTERVAL 1 DAY
  • formatDateTime(t, '%Y-%m-%d') (date): Format a datetime
  • toUnixTimestamp(t) (date): Datetime to unix seconds
  • toUnixTimestamp64Milli(t) (date): DateTime64 to unix milliseconds
  • fromUnixTimestamp(n) (date): Unix seconds to datetime
  • age('hour', a, b) (date): Full units between datetimes
  • lower(s) (string): Lowercase
  • upper(s) (string): Uppercase
  • length(x) (string): String or array length
  • cityHash64(x) (string): Deterministic 64-bit hash, for stable pseudo-random ordering or sampling
  • substring(s, from, len) (string): Substring (1-based)
  • substr(s, from, len) (string): Alias of substring (1-based)
  • concat(a, b, ...) (string): Concatenate strings
  • trim(s) (string): Strip whitespace
  • splitByChar(',', s) (string): Split into an array
  • replaceAll(s, from, to) (string): Replace all occurrences
  • replaceRegexpAll(s, re, to) (string): Regex replace
  • extract(s, re) (string): First regex capture
  • extractAll(s, re) (string): All regex matches as an array
  • match(s, re) (string): Regex test
  • position(haystack, needle) (string): 1-based substring position (0 = absent)
  • positionCaseInsensitive(haystack, needle) (string): Case-insensitive position
  • startsWith(s, prefix) (string): Prefix test
  • endsWith(s, suffix) (string): Suffix test
  • empty(x) (string): True when empty
  • notEmpty(x) (string): True when not empty
  • has(arr, x) (array): Array contains value
  • pattern_match('<experiment id>', '<pattern key>' [, '<comparison group key>']) (misc): Whether the event matched the pattern in the latest saved sample (events table only). Optionally restrict to its saved comparison group. Includes every saved match; it does not judge events outside the sample.
  • answered('<question id>') (misc): Whether Jev answered yes to a saved question on the event (events table only). Only events a count judged have answers.
  • hasAny(arr, [a, b]) (array): Array contains any of the values
  • hasAll(arr, [a, b]) (array): Array contains all of the values
  • arrayJoin(arr) (array): Explode an array into rows
  • arrayCount(x -> cond, arr) (array): Count matching elements
  • arrayFilter(x -> cond, arr) (array): Filter elements
  • arrayMap(x -> expr, arr) (array): Transform elements
  • arrayExists(x -> cond, arr) (array): Any element matches
  • arrayDistinct(arr) (array): Distinct elements
  • arrayFlatten(arr) (array): Flatten an array of arrays
  • arrayConcat(a, b, ...) (array): Concatenate arrays
  • arraySort(arr) (array): Sort elements
  • arraySlice(arr, from, len) (array): Slice an array
  • arrayElement(arr, n) (array): Element at index (1-based)
  • arrayStringConcat(arr, sep) (array): Join array to string
  • indexOf(arr, x) (array): 1-based index of value (0 = absent)
  • JSONExtractString(json, 'key') (json): Extract a string field
  • JSONExtractInt(json, 'key') (json): Extract an integer field
  • JSONExtractFloat(json, 'key') (json): Extract a float field
  • JSONExtractBool(json, 'key') (json): Extract a boolean field
  • JSONExtractRaw(json, 'key') (json): Extract raw JSON
  • JSONExtractArrayRaw(json) (json): JSON array to array of raw JSON
  • JSONExtractKeys(json) (json): Keys of a JSON object
  • JSONHas(json, 'key') (json): JSON field exists
  • toJSONString(x) (json): Serialize a value to JSON
  • mapKeys(m) (map): Keys of a map
  • mapValues(m) (map): Values of a map
  • mapContains(m, 'key') (map): Map has key
  • if(cond, then, else) (conditional): Conditional
  • multiIf(c1, r1, c2, r2, else) (conditional): Multi-branch conditional
  • coalesce(a, b, ...) (conditional): First non-null value
  • ifNull(x, alt) (conditional): Fallback when null
  • nullIf(a, b) (conditional): Null when equal
  • assumeNotNull(x) (conditional): Treat as non-null
  • isNull(x) (conditional): Is null
  • isNotNull(x) (conditional): Is not null
  • round(x, n) (math): Round
  • floor(x) (math): Floor
  • ceil(x) (math): Ceiling
  • abs(x) (math): Absolute value
  • greatest(a, b, ...) (math): Largest argument
  • least(a, b, ...) (math): Smallest argument
  • exp(x) (math): e^x
  • log(x) (math): Natural log
  • log2(x) (math): Base-2 log
  • sqrt(x) (math): Square root
  • pow(x, y) (math): x^y
  • intDiv(a, b) (math): Integer division
  • toString(x) (type): Cast to string
  • toInt64(x) (type): Cast to integer
  • toFloat64(x) (type): Cast to float
  • toInt64OrZero(x) (type): Cast to integer, 0 when not numeric
  • toInt32OrZero(x) (type): Cast to integer, 0 when not numeric
  • toInt64OrNull(x) (type): Cast to integer, NULL when not numeric
  • toFloat64OrZero(x) (type): Cast to float, 0 when not numeric
  • toFloat64OrNull(x) (type): Cast to float, NULL when not numeric
  • tuple(a, b) (misc): Tuple constructor
  • cityHash64(x) (misc): 64-bit hash of a value, e.g. for sampling
  • bar(x, min, max, width) (misc): Unicode bar chart of a value
  • formatReadableQuantity(n) (misc): 1234567 -> 1.23 million
  • formatReadableTimeDelta(sec) (misc): Seconds -> human duration