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

# Session

> The multi-turn handle returned by app.session() - participants, agent handoff, send/stream, and resolving approvals.

A `Session` is a lightweight handle for a multi-turn conversation. You do not
construct it directly - `app.session(...)` returns one. It carries metadata,
participants, and the current sub-agent, but the session object is not
the message store; conversation history lives with the harness and session
transcript. See the [concept page](/concepts/sessions-and-participants) for the
model.

## Create

```python theme={null}
session = app.session(metadata={"customer_id": "abc123"})
```

## Fields

| Field             | Type                | Meaning                                           |
| ----------------- | ------------------- | ------------------------------------------------- |
| `id`              | `str`               | Session identifier (maps to a harness thread).    |
| `metadata`        | `dict`              | Arbitrary key/values; route and look up by these. |
| `status`          | `str`               | `active`, etc.                                    |
| `participants`    | `list[Participant]` | Humans and AIs in the session.                    |
| `current_agent`   | `Agent \| None`     | The sub-agent handling turns now.                 |
| `pending_input`   | `dict \| None`      | A `request_id` awaiting an approval decision.     |
| `permission_mode` | `str \| None`       | How approval prompts are handled.                 |
| `parent_id`       | `str \| None`       | Parent session, for sub-sessions.                 |

## Send and stream

```python theme={null}
async def send(text, *, participant=None, thinking=False) -> Response
def      send_sync(...) -> Response
async def stream(...) -> AsyncIterator[StreamEvent]
def      stream_sync(...) -> list[StreamEvent]
```

```python theme={null}
session.send_sync("I need help with my order")
session.send_sync("This is order #12345")  # same thread
```

## Participants

```python theme={null}
from karta import HumanAgent

alice = HumanAgent(name="alice", display_name="Alice Chen")
session.add_participant(alice)
session.send_sync("Looking into it now", participant=alice)
```

Each message is attributed to its sending participant. Multiple humans and AIs
can share one session.

## Agent handoff

Assigning `current_agent` fires the `agent.handoff`
[hook](/sdks/python/hooks-and-policies):

```python theme={null}
session.current_agent = app.agents["billing-specialist"]
session.send_sync("Was invoice #789 charged twice?")
```

## Resolving approvals

When a turn pauses with an
[`input_required`](/concepts/streaming-events#input_required) event, resolve it
and continue streaming:

```python theme={null}
async for event in session.stream_pending_input("approve_once", request_id=req_id):
    if event.type == "text":
        print(event.data["part"]["text"], end="")
```

Decisions are `approve_once`, `approve_session`, or `deny`.
