What the recorders capture
A recorder watches a running application, so what it takes and where it sends it is published as a contract rather than described in marketing. This page mirrors docs/PROTOCOL.md in the kit repository.
This is a contract
Any change to what a recorder captures or transmits has to update that document in the same pull request, and divergence between the document and the code is treated as a security issue rather than a documentation bug.
Where data goes
Exclusively to the vitrinka server you configure — a base URL and a bearer token. There is no third-party telemetry, no analytics SDK, and no traffic to any host other than that server.
POST /api/v1/sessions create a recording session
POST /api/v1/sessions/:id/events the event stream (batched)
POST /api/v1/sessions/:id/shot screenshot keyframes
PATCH /api/v1/sessions/:id status (recording | paused | done)Four routes. That is the entire surface a recorder talks to.
When recording happens
Only during a session you explicitly start — and for Expo, only in a build that was allowed to carry the recorder at all.
- Expo — compile time — the recorder exists only in builds that bake
EXPO_PUBLIC_VITRINKA_URLand_TOKEN; every other build strips the whole recorder from the bundle. - Expo — run time — inside an enabled build, capture runs only between you pressing record and stop. A machine-driven session started over the Expo devtools channel shows a visible HUD indicator.
- Browser — scoped — capture runs only in tabs matching the project's configured domains, and only while a session you started is live. The popup always shows the recording state.
What is captured, per session
| Channel | Expo recorder | Browser extension |
|---|---|---|
| Screenshots | Keyframes on navigation and touch, throttled. | Keyframes plus an rrweb DOM stream. |
| Interactions | Tap coordinates, the pressed element's label, and the route. | Clicks and navigation. |
| Network | Method, URL, status, duration, and capped request/response bodies. | API calls including bodies, via CDP. |
| Console | Errors and warnings. | Errors. |
| Notes | Notes you type in the HUD. | Notes you type in the popup. |
Redaction
Network capture masks secrets before anything is buffered or sent — not on the server, and not on the way out. Secret-named keys are masked in JSON bodies, in headers and in URL query strings, including URL-encoded and double-encoded forms.
- What counts as secret —
password,token,authorization,cookie,apikey, and multi-word forms likeaccessTokenorrefreshToken. - One shared predicate — the policy lives in a single function with its own test suite, so the three channels cannot drift apart.
Screenshots are not content-filtered. Redaction covers the network channel only — do not record against screens showing data you would not put on the session's board.
Retention and access
Recorded sessions live on your vitrinka server, under its access rules. The recorders themselves keep only an undelivered upload tail on the device, which is removed once it is delivered or the session is discarded.