Skip to content

Events and payload

Every beacon is a single POST to <endpoint>/speed with Content-Type: application/json. The body is one object with one key, payload, whose value is the JSON envelope serialized as a string:

{
  "payload": "{\"name\":\"page_view\",\"originFrom\":\"launcher\",\"aid\":\"5df28c35-e6bb-4e3b-abd1-bdb3609b9a55\",\"uin\":\"\",\"version\":\"1.0\",\"env\":\"production\",\"platform\":3,\"netType\":4,\"vp\":\"1280 * 720\",\"sr\":\"2560 * 1440\",\"sessionId\":\"1f0c9b7d54a24f3c8e5b6a7d9c0e1f2a\",\"ext1\":\"AAAAAAAAAAE...\",\"ext2\":\"m3X...\"}"
}

No other top-level keys exist, and the inner object has exactly these fields:

field value
name always page_view
originFrom always launcher
aid a v4 UUID generated per page load
uin empty string
version 1.0
env production
platform 3
netType 4
vp viewport, "<innerWidth> * <innerHeight>"
sr screen, "<width> * <height>"
sessionId 32 random hex characters
ext1 base64url record: 8-byte counter plus the session payload
ext2 16 random bytes, base64url

The envelope is fixed on purpose: everything that varies is inside ext1.

Page views

k = page_view. A view is sent on load and on every SPA route change:

  • history.pushState and history.replaceState are wrapped, and popstate is observed.
  • Changes are debounced by 300 ms, so a burst of pushes during one navigation produces one beacon.
  • The URL is compared before sending, so a replaceState with the same path is dropped.

Custom events

InsightJS.track(name, props) sends the same envelope (still name: page_view), with k = event inside ext1, plus n (the event name, truncated to 64 characters) and p (the properties, as JSON). It does not increment the page-view count.

The session record

ext1 is a base64url string. Decoded, it is:

+----------------+--------------------------------------------+
| 8-byte counter | opaque session payload                     |
+----------------+--------------------------------------------+

The counter is unsigned big-endian. The client increments it with every beacon in the page. The rest is the client's session data; the endpoint should treat it as opaque bytes. For reference, the client writes a compact JSON object there:

key meaning
t session time in ms
k page_view, event or session
u URL of the view or event
pv page views so far
lcp, cls, inp, fid web vitals
ttfb, dcl, ld navigation timing
e, r, f error, rejection and resource-failure counts
m first error message, up to 120 characters
n, p event name and properties, events only

ext2 is random and carries no meaning yet; it exists so two beacons from the same session are not byte-identical.

Replies

The client does not read the response and does not retry. Any JSON reply is fine; an empty 204 is fine too.