List sessions
List sessions.
GET
/v1/sessionsRequest
| Method and path | GET/v1/sessions |
|---|---|
| Base URL | https://api.boxline.dev |
| Authentication | Your API key in the x-api-key header (or Authorization: Bearer). The examples read it from BOXLINE_API_KEY. |
Query parameters
| Name | Type | Default | Allowed values | Description |
|---|---|---|---|---|
status | string | – | – | Comma-separated statuses, e.g. RUNNING,STOPPED. |
kind | string | – | browser, combined, shell | browser (no shell), combined (browser and shell) or shell (no browser). |
q | string | – | – | A session id prefix, or text found in userMetadata. |
from | string | – | – | Created at or after (ISO date). Format: date-time. |
to | string | – | – | Created at or before (ISO date). Format: date-time. |
sort | string | created_desc | created_desc, created_asc, duration_desc | |
limit | integer | 50 | – | From 1 to 500. |
after | string | – | – | The next value of the previous page (same filters and sort). Opaque; do not build it yourself. |
curl "https://api.boxline.dev/v1/sessions?status=RUNNING&limit=20" \ -H "x-api-key: $BOXLINE_API_KEY"import { Boxline } from "@boxline/sdk";const bx = new Boxline(); // reads BOXLINE_API_KEY and BOXLINE_API_URLconst page = await bx.sessions.list({ status: "RUNNING", limit: 20 });console.log(page.total, page.data.map((s) => s.id), page.next);// Every page, one session at a time:for await (const s of bx.sessions.list({ status: "RUNNING" })) console.log(s.id);from boxline import Boxlinebx = Boxline() # reads BOXLINE_API_KEY and BOXLINE_API_URLpage = bx.sessions.list(status="RUNNING", limit=20)print(page.total, [s.id for s in page.data], page.next)# Every page, one session at a time:for s in bx.sessions.list(status="RUNNING"): print(s.id)boxline sessions list --status running --limit 20# Every page:boxline sessions list --status running --allResponses
200 OK
A page of sessions, and how many match the filters in all.
Fields
| Name | Type | Default | Allowed values | Description |
|---|---|---|---|---|
data | object[] | – | – | |
data[].id | string | – | – | |
data[].status | string | – | RUNNING, STOPPED, DELETED, ERROR | RUNNING; STOPPED (saved, no machine, free); DELETED (ended for good, its data gone); ERROR (only a session that never started). |
data[].projectId | string | – | – | |
data[].region | string | – | – | |
data[].browser | boolean | – | – | |
data[].shell | boolean | – | – | |
data[].keepAlive | boolean | – | – | |
data[].timeout | integer | – | – | Seconds. |
data[].idleTimeout | integer | null | – | – | Seconds without activity after which it stops (stopReason idle); null: off. |
data[].createdAt | string | – | – | Format: date-time. |
data[].startedAt | string | null | – | – | Format: date-time. |
data[].expiresAt | string | – | – | Format: date-time. |
data[].stoppedAt | string | null | – | – | When it stopped (null while it runs; cleared by a resume). Format: date-time. |
data[].stopReason | string | null | – | – | requested, timeout, idle, no_clients, agent_run, task, machine_lost, api_restart, account_recovered, suspended, spend_limit or out_of_credit. |
data[].deletesAt | string | null | – | – | When a stopped session is deleted automatically: stoppedAt plus the plan's retentionDays, fixed when it stops. Format: date-time. |
data[].deletedAt | string | null | – | – | Format: date-time. |
data[].deleteReason | string | null | – | requested, retention, null | |
data[].connectUrl | string | null | – | – | CDP WebSocket for Playwright/Puppeteer (null without a browser or unless the session is running). Treat it like a password. |
data[].liveUrl | string | null | – | – | The live view page (null without a browser |
data[].terminalUrl | string | null | – | – | The terminal WebSocket (null without a shell). Treat it like a password. |
data[].proxy | null | object | object[] | – | – | The session's proxy as given, without passwords. |
data[].proxy.type | string | – | residential, datacenter, custom | |
data[].proxy.country | string | – | – | Two-letter country code (residential and datacenter). |
data[].proxy.state | string | – | – | Residential, US states, e.g. us_california (implies US). |
data[].proxy.city | string | – | – | Residential, e.g. los_angeles (needs country). |
data[].proxy.ip | string | – | sticky, rotating | Default sticky for sessions and crawls, rotating for fetch, screenshot, pdf and extract. |
data[].proxy.scope | string | browser | browser, all | all also routes the session's shell. |
data[].proxy.server | string | – | – | custom: your proxy, http://host:port or https://host:port, on a public address. |
data[].proxy.username | string | – | – | |
data[].proxy[].domainPattern | string | – | – | Up to 256 characters. |
data[].browserSettings | object | – | – | What is in force (locale and timezone null = the browser's own default). |
data[].browserSettings.mode | string | – | standard, realistic | |
data[].browserSettings.locale | string | null | – | – | |
data[].browserSettings.timezone | string | null | – | – | |
data[].viewport | object | null | – | – | |
data[].viewport.width | integer | – | – | From 200 to 3840. |
data[].viewport.height | integer | – | – | From 200 to 2160. |
data[].trajectoriesEligible | boolean | – | – | |
data[].captcha | string | – | ask, ignore, solve | What 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. |
data[].attention | object | null | – | – | A CAPTCHA waiting (or being solved), else null. |
data[].attention.type | string | – | captcha | |
data[].attention.kind | string | – | recaptcha, hcaptcha, turnstile, cloudflare, datadome, arkose, human | |
data[].attention.url | string | – | – | |
data[].attention.tabId | string | – | – | |
data[].attention.since | string | – | – | Format: date-time. |
data[].attention.state | string | – | solving, waiting | |
data[].attention.reason | string | – | – | |
data[].blockAds | boolean | – | – | |
data[].blockedRequests | integer | – | – | Requests to ad and tracker sites refused so far (collected about every 30 s). |
data[].cookieBanners | string | – | reject, off | "off" for sessions without a browser, and for sessions created before the option existed. |
data[].extensions | string[] | – | – | The extension ids the session started with. |
data[].workspacePath | string | – | – | |
data[].profileId | string | null | – | – | |
data[].profilePersist | boolean | – | – | Whether the session saves its sign-ins back to profileId when it ends (persist:true, or attached with fromSession). false without a profile. |
data[].userMetadata | object | – | – | |
data[].checkpointAt | string | null | – | – | Format: date-time. |
data[].recoveries | integer | – | – | Times the session was brought back on a new machine after its machine stopped. |
data[].error | string | null | – | – | |
data[].recordSession | boolean | – | – | |
data[].setup | string[] | – | – | |
data[].setupStatus | string | – | none, running, done, failed | |
data[].setupError | string | null | – | – | |
data[].env | string[] | – | – | Names of the session's env variables (values are never returned). |
data[].credentials | string[] | – | – | Names of the credentials its shell exports (a profile's linked one included). |
data[].hasRecording | boolean | – | – | |
data[].usage | object | – | – | |
data[].usage.seconds | number | – | – | |
data[].usage.costUsd | number | – | – | |
total | integer | – | – | Sessions matching the filters. |
limit | integer | – | – | |
next | string | null | – | – | Pass it back as after for the next page; null on the last page. |
{ "data": [ { "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 } } ], "total": 0, "limit": 0, "next": "eyJvIjoiY3JlYXRlZF9kZXNjIiwidCI6IjIwMjYtMDktMjlUMTA6MDA6MDAuMTIzNDU2WiIsImkiOiI2YzFmIn0"}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.
| Status | Codes | When |
|---|---|---|
| 400 Bad Request | invalid_request, invalid_json, invalid_cursor, invalid_idempotency_key, invalid_extension, variables_with_extensions, terms_not_accepted, invalid_reset_token, invalid_confirmation_code, wrong_password, no_password, invalid_next, invalid_oauth_token | The request is not valid. |
| 401 Unauthorized | unauthorized | Missing or invalid API key. |
{ "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.