Sessions API
Lists the API routes that create sessions, create and delete their workspaces, set their environment, and end them.
Last updated
On this page
- The session document
- POST /v1/sessions
- GET /v1/sessions
- GET /v1/sessions/{id}
- DELETE /v1/sessions/{id}
- POST /v1/sessions/{id}/open
- POST /v1/sessions/{id}/stop
- GET /v1/sessions/teams
- POST /v1/sessions/{id}/hold
- PUT /v1/sessions/{id}/ttl
- PUT /v1/sessions/{id}/environment
- POST /v1/sessions/{id}/workspaces
- POST /v1/sessions/{id}/sandboxes
- DELETE /v1/sessions/{id}/workspaces/{workspace}
- POST /v1/sessions/{id}/intercepts
- DELETE /v1/sessions/{id}/intercepts/{service}
The session document
{ "id": "ses-9c8b7a6d5e4f3a2b", "name": "login-fix", "owner": "karthik", "team": "acme", "environment": "env-1f2e3d4c5b6a7988", "workspaces": [{ "id": "ws-0a1b2c3d4e5f6a7b", "name": "backend", "state": "running" }], "intercepts": [{ "service": "api", "workspace": "ws-0a1b2c3d4e5f6a7b", "ports": [{ "service": 8080, "workspace": 3000 }], "session": "ses-9c8b7a6d5e4f3a2b" }], "ttl_secs": 604800, "expires_at": "2026-10-25T09:30:00Z", "state": "running"}| Field | Type | Meaning |
|---|---|---|
id | string | ses- and 16 hex digits |
name | string | the name you gave it; unique among your sessions in that team |
owner | string | your handle, lower-cased |
team | string | the team slug. A personal session carries your own handle here, not "" |
environment | string or null | the id of the environment it is connected to |
workspaces | object[], omitted | the workspaces it manages: id, name, and state (running or stopped, the state you asked for). |
intercepts | object[], omitted | the intercepts this session holds in its environment, in the form the environment document uses. Empty with no environment |
ttl_secs | integer, omitted | unused seconds before it is deleted |
expires_at | string, omitted | RFC 3339; last active (else created) plus ttl_secs |
state | string | stopped after a stop; idle when unused past the idle limit; starting while it comes up; else running. Present in the list too |
workspaces and intercepts are present on every route that returns one session, and absent from the list.
POST /v1/sessions
Creates a session, optionally connected to an environment from birth.
| Field | Type | Required | Rule |
|---|---|---|---|
name | string | yes | The workspace name rule: 1 to 40 lowercase letters, digits or -; starts with a letter, ends with a letter or digit, no --; not ws, env, api, admin, system, kl or bld-…, and not shaped like an id. Unique among your sessions in that team |
team | string | no | A team you belong to. Absent, empty or your own handle means a personal session. Case is ignored |
environment | string | no | An environment (id, name or owner/name) of that same team. Absent or empty means none yet |
ttl_secs | integer | no | 600 to 2592000. Absent means never |
{ "name": "login-fix", "team": "acme", "environment": "acme-dev", "ttl_secs": 604800 }Response: 201, the session document.
Errors:
403— a session tool token naming a team that is not its own.404— a team you are not a member of; the environment is not found or not yours.409—you already have a session named login-fix in acme; the environment belongs to another owner (that environment is {owner}'s; a session in {team} connects only to {team}'s environments).422— the name breaks the rule (JSON);ttl_secs must be 600..=2592000 seconds;a system session takes no ttlfor a pipeline token.
GET /v1/sessions
Your sessions, as an array of documents without workspaces and intercepts. ?team={slug} lists one team's; ?team= (empty) lists the personal ones; absent lists every team's.
Response: 200.
[ { "id": "ses-9c8b7a6d5e4f3a2b", "name": "login-fix", "owner": "karthik", "team": "acme", "environment": "env-1f2e3d4c5b6a7988", "ttl_secs": 604800, "expires_at": "2026-10-25T09:30:00Z" }]GET /v1/sessions/{id}
One session. {id} is the id, a name, or team/name; ?owner={team} is the same as qualifying it. A bare name that matches a personal and a team session prefers the personal one.
Response: 200, the session document.
Errors:
404— not found, or not yours.409— more than one of your sessions has that name (more than one session is named login-fix; name it as team/login-fix).
DELETE /v1/sessions/{id}
Ends the session. Its managed workspaces are deleted (snapshots stay) and its sandboxes are ended (their run records stay). Its intercepts are released, then the session is deleted. Takes no body.
Response: 200 { "deleted": ["ws-…", "sbx-…"] }, the ids of the workspaces deleted and sandboxes ended. If a step fails, the call fails and the session stays; the same call finishes the job.
Errors:
404— not found, or not yours; a pipeline token ending a session its own run did not make.409—the environment was changed while this was being written; try again;the workspace was changed while this was being written; try again.
POST /v1/sessions/{id}/open
Opens the session: starts it when it is not running, wakes an idle one, and returns the tunnel token once it serves.
Body, all optional: start (boolean; start a stopped session and its stopped workspaces), model (string; used at creation) and env (object of environment variables; used at creation).
Response: 201 { "token", "gateway", "expires_at" } when the session serves. 202 { "state" } while it starts or wakes; call again.
Errors:
403—your access to {team} is paused.404— not found, or not yours.409—the session is stopped; start it with start; a quota refusal for the start.
POST /v1/sessions/{id}/stop
Stops the session and every workspace in it, through the ordinary workspace stop. A sandbox and the connected environment are not touched. Takes no body.
Response: 202 { "stopped": [workspace ids] }.
Errors:
403—your access to {team} is paused.404— not found, or not yours.
GET /v1/sessions/teams
Lists the teams in which you can open a session: your personal team first, then the teams you belong to. Takes no parameters.
Response: 200, an array of { "slug", "name", "region", "personal" }. region is "" when the team has none.
Errors:
503—team list unavailable.
POST /v1/sessions/{id}/hold
Records that you are using the session, and wakes it and its idle-stopped environment. A laptop connection calls this every 60 seconds while in use. Takes no body.
Response: 204 with an empty body.
Errors:
404— not found, or not yours.
PUT /v1/sessions/{id}/ttl
Sets or clears how long the session can stay unused before it is deleted. A session that is awake is never deleted by its time to live.
| Field | Type | Required | Rule |
|---|---|---|---|
ttl_secs | integer or null | no | 600 to 2592000 to set; null or an absent key clears it |
{ "ttl_secs": 86400 }Response: 200, the session document with ttl_secs and expires_at.
Errors:
404— not found, or not yours.422—ttl_secs must be 600..=2592000 seconds;a system session takes no ttl.
PUT /v1/sessions/{id}/environment
Connects the session to an environment, switches it, or clears it. The intercepts the session held in the old environment are released first. Connecting counts as use and wakes the session and an idle-stopped environment.
| Field | Type | Required | Rule |
|---|---|---|---|
environment | string or null | yes | An environment (id, name or owner/name) of the session's team. null or an empty string clears it |
{ "environment": "acme-dev" }Response: 200, the session document. Asking for the environment it already has changes nothing.
Errors:
404— the session or the environment is not found or not yours.409— the environment belongs to another owner than the session's team (that environment is {owner}'s; a session in {team} connects only to {team}'s environments);the session changed; retry.
POST /v1/sessions/{id}/workspaces
Creates a workspace managed by the session, and wakes an idle session. The workspace is in the session's team. From then on the session controls it. Start, stop, delete and ttl on the workspace itself are refused with 409 (see workspaces). The session itself can call this route. Another session gets 403.
The body is the POST /v1/workspaces body without session. team is optional. If given, it must be the session's team.
Response: 201, the workspace document, with session set.
Errors:
400—teamis not the session's team;sessionin the body.404— the session is not found or not yours.403— the token of another session.- The errors of
POST /v1/workspaces: name, quota, region and package refusals. 409—this session has no environment; connect one with PUT /v1/sessions/{id}/environmentwhen the session names an environment that no longer exists.
POST /v1/sessions/{id}/sandboxes
Creates a sandbox managed by the session, and wakes an idle session. The sandbox is in the session's team and reaches the session's environment. From then on the session controls it: POST /v1/sandboxes/{id}/terminate and DELETE /v1/sandboxes/{id} from any other caller are refused with 409 ({name} is managed by session {session}; use the session), and ending the session ends the sandbox. A standalone sandbox is made with POST /v1/sandboxes, which does not take a session.
The body is the POST /v1/sandboxes body without session. team is optional. If given, it must be the session's team.
Response: 202, the sandbox document, with session set.
Errors:
400—teamis not the session's team;sessionin the body.404— the session is not found or not yours.403— the token of another session.- The errors of
POST /v1/sandboxes: command, env, quota, region and package refusals. 409—this session has no environment; connect one with PUT /v1/sessions/{id}/environmentwhen the session names an environment that no longer exists.
DELETE /v1/sessions/{id}/workspaces/{workspace}
Deletes a workspace the session manages, releasing its intercepts first, through the same path as DELETE /v1/workspaces/{id}. Snapshots stay. A sandbox is ended, not deleted: its run record stays. Takes no body.
Response: 204 with an empty body.
Errors:
404— the session or the workspace is not found or not yours; the workspace is not managed by this session.403— the token of another session.409—the environment was changed while this was being written; try again.
POST /v1/sessions/{id}/intercepts
Makes a workspace of the session take over a service of its environment, under every rule of POST /v1/environments/{id}/intercepts. This session is the holder and the only one that releases it; leaving or ending the session releases it too.
| Field | Type | Required | Rule |
|---|---|---|---|
service | string | yes | A service of the session's environment that declares at least one port |
workspace | string | yes | A workspace of this session (id, name or team/name), running |
ports | object[] | no | { "service": int, "workspace": int }, as on the environment route |
{ "service": "api", "workspace": "api", "ports": [{ "service": 8080, "workspace": 3000 }] }Response: 202, the session document; intercepts now holds the wish.
Errors:
404— the session or workspace is not found or not yours;this environment has no service named "api".409—this session has no environment; connect one with PUT /v1/sessions/{id}/environment;api is not in this session; create it in the session; another session holds the service (session {name} ({owner}) already intercepts this service; it must be released first);that workspace is stopped; start it before it can answer for a service;the environment was changed while this was being written; try again.422— the same port and service refusals as the environment route. They are a service with no ports, an undeclared port, port0, and a port mapped twice. A port that lands on the tool server port 7788 is also refused.
DELETE /v1/sessions/{id}/intercepts/{service}
Releases an intercept this session holds. One that is not there succeeds. One held by another session, or made on the environment directly, is refused. Takes no body.
Response: 204 with an empty body.
Errors:
404— the session is not found or not yours.409—this session has no environment; connect one with PUT /v1/sessions/{id}/environment;this session does not hold api;the environment was changed while this was being written; try again.