> ## 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.

# Sessions and authentication

> Exchange your connector token for a short-lived access token, then create a session.

Before opening a WebSocket, you obtain an access token and create a session.

## Obtain an access token

Exchange your connector token for a short-lived JWT access token.

**`POST /api/v1/access-token`**

### Headers

| Header         | Required | Description                                                                                                                                             |
| -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Token`      | Yes      | Your connector token (provided by PolyAI)                                                                                                               |
| `X-Host`       | Yes      | The domain or app namespace you registered when generating the token (e.g. `https://www.yourcompany.com` or `com.yourcompany.app`). Must match exactly. |
| `Content-Type` | Yes      | `application/json`                                                                                                                                      |

### Request body

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{}
```

### Response — `200 OK`

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "access_token": "eyJhbGc...",
  "expires_in": 86400,
  "token_type": "Bearer"
}
```

| Field          | Type    | Description                            |
| -------------- | ------- | -------------------------------------- |
| `access_token` | string  | JWT to use for all subsequent requests |
| `expires_in`   | integer | Seconds until the token expires        |
| `token_type`   | string  | Always `"Bearer"`                      |

Use this token in two places:

* As a `Bearer` token in the `Authorization` header for [Create session](#create-session)
* As the `access_token` query parameter when [connecting the WebSocket](/api-reference/messaging/websocket)

<Warning>
  Treat the access token as sensitive. Do not log it, store it in `localStorage`, or expose it to third-party scripts. Always connect over `wss://` (TLS).
</Warning>

## Create session

A session represents one conversation. Create a session before opening a WebSocket.

**`POST /api/v1/sessions`**

### Headers

| Header          | Required | Description                                    |
| --------------- | -------- | ---------------------------------------------- |
| `Authorization` | Yes      | `Bearer <access_token>` from the previous step |
| `Content-Type`  | Yes      | `application/json`                             |
| `User-Agent`    | No       | The browser or device user agent               |

### Request body (optional)

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "platform": "web",
  "streaming_enabled": true
}
```

| Field               | Type    | Default | Description                                                                                                                                                                                                                                                                                                                         |
| ------------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `streaming_enabled` | boolean | `false` | When `true`, agent responses arrive as a series of incremental chunks. When `false`, each response arrives as a single complete message. See [Streaming](/api-reference/messaging/streaming).                                                                                                                                       |
| `platform`          | string  | `web`   | One of `web`, `ios`, `android`, `ios-web`, `android-web`, or `custom`. Use `ios` / `android` from native SDKs that post to this endpoint directly. The webchat script reports `web`, `ios-web`, or `android-web` automatically based on its `data-platform` attribute — you don't need to set this field when embedding the script. |

The request body is optional — if omitted, `streaming_enabled` defaults to `false`.

### Response — `200 OK`

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```

Keep the `session_id` — you need it to open the WebSocket and to reconnect if the connection drops.

<Note>
  Sessions expire after roughly 10 minutes of inactivity. After expiry, create a new session — you cannot resume an expired session.
</Note>
