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

# Sessions API

> Programmatically create investigations, send follow-up questions, and retrieve results from Traversal using the V1 Sessions API.

The Sessions API lets you launch investigations, send follow-up questions, and fetch results programmatically. Sessions are the same investigation primitive that powers the Traversal web application — anything a member can do in the UI, you can do over the API.

All endpoints require authentication — see [Authentication](/api/authentication) to create an API key. For base URL, error envelope, and generic status codes, see the [API overview](/api/overview).

<Note>
  The V1 Sessions API must be explicitly enabled for your organization. If your organization does not yet have access, contact your Traversal point of contact or [support@traversal.com](mailto:support@traversal.com).
</Note>

## Endpoints

See the **Endpoints** section in the sidebar for the full API reference, generated from the OpenAPI spec.

### Required roles

API keys inherit the role of the user who created them. Most Sessions endpoints work for any `member`, but `GET /v1/sessions` is admin-only because it returns sessions across the whole organization.

| Endpoint                                                     | Minimum role |
| ------------------------------------------------------------ | ------------ |
| `POST /v1/sessions` — Create a session                       | `member`     |
| `GET /v1/sessions` — List sessions                           | **`admin`**  |
| `GET /v1/sessions/{session_id}` — Get a session              | `member`     |
| `POST /v1/sessions/{session_id}/messages` — Send a follow-up | `member`     |

A request from an underprivileged key returns `403 Forbidden` with a message naming the required role. If `GET /v1/sessions` is failing for you, check the role of the user who issued the key in **[Settings > User Management](https://app.traversal.com/settings/user-management)**.

## Session lifecycle

Investigations are **asynchronous**. Creating a session or sending a follow-up returns immediately while Traversal investigates in the background. To retrieve the result, poll `GET /v1/sessions/{session_id}` until the session reaches a terminal state.

### Status values

| Status              | Meaning                                              |
| ------------------- | ---------------------------------------------------- |
| `running`           | A new investigation is in progress.                  |
| `idle`              | Investigation is complete and ready for follow-ups.  |
| `follow_up_running` | A follow-up message is being processed.              |
| `failed`            | The investigation or follow-up errored or timed out. |

`idle` and `failed` are terminal-for-polling — once the session reaches one of these states, no further work is in progress.

### Status transitions

```mermaid theme={null}
stateDiagram-v2
    [*] --> running: POST /v1/sessions
    running --> idle: Investigation complete
    running --> failed: Investigation error
    idle --> follow_up_running: POST /v1/sessions/{id}/messages
    follow_up_running --> idle: Follow-up complete
    follow_up_running --> failed: Follow-up error
```

### Recommended polling pattern

After creating a session or sending a follow-up, poll `GET /v1/sessions/{session_id}` at a steady interval until the session is no longer in `running` or `follow_up_running`.

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

def poll_session(base_url, session_id, api_key, interval=5, timeout=3600):
    """Poll until the session reaches a terminal state."""
    headers = {"Authorization": f"Bearer {api_key}"}
    elapsed = 0
    while elapsed < timeout:
        resp = requests.get(f"{base_url}/v1/sessions/{session_id}", headers=headers)
        data = resp.json()
        if data["status"] in ("idle", "failed"):
            return data
        time.sleep(interval)
        elapsed += interval
    raise TimeoutError("Session did not complete within timeout")
```

<Tip>
  A 5-second polling interval is a reasonable default. Investigations typically complete in a few minutes, but complex incidents may take longer.
</Tip>

<Warning>
  Investigations have a **1-hour server-side timeout**. If an investigation has not completed within that window, the session status transitions to `failed`.
</Warning>

## Session-specific errors

In addition to the [generic status codes](/api/overview#status-codes), the Sessions API returns these session-specific responses:

| Status code | Meaning           | When it occurs                                                                                             |
| ----------- | ----------------- | ---------------------------------------------------------------------------------------------------------- |
| `404`       | Not Found         | Session does not exist or does not belong to your organization.                                            |
| `409`       | Conflict          | Session is not `idle` (e.g., still `running` or `follow_up_running`). Includes `retry_after`.              |
| `429`       | Too Many Requests | Organization has reached the limit of 5 concurrent running sessions. Includes `retry_after` (default 30s). |
