Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/voice/sessions | Start a session |
GET | /api/v1/voice/sessions/:id | Get session status |
POST | /api/v1/voice/sessions/:id/complete | Complete with transcript and get structured results |
POST | /api/v1/voice/webhooks/livekit | LiveKit-signed webhook receiver |
Authentication
POST /api/v1/voice/webhooks/livekit does not use Pi API key authentication. LiveKit signs the raw request body; Pi verifies the signature using your LiveKit webhook credentials.Start a session
201 with status: "active".
Request parameters
UUID of the voice agent to use for this session. The agent must be active.
Identity of the call participant.
JSON object with any caller context you want to make available to the agent (e.g. account details, prior conversation history). Serialized length must be at most 16,000 characters.
Expiry window in seconds for the LiveKit room, JWT, and Gemini ephemeral token. Range: 60–3600. Default:
600.When you also set max_duration_seconds, ttl_seconds must be greater than or equal to max_duration_seconds.Maximum call length in seconds for this session. Range: 60–1800. Overrides the agent’s
behaviors.max_duration_seconds for this session only.When set, your client is responsible for ending the call and disconnecting from LiveKit when this duration elapses.Override the agent’s voice configuration for this session only.
Example request
Response (201)
Top-level session status:
"active".UUID of the created session.
UUID of the agent used for this session.
LiveKit server URL. Use the
wss:// URL when connecting from a browser or mobile client.LiveKit user JWT. Pass this to the LiveKit SDK to join the room.
Gemini Live ephemeral WebSocket URL.
Gemini Live ephemeral token. Valid for the
ttl_seconds window.The compiled system instruction locked into the session.
Unix timestamp when the session credentials expire.
Effective call cap in seconds, or
null if no duration limit is set. When non-null, your client must end the call and disconnect from LiveKit when this many seconds have elapsed since the call started.Error codes
| Code | HTTP | Description |
|---|---|---|
voice_agent_not_found | 404 | No active agent with the given agent_id. |
voice_gemini_ephemeral_failed | 502 | Failed to mint a Gemini Live ephemeral token. |
voice_session_ttl_too_short | 400 | ttl_seconds is less than max_duration_seconds. |
Get session status
Path parameters
UUID of the voice session.
Query parameters
Set to
true to long-poll until the session reaches a terminal status or the timeout elapses.Long-poll timeout in seconds. Range: 1–120.
Response fields
UUID of the session.
Session status:
"active", "completed", or "failed".Array of transcript entries once available (set via
POST .../complete).Structured extraction results once available.
Effective call cap, or
null.Unix timestamp when the session credentials expire.
Complete a session
output_schema keys or output_schema_strict set, the backend runs a non-live Gemini extraction pass and returns structured results. Otherwise it stores a transcript summary.
Path parameters
UUID of the active voice session to complete.
Request parameters
Array of transcript entries from the call. Minimum 1 entry, maximum 5,000 entries. Each entry has:
Actual call duration in seconds. Range: 0–86400.
Example request
Response fields
The response mirrorsGET /api/v1/voice/sessions/:id and additionally includes:
Top-level structured extraction results aligned with the agent’s
output_schema or output_schema_strict.Present when strict-schema validation finds issues during extraction. Also mirrored under
metadata.pi_extraction_warnings.UUID of the session.
"completed" or "failed".The stored transcript entries.
Structured results (same as top-level
results).Stored call duration.
Effective call cap.
Any non-fatal errors logged during completion.
Unix timestamp of credential expiry.
Unix timestamp of session creation.
Unix timestamp of the last update.
Error codes
| Code | HTTP | Description |
|---|---|---|
voice_session_not_active | 409 | The session is not in active status. |
voice_result_extraction_failed | 502 | The Gemini extraction pass failed. |
LiveKit webhook
This route does not accept Pi API key authentication. LiveKit signs the raw request body using your webhook credentials (
LIVEKIT_WEBHOOK_API_KEY / LIVEKIT_WEBHOOK_API_SECRET). Pi verifies the signature before processing the event.room_finished events, Pi may merge metadata into the matching session record. Final session completion and structured extraction still require an explicit call to POST /api/v1/voice/sessions/:id/complete.