---
title: "Mint an ephemeral Omni session token"
method: POST
path: "/v1/omni/sessions"
tags: ["Omni"]
---

# Mint an ephemeral Omni session token

`POST /v1/omni/sessions`

## Request

- Base URL: `https://api.pyai.com`
- URL: `https://api.pyai.com/v1/omni/sessions`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

**Most integrations do not need this endpoint.** Server-side apps, telephony, and backend agents connect to `wss /v1/omni` directly with their API key (see "Open an Omni voice-agent session"). Use this only when a browser or other untrusted client must open an Omni session without holding your secret key.

It mints a short-lived, origin-locked token the browser can use to open ONE Omni realtime session, the public/private split for realtime. Call this from your server with your secret key (which must hold `omni:session`); never ship the secret key to a page. The returned `token` carries only `omni:session`, is limited to one concurrent session, is locked to the `allowed_origins` you supply, and expires after `ttl_seconds` (default 60s, max 600s). Use it as the WebSocket subprotocol `pyai-key.<token>`, offered after the `pyai.v1` marker, against the returned `url`. See the Omni browser guide for the full flow.

## Request body

- object
  - `allowed_origins` string[], required: Browser origins (scheme://host[:port]) the token may connect from. Required and non-empty, a browser token must be origin-locked. `*` is not allowed.
  - `ttl_seconds` integer: Token lifetime in seconds. Keep it short; a leaked token is worth seconds, not minutes.
  - `session_label` string: Optional opaque tag echoed back to your `kb_endpoint` and recorded on the call.

## Response `201`

Minted session token

- OmniSession
  - `object` string
  - `token` string: The ephemeral session token. Offer it as the WebSocket subprotocol `pyai-key.<token>` after the `pyai.v1` marker. Short-lived and origin-locked; safe to hand to the browser.
  - `expires_at` integer: Token expiry, Unix epoch milliseconds.
  - `url` string: The Omni realtime WebSocket URL to connect to.
  - `session_label` string, nullable: Echoed back when supplied on the request.

## Other responses

- `400`: Invalid request (bad field, unsupported value)
- `401`: Missing or invalid API key (`code: unauthorized`)
- `403`: Key lacks the required scope or the origin is not allow-listed (`code: forbidden | origin_not_allowed`)

---

[API](https://skmtc.dev/pyai/apis/pyai-api.md) · [All operations](https://skmtc.dev/pyai/apis/pyai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/pyai/apis/pyai-api/revisions/271a1539185b?raw)
