---
title: "Mint a hosted widget voice session"
method: POST
path: "/public/widgets/{publicId}/session"
tags: ["Agents"]
---

# Mint a hosted widget voice session

`POST /public/widgets/{publicId}/session`

## Request

- Base URL: `https://api.pyai.com`
- URL: `https://api.pyai.com/public/widgets/{publicId}/session`
- Auth: none required

Validates the published widget, exact browser Origin, Agent/account status, credit posture, and durable per-widget/per-IP daily limits, then returns one short-lived origin-locked `omni:session` token. The request body cannot select an organization, project, or Agent.

## Path parameters

- `publicId` string, required

## Headers

- `Origin` string, uri, required

## Response `201`

Short-lived widget session

- 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)
- `402`: Account credit is exhausted.
- `403`: Key lacks the required scope or the origin is not allow-listed (`code: forbidden | origin_not_allowed`)
- `404`: Resource not found (`code: not_found`)
- `429`: Widget or visitor daily mint cap reached.

---

[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/819d8e7c4d09?raw)
