API: text is screened before synthesis
Text you send for synthesis is now screened before Speechify produces audio from it. A request whose content is not permitted returns 400 content_policy_violation with no audio, and is not billed. This applies to /v1/audio/speech, /v1/audio/stream, /v1/audio/stream/with-timestamps and /v1/audio/dialogue, and to an agent’s prompt and first_message when you create or update one.
Cloned voices on agents; GET /v1/agents/voices paginates
Your workspace’s cloned voices can now be assigned to voice agents
A voice agent can now use any voice your workspace cloned. The voice picker lists them alongside the curated shared catalogue, marked type: "personal", and POST/PATCH /v1/agents accepts their slugs.
Only workspace-owned clones are selectable — a personal voice scoped to an individual stays invisible to agents, which are workspace-shared resources. The same ownership gate applies here as on GET /v1/voices: a clone is usable on an agent exactly when it appears in your TTS voice catalogue.
Agent share links (public beta)
Share links are revocable, budget-capped URLs that let anyone talk to an agent — no account, no embed, no setup. Create one, share the URL, the recipient opens it and talks.
Three unauthenticated endpoints power the recipient experience:
Multilingual language list is now server-driven
GET /v1/agents/voices now returns a multilingual_languages array alongside the voice catalogue. It lists every language an agent may declare in additional_languages — read it rather than hard-coding a list, because the supported set grows as the voice catalogue expands and a stale client-side list would offer languages the server rejects on save.
This extends the multilingual agents support introduced on 2026-07-24. The shape of additional_languages is unchanged: each entry is a BCP-47 tag, must be unique per agent, and must differ from the agent’s default language.
Widget error codes, startAgent contract change
Widget failures now carry a real code, and the visitor sees the real reason
Every widget failure used to reach you as errorCode: "unknown" and show the visitor the same generic “Something went wrong starting the call.” Both are fixed: the error now carries the code for the failure that actually happened, and the visitor sees copy written for that failure — a blocked microphone now reads “Microphone access was blocked. Allow it in your browser settings to talk.”
Widget delivered from cdn.speechify.ai; 'flow_budget_exhausted' call end reason documented
The voice-agent widget now ships from cdn.speechify.ai
New widget embeds load the bundle from cdn.speechify.ai:
That URL tracks the current release and is cached for five minutes, so a correction reaches a returning visitor quickly. It is what the docs and console snippets now hand you.
Widget bundle served compressed, and session spend limits return 402
The <speechify-agent> bundle is now served compressed
GET /v1/widget/agents.js was served uncompressed. It now negotiates
compression like every other text response, cutting the transfer from roughly
676 kB to roughly 190 kB for every visitor of every page carrying the widget.
No embed change is required.
API: multilingual agents - `additional_languages` and mid-call language switching
An agent can now serve multiple languages in one session instead of needing a sibling agent per language plus a transfer. Set additional_languages on create or update; the agent switches language mid-call with full context preserved - no handoff, no dropped state.
Agent test runs return 402 on exhausted balance; model_override tier check enforced
Every agent test-run endpoint admits the run against the workspace’s remaining
credit and its spending limits before the run is created, and documents 402
for a depleted balance or an exhausted spend limit:
POST /v1/agents/tests/{test_id}/runsPOST /v1/agents/{agent_id}/tests/runsPOST /v1/agents/tests/runs/batchPOST /v1/agents/tests/suite-runs/{suite_run_id}/resubmit
API: per-agent `max_call_duration_seconds`
Agents now carry a max_call_duration_seconds field — a hard cap on the wall-clock length of a single call on that agent. When a live call reaches the cap, the agent ends it automatically. Set it when you create or update an agent.
null(the default) means no per-agent cap: the call is bounded only by your plan’s call ceiling.- Your plan’s call ceiling is also the hard upper bound for this field, so a value above it is rejected.
API: cross-resource field-naming sweep
Several same-concept-different-name fields are renamed to one consistent spelling and type across the voice-agents wire. Every change is served in its pre-2026-06-28 shape to a caller that pins an earlier Speechify-Version; the official SDKs pin their build date automatically.
Voice gender notSpecified → not_specified
API version pinning with `Speechify-Version`
The API now supports date-based version pinning with the Speechify-Version request header.
- Current version:
2026-06-25 - Header format:
YYYY-MM-DD - Resolution order: request header, workspace default, oldest supported version
- Migration path: official SDKs pin their build-date version automatically; raw HTTP callers should send
Speechify-Versionexplicitly.
Voice Agents is now publicly available
Voice Agents is now available to all Speechify accounts, in both the console and the documentation. You can build, configure, test, and deploy phone and web voice agents.
Console
- The Voice Agents product now appears in the product switcher for every account.
- The agent flow editor for designing multi-step conversations is open to all customers.