Skip to main content
A session carries a status that governs what may be done with it. A freshly created session is open and fully writable. From there it can be closed — frozen read-only while its history is preserved — reopened, or deleted, which permanently removes it and everything it contains.

Statuses

closed is read-only, not read-blocked. Everything in a closed session — objects, thread items, graph elements, execution history — stays fully readable. That is the point of closing rather than deleting.* Reads during deleting succeed only until the underlying data is purged; once teardown completes the session no longer exists and reads return 403.

Transitions

Only these transitions are legal. Every one is applied atomically, so concurrent callers cannot both win — the loser receives 409. Anything else is rejected: close_session, reopen_session and delete_session all require the write role on the blob.

The write gate

The moment a session leaves open, every mutating operation on it is rejected with 409 session_not_open. This includes upload_session_object, delete_session_object, post_session_thread_item, apply_session_graph_mutations and create_execution. Reads are never gated: get_session, list_sessions, list_session_events, download_session_object, list_session_objects and the thread and graph read commands all keep working, in every status, until the session is actually gone.
Editing the workflow definition is not affected. A session’s status governs that session’s data, not the revision it belongs to — you can keep editing the workflow while a session is closed.

Closing is asynchronous

close_session returns immediately with status: "closing". The write gate is already in force at that point, so no new work can start. In the background BlobHub then stops every execution still running in the session and waits for each to reach a terminal status. Only once the session is quiescent does it become closed. A close therefore takes a little time to complete even though the command returns at once — typically tens of seconds when executions must be stopped, and near-immediate when there is nothing running. Clients should treat closing as a transient state and wait for session_closed (or poll get_session) rather than assuming the close is finished when the command returns.
Executions stopped by a close or delete finish with status stopped and do not emit execution_ended, which is reserved for executions that run to completion on their own. To observe a drained execution, read its status with get_execution rather than waiting for that event.

Deleting is permanent

delete_session is a hard delete. There is no tombstone, retention window or undo. Once teardown completes, the session and everything belonging to it are gone:
  • every session object, including thread items and graph elements
  • the session’s execution history and execution events
  • the session’s stored events
  • the session row itself
The command may be issued from any live status. It returns immediately with status: "deleting" and the teardown proceeds in the background.

Nothing is purged while work is running

Deletion drains before it purges. Any execution still running is stopped and must reach a terminal status before the first piece of data is removed. This ordering is what prevents an in-flight execution from writing into a session that is being torn down and leaving orphaned data behind. Deleting an open session therefore performs the whole sequence — stop the work, then purge — as a single action. It does not pass through closed, and consequently emits no session_closed event on the way (see Session Events).

After a delete

Once the session is gone, requests that reference it return 403, including download_session_object for objects it used to contain, and it no longer appears in list_sessions. Its per-revision session quota is released.

Choosing between close and delete

Close when the work is finished but the record matters — a completed run you may want to inspect, audit or resume later. It stops anything still running, freezes the contents, and can be undone with reopen_session.Delete when the data itself should not persist. It is irreversible.

Reacting to lifecycle changes

Four events mark the transitions — session_closing, session_closed, session_deleting and session_deleted. They are delivered over the realtime WebSocket API and, apart from session_deleted, also recorded in the session’s event stream. See Session Events for payloads and the ordering rules, including why a delete from open produces no session_closed. reopen_session emits no event: the caller learns the new status from the command’s response.

Close Session

Freeze a session read-only.

Reopen Session

Return a closed session to writable.

Delete Session

Permanently remove a session.

Session Events

The events emitted by each transition.