Skip to main content

Voice API

Outbound and inbound voice calling, transcripts, and analytics Base path: /api/v1/voice Endpoint count: 17

List agent-guided call scripts for a queue

GET /api/v1/voice/queues/{id}/scripts
Returns every active script attached to the queue, ordered by name ascending. Used by the agent console at call-bridge time to render the scripted-prompts panel.
id
string
required

Get one queue script with its sections

GET /api/v1/voice/queues/{id}/scripts/{scriptId}
Returns the script row plus the full section tree (sorted by sort_order). The agent console renders this client-side at call-bridge time.
id
string
required
scriptId
string
required

List tenant skill catalog

GET /api/v1/voice/skill-catalog
Returns every active skill in the tenant’s catalog ordered by slug. Drives the softphone autocomplete + queue + agent edit forms. Use ?includeInactive=true for the admin catalog editor’s tombstone view.
includeInactive
string (enum: true|false)
When true, includes soft-deleted (is_active=false) rows. Default false.

List department voicemail boxes

GET /api/v1/voice/voicemail-boxes/
Returns a page of department voicemail boxes owned by the caller’s organization, ordered by name ascending. Each box carries its member roster and optional inbound_route_id back-ref. The list is cursor-paginated: a request returns at most limit boxes (default 50), and meta.pagination reports whether more pages remain.
cursor
string
Opaque cursor for the next page. Pass meta.pagination.cursor from the previous response to fetch the next page; omit for the first page.
limit
integer
default:"50"
Maximum boxes to return per page (1–100, default 50).
meta.pagination.cursor
string | null
Cursor to pass as cursor to fetch the next page. null on the final page.
meta.pagination.has_more
boolean
true when more boxes remain beyond this page (fetch the next page with cursor); false on the final page.

Get one department voicemail box

GET /api/v1/voice/voicemail-boxes/{id}
Returns the box identified by :id when it belongs to the caller’s organization. 404 if the id does not exist or belongs to another org.
id
string
required

Mint a short-lived transcript SSE ticket

POST /api/v1/voice/calls/{callId}/transcript/ticket
Returns a 60s single-use ticket bound to (tenant, call_id) that the SSE client passes as ?ticket= on /transcript/stream. Removes the need to put a long-lived API key on the SSE URL.
callId
string
required

Generate AI call summary

POST /api/v1/voice/calls/{id}/summary
AI-generated structured summary; cached after first invocation.
id
string
required

Create a queue script

POST /api/v1/voice/queues/{id}/scripts
Creates a new script optionally with its initial section tree. Sections are full-replace on subsequent PATCHes — there is no per-section CRUD surface.
id
string
required
name
string
required
description
string | null
isActive
boolean
sections
object[]

Create a tenant skill catalog row

POST /api/v1/voice/skill-catalog
Creates a new skill row. Returns 201 with the created row. A second insert of the same active slug returns 409 SKILL_SLUG_ALREADY_EXISTS.
slug
string
required
Lowercased + trimmed at the Zod boundary. UNIQUE per (org, slug) where is_active=TRUE — a duplicate active slug returns 409 SKILL_SLUG_ALREADY_EXISTS.
label
string
required
description
string

Create a department voicemail box

POST /api/v1/voice/voicemail-boxes/
Creates a new department voicemail box scoped to the caller’s organization. name MUST be unique within the org and is slug-shaped. Every members[*] id is validated against the org’s user roster — leaked ids from other tenants are rejected with 422. Returns 201 with the created row.
name
string
required
Slug-shape name; UNIQUE within the org.
label
string
required
members
string[]
Initial roster of subscribed user ids (max 50).
retention_days
integer | null

Update a department voicemail box

PUT /api/v1/voice/voicemail-boxes/{id}
Partial update — only fields supplied in the body are written. members (when supplied) replaces the roster (not delta-merged); every id is re-validated against the org. Returns the persisted row.
id
string
required
name
string
label
string
members
string[]
retention_days
integer | null

Update softphone in-call notes

PATCH /api/v1/voice/calls/{id}/notes
Saves operator-typed notes onto call_logs.metadata.notes. Auto-saved by the softphone widget every 5s and on hangup.
id
string
required
notes
string
required

Update queue script metadata and sections

PATCH /api/v1/voice/queues/{id}/scripts/{scriptId}
Partial update — only fields supplied are written. When sections is supplied it FULLY REPLACES the existing section tree (delete + insert in one transaction). Empty patch (no fields) returns 400.
id
string
required
scriptId
string
required
name
string
description
string | null
isActive
boolean
sections
object[]

Update a tenant skill catalog row

PATCH /api/v1/voice/skill-catalog/{id}
Partial update of label, description, isActive. At least one field MUST be present. description: null clears the field; omission preserves it. Setting isActive: false soft-deletes the row.
id
string
required
label
string
description
string | null
isActive
boolean

Delete a queue script

DELETE /api/v1/voice/queues/{id}/scripts/{scriptId}
Hard-deletes the script row (CASCADEs to sections via the FK). Returns 204 with no body on success; 404 if the script id does not belong to the queue.
id
string
required
scriptId
string
required

Soft-delete a tenant skill catalog row

DELETE /api/v1/voice/skill-catalog/{id}
Soft-deletes the skill by setting is_active=false. The historical row is preserved for analytics + audit; future writes referencing the slug will fail assertSkillsRegistered. Operators may re-create the slug with a fresh row (the partial unique excludes tombstones).
id
string
required

Delete a department voicemail box

DELETE /api/v1/voice/voicemail-boxes/{id}
Removes the box. Captured voicemails with box_id pointing at this row are NOT deleted — they surface under the dashboard’s Archived / orphan box group (matches user-deletion semantics for assigned_user_id). Returns 204 on success.
id
string
required