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

# Session lifecycle

> Every event in order, from connection through session end.

This page lists every event in order for a complete session — what your client sends and what it receives.

## Connection and agent join

| Step | Direction | Event | What to do |
| - | - | - | - |
| 1 | ← Server | `EVENT_TYPE_EVENT_BATCH` | History replay. Flatten the `events` array. Contains at least `SESSION_START`. |
| 2 | | ↳ `EVENT_TYPE_SESSION_START` | Read `capabilities` (streaming, heartbeat interval). |
| 3 | Client → | `EVENT_TYPE_REQUEST_POLY_AGENT_JOIN` | Send to start the conversation. **New sessions only** — skip on reconnect if agent already joined. |
| 4 | ← Server | `EVENT_TYPE_REQUEST_POLY_AGENT_JOIN` | Echo of your join request. |
| 5 | ← Server | `EVENT_TYPE_POLY_AGENT_JOINED` | Agent has joined. Read `agent_name` and `agent_avatar_url` for your UI. |
| 6 | ← Server | `EVENT_TYPE_POLY_AGENT_THINKING` | Show a typing indicator. |
| 7 | ← Server | `EVENT_TYPE_POLY_AGENT_MESSAGE` | The agent's greeting. (If streaming: `POLY_AGENT_MESSAGE_CHUNK` events instead.) |

## Conversation turn (repeats)

| Step | Direction | Event | What to do |
| - | - | - | - |
| 8 | Client → | `EVENT_TYPE_USER_TYPING` (`STARTED`) | Optional. Send when the user begins typing. |
| 9 | Client → | `EVENT_TYPE_USER_TYPING` (`STOPPED`) | Optional. Send when the user stops typing. |
| 10 | Client → | `EVENT_TYPE_USER_MESSAGE` | Send the user's message. |
| 11 | ← Server | `EVENT_TYPE_USER_MESSAGE` | Echo with server-assigned `message_id`. Confirms receipt. |
| 12 | ← Server | `EVENT_TYPE_POLY_AGENT_THINKING` | Show typing indicator. |
| 13 | ← Server | `EVENT_TYPE_POLY_AGENT_MESSAGE` | The agent's response. (If streaming: `POLY_AGENT_MESSAGE_CHUNK` events instead.) |

## Handoff to live agent (if triggered)

| Step | Direction | Event | What to do |
| - | - | - | - |
| 14 | ← Server | `EVENT_TYPE_POLY_AGENT_TRIGGERED_HANDOFF` | Inform the user they're being connected to a human. |
| 15 | ← Server | `EVENT_TYPE_POLY_AGENT_LEFT` | The PolyAI agent has left. |
| 16 | ← Server | `EVENT_TYPE_HANDOFF_ACCEPTED` | The live agent system accepted the request. |
| 17 | ← Server | `EVENT_TYPE_HANDOFF_QUEUE_STATUS` | Periodic. Show queue position (e.g. "You're #3 in line"). |
| 18 | ← Server | `EVENT_TYPE_LIVE_AGENT_JOINED` | A human agent has connected. Show their name. |
| 19 | Client → | `EVENT_TYPE_USER_MESSAGE` | User messages are now routed to the human agent. |
| 20 | ← Server | `EVENT_TYPE_LIVE_AGENT_TYPING` | Show typing indicator. |
| 21 | ← Server | `EVENT_TYPE_LIVE_AGENT_MESSAGE` | Message from the human agent. |
| 22 | ← Server | `EVENT_TYPE_LIVE_AGENT_LEFT` | The human agent has left. |

## Session end

| Direction | Event | What to do |
| - | - | - |
| Client → | `EVENT_TYPE_USER_END_SESSION` | User clicks "Leave". |
| ← Server | `EVENT_TYPE_USER_END_SESSION` | Echo confirming receipt. |
| ← Server | `EVENT_TYPE_SESSION_END` (`REASON_USER_END`) | Session over. Disable input, close WebSocket. |

## Alternative endings

| Scenario | What happens |
| - | - |
| **User closes browser** | No more heartbeats → session times out after \~10 minutes → `SESSION_END` with `REASON_USER_ABANDONED` |
| **Conversation completes naturally** | Agent finishes → `SESSION_END` with `REASON_NATURAL_END` |
| **Client-managed handoff** | Server sends `CLIENT_HANDOFF_REQUIRED` instead of `HANDOFF_ACCEPTED` — your app routes the user to an alternative channel |
| **Handoff fails** | `HANDOFF_FAILED` or `HANDOFF_TIMEOUT` — show an error and let the user try again or end the session |
| **Connection drops** | Reconnect with `cursor=<last_sequence>` using the same `session_id` and `access_token` |

## Background (send throughout)

| Direction | Event | Frequency |
| - | - | - |
| Client → | `EVENT_TYPE_HEARTBEAT` | Every 30 seconds (or per `capabilities.heartbeat_interval_seconds`) |
| ← Server | `EVENT_TYPE_HEARTBEAT` | Echo of your heartbeat |

## Reconnection flow

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
sequenceDiagram
    participant Client as Your App
    participant Server as PolyAI

    note over Client: Connection dropped

    Client->>Server: WebSocket connect (session_id, access_token, cursor=12)
    Server-->>Client: EVENT_BATCH (events after sequence 12)
    note over Client: Conversation state restored — continue as normal
```
