Skip to main content
Real user monitoring (RUM) measures your site as your users’ browsers experienced it: page views, sessions, Core Web Vitals, JavaScript errors and how long each asset took to load. It is measured in the browser, so it sees what no server-side trace can — a slow network, a heavy bundle, a script that threw before any request was made.
Plan entitlement. RUM data is served only to organizations whose plan includes the rum feature. Without it, the RUM tabs show Not included in this plan with the reason, instead of an error. The install snippet itself is available whatever your plan, so you can install first.

How browser telemetry arrives

There is no OpenTelemetry step for the browser. A small aiAxonIQ browser agent, loaded by a snippet in your pages, sends beacons straight to the /rum path on the same host that serves your dashboard — for aiAxonIQ Cloud, https://app.aiaxoniq.com/rum. The agent’s own code is served from that host too, under /rum-agent/. The beacons are authenticated by a Browser project’s agent key, which is written into the snippet. That key is public by design — it ships in your page source, where anyone can read it — so it is not treated as a secret:
  • Each project’s ingest is rate-limited per project. That is the control that refuses traffic.
  • A project can carry a list of allowed page origins. That list stops another site pasting your snippet and polluting your numbers; it is a data-quality control, not an authentication boundary, because anything that is not a browser can simply omit the origin.

What the agent collects

Why replay is off at the server, not only in the snippet. A snippet is text on your page, and anyone can edit it. The server tells the agent which features it may run, and it denies session replay and console capture regardless of what the page asks for.

Install the snippet

Open RUM and choose Set up a website (or go to /rum/setup). You need the Editor role or above to create a website. The setup takes four steps:
1

Name your website

One per site or single-page app. This creates a Browser project and its agent key. Picking a website you already set up reuses it — no second key is created.
2

Configure collection

Three settings, all applied by the collector when page views arrive:
  • Allowed sites — page views are accepted only from these addresses. Empty accepts any site. This keeps a site that copies your snippet out of your numbers; it is not an authentication control.
  • Anonymise visitor IP addresses — on by default: sessions are located to their country. Off adds the city. The IP address itself is never stored.
  • URL grouping — numbers, UUIDs and long hex strings in a path are grouped as :id automatically. Add a regular expression for any other segment that is really an id; the page previews the route a URL will be stored under.
Changes reach the collector within five minutes.
3

Install the snippet

Copy the snippet into the <head> of every page — the page shows where it goes for plain HTML, Vite (React, Vue, Svelte), Angular and Next.js — and the Content-Security-Policy directives to add if your site sends one.
4

See it report

Deploy, then open any page of your site. The setup page checks every five seconds whether this website’s page views have arrived, and turns green with the first page views, sessions, browser and latest page as soon as they do.

Through the API instead

For automation, the same flow is available through the API. You need a session token — see Authentication — and the Editor role or above to create a project.
1

Find your organization id

Every call names your organization as tenantId:
2

Create a Browser project

The response is the new project (201); its _id is the project id. Creating the same name and type again returns the existing project (200) rather than a second one. If you already have a Browser project, list it instead:
3

Fetch the snippet

The response is two <script> elements: a configuration block carrying the project’s agent key and id, then the agent loader.
4

Paste it into every page

Put the snippet in the <head> of every page you want measured. Paste it exactly as returned: the beacon address and the address the agent loads its code from must both point at the host that issued it.
5

Check that it is reporting

reporting turns true once a page view from this project has arrived in the last 24 hours, with pageviews, sessions, lastSeen, lastPage and browser. Until then those are 0 or null — never a value for a page view that did not happen.
Expected result. Load a page. In the browser’s network tab you should see the loader fetched from /rum-agent/… and beacons sent to /rum/… answered with a success status. Once the first page load has reported, RUM → Overview shows a non-zero Sessions and Page views count. To see original file names and line numbers in error stacks, also upload your source maps — see Source maps for browser errors.
Do not rotate the project’s agent key casually. The snippet already on your pages carries the current key; replacing it stops every page that has not been updated from reporting.

What the RUM section shows

RUM opens on Websites: every Browser project on the account with its sessions, page views, JavaScript errors and Core Web Vitals for the selected time range. Open a website for its own workspace. Every page in it reads only that website’s data, and its side navigation groups the pages as Monitor (Summary, Page views, AJAX, Web vitals, Assets, Releases), Triage (JS errors, Frustration), Users (Session traces, Page actions, Browsers, Geography) and Settings (Application settings). A page view opens its own page: the same summary for that one route, and the API calls, errors and sessions seen on it. An AJAX endpoint opens its status codes, the pages that call it and its slowest calls. An error group opens its stack, the sessions it hit, what the person did just before it, and where it happens — its sessions by browser, operating system, device, page and release beside the same split of your traffic, naming the one it is markedly over-represented on. A session opens its trace: page loads, route changes, API calls, flagged clicks, page actions, errors and vitals in order.
Sessions, Page views, Bounce rate (sessions with one page view), Sessions with errors, Page load p75 and Users (distinct user ids your site set; anonymous visitors are not users). Below them: the five vitals, traffic and JavaScript errors over time on one grid, where the average page load goes (server response, download and parse, subresources), the slowest pages at p75, and browsers, devices, operating systems and countries by page views. A page view is a full page load or a route change inside a single-page app, so moving around an app is not a bounce. A performance score (0–100) weighs the vitals as Sentry does — LCP and INP 30 each, CLS and FCP 15, TTFB 10 — scoring 90 at a vital’s “good” threshold and 50 at its “poor” one. The Frustration card gives the share of sessions with a rage, dead or error click.
LCP, INP and CLS (the Core Web Vitals) plus FCP and TTFB, each judged at the 75th percentile against web.dev’s thresholds — for example LCP good at 2.5 s or less and poor above 4 s, CLS good at 0.1 or less and poor above 0.25, INP good at 200 ms or less and poor above 500 ms. Every card shows the share of samples that were good, needed improvement or were poor, and how many samples the verdict stands on; fewer than 20 is marked as indicative. Pick a vital to see its p75 over time drawn on the three bands, and a per-page table judging every route the same way, with its score and its opportunity — how many points the whole site would gain if that page scored 100.For LCP, INP and CLS, What to fix shows where the time goes (INP’s input delay, processing and presentation; LCP’s time to first byte, load delay, load duration and render delay) and the elements behind it, worst first.A vital with no samples is marked as not measured, never shown as zero. INP needs someone to interact with the page. FID is not shown: INP replaced it as a Core Web Vital in March 2024.
One row per session that started in the window: user, start, duration, views (with a Bounced badge for one-page sessions), errors, entry page (grouped into its route), browser and OS, device and country. Expand a row for its referrer and campaign parameters, the client build, and its page-load waterfall.
JavaScript errors grouped by a fingerprint computed from the stack, so a rebuild that only changes a bundle hash does not create a new group. Each row shows occurrences, affected sessions and users, the page and the last time it was seen. Expand a row for the stack, with each frame marked Symbolicated or Not symbolicated depending on whether a matching source map is uploaded.
Every XHR and fetch your pages made, by endpoint (ids in the path grouped as :id): calls, how many failed (status 400 or above, or no response) and their share, and p50, p75 and slowest duration. The agent’s own reports are left out.
Clicks that did not do what someone expected: rage clicks (several fast clicks on one element), dead clicks (a click that changed nothing) and error clicks (a click followed by a JavaScript error) — over time, by the element people clicked, and by page.
Every release of your site that reported in the window, newest first: sessions, the share that hit an error, the error groups it introduced, and LCP, INP and CLS — each compared with the release before it, with a vital that moved to a worse band flagged. Needs setApplicationVersion (below).
The events your pages report with addPageAction, by name: how often, in how many sessions, by how many users and on which page. A name opens its trend, its attribute values and its latest occurrences, each linked to its session.
Scripts, stylesheets, images and fonts by host and type, from the browser’s Resource Timing API: requests, average and p75 duration, the share served from the browser cache, and bytes transferred.
At the time of writing, no browser has been verified reporting to a deployed aiAxonIQ environment. The pipeline has been exercised in a real browser against the snippet this page describes, and the RUM section is available so that you can install it — but treat your first installation as the check, and use the expected result above to confirm it.

Tell RUM about your app

Three calls, made on every page after the snippet, give the RUM pages what only your code knows. The agent’s API is on window.AIAXONIQ.
A user id is whatever identifier you choose to send; send an opaque id rather than an email address. Source maps are matched to errors by the release you declare with addRelease(name, id) — see Source maps.

Troubleshooting

No browser telemetry yet means no page views and no sessions arrived in the window. That is what an un-instrumented site looks like, and waiting will not change it. Check that the snippet is in the page’s <head>, then load a page and watch the network tab: the loader should come from /rum-agent/… and the beacons should go to /rum/….
The snippet was probably edited or assembled by hand. The agent fetches the rest of its code from the address in the snippet’s configuration; if that address is missing or points at your own site, the agent fails to load its code and sends nothing. Replace the snippet with a fresh copy from the rum-snippet call.
The response body says which of three reasons applies. Unknown agent key means the key in the snippet is not a current project key — the project was deleted, or its key was replaced after the snippet was pasted; fetch the snippet again. Origin not allowed for this project means the project has a list of allowed origins and the page is not on it. No agent key supplied means the snippet’s configuration block is missing or was edited. A burst of refusals under heavy load can also be the per-project rate limit.
Your organization’s plan does not include RUM. The snippet can still be installed; the data becomes visible when the plan includes the rum feature.
No browser reported that vital in the window. Some browsers do not report every vital, and a page that is closed before it finishes loading reports none.
A cross-origin asset served without a Timing-Allow-Origin header reports no timing to the browser, so it is counted but left out of the durations. Add the header on the asset’s host if you control it.
The collector records each visitor’s network prefix but needs a GeoIP database to name a country, and none is configured yet. No country is guessed.

Next

Source maps for browser errors

Show original file and line numbers in stacks.

APM

The server side of the same requests.