# Headless sessions

> Run a voice call with your agent and draw the interface yourself, from typed events.

Source: https://voxio.in/docs/sessions · voxioagent 2.0.0 · Index: https://voxio.in/docs/llms.txt

`voxioagent/client` gives you the call with no interface of ours. It handles the microphone, the WebRTC connection, reconnects, audio levels and web actions, and tells you what happens through events.

## Before you begin

You need:

- The package: `npm install voxioagent`.
- A flow key.
- A page served over HTTPS or from `localhost`.

## Start a session

Create a session, listen for its events, and start it from a click:

call.js:

```js
import { createSession } from "voxioagent/client";

const session = createSession({ flowKey: "YOUR_FLOW_KEY" });

session.on("state", (state) => console.log("state:", state));
session.on("error", (error) => console.warn("error:", error.code));
session.on("ended", ({ reason, seconds }) => console.log("ended:", reason, seconds));

document.querySelector("#start").onclick = () => session.start();
document.querySelector("#end").onclick = () => session.stop();
```

Replace `YOUR_FLOW_KEY` with your flow key, from the flow's **Overview** in the dashboard.

When you click `#start` and allow the microphone, the console shows:

Console:

```text
state: connecting
state: listening
state: speaking
```

> **Note**
>
> Browsers only open the microphone from a click or a tap. Call `start()` inside the handler, not on page load.

## Options

- `flowKey` (string, required): The flow to talk to.
- `environment` ("standard" | "gpu"): The deployment. See [Servers and environments](https://voxio.in/docs/environments.md).
- `endpoints` ({ voice? }): Overrides the voice server.
- `media` ({ audio?, video?, camera? }): Sends the microphone (default: true), receives the [avatar](https://voxio.in/docs/avatar.md), sends the camera.
- `customs` (object): Overrides for this session only, such as workflow variables, voice and thresholds. They’re merged into the flow.
- `participants` (ParticipantsGraph): Who sees and hears whom. See [Describe the participants](https://voxio.in/docs/avatar.md#describe-the-participants).
- `recording` (boolean): Records this session.
- `sessionId` (string): Continues an existing conversation, such as a chat, instead of starting a new one.
- `webActions` (boolean | WebActionOptions): The built-in web action runner. Default: on. See [Web actions](https://voxio.in/docs/web-actions.md).
- `maxRetries` (number): Reconnect attempts after a failure. Default: 3.
- `retryDelayMs` (number): The first retry delay, doubled on each attempt. Default: 1000.
- `microphone` (string): A microphone `deviceId`.
- `debug` (boolean): Prints diagnostics. Otherwise the SDK writes nothing to the console.

## Pass values to the workflow

To give the agent details it should know for this call, pass them in `customs`:

```js
createSession({
  flowKey: "YOUR_FLOW_KEY",
  customs: { variables: { customer_name: "Priya", order_id: "A-1042" } },
});
```

The workflow can use `customer_name` and `order_id`, so the agent can greet Priya by name and look up her order.

## Events

`session.on(event, listener)` returns a function that removes the listener.

| Event | The listener gets | Fires when |
| --- | --- | --- |
| `state` | `idle`, `connecting`, `listening`, `speaking`, `ended` or `error` | The call changes state. |
| `level` | `{ user, agent }`, each 0 to 1 | About 20 times a second during a call. |
| `agentAudio` | `MediaStream` | The agent’s voice arrives. It’s already playing. |
| `agentVideo` | `MediaStream` | The avatar video arrives. |
| `mute` | `boolean` | The microphone is muted or unmuted. |
| `webAction` | `(message, ack)` | The agent asks for a web action, when `webActions` is `false`. |
| `webActionResult` | `(message, status)` | The built-in runner finishes an action. |
| `message` | any | The agent sends any other message. |
| `ended` | `{ reason, seconds, sessionId }` | The call ends. `reason` is `user` (you stopped it), `remote` (the agent hung up) or `error`. |
| `error` | `VoxioError` | Something fails. See [Errors](https://voxio.in/docs/errors.md). |

## Methods and properties

| Member | What it does |
| --- | --- |
| `start()` | Opens the microphone and connects. Call it from a click or tap. |
| `stop()` | Hangs up and releases the microphone. You can start the session again. |
| `mute(muted = true)` | Mutes or unmutes without dropping the call. |
| `setMicrophone(deviceId)` | Switches microphone during a call. |
| `destroy()` | Stops the session for good and removes every listener. |
| `state` | The current state. |
| `muted` | Whether the microphone is muted. |
| `sessionId` | The conversation’s id. Use it to look the session up later or match it to a webhook. |
| `localStream` | The visitor’s microphone, and camera if on, while a call is live. |

## Reconnects

The SDK retries a failed connection up to `maxRetries` times, doubling the wait each time. A call that drops is reconnected the same way, and a call that stays up for ten seconds resets the count. A refused key or any other 4xx answer is never retried. When the agent ends the call, `ended` fires with `reason: "remote"`.

## Next steps

- [Web actions](https://voxio.in/docs/web-actions.md): let the agent act on your page during the call.
- [Errors](https://voxio.in/docs/errors.md): handle each error code.
- [Sessions and usage](https://voxio.in/docs/sessions-usage.md): read the transcript after the call.
