Docs
Dashboard
Guides / SessionsBeta

Recordings

A frame-by-frame recording of every session's screen, its log of events (console, network, pages, actions and every shell command, whoever ran it), a live stream, and how long both are kept.

Every session keeps two records of what happened in it. Both can be read while the session runs and after it stops:

  • a recording: a frame-by-frame replay of its screen;
  • a log of events: console messages, network requests, page loads, errors, actions, every shell command and more.

They are kept while the session is stopped, for your plan’s retention days: 7 on Free, 30 on Hobby and Startup, 90 on Scale. Then the session is deleted, with its recording and log. You can delete it earlier. See How long they are kept.

Recordings

Sessions record by default (recordSession: true when you create one), on plans that include session recordings (see Plans and features). Create a session with recordSession: false to record nothing.

The platform keeps a JPEG frame:

  • whenever the screen has changed, checked every two seconds;
  • each time a page finishes loading, so a short visit between two checks still shows (at most one such frame every quarter of a second);
  • after each step of an agent run that clicks, types, selects or presses a key, so every step has its own screen;
  • once more when the session stops, so the last screen is there.

A session without a browser (browser: false, a shell only) has nothing to record: it has no frames, hasRecording stays false, and its log has no console, network or navigation events.

GET /v1/sessions/:id/recording lists the frames (index, at and the page’s url) and the recording’s length. GET /v1/sessions/:id/recording/frames/:index returns one frame as an image. The session’s hasRecording tells you whether there is anything to show.

curl https://api.boxline.dev/v1/sessions/$SESSION_ID/recording \  -H "x-api-key: $BOXLINE_API_KEY"curl https://api.boxline.dev/v1/sessions/$SESSION_ID/recording/frames/0 \  -H "x-api-key: $BOXLINE_API_KEY" \  -o frame-0.jpg

Events

A session’s events are the one place for everything that happened in it, live and after it has stopped: what the page did, what your code called, what an agent run did, and every shell command, whoever ran it. GET /v1/sessions/:id/events returns them oldest first. Filter with types. To page forward, or to poll for new events, pass nextAfter back as after. To see only what one agent run did in the session, pass its id as runId.

TypeWhat it records
consolePage console messages, with level (log, info, warn, error, debug).
networkEach finished request: method, URL, status, type, duration and data.bytes, the bytes that came over the network (compressed, headers included). Failed requests have level: "error".
navigationMain-frame page loads, with the tab.
errorUncaught exceptions in the page.
lifecycleWhat happened to the session, for example: created, connected, disconnected, stopped (with the stop reason), resumed, recovered, extended (when you change timeout), updated, proxy changed, session URLs rotated, setup started, setup finished, and the reports of browser settings: ads and trackers blocked, ad blocking on or off, cookie banner rejected or hidden, cookie banners changed, extensions loaded, extension missing. Also processes stopped by a stop, credentials not set in the shell, and warnings when credentials are used in a session with extensions.
actionEvery browser action, whoever ran it, with its result line in text (for example Clicked “Jobs” link at (814, 124)) and its duration. data.by says who. See Browser actions, whoever ran them.
execEvery shell command in the session, whoever ran it, with the exit code and the duration. data.by says who: api, agent (with data.runId and data.step), setup or script. Exported credentials show as placeholders such as %NAME%. See Shell commands.
filesA write, upload or delete through the Files API, for example wrote /workspace/a.csv (1.4 KB). Reads are not logged. See Files.
captchaA CAPTCHA started waiting for a person (data.state: "detected", level: "warn") or is gone ("cleared", with data.waitedMs). With automatic solving, also "solving", "solved", "solve_failed" and "solve_refused" (with data.reason). data.kind says which one, url and tabId where. See CAPTCHAs.

Each event has seq (its number in the session), at, type, and the fields that fit its type: level, text, url, method, status, resourceType, durationMs, tabId and data.

curl "https://api.boxline.dev/v1/sessions/$SESSION_ID/events?types=console,error,captcha" \  -H "x-api-key: $BOXLINE_API_KEY"

A page holds up to 500 events by default (at most 2,000 with limit). next has the same value as nextAfter while the page was full, and is null once you have caught up.

Shell commands, whoever ran them

Every command the session runs is an exec event, from every source. An agent run’s bash commands are in the session’s events too, not only in the run’s steps, so one stream shows what your own calls and the agent did, in order.

data.byWho ran itAlso in data
apiA call to POST /v1/sessions/:id/shell/exec (also the CLI and the SDKs).exitCode, credentials (the names the command was given)
agentThe bash tool of an agent run.runId (the run), step (its step number) and files (the paths the command created or changed)
setupOne of the session’s setup commands, one event per command.setup: true, step (the command’s place in setup)
scriptThe run of a Playwright script.nothing more

An event has the command in text (credential values hidden), durationMs, and the exit code in data.exitCode. The output is not in the event: it stays with whoever ran the command. You get it in the answer to your own call, and an agent’s output is in the run’s steps.

curl "https://api.boxline.dev/v1/sessions/$SESSION_ID/events?types=exec" \  -H "x-api-key: $BOXLINE_API_KEY"

Browser actions, whoever ran them

Every browser action is an action event too: text is the result line, and data says what it was and who ran it. A failure has level: "error" and, when the error has a code, data.code (for example feature_not_in_plan).

data.byWho ran itAlso in data
apiA call to the Actions API (also the SDKs, the CLI, and the computer and MCP browser tools).action (the action’s name)
agentA browser tool of an agent run.runId, step (the step’s n) and frame, the recording frame the step ended on
scriptA step() or extract() call in a Playwright script.line, the line of your script that made the call

An agent run and its events link by runId and step: the run’s steps say why and what (what the agent saw, thought and did, and what it cost), and the events say what happened in the machine. The step keeps the output; the event keeps only the fact. Pass runId to list or stream just one run’s events.

curl "https://api.boxline.dev/v1/sessions/$SESSION_ID/events?runId=$RUN_ID&types=action,exec" \  -H "x-api-key: $BOXLINE_API_KEY"

Files

A write, upload or delete through the Files API is a files event: data: {op: "write" | "delete", path, bytes, by: "api"}, with the path relative to the workspace. Reading, listing and downloading folders are not logged. The files a shell command creates or changes are on that command’s exec event (data.files, for an agent’s command), never also as files events.

Live stream

GET /v1/sessions/:id/events/stream is a server-sent events stream: it sends what is already logged after after, then each new event as it happens, one per data: line. It carries the same events as the list, an agent run’s shell commands included, and takes runId too.

curl -N https://api.boxline.dev/v1/sessions/$SESSION_ID/events/stream \  -H "x-api-key: $BOXLINE_API_KEY"

Pages visited

GET /v1/sessions/:id/pages lists each URL the session opened, per tab, with its title, the number of visits and the first and last time it was seen.

curl https://api.boxline.dev/v1/sessions/$SESSION_ID/pages \  -H "x-api-key: $BOXLINE_API_KEY"

How long they are kept

A stopped session keeps its recording and log until its deletesAt: your plan’s retentionDays after it stopped. The platform checks once an hour, and then deletes the session.

PlanKept after the session stops
Free7 days
Hobby30 days
Startup30 days
Scale90 days

The day is fixed when the session stops (deletesAt = stoppedAt + retentionDays), so a later plan change does not move it. Resuming a session and stopping it again sets a new day. You can also delete a session yourself, at any time: DELETE /v1/sessions/:id. That deletes everything below at once and cannot be undone.

What is deleted:

  • the recording (every frame);
  • the event log and the list of pages visited;
  • the steps of agent runs in the session: their tool output and screenshot notes;
  • what the session saved when it stopped: the browser (tabs, cookies and site storage) and the files in /workspace (downloads and uploads too), and any copy left from its checkpoints.

The session record stays, with its usage and cost for billing. Its status becomes DELETED, with deletedAt and deleteReason (requested or retention), and a session.deleted webhook is sent. After that, the recording and log calls answer with empty lists, and hasRecording is false. Agent runs keep their task, result and token counts.

Not affected: browser profiles (until you delete them), usage and billing records, and webhook bodies, which have their own rule (7 days). Your plan’s value is limits.retentionDays in GET /v1/auth/me.

These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.