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

# Sessions API

> List, inspect, and delete sessions

## Introduction

Manage user sessions used to group related tasks and context.

Notes:

* Soft delete only. `DELETE` marks a session as deleted (keeps data) and returns 204.
* Deleted sessions are excluded from reads and cannot be fetched (404).

## List Sessions

```
GET /api/v1/sessions?limit=20&offset=0
```

Query params:

* `limit` (1–100, default 20)
* `offset` (>= 0, default 0)

Response (200):

```json theme={null}
{
  "sessions": [
    {
      "session_id": "a0c2b1e2-...",
      "user_id": "00000000-0000-0000-0000-000000000002",
      "task_count": 3,
      "total_tokens_used": 1234,
      "token_budget": 10000,
      "created_at": "2025-10-28T06:00:00Z"
    }
  ],
  "total_count": 1
}
```

## Get Session

```
GET /api/v1/sessions/{sessionId}
```

Path params:

* `sessionId` (UUID or external\_id string)

Response (200): session metadata including token usage and task count.
Errors: 401, 403, 404.

### Session ID Format

Shannon supports **dual-ID pattern** for sessions:

1. **UUID Format** (internal): `a0c2b1e2-fd3e-4567-890a-bcdef1234567`
2. **External ID Format** (custom strings): `"user-123-chat"`, `"analytics-session-456"`

When you submit a task with a non-UUID `session_id`, Shannon:

* Creates an internal UUID for database storage
* Stores your custom ID in `context.external_id`
* Accepts **either format** in all session API calls

**Example**:

```bash theme={null}
# Create session with custom ID
curl -X POST http://localhost:8080/api/v1/tasks \
  -H "X-API-Key: sk_test_123456" \
  -d '{"query": "Hello", "session_id": "my-chat-session"}'

# Query using same custom ID
curl http://localhost:8080/api/v1/sessions/my-chat-session \
  -H "X-API-Key: sk_test_123456"
```

This allows natural session naming without managing UUIDs.

## Get Session History

```
GET /api/v1/sessions/{sessionId}/history
```

Path params:

* `sessionId` (UUID or external\_id string)

Returns all tasks in the session with execution details.
Errors: 401, 403, 404.

## Get Session Events (Grouped by Turn)

```
GET /api/v1/sessions/{sessionId}/events?limit=10&offset=0
```

Path params:

* `sessionId` (UUID or external\_id string)

Returns chat history grouped by task/turn, including full events per turn (excludes `LLM_PARTIAL`).

Query params:

* `limit` (1–100, default 10) — number of turns to return
* `offset` (>= 0, default 0) — number of turns to skip

Response (200):

```json theme={null}
{
  "session_id": "chat-session-123",
  "count": 2,
  "turns": [
    {
      "turn": 1,
      "task_id": "task-001",
      "user_query": "What is 2+2?",
      "final_output": "2 + 2 equals 4.",
      "timestamp": "2025-10-29T06:00:01.513288Z",
      "events": [
        { "workflow_id": "wf-1", "type": "LLM_PROMPT", "message": "...", "timestamp": "..." },
        { "workflow_id": "wf-1", "type": "LLM_OUTPUT", "message": "2 + 2 equals 4.", "timestamp": "..." }
      ],
      "metadata": {
        "tokens_used": 150,
        "execution_time_ms": 8000,
        "agents_involved": ["planner", "simple-agent"]
      }
    }
  ]
}
```

Notes:

* `final_output` falls back to the first `LLM_OUTPUT` event if the task result is empty.
* `turn` numbers are global (offset+index).
* Returns 404 if the session is deleted or not owned by the requester.

## Update Session Title

```
PATCH /api/v1/sessions/{sessionId}
```

Path params:

* `sessionId` (UUID or external\_id)

Body:

```json theme={null}
{ "title": "New Title" }
```

Rules:

* Title is trimmed; control characters removed.
* Max 60 characters (UTF-8 safe). Longer titles are rejected.

Responses:

* 200 OK with updated title
* 400 Invalid request (empty or too long title)
* 401 Unauthorized
* 403 Forbidden (not the owner)
* 404 Not Found

## Delete Session (Soft Delete)

```
DELETE /api/v1/sessions/{sessionId}
```

Path params:

* `sessionId` (UUID or external\_id string)

Behavior:

* Marks the session as deleted (`deleted_at`, `deleted_by`), does not remove data.
* Idempotent: always returns 204 for the owner.
* Clears session cache to prevent stale reads.

Responses:

* 204 No Content
* 401 Unauthorized
* 403 Forbidden (not the owner)
* 404 Not Found
