/api/v1/rum prefix and require a bearer token.
rum.write; an application-bound client token holds
exactly this permission for one application. Reading requires streams.query. A platform caller can use sys.telemetry.read
in the protected _sys scope. Creating, changing, and deleting an application requires api_tokens.manage, and setting the state, the team,
or the person of an issue requires rum.manage.
A type names the kind of row an endpoint works on: sessions, views, actions, errors, resources, long_tasks,
or vitals. Each type is the stream of the same name with the rum_ prefix
removed.
Endpoints
GET /api/v1/auth/tokens/rum returns the client token of an application.
Send a replay segment
session_id, seq, and events are required. env, service, and version may be sent too, as the SDK was set up with them:
they tell the retention filters of the application what the session is like, so that a segment of a
session that is not kept is not stored. No other field is accepted. events are rrweb events. A client token writes
to its own application: application can be left out, and a different value answers 403. Any other credential
names the application. An application that does not exist answers 404. The answer describes the stored segment:
its id, seq, event_count, and has_full_snapshot.
GET /api/v1/rum/replay/{session_id} returns session_id, segment_count, and events, the events of all the
segments of the session in order.
Manage applications
An application has anid, a name, a platform, and settings:
POST answers the new application. An identifier or a name that exists answers 409. PATCH takes any of name, platform, and
settings. DELETE answers { "deleted": true }. The events the application already sent stay in the streams until
their retention ends them.
Search rows
POST takes the same names in a JSON body and suits queries too long for an address. In an address, filters, free_text, and
columns are JSON-encoded lists.
A filter has a
field, an op, and a value. At most 32 filters, and a value of at most 512 characters.
A field that the type does not have, or an operator the field cannot answer, fails the request with
400.
The answer holds the rows of one page, newest first:
timestamp_micros and the columns asked for. A JSON column holds the document. Views and sessions
appear once, in their latest version.
Count and describe rows
facets takes the parameters of search without paging and adds field (required) and limit (from 1 to 100, default 10).
It answers the most common values of the field across the matching rows:
unavailable set to time_budget or busy.
A field that holds a JSON document answers 400.
histogram takes the same selection and the bars to count into: bucket_micros (at least 1000) and origin_micros, the start of
the first bar, which is from when left out and cannot be after it. A range holds at most 512 bars. Each bucket is { start_micros, total, errors }. errors counts the rows
that went wrong: sessions and views with errors, actions with frustration, and requests with a status of 400 or more, or
0. split is false for the types that have no such rows.
GET /api/v1/rum/schema/{type} lists the columns the other endpoints take and answer with:
data_type is bool, int64, float64, utf8, or json. unit is ns, ms, bytes, count, score, percent,
per_second, px, or none: durations are stored in the nanoseconds the SDK sent, and a client formats them. A
facetable field can be counted by value, an indexed field filters without reading every row, and id_field names the
column that tells one row from another.
Measure rows
aggregate takes the selection of search and measures across every matching row. It answers the numbers behind charts,
tables, and maps: how many sessions, the 75th percentile of a vital, per page or per hour.
A measure has an
fn and a field, and may have a name, a where, and a fallback.
where is a list of filters, as in search, and the measure takes only the rows that meet them:
{"fn":"count","where":[{"field":"session.error.count","op":"=","value":"0"}]} counts the sessions without errors. A measure
is called by its name, else fn(field), else fn when it has no field, and two measures cannot have the same name. A field
that the type does not have, or a number asked of a field that is not one, fails the request with 400.
group it is of, in the order of group_by, and the values of the measures, in their order. Over time it
also has start_micros, where its bar begins. A group whose rows have no value is null, and so is a percentile of no
values. unit is count, or the unit of the field as schema gives it. Views and sessions are counted once, in their
latest version. Where no row matches, an answer with groups or bars has no rows, and one with neither has one row: counts are 0 and the other measures null. A value the reader may not see comes back as the text it is masked to. A count that takes too long or finds
the system busy answers no rows, with unavailable set to time_budget or busy.
Funnels, paths, and retention
The three endpoints under/api/v1/rum/analytics answer the questions of RUM analytics. Each takes the
selection of search that applies to sessions, views, and actions: from and to in microseconds, and filters, what every
row has to meet, usually the application (application.id) and the environment (env). With GET, the lists are JSON in their
parameters, so a question is a link; POST takes the same names in a JSON body. They need streams.query, or sys.telemetry.read
in the protected _sys scope. A count that takes too long or finds the system busy answers no figures, with unavailable set
to time_budget or busy. The answers carry the from and to they are of.
Funnel
A session counts for the first step by its first row that meets it, and for each step after by its first row that meets it later
than the row of the step before, in the same session.
breakdown, in the order of their sessions at the first step,
and value is null for all of them together, or for the sessions whose row has no value. conversion is the share of the
sessions of the first step, from_previous the share of the sessions of the step before, and median_ms the middle of the times
since the step before; each is null where it has no meaning. A field of a type that is not text, or that the type does not have,
fails the request with 400.
Paths
columns, one more than depth, the page the paths are of being column 0 (the last column going back).
A node is a page of a column with the sessions that were there and the ends that went no further (that began there,
going back). A link goes from a page of column to a page of the next column (the one after in time, also going back) with the
sessions that went that way. Pages are taken in the order they were opened, one page opened again at once counting once. A
column names the 8 pages with the most sessions, and the rest are __other__. sessions is the number of sessions that have
the page the paths are of.
Retention
start_micros, in the time range asked for. A person is
the usr.id of a session, or where it has none its usr.anonymous_id. returned has, for each period after, how many of the
cohort were seen then; it is null for a period that has not ended by to.
Playlists
A playlist is a named list of the sessions of one application, each with the moment worth opening it at.GET /api/v1/rum/playlists answers the playlists without sessions, the one changed last first, and takes application to
narrow to one. Reading requires streams.query, and a platform caller can use sys.telemetry.read. The others change a playlist
and require rum.manage; every one of them answers the playlist with its sessions, except DELETE, which answers { "deleted": true }.
A session in a request is
{ "session_id": "...", "at_micros": 1790000005000000 }: the id is 1 to 128 characters, and at_micros, when
given, is a moment after the epoch in microseconds that the session opens at; without it, the session opens at its beginning. The
playlist holds ids, not sessions: it does not check that a session exists, and a session whose rows have been deleted by retention stays
in the list. GET /api/v1/rum/sessions/{id}/playlists answers the playlists, without their sessions, that hold a session.
Read one row, one session
GET /api/v1/rum/{type}/{id} answers one row with all its columns, or 404. from and to narrow where to look; without
them the lookup covers the last 30 days. {id} is the value of the id_field of the type.
GET /api/v1/rum/sessions/{id}/timeline answers:
GET /api/v1/rum/sessions/{id}/related-traces lists the backend traces of a session. It names the traces whose ID a request
of the session carried (relation: direct), and when there are none, the traces that ran while the session did
(relation: time-correlated). Each trace has its trace_id, service, span_count, duration_ms, and
started_at_micros, and the answer has the primary_service. GET /api/v1/rum/traces/{trace_id}/session goes the other way
and answers the session, or null.
Issues
Errors that are alike are grouped into issues, and every error row carries the id of its issue inerror.issue_id.
The numbers of an issue are counted from its errors in the range asked for. Its state and its history are kept apart.
Times are microseconds since the Unix epoch.
regressed_environment is the environment of the error that brought the issue back, and null when that error names none. An issue
belongs to the whole application, whatever environment its errors are in. The server also keeps the first time each environment saw
it, which is what alert rules count to tell the new issues of an environment.
The list reads the 250 issues with the most sessions (or users, or occurrences, by sort) and narrows them by status, assignee,
team, search, and fresh. total is how many issues the filters leave, before limit cuts the list. trend holds the occurrences
in each of up to 12 equal parts of the range, oldest first. overflow marks the issue that counts the errors of an application past
the issues it may open in an hour. A count that takes too long or finds the system busy
answers no issues, with unavailable set to time_budget or busy.
GET /api/v1/rum/issues/{id} answers the issue as the list has it, without trend, with sessions, users, and occurrences
counted over from and to, and two more fields:
An issue that does not exist answers
404.
PATCH /api/v1/rum/issues/{id} takes any of status, assignee_id, and team_id, and answers the issue after the change.
status is open, investigating, resolved, or ignored. regressed is set by the rules when a resolved issue is seen again in
a newer version, and answers 400. assignee_id has to be a member of the organization and team_id a team of it; null or an
empty text takes the person or the team off. A field left out stays. Resolving records resolved_at, resolved_by, and the newest version of
the application as resolved_version, and any new state ends the record of an earlier resolving or regression. A request that names no field to change answers 400; one that sets what is already set answers 200 and changes nothing. Each change is written to the audit log as rum.issue.update.
Preview an alert rule
streams.query.
unit is count, percent, milliseconds, or score. A point has the start of its window in at, the figure in value, and the
rows the figure is made of in samples; a window that holds fewer rows than min_samples has neither. current is the last point,
the window that ends at to. A count that takes too long or finds the system busy answers no points, with unavailable set to
time_budget or busy. An application that does not exist answers 404, and a rule that does not fit its figure answers 400.