> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runtm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Session Status (v0)

> Polling-friendly status endpoint for background agents

Returns the current state of a session along with `last_prompt` (the polling status of the most recent prompt), `prompt_history`, and `lifecycle` policy. This is the endpoint to poll after [`POST /api/v0/sessions/launch`](/cloud-api/sessions/launch) or after sending a prompt via [`POST /api/v0/sessions/{id}/prompt`](/cloud-api/sessions/v0-prompt).

The response shape is intentionally different from [`GET /api/sessions/{id}`](/cloud-api/sessions/get) - v0 includes the polling fields needed for fire-and-forget agent workflows.

**Required scope:** `sessions:read`

## Path Parameters

<ParamField path="session_id" type="string" required>
  The session ID returned by `launch` or `create`.
</ParamField>

## Headers

<ParamField header="Authorization" type="string" required>
  Bearer token. Example: `Bearer runtm_xxx`
</ParamField>

## Response

<ResponseField name="id" type="string">Session ID.</ResponseField>
<ResponseField name="state" type="string">Sandbox state: `creating`, `running`, `paused`, `error`.</ResponseField>
<ResponseField name="agent" type="string">Coding agent (e.g. `claude-code`).</ResponseField>
<ResponseField name="template" type="string | null">Template the session was scaffolded from.</ResponseField>
<ResponseField name="created_at" type="string">ISO 8601 creation timestamp.</ResponseField>
<ResponseField name="expires_at" type="string | null">TTL expiry. `null` for `keep_alive` sessions.</ResponseField>
<ResponseField name="total_cost_usd" type="number">Aggregate cost across all prompts.</ResponseField>
<ResponseField name="prompt_count" type="integer">Number of prompts run in this session.</ResponseField>
<ResponseField name="name" type="string | null">Display name.</ResponseField>
<ResponseField name="github_repo" type="string | null">GitHub `owner/repo` link.</ResponseField>

<ResponseField name="last_prompt" type="object | null">
  Status of the most recent prompt - the primary polling field.

  * **`status`** - `idle`, `running`, `completed`, `error`, `timed_out`
  * **`prompt_preview`** - first 200 chars of the prompt
  * **`model`** - model used (e.g. `sonnet`)
  * **`started_at`** / **`completed_at`** - ISO 8601 timestamps
  * **`cost_usd`** - cost in USD for this prompt
  * **`summary`** - first 500 chars of the agent's final response
  * **`error`** - error string if `status` is `error` or `timed_out`
  * **`plan_mode`** - whether plan mode was enabled
</ResponseField>

<ResponseField name="prompt_history" type="array">
  Ordered list of all prompts run in this session, each with the same shape as `last_prompt`.
</ResponseField>

<ResponseField name="lifecycle" type="object | null">
  Lifecycle policy applied at launch:

  * **`on_complete`** - `pause`, `destroy`, or `keep_alive`
  * **`ttl_minutes`** - TTL in minutes
  * **`ttl_expires_at`** - ISO 8601 expiry timestamp
</ResponseField>

## Polling pattern

```python theme={null}
import requests, time

session_id = "86e11104-..."
while True:
    status = requests.get(
        f"https://app.runtm.com/api/v0/sessions/{session_id}",
        headers={"Authorization": "Bearer runtm_xxx"},
    ).json()

    last = status.get("last_prompt") or {}
    if last.get("status") in ("completed", "error", "timed_out"):
        print(f"Done: {last['status']} (${last.get('cost_usd', 0):.4f})")
        print(last.get("summary"))
        break

    time.sleep(5)
```

For high-volume agents, use [webhooks](/cloud-api/patterns/outbound-webhooks) instead of polling.

<RequestExample>
  ```bash cURL theme={null}
  curl "https://app.runtm.com/api/v0/sessions/86e11104-cdbb-42c9-bdc3-5212024ddb7b" \
    -H "Authorization: Bearer runtm_xxx"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://app.runtm.com/api/v0/sessions/86e11104-cdbb-42c9-bdc3-5212024ddb7b",
      headers={"Authorization": "Bearer runtm_xxx"},
  )

  session = response.json()
  print(f"State: {session['state']}")
  print(f"Last prompt: {(session.get('last_prompt') or {}).get('status', 'idle')}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://app.runtm.com/api/v0/sessions/86e11104-cdbb-42c9-bdc3-5212024ddb7b",
    { headers: { "Authorization": "Bearer runtm_xxx" } }
  );

  const session = await response.json();
  console.log(`State: ${session.state}`);
  console.log(`Last prompt: ${(session.last_prompt || {}).status || "idle"}`);
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "86e11104-cdbb-42c9-bdc3-5212024ddb7b",
    "state": "running",
    "agent": "claude-code",
    "template": "backend-service",
    "created_at": "2026-05-09T21:00:00Z",
    "expires_at": "2026-05-09T22:00:00Z",
    "total_cost_usd": 0.23,
    "prompt_count": 1,
    "name": "Refactor billing service",
    "github_repo": "acme/billing",
    "last_prompt": {
      "status": "completed",
      "prompt_preview": "Build a REST API with FastAPI that manages TODO items",
      "model": "sonnet",
      "started_at": "2026-05-09T21:00:30Z",
      "completed_at": "2026-05-09T21:04:12Z",
      "cost_usd": 0.23,
      "summary": "Created FastAPI app at /home/user/main.py with CRUD endpoints…",
      "error": null,
      "plan_mode": false
    },
    "prompt_history": [],
    "lifecycle": {
      "on_complete": "pause",
      "ttl_minutes": 60,
      "ttl_expires_at": "2026-05-09T22:00:00Z"
    }
  }
  ```
</ResponseExample>
