---
title: "Mic Sessions"
description: "Start browser-audio sessions that let you talk to an agent in real time from a web page — the same path the dashboard uses for agent testing and live demos."
---

Mic sessions let you talk to an agent directly from a web browser using
your microphone — no phone number required. ThunderPhone creates a
LiveKit room and returns a join token; your front-end uses the
LiveKit Web SDK to publish audio. This endpoint is typically used for
agent iteration and demos.

## Endpoint

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/v1/mic-session` | Create a mic session against an agent |

## Create a session

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/mic-session \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agent_id": 12}'
```

```python Python
session = requests.post(
    "https://api.thunderphone.com/v1/mic-session",
    headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
    json={"agent_id": 12},
).json()
```

```javascript Node.js
const session = await fetch("https://api.thunderphone.com/v1/mic-session", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.THUNDERPHONE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ agent_id: 12 }),
}).then((r) => r.json());
```
</CodeGroup>

### Request fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `agent_id` | integer | yes | Agent id in this org |

### Response

```json
{
  "call_id": 987654321,
  "token": "<livekit-jwt>",
  "room_name": "mic-987654321",
  "server_url": "wss://livekit.thunderphone.com"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `call_id` | integer | Call id — the session appears in [Call history](/api-reference/calls) with `direction="test"` |
| `token` | string | Short-lived LiveKit JWT |
| `room_name` | string | LiveKit room |
| `server_url` | string | LiveKit WebSocket URL — pass to the Web SDK |

### Connecting from the browser

Use the LiveKit Web SDK to join the room with the returned token. The
agent joins the room from Core's side and you publish your microphone
as the local participant.

```javascript
import { Room, RoomEvent } from "livekit-client";

const room = new Room();
await room.connect(session.server_url, session.token);
await room.localParticipant.setMicrophoneEnabled(true);

room.on(RoomEvent.TrackSubscribed, (track) => {
  if (track.kind === "audio") track.attach(document.body);
});
```

### Errors

| Status | Condition |
|--------|-----------|
| `400` | `agent_id is required` |
| `402` | Insufficient balance |
| `404` | Agent not found |
| `429` | `concurrent_call_limit_reached`: the organization is at its [concurrent-call limit](/api-reference/introduction#call-limits); retry after `Retry-After` seconds |
| `502` | LiveKit room creation failed |

<Note>
  Mic sessions count as calls for billing purposes. The session is
  billed as a regular voice call using the agent's `product` tier.
</Note>

---

## Related

<CardGroup cols={2}>
  <Card title="Agents" icon="robot" href="/api-reference/agents">
    Configure the agent you'll talk to.
  </Card>
  <Card title="Calls" icon="phone" href="/api-reference/calls">
    Inspect mic-session call logs and transcripts.
  </Card>
  <Card title="Web Widget" icon="window-maximize" href="/widget/overview">
    Embed a production-ready mic widget on your own site.
  </Card>
</CardGroup>
