Agents APISessions

Manage sessions

Check a session's state, pause and resume it, find your sessions, and clean up.

Session state

Retrieve a session
const current = await sessions.get(session.id)
console.log(current.status, current.last_seq, current.error)
JSON
{
  "id": "ags_4843742656c9cbc90685c6d2",
  "object": "agent.session",
  "status": "idle",
  "agent": { "model": "bedrock/us.anthropic.claude-sonnet-5", "instructions": "Answer in one short sentence.", "permissions": null },
  "environment": { "type": "none" },
  "metadata": { "customer": "cus_123" },
  "created_at": "2026-09-28T07:17:41.522000+00:00",
  "updated_at": "2026-09-28T07:17:52.106000+00:00",
  "paused_at": null,
  "ended_at": null,
  "instance_number": 1,
  "instance_context": "new",
  "last_seq": 8,
  "error": null
}
FieldMeaning
statusWhere the session is in its lifecycle (below).
last_seqThe newest event number. Pass it as after to read only what comes next.
error{ type, message } if something went wrong with the sandbox, otherwise null.
instance_number · instance_contextWhether the conversation was restored after a pause: instance_context is full, workspace_only or new. instance_number goes up by one each time the session resumes (see Pause and resume).
environment · metadataThe repositories it works on, and your own key/values.

Statuses

StatusMeaning
provisioningA sandbox is starting. Messages sent now are delivered when it's ready.
idleReady and not working. A message starts a run.
runningWorking on a run. A message steers it.
waitingBlocked on an approval.
pausing · pausedThe sandbox has been released. The conversation and files are kept, and a message resumes it.
stopping · stoppedDeleted, or paused for too long. Events and patches can still be read.
failedCouldn't start. See error, and create a new session.

Pause and resume

Sandboxes are temporary, but sessions aren't. A paused session keeps its conversation and files without holding a sandbox. The next message starts a new sandbox from where it left off, with repositories back at the commits they started from and the agent's changes on top.

Pause, then continue with a message
await sessions.pause(session.id)
await sessions.wait(session.id, { until: ["paused"] })

// Later: a message resumes it. No need to call resume() first.
const { last_seq } = await sessions.get(session.id)
await sessions.message(session.id, "What word did I ask you to remember?")

for await (const event of sessions.events(session.id, { after: last_seq })) {
  if (event.type === "text.ended") console.log(event.data?.text)
  if (event.type === "run.completed" || event.type === "run.failed") break
}

const resumed = await sessions.get(session.id)
console.log(resumed.instance_number, resumed.instance_context)
You asked me to remember the word "pelican".
2 full

The session resumed (instance_number: 2) with the whole conversation restored (instance_context: "full"). With workspace_only, the files came back but the conversation starts over, so include the context the agent needs in your message. new means the session hasn't been resumed yet.

Sessions pause or stop on their ownDefault
Idle, with nothing to do → paused30 minutes
One sandbox running for a long time → paused4 hours
Paused and untouched → stopped7 days

A session that's waiting for an approval is never paused for being idle. These are the defaults; your administrator may set others. If a sandbox disappears unexpectedly, the session moves to paused with an error, and the next message resumes it with its files.

Find your sessions

Sessions are listed newest first, 20 per page by default and up to 100. Use metadata to tie them to your own records. You only ever see sessions you created, in the organization you're working in.

List sessions and filter by metadata
const page = await sessions.list({ limit: 20 })
const mine = page.data.filter((s) => s.metadata?.customer === "cus_123")
console.log(mine.map((s) => `${s.id} ${s.status}`))

When has_more is true, pass next_after as after for the next page.

Delete a session

Deleting stops the session for good and releases its sandbox. A final patch is saved first, and events and patches stay readable afterwards.

Delete a session
const stopped = await sessions.delete(session.id)
console.log(stopped.status)
Always clean up
An idle session holds its sandbox until it pauses on its own. In scripts, CI and batch jobs, delete sessions in a finally block, as every example on these pages does.

Retry safely

Pass an idempotency key when creating sessions from code that may run twice, such as a queue worker or a webhook handler. A second call with the same key returns the first session instead of starting another. The same key with different settings raises conflict.

Create a session exactly once
const settings = {
  agent: { model: "bedrock/us.anthropic.claude-sonnet-5" },
  input: `Summarize ticket ${ticket} in one line.`,
  idempotencyKey: `summarize-${ticket}`,
}

const first = await sessions.create(settings)
const retry = await sessions.create(settings) // e.g. your job queue ran twice
console.log(first.id === retry.id) // true: one session, not two
  • When there's no capacity, creating or resuming fails with runner_unavailable. Retry after a short wait, with the same key.
  • Your organization may cap active sessions. Past the cap, creation fails with session_limit_reached.