Skip to content
DocsAll docs
Console

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

json
{  "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"}
FieldTypeMeaning
idstringses- and 16 hex digits
namestringthe name you gave it; unique among your sessions in that team
ownerstringyour handle, lower-cased
teamstringthe team slug. A personal session carries your own handle here, not ""
environmentstring or nullthe id of the environment it is connected to
workspacesobject[], omittedthe workspaces it manages: id, name, and state (running or stopped, the state you asked for).
interceptsobject[], omittedthe intercepts this session holds in its environment, in the form the environment document uses. Empty with no environment
ttl_secsinteger, omittedunused seconds before it is deleted
expires_atstring, omittedRFC 3339; last active (else created) plus ttl_secs
statestringstopped 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.

FieldTypeRequiredRule
namestringyesThe 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
teamstringnoA team you belong to. Absent, empty or your own handle means a personal session. Case is ignored
environmentstringnoAn environment (id, name or owner/name) of that same team. Absent or empty means none yet
ttl_secsintegerno600 to 2592000. Absent means never
json
{ "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 ttl for 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.

json
[  { "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.

FieldTypeRequiredRule
ttl_secsinteger or nullno600 to 2592000 to set; null or an absent key clears it
json
{ "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.

FieldTypeRequiredRule
environmentstring or nullyesAn environment (id, name or owner/name) of the session's team. null or an empty string clears it
json
{ "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 — team is not the session's team; session in 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}/environment when 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 — team is not the session's team; session in 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}/environment when 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.

FieldTypeRequiredRule
servicestringyesA service of the session's environment that declares at least one port
workspacestringyesA workspace of this session (id, name or team/name), running
portsobject[]no{ "service": int, "workspace": int }, as on the environment route
json
{ "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, port 0, 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.