Docs
Dashboard
API reference / SessionsBeta

Stop a session

Saves the session exactly as it is (the whole browser and /workspace), frees the machine and stops billing. The recording, events, pages and agent-run steps stay. A stopped session is kept for its plan's retentionDays (see deletesAt), then deleted; resume it any time before. If its state cannot be saved the call fails and the session keeps running. 409 session_not_running for a deleted session.

POST/v1/sessions/{id}/stop

Request

Method and pathPOST/v1/sessions/{id}/stop
Base URLhttps://api.boxline.dev
AuthenticationYour API key in the x-api-key header (or Authorization: Bearer). The examples read it from BOXLINE_API_KEY.

Path parameters

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

Responses

200 OK

The stopped session (status STOPPED).

Fields

NameTypeDefaultAllowed valuesDescription
idstring––
statusstring–RUNNING, STOPPED, DELETED, ERRORRUNNING; STOPPED (saved, no machine, free); DELETED (ended for good, its data gone); ERROR (only a session that never started).
projectIdstring––
regionstring––
browserboolean––
shellboolean––
keepAliveboolean––
timeoutinteger––Seconds.
idleTimeoutinteger | null––Seconds without activity after which it stops (stopReason idle); null: off.
createdAtstring––Format: date-time.
startedAtstring | null––Format: date-time.
expiresAtstring––Format: date-time.
stoppedAtstring | null––When it stopped (null while it runs; cleared by a resume). Format: date-time.
stopReasonstring | null––requested, timeout, idle, no_clients, agent_run, task, machine_lost, api_restart, account_recovered, suspended, spend_limit or out_of_credit.
deletesAtstring | null––When a stopped session is deleted automatically: stoppedAt plus the plan's retentionDays, fixed when it stops. Format: date-time.
deletedAtstring | null––Format: date-time.
deleteReasonstring | null–requested, retention, null
connectUrlstring | null––CDP WebSocket for Playwright/Puppeteer (null without a browser or unless the session is running). Treat it like a password.
liveUrlstring | null––The live view page (null without a browser
terminalUrlstring | null––The terminal WebSocket (null without a shell). Treat it like a password.
proxynull | object | object[]––The session's proxy as given, without passwords.
proxy.typestring–residential, datacenter, custom
proxy.countrystring––Two-letter country code (residential and datacenter).
proxy.statestring––Residential, US states, e.g. us_california (implies US).
proxy.citystring––Residential, e.g. los_angeles (needs country).
proxy.ipstring–sticky, rotatingDefault sticky for sessions and crawls, rotating for fetch, screenshot, pdf and extract.
proxy.scopestringbrowserbrowser, allall also routes the session's shell.
proxy.serverstring––custom: your proxy, http://host:port or https://host:port, on a public address.
proxy.usernamestring––
proxy[].domainPatternstring––Up to 256 characters.
browserSettingsobject––What is in force (locale and timezone null = the browser's own default).
browserSettings.modestring–standard, realistic
browserSettings.localestring | null––
browserSettings.timezonestring | null––
viewportobject | null––
viewport.widthinteger––From 200 to 3840.
viewport.heightinteger––From 200 to 2160.
trajectoriesEligibleboolean––
captchastring–ask, ignore, solveWhat happens when a CAPTCHA waits for a person. ask (default): agent runs and steps pause and hand over. ignore: they carry on. solve (opt-in, paid plans): the platform tries to solve it first.
attentionobject | null––A CAPTCHA waiting (or being solved), else null.
attention.typestring–captcha
attention.kindstring–recaptcha, hcaptcha, turnstile, cloudflare, datadome, arkose, human
attention.urlstring––
attention.tabIdstring––
attention.sincestring––Format: date-time.
attention.statestring–solving, waiting
attention.reasonstring––
blockAdsboolean––
blockedRequestsinteger––Requests to ad and tracker sites refused so far (collected about every 30 s).
cookieBannersstring–reject, off"off" for sessions without a browser, and for sessions created before the option existed.
extensionsstring[]––The extension ids the session started with.
workspacePathstring––
profileIdstring | null––
profilePersistboolean––Whether the session saves its sign-ins back to profileId when it ends (persist:true, or attached with fromSession). false without a profile.
userMetadataobject––
checkpointAtstring | null––Format: date-time.
recoveriesinteger––Times the session was brought back on a new machine after its machine stopped.
errorstring | null––
recordSessionboolean––
setupstring[]––
setupStatusstring–none, running, done, failed
setupErrorstring | null––
envstring[]––Names of the session's env variables (values are never returned).
credentialsstring[]––Names of the credentials its shell exports (a profile's linked one included).
hasRecordingboolean––
usageobject––
usage.secondsnumber––
usage.costUsdnumber––
Response 200
{  "id": "6c1f3c9e-1d2a-4f67-9b0e-1b2c3d4e5f60",  "status": "RUNNING",  "projectId": "prj_Hk2Lq8Zx0Vb5Nm1C",  "region": "us-east-1",  "browser": true,  "shell": false,  "keepAlive": false,  "timeout": 300,  "createdAt": "2026-09-29T10:00:00.000Z",  "startedAt": "2026-09-29T10:00:00.000Z",  "expiresAt": "2026-09-29T10:05:00.000Z",  "stoppedAt": null,  "stopReason": null,  "deletesAt": null,  "deletedAt": null,  "deleteReason": null,  "connectUrl": "wss://connect.boxline.dev/v1/connect?sessionId=6c1f3c9e-1d2a-4f67-9b0e-1b2c3d4e5f60&token=…",  "liveUrl": "https://api.boxline.dev/live/6c1f3c9e-1d2a-4f67-9b0e-1b2c3d4e5f60?token=…",  "terminalUrl": null,  "proxy": null,  "browserSettings": {    "mode": "standard",    "locale": null,    "timezone": null  },  "viewport": {    "width": 1280,    "height": 720  },  "trajectoriesEligible": false,  "captcha": "ask",  "attention": null,  "blockAds": false,  "blockedRequests": 0,  "cookieBanners": "reject",  "extensions": [],  "workspacePath": "/workspace",  "profileId": null,  "profilePersist": false,  "userMetadata": {},  "checkpointAt": null,  "recoveries": 0,  "error": null,  "recordSession": true,  "setup": [],  "setupStatus": "none",  "setupError": null,  "env": [],  "credentials": [],  "hasRecording": false,  "usage": {    "seconds": 12.3,    "costUsd": 0.00015  }}

Errors

Errors have a matching HTTP status and the same body. code is stable, so check it in your code; message is for people. See Errors and request ids.

StatusCodesWhen
401 UnauthorizedunauthorizedMissing or invalid API key.
404 Not Foundnot_found, invite_not_found, provider_unavailableNo such thing in this project (or organization), or no such route.
409 Conflictsession_not_running, shell_disabled, browser_disabled, nothing_saved, not_resumable, invalid_state, conflict, email_taken, identity_in_use, provider_already_linked, last_sign_in_method, not_impersonating, machine_too_old, too_many_credential_values, limit_reached, terms_version_mismatch, no_project, last_owner, organization_not_empty, project_has_sessions, already_member, invite_pending, idempotency_in_progressThe current state does not allow it, or a request with this Idempotency-Key is still being answered.
Error body
{  "error": {    "code": "not_found",    "message": "session not found",    "requestId": "req_4fJx0aQm2Lk9Pz7N"  }}

Learn more

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