sessions
GET /sessions
The calling studio's sessions, most recently opened first.
Ordered by `opened_at` descending with never-opened sessions last, then `created_at` descending. Deleted sessions are not listed.
Needs the kv capability.
| Go | List(ctx context.Context, params *SessionsListParams) (*SessionPage, error) |
|---|---|
| Python | def list(self, *, limit: Optional[Any] = None, cursor: Optional[Any] = None) -> Any |
| JavaScript | list(params = {}) |
| Parameter | In | Type | About |
|---|---|---|---|
| limit | query | integer | |
| cursor | query | string | The `next_cursor` of the previous page, unchanged. |
| Status | Body | Means |
|---|---|---|
| 200 | SessionPage | A page of sessions. |
| 400 | Error | The request is malformed. Codes: `bad_request`, `bad_filter`, `bad_cursor`, `invalid_document`. |
| 401 | Error | No studio token, or a revoked or unknown one. Code `unauthenticated`. |
| 403 | Error | The token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`). |
POST /sessions
Create a session.
A name is unique among the studio's live sessions (409 `name_taken`). The state's bytes count toward `kv_bytes` (Q20).
Needs the kv capability.
| Go | Create(ctx context.Context, body SessionCreate) (*Session, error) |
|---|---|
| Python | def create(self, body: Dict[str, Any]) -> Any |
| JavaScript | create(body) |
Request body: SessionCreate (application/json)
| Status | Body | Means |
|---|---|---|
| 201 | Session | The new session. |
| 400 | Error | The request is malformed. Codes: `bad_request`, `bad_filter`, `bad_cursor`, `invalid_document`. |
| 401 | Error | No studio token, or a revoked or unknown one. Code `unauthenticated`. |
| 403 | Error | The token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`). |
| 409 | Error | Codes: `etag_mismatch`, `name_taken`, `job_finished`, `already_running`, `not_running`, `port_conflict`, `heavy_conflict` (with `details.heavy`), `not_installed`, `conflict`, `in_use`, `missing`, `confirm_required` and `preview_changed` (with `details.preview`), `not_reclaimable`, and from M7: `approval_required` (with `details.approval`), `id_taken`, `not_fetched`, `already_exists`. |
| 413 | Error | The body is over its limit. Code `too_large`, with `details.limit` in bytes. |
| 429 | Error | A per-studio quota is full. Code `quota_exceeded`, with `details` as QuotaDetails. |
GET /sessions/{id}
One session. A deleted session, or another studio's, is 404.
Needs the kv capability.
| Go | Get(ctx context.Context, id string) (*Session, error) |
|---|---|
| Python | def get(self, id: str) -> Any |
| JavaScript | get(id) |
| Parameter | In | Type | About |
|---|---|---|---|
| id | path · required | ULID |
| Status | Body | Means |
|---|---|---|
| 200 | Session | The session. |
| 401 | Error | No studio token, or a revoked or unknown one. Code `unauthenticated`. |
| 403 | Error | The token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`). |
| 404 | Error | Absent, deleted, or not the caller's to see. Code `not_found`. |
PATCH /sessions/{id}
Rename, or merge changes into the state document.
R31a, M4 first review #11. A JSON merge patch over `{name, state}`: members of `state` merge into the stored state, and a `null` member removes that key. `name` cannot be null. With `If-Match`, only when the etag matches: two open tabs must not silently overwrite each other.
Needs the kv capability.
| Go | Update(ctx context.Context, id string, body map[string]any, params *SessionsUpdateParams) (*Session, error) |
|---|---|
| Python | def update(self, id: str, body: Dict[str, Any], *, if_match: Optional[Any] = None) -> Any |
| JavaScript | update(id, body, params = {}) |
| Parameter | In | Type | About |
|---|---|---|---|
| id | path · required | ULID | |
| If-Match | header | string | The etag last read. When given and stale, the write is refused with 409 `etag_mismatch`. |
Request body: SessionUpdate (application/merge-patch+json)
| Status | Body | Means |
|---|---|---|
| 200 | Session | The updated session. |
| 400 | Error | The request is malformed. Codes: `bad_request`, `bad_filter`, `bad_cursor`, `invalid_document`. |
| 401 | Error | No studio token, or a revoked or unknown one. Code `unauthenticated`. |
| 403 | Error | The token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`). |
| 404 | Error | Absent, deleted, or not the caller's to see. Code `not_found`. |
| 409 | Error | Codes: `etag_mismatch`, `name_taken`, `job_finished`, `already_running`, `not_running`, `port_conflict`, `heavy_conflict` (with `details.heavy`), `not_installed`, `conflict`, `in_use`, `missing`, `confirm_required` and `preview_changed` (with `details.preview`), `not_reclaimable`, and from M7: `approval_required` (with `details.approval`), `id_taken`, `not_fetched`, `already_exists`. |
| 413 | Error | The body is over its limit. Code `too_large`, with `details.limit` in bytes. |
| 429 | Error | A per-studio quota is full. Code `quota_exceeded`, with `details` as QuotaDetails. |
DELETE /sessions/{id}
Soft-delete. Its name becomes free; items keep their session_id.
Needs the kv capability.
| Go | Delete(ctx context.Context, id string, params *SessionsDeleteParams) error |
|---|---|
| Python | def delete(self, id: str, *, if_match: Optional[Any] = None) -> Any |
| JavaScript | delete(id, params = {}) |
| Parameter | In | Type | About |
|---|---|---|---|
| id | path · required | ULID | |
| If-Match | header | string | The etag last read. When given and stale, the write is refused with 409 `etag_mismatch`. |
| Status | Body | Means |
|---|---|---|
| 204 | Deleted. | |
| 401 | Error | No studio token, or a revoked or unknown one. Code `unauthenticated`. |
| 403 | Error | The token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`). |
| 404 | Error | Absent, deleted, or not the caller's to see. Code `not_found`. |
| 409 | Error | Codes: `etag_mismatch`, `name_taken`, `job_finished`, `already_running`, `not_running`, `port_conflict`, `heavy_conflict` (with `details.heavy`), `not_installed`, `conflict`, `in_use`, `missing`, `confirm_required` and `preview_changed` (with `details.preview`), `not_reclaimable`, and from M7: `approval_required` (with `details.approval`), `id_taken`, `not_fetched`, `already_exists`. |
POST /sessions/{id}:activate
Set opened_at to now. Changes neither the state nor the etag, nor any process.
Needs the kv capability.
| Go | Activate(ctx context.Context, id string) error |
|---|---|
| Python | def activate(self, id: str) -> Any |
| JavaScript | activate(id) |
| Parameter | In | Type | About |
|---|---|---|---|
| id | path · required | ULID |
| Status | Body | Means |
|---|---|---|
| 204 | Activated. | |
| 401 | Error | No studio token, or a revoked or unknown one. Code `unauthenticated`. |
| 403 | Error | The token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`). |
| 404 | Error | Absent, deleted, or not the caller's to see. Code `not_found`. |
POST /sessions/{id}:duplicate
Copy a session's state under a new name. The copy has never been opened.
Needs the kv capability.
| Go | Duplicate(ctx context.Context, id string, body SessionDuplicate) (*Session, error) |
|---|---|
| Python | def duplicate(self, id: str, body: Dict[str, Any]) -> Any |
| JavaScript | duplicate(id, body) |
| Parameter | In | Type | About |
|---|---|---|---|
| id | path · required | ULID |
Request body: SessionDuplicate (application/json)
| Status | Body | Means |
|---|---|---|
| 201 | Session | The copy. |
| 400 | Error | The request is malformed. Codes: `bad_request`, `bad_filter`, `bad_cursor`, `invalid_document`. |
| 401 | Error | No studio token, or a revoked or unknown one. Code `unauthenticated`. |
| 403 | Error | The token lacks a capability (`capability_required`, with `details.capability`), the job is not a task the studio may change (`not_a_task`), or the request came from another origin (`bad_origin`). |
| 404 | Error | Absent, deleted, or not the caller's to see. Code `not_found`. |
| 409 | Error | Codes: `etag_mismatch`, `name_taken`, `job_finished`, `already_running`, `not_running`, `port_conflict`, `heavy_conflict` (with `details.heavy`), `not_installed`, `conflict`, `in_use`, `missing`, `confirm_required` and `preview_changed` (with `details.preview`), `not_reclaimable`, and from M7: `approval_required` (with `details.approval`), `id_taken`, `not_fetched`, `already_exists`. |
| 429 | Error | A per-studio quota is full. Code `quota_exceeded`, with `details` as QuotaDetails. |