> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# Realtime API

> Create a short-lived Realtime API browser session and receive a client secret for the BeatAPI realtime SDK.

`POST https://api.beatapi.io/v1/realtime/sessions`

Create a short-lived Realtime API browser session and receive a client secret for the BeatAPI realtime SDK.

## Authorization

`Authorization`   `string`   **required**

Send your BeatAPI API key as a Bearer token. Create one on the [Dashboard](https://beatapi.io/dashboard).

```
Authorization: Bearer <BEATAPI_API_KEY>
```

Keep permanent API keys on trusted servers. `Content-Type: application/json` is required for the request body. `Idempotency-Key` is optional when the endpoint exposes it and is recommended for safe retries with the exact same body.

## Request body

`max_duration_seconds`   `enum<integer>`   **required**

Required maximum live session duration in seconds. The USD amount is reserved for the selected 15, 60, or 300 second tier.

**Available options:** `15`, `60`, `300`

---

`allowed_origins`   `string[]`   **required**

Exact browser origins allowed to use the short-lived session secret.

**Count:** 1 to 10 items

---

`metadata`   `object`   **optional**

Optional server-defined string metadata for your own correlation. Up to 20 keys; keys are at most 64 characters and values at most 256 characters.

## Response

A successful request returns HTTP `201`.

```json
{
  "data": {
    "id": "rts_8K2qA",
    "object": "realtime.session",
    "status": "ready",
    "client_secret": "brt_live_example_short_lived_secret",
    "expires_at": "2026-08-12T10:01:00.000Z",
    "max_duration_seconds": 60,
    "allowed_origins": [
      "https://app.example.com"
    ],
    "credits": {
      "reserved": 1.2,
      "settled": 0,
      "refunded": 0
    },
    "request_id": "req_abc123",
    "created_at": "2026-08-12T10:00:00.000Z",
    "connected_at": null,
    "closed_at": null
  }
}
```

## Connect in the browser

Install the browser SDK:

```bash
npm install @beatapi/realtime
```

```ts
import { createRealtimeClient } from '@beatapi/realtime';

const camera = await navigator.mediaDevices.getUserMedia({ video: true });
const output = document.querySelector<HTMLVideoElement>('#output')!;
const client = createRealtimeClient({ clientSecret: session.client_secret });
const connection = await client.connect({
  input: camera,
  output,
  initial: { prompt: 'Preserve motion while applying the requested style.' },
});
```

Pass only the short-lived `client_secret` to the exact origin listed in `allowed_origins`. The selected duration is reserved at creation and settles only after the first remote output frame produces an accepted BeatAPI billing heartbeat.

* `GET /v1/realtime/sessions/{session_id}` inspects a Realtime Session.
* `DELETE /v1/realtime/sessions/{session_id}` closes a Realtime Session.

Disconnect the browser connection, stop local media tracks, and close the server-side Session when the experience ends.

## Next step

Pass the returned `client_secret` to `@beatapi/realtime`. Keep the permanent API key on your trusted server, and close the session when the browser experience ends.

## Errors

| Status | Meaning                                                                                                                                                                                                                                                                |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Malformed JSON or a field, value or combination this endpoint does not accept (`bad_request`; the message names the field), or input refused by moderation (`content_policy_violation`). Not retryable unchanged.                                                      |
| `401`  | No API key (`missing_api_key`), or a key that is wrong, expired, disabled or exhausted (`invalid_api_key`; the message says which). Send it as `Authorization: Bearer <key>`; the key works with or without the `sk-` prefix. Not retryable.                           |
| `402`  | Insufficient balance (`insufficient_credits`). The account balance is zero or below the price of this request. Top up, then send it again; not retryable before that.                                                                                                  |
| `409`  | The `Idempotency-Key` was already used with a different request body or path within 24 hours, or the first request with it is still running (`idempotency_conflict`). Not retryable unchanged.                                                                         |
| `429`  | Too many requests (`rate_limit_exceeded`, including the free-model limits). Retryable after `Retry-After` seconds (also `error.retry_after_seconds`).                                                                                                                  |
| `503`  | Realtime Video is not enabled on this deployment (`realtime_disabled`, not retryable; no self-service action, contact support) or capacity is temporarily unavailable (`realtime_capacity_unavailable`, retryable; retry shortly with backoff, no delay is indicated). |