Skip to main content
Sessions are the core unit of work in Runtime. This guide covers the patterns you need when managing sessions programmatically - whether you are calling the API from your own terminal, letting a coding agent spin up cloud environments, or orchestrating sessions from a CI pipeline. For the full endpoint reference, see Manage Sessions and Lifecycle.

When to use this

  • You are calling the Runtime API from a local script, coding agent, or your own tooling
  • You are orchestrating sessions from a CI pipeline or backend service
  • You need sessions to stay alive during long-running jobs
  • You want to handle edge cases (sandbox expiry, network errors, orphaned sessions) gracefully

Prerequisites

  • An API key with sessions:read and sessions:write scopes
  • For prompts: sessions:prompt scope

Session states

Every session moves through a fixed set of states:

Wait for a session to become running

After POST /api/sessions, the session starts in creating state. You have two options: POST /api/sessions/{id}/start blocks until the session is running and the dev server is up. It handles every state transition transparently:

Option 2: Poll GET /api/sessions/

If you need more control over the wait loop (e.g. to show a progress indicator), poll until state is running:
Python
Poll with refresh=true (the default) to catch sandboxes that were destroyed externally. Pass refresh=false for faster reads when eventual consistency is acceptable.

Keep sessions alive with heartbeats

Running sessions that receive no activity for 20 minutes are automatically paused. If you have gaps between prompts (e.g. waiting for a local build to finish, or processing results before the next step), send periodic heartbeats:
A heartbeat resets the idle timer without doing any real work. Send one every 10-15 minutes during long gaps.

Pause and resume

Use pause to save resources between bursts of work. Paused sessions accrue no compute cost and resume in seconds with the filesystem intact.
Key behaviors:
  • Pausing an already-paused session is a no-op (returns 200)
  • Pausing while a prompt is running returns 409 - cancel the prompt first
  • Resuming an already-running session is a no-op
  • Any mutating endpoint (prompt, file write) on a paused session triggers an automatic resume

Clean up sessions

Always destroy sessions when done. Orphaned running sessions consume resources and count against your limits.
Python
DELETE /api/sessions/{id} is permanent. The sandbox and all files are destroyed and cannot be recovered. Use pause if you might need the session later.

Error recovery patterns

Retry transient failures

API calls can fail due to network issues or temporary overload. Wrap calls in a retry loop with exponential backoff:
Python

Handle sandbox expiry

Paused sessions can expire if their retention period lapses. When you try to resume an expired session, you get 410 Gone:
Your code should catch 410 and create a fresh session.

Handle concurrent prompt conflicts

Only one prompt runs per session at a time. If you submit a prompt while one is already in flight, you get 202 with status: "already_running". Two strategies:
  1. Wait and retry - poll GET /api/sessions/{id} until last_prompt.status is completed or error, then submit.
  2. Cancel and resubmit - call POST /api/sessions/{id}/prompt/cancel, then submit the new prompt.

Set a TTL for unattended runs

For fire-and-forget agent runs, set ttl_minutes at creation time. The session is automatically destroyed when the TTL elapses, regardless of activity:
Combine with on_complete: "destroy" to clean up immediately after the first prompt finishes, or on_complete: "pause" to preserve the workspace for inspection.

Next steps

Stream prompts over WebSockets

Send prompts and receive agent events in real time.

Handle long-running prompts

Cancel, rewind, and replay prompt history.

Sessions API reference

Full endpoint reference for session CRUD.

Lifecycle API reference

Pause, resume, start, and cleanup endpoints.