---
title: "Close a session workspace (ends the session: the workspace is deleted)"
method: POST
path: "/v1/workspaces/{workspace_id}/close"
tags: ["Workspaces"]
---

# Close a session workspace (ends the session: the workspace is deleted)

`POST /v1/workspaces/{workspace_id}/close`

## Request

- Base URL: `https://api.shardflux.dev`
- URL: `https://api.shardflux.dev/v1/workspaces/{workspace_id}/close`
- Auth: HTTP bearer

Sessions only (409 not_session for a persistent workspace; the SDK then only closes local streams). Ends the session exactly like a delete (VM stopped without a snapshot, layer and checkpoints released) with ended_reason closed; the key then opens a NEW workspace. 202 with the `delete` operation (input.reason session_closed). Idempotent: repeating returns the active or last delete operation. Supports Idempotency-Key.

## Path parameters

- `workspace_id` string, uuid, required

## Response `202`

Default Response

- object
  - `operation` Operation, required
    - `id` string, uuid, required: UUIDv7, lowercase canonical form.
    - `kind` 'open' | 'suspend' | 'resume' | 'fork' | 'snapshot' | 'restore' | 'delete' | 'move' | 'resize' | 'upgrade' | 'volume_create' | 'volume_attach' | 'volume_detach' | 'volume_delete' | 'reset' | 'layer_snapshot', required
    - `state` 'queued' | 'capacity_pending' | 'running' | 'succeeded' | 'failed' | 'canceled', required
    - `workspace_id` string, uuid, nullable, required: UUIDv7, lowercase canonical form.
    - `volume_id` string, uuid, nullable: UUIDv7, lowercase canonical form.
    - `created_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
    - `updated_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
    - `started_at` string, date-time, nullable: RFC 3339 UTC timestamp with Z.
    - `completed_at` string, date-time, nullable: RFC 3339 UTC timestamp with Z.
    - `state_reason` string, nullable: Closed reason code while waiting (e.g. capacity_pending: no_ready_host).
    - `input` object
    - `error` object
    - `result` object
      - `durable` boolean: suspend and fork: whether the capture is in durable storage. false while `durability.state` is pending (the suspend completed on its host) or lost; true once it committed. Absent on other kinds.
      - `suspend_path` string: suspend: `local_commit` when the suspend completed on its host and the durable copy followed in the background.
      - `durability` object
        - `state` 'pending' | 'durable' | 'lost', required: pending: sealed on its host, the durable copy is being written; durable: the copy committed; lost: the copy could not be made and the previous recovery point stays current.
        - `checkpoint_id` string: The checkpoint being made durable.
        - `generation_id` string: Its generation on the host.
        - `local_commit_at` string: RFC 3339: when the suspend (or fork) completed on its host.
        - `durable_by` string: RFC 3339: when the durable copy is expected to have committed (local_commit_at + the deadline).
        - `durable_at` string: RFC 3339 (state durable): when the durable copy committed.
        - `local_commit_to_durable_ms` number: State durable: local_commit_at to durable_at, in milliseconds.
        - `overdue_at` string: RFC 3339: set once durable_by passed while the copy was still pending; it keeps retrying.
        - `reason` string: State lost: why, e.g. host_lost.
        - `code` string: State lost: the error code of the failed copy.
        - `recovery_point_checkpoint_id` string, nullable: State lost: the durable checkpoint that stays the recovery point (null when there is none).
      - `lost_suspend` object
        - `checkpoint_id` string, required: The suspend checkpoint whose durable copy was lost.
        - `generation_id` string: Its generation on the host.
        - `reason` string: Why it was lost, e.g. host_lost.
        - `suspended_at` string: RFC 3339: when that suspend captured the workspace.
        - `restored_checkpoint_id` string: The earlier durable checkpoint this resume restored.
        - `state_as_of` string: RFC 3339: when the restored checkpoint committed; the workspace state is as of then.
      - `host_lost` object
        - `detected_at` string, required: RFC 3339: when the host failure was detected; the workspace was suspended then.
        - `restored_from` 'disk' | 'checkpoint': resume and open: disk when the workspace booted from its disk (files kept, processes and memory not); checkpoint when it was restored from its newest checkpoint (see state_as_of). Absent on a suspend.
        - `restored_checkpoint_id` string: restored_from checkpoint: the checkpoint this resume restored.
        - `state_as_of` string: restored_from checkpoint, RFC 3339: when that checkpoint committed; the workspace state is as of then.
    - `progress` SuspendProgress
      - `operation_id` string, uuid, required: UUIDv7, lowercase canonical form.
      - `state` 'queued' | 'capacity_pending' | 'running' | 'succeeded' | 'failed' | 'canceled', required
      - `workspace_state` 'creating' | 'starting' | 'running' | 'suspending' | 'suspended' | 'resuming' | 'forking' | 'stopping' | 'failed' | 'deleting' | 'deleted', required
      - `phase` string, required: Actual snapshot preparation/capture phase, or an explicitly unavailable control status.
      - `cancelable` boolean, required: True only while the host can acknowledge cancellation before its capture cut.
      - `supported` boolean, required
      - `safe_action` 'wait_for_terminal' | 'resume' | 'retry_tools' | 'inspect_failure', required
      - `phase_started_at` string, date-time: RFC 3339 UTC timestamp with Z.
      - `deadline_at` string, date-time: RFC 3339 UTC timestamp with Z.
      - `accepted` boolean
  - `workspace` Workspace, required
    - `secret_redaction_required` boolean: Bound secrets require tool-call capture redaction inside the guest before storage.
    - `agents` Agent[]
      - `id` string, required
      - `workspace_id` string, uuid, required: UUIDv7, lowercase canonical form.
      - `workspace_key` string, required
      - `app` union, required
        - 'claude'
        - 'codex'
      - `state` union, required
        - 'working'
        - 'waiting'
        - 'exited'
      - `since` string, date-time, required: RFC 3339 UTC timestamp with Z.
      - `title` string, required
      - `remote_control_url` string, required
      - `last_message` string, required: The session's latest message as one line of plain text: the agent's last reply when it waits or exits, its latest text while it works. Empty until it says one.
      - `labels` object, required
      - `conversation_id` string, nullable: The session's own conversation: the one whose harness session it is, else its computer's only live conversation. Several threads can share one computer, so prefer it over labels.shard_conversation, which names the computer's first conversation. Null when it cannot be told; absent before conversations exist.
      - `orchestrator_conversation_id` string, nullable
      - `orchestrator_input_id` string, nullable
      - `settled_reason` union: The conversation computer suspended or failed while a native turn was active. Null or absent does not establish completion.
        - 'computer_suspended'
        - 'computer_failed'
      - `credential_status` union
        - 'ready'
        - 'needs_sign_in'
    - `id` string, uuid, required: UUIDv7, lowercase canonical form.
    - `organization_id` string, uuid, required: UUIDv7, lowercase canonical form.
    - `project_id` string, uuid, required: UUIDv7, lowercase canonical form.
    - `workspace_key` string, required
    - `labels` object, required: Searchable workspace metadata; not secrets. At most 50 labels.
    - `retention` object, nullable
      - `delete_after_idle_days` integer, required
      - `delete_at` string, date-time, nullable, required
    - `template_version_id` string, uuid, required: UUIDv7, lowercase canonical form.
    - `template` object, required: The workspace’s current template base (changed only by an explicit upgrade), and the version its immutable paths show.
      - `version_id` string, uuid, required: UUIDv7, lowercase canonical form.
      - `template_id` string, uuid, required: UUIDv7, lowercase canonical form.
      - `slug` string, required
      - `version` integer, required
      - `immutable_version` integer, nullable, required: Immutable paths: the template version whose read-only content the workspace has mounted at the template’s immutable paths. It follows the template’s newest published version at a cold boot or a resume. null when the workspace mounts none (its version declares no immutable paths, a draft or a test instance, or not booted yet).
    - `desired_state` 'running' | 'suspended' | 'deleted', required
    - `observed_state` 'creating' | 'starting' | 'running' | 'suspending' | 'suspended' | 'resuming' | 'forking' | 'stopping' | 'failed' | 'deleting' | 'deleted', required
    - `cell_id` string, nullable, required
    - `cell_endpoint` string, nullable, required: Cell gateway base URL when placed and resolvable.
    - `ownership_epoch` integer, required
    - `caps` object, required: CPU and memory user caps (null = no user restriction), the effective disk cap, and the memory allocation mode.
      - `cpu_millis` integer, nullable, required
      - `memory_mib` integer, nullable, required
      - `disk_gib` integer, nullable, required: Requested disk cap (GiB), bounded by the admitted plan/template ceiling and acknowledged VM disk. Null means no user disk restriction.
      - `allocation_mode` 'fixed' | 'elastic', required: Memory allocation: fixed (default) boots memory_mib and holds it; elastic holds memory_mib_held while idle and is grown up to memory_mib (the promise) when a command needs it. The mode the next VM start uses: an elastic request whose promise does not exceed the held floor by at least 512 MiB is fixed at the promise.
      - `memory_mib_held` integer: Elastic only: the memory held while idle (MiB).
    - `memory` object, required: Memory of the workspace.
      - `allocation_mode` 'fixed' | 'elastic', required: The layout of the running VM, else the one the next start uses.
      - `promised_mib` integer, nullable, required: The memory the workspace may use (MiB): the running allocation, else the last admitted size; null before the first start.
      - `held_mib` integer, nullable, required: The memory held while idle (MiB): the elastic floor; equal to promised_mib for fixed.
      - `plugged_mib` integer, nullable, required: Elastic and running: the memory currently plugged above the held floor (MiB, from the host’s latest report); null otherwise.
    - `ceilings` object, nullable, required: Effective per-workspace ceilings computed at the last admission (start/resume/fork).
      - `cpu_millis` integer, required
      - `memory_mib` integer, required
      - `disk_gib` integer, required
      - `sources` object, required: Which input bounded each ceiling: min(template, user cap, plan cap).
        - `cpu_millis` 'template' | 'user' | 'plan', required
        - `memory_mib` 'template' | 'user' | 'plan', required
        - `disk_gib` 'template' | 'user' | 'plan', required
      - `resolved_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
    - `grants` object, nullable, required: Actual grants reported by the cell; live memory allocation overrides the last successful start.
    - `storage_recovery` object: Files stored independently of compute. Resume restarts processes from the kept filesystem.
      - `state` 'stored', required
      - `reason` 'maintenance', required
      - `copy_id` string, uuid, required: UUIDv7, lowercase canonical form.
      - `files_kept` true, required
      - `message` string, required
    - `active_operation` Operation, required
      - `id` string, uuid, required: UUIDv7, lowercase canonical form.
      - `kind` 'open' | 'suspend' | 'resume' | 'fork' | 'snapshot' | 'restore' | 'delete' | 'move' | 'resize' | 'upgrade' | 'volume_create' | 'volume_attach' | 'volume_detach' | 'volume_delete' | 'reset' | 'layer_snapshot', required
      - `state` 'queued' | 'capacity_pending' | 'running' | 'succeeded' | 'failed' | 'canceled', required
      - `workspace_id` string, uuid, nullable, required: UUIDv7, lowercase canonical form.
      - `volume_id` string, uuid, nullable: UUIDv7, lowercase canonical form.
      - `created_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
      - `updated_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
      - `started_at` string, date-time, nullable: RFC 3339 UTC timestamp with Z.
      - `completed_at` string, date-time, nullable: RFC 3339 UTC timestamp with Z.
      - `state_reason` string, nullable: Closed reason code while waiting (e.g. capacity_pending: no_ready_host).
      - `input` object
      - `error` object
      - `result` object
        - `durable` boolean: suspend and fork: whether the capture is in durable storage. false while `durability.state` is pending (the suspend completed on its host) or lost; true once it committed. Absent on other kinds.
        - `suspend_path` string: suspend: `local_commit` when the suspend completed on its host and the durable copy followed in the background.
        - `durability` object
          - `state` 'pending' | 'durable' | 'lost', required: pending: sealed on its host, the durable copy is being written; durable: the copy committed; lost: the copy could not be made and the previous recovery point stays current.
          - `checkpoint_id` string: The checkpoint being made durable.
          - `generation_id` string: Its generation on the host.
          - `local_commit_at` string: RFC 3339: when the suspend (or fork) completed on its host.
          - `durable_by` string: RFC 3339: when the durable copy is expected to have committed (local_commit_at + the deadline).
          - `durable_at` string: RFC 3339 (state durable): when the durable copy committed.
          - `local_commit_to_durable_ms` number: State durable: local_commit_at to durable_at, in milliseconds.
          - `overdue_at` string: RFC 3339: set once durable_by passed while the copy was still pending; it keeps retrying.
          - `reason` string: State lost: why, e.g. host_lost.
          - `code` string: State lost: the error code of the failed copy.
          - `recovery_point_checkpoint_id` string, nullable: State lost: the durable checkpoint that stays the recovery point (null when there is none).
        - `lost_suspend` object
          - `checkpoint_id` string, required: The suspend checkpoint whose durable copy was lost.
          - `generation_id` string: Its generation on the host.
          - `reason` string: Why it was lost, e.g. host_lost.
          - `suspended_at` string: RFC 3339: when that suspend captured the workspace.
          - `restored_checkpoint_id` string: The earlier durable checkpoint this resume restored.
          - `state_as_of` string: RFC 3339: when the restored checkpoint committed; the workspace state is as of then.
        - `host_lost` object
          - `detected_at` string, required: RFC 3339: when the host failure was detected; the workspace was suspended then.
          - `restored_from` 'disk' | 'checkpoint': resume and open: disk when the workspace booted from its disk (files kept, processes and memory not); checkpoint when it was restored from its newest checkpoint (see state_as_of). Absent on a suspend.
          - `restored_checkpoint_id` string: restored_from checkpoint: the checkpoint this resume restored.
          - `state_as_of` string: restored_from checkpoint, RFC 3339: when that checkpoint committed; the workspace state is as of then.
      - `progress` SuspendProgress
        - `operation_id` string, uuid, required: UUIDv7, lowercase canonical form.
        - `state` 'queued' | 'capacity_pending' | 'running' | 'succeeded' | 'failed' | 'canceled', required
        - `workspace_state` 'creating' | 'starting' | 'running' | 'suspending' | 'suspended' | 'resuming' | 'forking' | 'stopping' | 'failed' | 'deleting' | 'deleted', required
        - `phase` string, required: Actual snapshot preparation/capture phase, or an explicitly unavailable control status.
        - `cancelable` boolean, required: True only while the host can acknowledge cancellation before its capture cut.
        - `supported` boolean, required
        - `safe_action` 'wait_for_terminal' | 'resume' | 'retry_tools' | 'inspect_failure', required
        - `phase_started_at` string, date-time: RFC 3339 UTC timestamp with Z.
        - `deadline_at` string, date-time: RFC 3339 UTC timestamp with Z.
        - `accepted` boolean
    - `pending_reason` string, nullable, required: Why the active operation is waiting (capacity_pending reason), else null.
    - `forked_from_workspace_id` string, uuid, nullable, required: UUIDv7, lowercase canonical form.
    - `disk_layout` 'legacy' | 'layered', required: legacy: one disk (template copy + changes). layered: the template chain read-only plus a workspace layer holding only the changes. Immutable.
    - `lifetime` 'persistent' | 'session', required: persistent: kept until deleted (default). session: discarded when the session ends (close(), idle timeout or draft discard;).
    - `purpose` 'standard' | 'template_draft' | 'template_test', required: standard, template_draft (a template’s dev-mode draft) or template_test (a test instance of a draft state;).
    - `idle_timeout_seconds` integer, nullable, required: Sessions only: the session ends after this long without activity (template default, else 600). Null for persistent workspaces.
    - `idle` object, nullable, required: Automatic suspend of a persistent workspace. Null for session workspaces.
      - `policy` string, required: The effective policy: adaptive, never or fixed:<seconds>.
      - `source` 'workspace' | 'template' | 'default', required: Where the policy comes from.
      - `mode` 'adaptive' | 'fixed' | 'never', required
      - `timeout_seconds` integer, nullable, required: The timeout applied to the current idle period while the workspace runs (as of the idle loop’s last decision), else null.
      - `basis` string, nullable, required: What the timeout comes from, e.g. "learned from 37 idle periods (active-hours)", "template prior", "default".
      - `next_eligible_at` string, date-time, nullable, required: When the workspace becomes eligible for automatic suspend if nothing happens before (work signals always win).
      - `suspend_request` SuspendRequest, required: A pending suspend-when-idle request: once the workspace has been idle for after_seconds, it is suspended. A tool call after requested_at (the next turn) or a resume cancels it; other work only defers it.
        - `requested_at` string, date-time, required: When the request was made; a newer request replaces it.
        - `after_seconds` integer, required
        - `not_before` string, date-time, required: requested_at + after_seconds: the earliest suspend (within a few seconds of activity flush grace after it). A running command, an attached stream or a keepalive still active then defers the suspend until after_seconds after it ends.
    - `origin` union, required: Where the workspace’s disk came from; null for a workspace opened from its template.
      - object: Forked from workspace_id.
        - `kind` 'fork', required
        - `workspace_id` string, uuid, required: UUIDv7, lowercase canonical form.
      - object: A test instance of a draft state: the draft and the captured state (checkpoint_id is null until the cell placed an instance whose state is being captured).
        - `kind` 'draft_state', required
        - `template_id` string, uuid, required: UUIDv7, lowercase canonical form.
        - `draft_workspace_id` string, uuid, required: UUIDv7, lowercase canonical form.
        - `checkpoint_id` string, uuid, nullable, required: UUIDv7, lowercase canonical form.
        - `captured_at` string, date-time, nullable, required: RFC 3339 UTC timestamp with Z.
      - object: A test instance of a template version, published or not: a fresh workspace on that version.
        - `kind` 'template_version', required
        - `template_id` string, uuid, required: UUIDv7, lowercase canonical form.
        - `version` integer, required
    - `ended_reason` 'closed' | 'idle_timeout' | 'draft_discarded', nullable, required: How a session ended (closed, idle_timeout, draft_discarded); null otherwise.
    - `dev_template_id` string, uuid, nullable, required: UUIDv7, lowercase canonical form.
    - `startup` WorkspaceStartup, required: Start commands and services of the workspace’s template version; null when the version has none.
      - `state` 'pending' | 'running' | 'ready' | 'failed', required: pending: a start is in progress and its startup has not begun (or never ran); running: start commands, services or readiness waits are running; ready: every step succeeded; failed: a step failed (the workspace still runs so it can be inspected; the next open runs the failed step again).
      - `trigger` 'create' | 'boot' | 'resume', nullable, required: create: a new workspace layer; boot: a cold boot; resume: a memory restore. null while pending.
      - `step` string, nullable, required: The start command (or `services`, `ready:<service>`) running or failed.
      - `service` string, nullable, required: The service that failed or is awaited.
      - `exit_code` integer, nullable, required
      - `output_tail` string, nullable, required: Up to the last 4096 bytes of the failed step’s output (stdout and stderr interleaved).
      - `reason` string, nullable, required: Failure reason: startup_failed, service_not_ready, secrets_unavailable, secret_not_available or guest_feature_unavailable.
      - `operation_id` string, uuid, nullable, required: UUIDv7, lowercase canonical form.
      - `at` string, date-time, nullable, required: RFC 3339 UTC timestamp with Z.
    - `mode` 'processful' | 'file_first', required: processful (default): one VM keeps processes, memory and files between calls; it can be suspended, resumed and forked. file_first: the state is a versioned file tree (tree_revision); there is no VM between executions, each exec runs in a fresh VM and publishes the changed files as the next revision, nothing but files survives an execution. A file-first workspace is ready (running) from creation and is never suspended; suspend, resume, snapshot, fork, reset, save-as-template, volumes and idle policies are 409 not_supported_for_mode. Immutable.
    - `tree_revision` integer, required: file_first: the latest revision of the file tree (0 = the empty tree the workspace starts with; each mutating file call or execution publishes the next one; cell file responses carry it as X-Tree-Revision). Always 0 for processful workspaces.
    - `upgrade_available` object, nullable: Supported target dimensions of an opt-in upgrade; null dimension stays unchanged.
      - `memory_layout` integer, nullable, required
      - `guest_revision` integer, nullable, required
      - `template_version` integer, nullable, required
    - `upgrade_pending` object, nullable: The pinned upgrade target awaiting its cold start.
    - `computer_use` ComputerUse, required
      - `enabled` boolean, required: Effective: tool tokens carry the computer tool (the workspace’s value, else the template’s, and the version runs a desktop).
      - `workspace` boolean, nullable, required: The workspace’s own value; null follows the template.
      - `template` boolean, required: The template’s switch for its workspaces.
      - `available` boolean, required: The workspace’s template version can run a desktop (its guest agent has desktop.v1).
    - `created_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
    - `updated_at` string, date-time, required: RFC 3339 UTC timestamp with Z.
    - `deleted_at` string, date-time, nullable, required: RFC 3339 UTC timestamp with Z.

## Other responses

- `4XX`: Default Response
- `5XX`: Default Response

---

[API](https://skmtc.dev/shardflux/apis/shardflux-api.md) · [All operations](https://skmtc.dev/shardflux/apis/shardflux-api/llms.txt) · [OpenAPI document](https://skmtc.dev/shardflux/apis/shardflux-api/revisions/ea685f7b39c4?raw)
