Docs
Dashboard
Guides / SessionsBeta

Lifecycle

How long a session lives, why it stops, how long a stopped session is kept, and how to find, update, stop, resume and delete sessions, one at a time or in bulk.

A session starts RUNNING. When its work is done, you stop it: the platform saves it exactly as it is and frees the machine, and billing stops. A stopped session can be resumed later, with the same id. Or you delete it, which ends it for good. This page covers the whole life of a session, and how to manage many at once.

Statuses

StatusWhat it meansBilled
RUNNINGThe machine is up. You can connect, run commands and read files.Per second
STOPPEDSaved, with no machine. Resume it to use it again. It is kept until its deletesAt (your plan’s retention days), then deleted. It does not count towards your concurrent sessions. See Stop and resume.No
DELETEDEnded for good. What it saved, its recording, its logs and its pages are gone. The session record stays, with its usage and cost, for billing.No
ERRORThe session never started. error says what failed.No

Stopping is how a session’s work always ends: you stop it, or the platform does when its time runs out, it goes idle, or a limit is reached. There is no other way. A session is deleted only when you delete it, or when its retention days pass.

How long a session lives

  • Every session stops when it reaches its timeout (stopReason: "timeout"), unless you stop it first. expiresAt tells you when. Resuming it starts a new clock of timeout seconds. To give a running session more time, change its timeout (see Update a session).
  • A browser-only session without keepAlive stops about 5 seconds after its last CDP client disconnects ("no_clients"). The short grace period lets a client reconnect. Set keepAlive: true to keep it running between connections. It never stops this way while an agent run, a script or a plain-English step works in it, or while a run in it can still be resumed.
  • A session with a shell, and one no client ever connected to, keeps running until you stop it or it times out.
  • With an idleTimeout (opt-in, 30 seconds up to its timeout), it stops after that long with no activity at all ("idle"), up to about 15 seconds late. Use it for keepAlive and shell sessions whose client may crash. See idleTimeout for crashed clients.

Every rule for how sessions and agent runs end, with best practices, is on How runs and sessions end.

Why a session stopped

A stopped session shows stoppedAt and stopReason. Both are null while it runs, and a resume clears them.

stopReasonWhat happened
requestedYou (or the console) stopped it.
timeoutIt reached its timeout.
idleIts idleTimeout passed with no activity.
no_clientsA browser-only session without keepAlive lost its last CDP client, with no agent run, script or step working in it.
agent_runAn agent run finished and stopped the session it had created, or its resume window passed unused.
taskA task’s run finished and stopped its session.
machine_lostIts machine failed and could not be recovered. What it saved is its last checkpoint; error says what happened. With no checkpoint, nothing was saved and a resume answers 409 nothing_saved.
api_restartThe API restarted and the session’s machine could not be taken back, with no checkpoint to start it again from. Nothing was saved.
account_recoveredA password reset recovered an account whose email was not confirmed. Nothing is kept. See Password resets.
suspendedAn admin suspended the organization. Its running sessions stop, saving what they can. See Suspended organizations and projects.
spend_limitThe organization or the project reached the monthly spending limit its owners set. Running sessions stop within about a minute, saved like any stop. See Credit and spending limits.
out_of_creditThe organization had no credit left. Used only when refusing work at zero credit is switched on, which it is not yet: today, running out of credit only sends an alert.

How long a stopped session is kept

A stopped session keeps its saved browser and files, its recording, its logs and its pages, and the steps of agent runs in it, for your plan’s retentionDays, counted from stoppedAt.

PlanDays a stopped session is kept
Free7
Hobby30
Startup30
Scale90
  • The day is fixed when the session stops: deletesAt = stoppedAt + retentionDays. A later plan change does not change it. If you resume the session and stop it again, it gets a new deletesAt.
  • When deletesAt passes, the session is deleted: status: "DELETED", deleteReason: "retention", and a session.deleted webhook. Resume a session before then if you need it.
  • The session record stays after a delete, with its usage and cost. Agent runs keep their task, result and token counts. Browser profiles, usage and billing records are not affected.
  • While an organization is suspended, nothing of it is deleted. The days keep counting, so what has passed is deleted once the suspension is lifted.

Checkpoints and recovery

The platform saves every running session’s whole browser and its workspace about every 5 minutes. This is a checkpoint; checkpointAt shows the last one. The browser is saved while it runs. Tabs with their history, cookies, every site’s storage and form values are in it; the caches are not. See What a session keeps.

If a machine stops (a crash, or a lost server), the platform starts the session again on a fresh machine from its last checkpoint. It keeps its id and its URLs. recoveries counts how often this happened, and a lifecycle event says how old the checkpoint was. Work done after that checkpoint is lost, and running processes start again. A recovery can miss the last few seconds of changes in the browser, because a checkpoint copies it while it runs.

If the browser is too big to save whole (over 256 MB compressed for a checkpoint, over 1 GB compressed for a stop), or the machine is from an older version, the session comes back with what its open tabs held, and a lifecycle warning says so, once per session and reason. See When the browser cannot be saved whole.

When a machine is about to go away (a planned server change), the platform starts the session on a new machine first, with nothing lost. You do not need to do anything.

When the platform’s API restarts, for example during a deploy, sessions keep running: the new API takes their machines back. An agent run working in one ends as server_restarted, and can be resumed in the same browser. See When the API restarts.

Find sessions

GET /v1/sessions lists your sessions, newest first, with filters. The response has total (how many match) and next (a cursor for the next page). See Pagination.

QueryMeaning
statusOne or more of RUNNING, STOPPED, DELETED, ERROR, comma-separated.
kindbrowser (no shell), combined (browser and shell) or shell (no browser). See Three kinds of session.
qThe start of a session id, or text inside userMetadata.
from, toISO dates, compared with createdAt.
sortcreated_desc (default), created_asc or duration_desc.
limit, afterPage size (default 50, at most 500) and the next value of the previous page. Pages are always read with after.
curl "https://api.boxline.dev/v1/sessions?status=RUNNING,STOPPED&q=customer-42&limit=25" \  -H "x-api-key: $BOXLINE_API_KEY"# Only sessions with a shell and no browser:curl "https://api.boxline.dev/v1/sessions?kind=shell&status=RUNNING" \  -H "x-api-key: $BOXLINE_API_KEY"# The next page: send the previous answer's "next" back as "after":curl "https://api.boxline.dev/v1/sessions?limit=25&after=$NEXT" \  -H "x-api-key: $BOXLINE_API_KEY"

In the SDKs, a list call returns its first page, and iterating it goes through every match. See Pagination.

Get a session

GET /v1/sessions/:id returns the session object, with connectUrl, liveUrl and terminalUrl signed afresh every time. A stopped or deleted session has no URLs, and each URL is null for a part the session was created without (see Three kinds of session).

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

Update a session

PATCH /v1/sessions/:id is the one call for every change to a running session. It takes the same field names and shapes as Create a session. Send any of these together; fields you leave out do not change. The checks run first and the changes after, so a bad value leaves the session as it was. The answer is the session.

FieldWhat it does
timeoutThe session’s length in seconds, counted from its last start (a resume starts it again). expiresAt follows. At least 60 seconds from now, at most your plan’s longest session (402 plan_limit above it). See Give a session more time.
idleTimeoutSeconds without activity before it stops, counted from now, 30 up to its timeout. null switches it off.
keepAlive, userMetadataAs on create.
proxyA new proxy, applied at once: open connections are closed, so every request after the change uses it. null removes the proxy. See Proxies.
rotateProxytrue gives the proxy a new IP now (a sticky IP stays the same until then). 400 without a proxy. See Proxies.
rotateUrlstrue makes every earlier connectUrl, liveUrl and terminalUrl stop working. The answer carries the new ones. See Live view.
captcha"ask", "ignore" or "solve", applied at once. See CAPTCHAs.
browserThe browser’s settings, { mode, locale, timezone }, never on or off. See Browser mode.
blockAds, cookieBannersApplied at once. See Ad and cookie-banner blocking.

A change that needs a feature your plan does not include, such as a residential proxy or captcha: "solve", gets 402 feature_not_in_plan (see Plans and features). A session that is not running answers 409 session_not_running.

Fixed when the session is created

These cannot change while the session lives. Sending one answers 400 not_updatable and names the field; the SDKs raise it as a NotUpdatableError.

  • browser or shell on or off (the kind of session; only the browser’s settings above change).
  • viewport, profile and recordSession.
  • setup, extensions, env and credentials.

For any of these, create a new session with the setting you need.

curl -X PATCH https://api.boxline.dev/v1/sessions/$SESSION_ID \  -H "x-api-key: $BOXLINE_API_KEY" \  -H "content-type: application/json" \  -d '{"keepAlive": true, "userMetadata": {"customer": "customer-42"}}'# A viewport cannot change: 400 not_updatable, naming "viewport"curl -X PATCH https://api.boxline.dev/v1/sessions/$SESSION_ID \  -H "x-api-key: $BOXLINE_API_KEY" \  -H "content-type: application/json" \  -d '{"viewport": {"width": 390, "height": 844}}'

Give a session more time

A session’s timeout is its whole length, counted from its last start, so to add time, send a bigger number: the current timeout plus what you need. expiresAt follows. The total can never pass your plan’s longest session; past that you get 402 plan_limit. A link is valid until 5 minutes after the expiresAt it was signed with, so take the fresh links from the answer. The session.expiring webhook comes about a minute before a session stops by time, a good moment to raise its timeout; an agent run shows its session’s end as sessionExpiresAt.

curl -X PATCH https://api.boxline.dev/v1/sessions/$SESSION_ID \  -H "x-api-key: $BOXLINE_API_KEY" \  -H "content-type: application/json" \  -d '{"timeout": 1500}'   # it had 900: ten more minutes

Stop a session

POST /v1/sessions/:id/stop saves the session exactly as it is (the whole browser, with every tab and its history, and the files in /workspace), frees the machine and returns the session with status STOPPED. Billing stops at that second. Stopping a session that is already stopped is safe: you get it back as it is. If the state cannot be saved, the call fails and the session keeps running: stop it again.

If the session uses a browser profile with persist: true, its cookies and storage are saved to the profile too.

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

A stop ends the session’s signed URLs for good. It rotates connectUrl, liveUrl and terminalUrl, as rotateUrls: true in Update a session does: the links you held stay refused after a resume, and the session that resume returns has fresh ones. So a link you shared cannot reach a session that was stopped and resumed. Share the fresh links only with the people who should have them.

Resume a session

POST /v1/sessions/:id/resume brings a stopped session back on a fresh machine, with the same id and everything as it was when it stopped, and returns it with status RUNNING. It gets a full timeout again, and fresh connectUrl, liveUrl and terminalUrl. You can stop and resume a session any number of times. Running processes and page memory do not come back: pages reload. See What a session keeps.

A call on a stopped session does not resume it. Browser actions, commands, writing files, the live view and connect answer 409 session_not_running until you call resume. Reading its files works without a resume: see Files of a stopped session. An agent run given a stopped sessionId resumes it itself.

AnswerWhy
409 nothing_savedNothing was saved when the session stopped: its machine was lost before its first checkpoint, or it stopped without saving (see Why a session stopped). Start a new session.
409 session_not_stoppedThe session was deleted. A deleted session cannot come back.
409 conflictIts browser profile is in use by another running session.
429 concurrency_limitYour plan’s concurrent sessions are all running. Stop one first.
402 spend_limit, 402 out_of_creditA spending limit is reached, or there is no credit. Raising the limit lets work start again.
curl -X POST https://api.boxline.dev/v1/sessions/$SESSION_ID/resume \  -H "x-api-key: $BOXLINE_API_KEY"

Delete a session

DELETE /v1/sessions/:id ends the session for good and returns it with status DELETED. A running session is stopped without saving first. What it saved (the browser and the files), its recording, its logs, its pages and the steps of agent runs in it are deleted now. The session record, with its usage and cost, stays for billing. A delete cannot be undone. Deleting a session that is already deleted is safe: you get it back as it is.

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

Act on many sessions

POST /v1/sessions/bulk with { action, ids } stops, resumes or deletes up to 100 sessions. action is "stop", "resume" or "delete". Each id gets its own result, with the refusals of a single call (for a resume, nothing_saved and the others), so one failure never blocks the rest.

curl -X POST https://api.boxline.dev/v1/sessions/bulk \  -H "x-api-key: $BOXLINE_API_KEY" \  -H "content-type: application/json" \  -d '{"action": "stop", "ids": ["<session-id>", "<session-id>"]}'

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