openai-python 3.32.0 and openai-node 7.35.0: prompt-created voices, Live audio fixtures, and Decisions in Live
Both official SDKs shipped on 2026-10-16: voices created from a text description (Live only), 30-second Live audio fixtures, Decisions transcript triggers, and prompt caching for the Decisions API - all from the CHANGELOGs and tag sources.
On 2026-10-16 the two official SDKs shipped together yet again: openai-python v3.32.0 (20:17 UTC) and openai-node v7.35.0 (20:16 UTC), per the GitHub Releases (checked by this site on 2026-10-17). After the 10-14 browser/computer toolsets batch (labeled 1/4), this release pushes the voice and Live-session surface forward on several fronts: a voice can now be created from a written description, Live sessions can play prepared audio clips, Decisions evaluations attach to Live transcript triggers, and the Decisions API gets prompt caching of its own. As always in this series, everything below is readable in the two CHANGELOGs and the v3.32.0 / v7.35.0 tag sources.
Prompt-created voices: a text description instead of a recording session
This is the headline. voices.create used to have exactly one path - upload an audio sample plus a consent recording. From v3.32.0 / v7.35.0 it has two, with a new type: "prompt" variant. From the voices.py docs string at the v3.32.0 tag:
For prompt-based creation, send
type: "prompt"with anameandpromptas JSON or multipart form data.
Parameters (identical in the python and node type definitions):
name(required): the name of the new voiceprompt(required): a description of the desired voice; must not contain only whitespacetype(required, literalprompt)model(optional): the voice creation model; defaults toauto, with2026-10-08as the other literalscript_hint(optional): text for the voice to speak during creation; omitted means a script is generated from the prompt, and scripts that are too short are rejected
voice = client.voices.create(
name="brand-narrator",
type="prompt",
prompt="A calm mid-range adult voice, unhurried pace, "
"soft studio tone with clean consonants",
)
The returned Voice object extends in two ways: type widens from the single value audio_sample to audio_sample | prompt, and a new optional prompt field appears - present only for prompt-generated voices with a stored prompt, and absent for audio-sample voices and older voices without a stored prompt.
The boundary is in the docs string too, stated three times across the release (voices.py, speech_create_params.py, and the Realtime audio output config): Voices created from text prompts are supported only in Live, not in Realtime or the speech endpoint. The response also does not include preview audio.
Live audio fixtures: one clip at a time, 30 seconds max
Live sessions gain a client event, session.output_audio.fixture.play, that plays one complete prepared clip through the session output. The docs string is unusually specific:
Audio must be raw mono PCM16 little-endian at 24 kHz, regardless of the session audio format, and at most 30 seconds. The entire payload is validated before model speech is interrupted and input is muted. Only one fixture can be active.
Unpacked: the audio is base64-encoded raw PCM16, mono, little-endian, at 24 kHz, with no WAV or other container header, regardless of the session audio format; at most 30 seconds; the server validates the whole payload first and only then interrupts model speech and mutes input; and only one fixture can be active at a time. Two companion server events - fixture.playing acknowledges acceptance and fixture.played reports server mixer drain - are explicitly not exact transport-media boundaries. Input arriving during playback is dropped and not replayed.
The event can be sent over the primary WebSocket or a server sideband.
Decisions in Live: transcript triggers, a decisions delegation, and shared Decision items
Decisions (question evaluation) hooks into Live sessions in four pieces this release:
Triggers: the session config gains a triggers array; each element binds a set of questions to a transcript event type. event_type has exactly two literals - session.input_transcript.delta and session.output_transcript.delta - with at most one trigger per transcript event type. Questions come in three discriminated shapes:
| type | structure | docs-string summary |
|---|---|---|
predicate | instructions (plus optional name) | Estimate how likely it is that a statement about the input is true |
choice | instructions + choices (2-255 unique options; values are strings or booleans, and the same text with different types counts as distinct) | Choose from the supplied options based on the input |
score | instructions + ordered levels (label plus optional description) | Rate the input against the supplied ordered levels |
The official text also says triggers run independently of delegation; when updating a session, omitting triggers keeps the current configuration, sending a list replaces it, and an empty list disables triggers.
The decisions delegation: the delegation union gains a type: "decisions" member - model plus questions (the same three question shapes) - alongside your-application and responses. The docs string correspondingly changes from letting the API manage a Responses backend to delegating to the corresponding API via responses or decisions.
Decision item events: decision.item.create, decision.item.created, decision.item.delete, and decision.item.deleted append or remove input items for future evaluations - in the docs string's words, Append an input item for future decisions without starting an evaluation or changing Live voice context. Items are user-role messages whose content is a string or a list of input_text / input_image parts (images as inline data URLs; detail supports low, high, auto, or original, defaulting to auto).
Startup history wording: the docs string for the session input (pre-startup text-only history) changes from at most 128 messages and 8,192 rendered tokens in total to at most 128 messages and a configured rendered-token limit (8,192 by default) - the cap moved from fixed to configurable, matching node #2949, the clarify the Live startup history token limit chore.
Prompt caching comes to the Decisions API
The standalone Decisions API (client.decisions.create) gains prompt_cache_key and prompt_cache_options (python #4087, whose title carries a [2/2] label; node #2956 has no such label). The PromptCacheOptions docs string matches the Responses-side rules: supported for gpt-5.6 and later models only; implicit mode by default creates one implicit breakpoint and writes up to the latest three explicit breakpoints, while explicit mode skips the implicit breakpoint and writes up to four explicit breakpoints (with no explicit breakpoints, the request does not use prompt caching); ttl defaults to 30m, currently the only supported value; cache matching considers up to the latest 80 breakpoints in the conversation.
Breakpoints attach to content blocks: input_text and input_image blocks accept an optional prompt_cache_breakpoint (with mode always explicit). The docs string says it marks the exact end of a reusable prompt prefix, inherits its TTL from the request's prompt_cache_options.ttl, and is not rounded to a token block.
Error diagnostics and Realtime error messages
The response.error object gains two nullable fields in three places at once (Responses, beta Responses, and videos):
param: The request parameter associated with the error, or null if none was recordedtype: The original error type, or null if it was not recorded
On the Realtime side, the error inside response status gains a nullable message (A human-readable error message). A new SDK test asserts reading back type, param, code, and message across all three routes.
Project API keys: scopes decoupled from expiry
The project API key update operation unlocks scope changes in this release (python api_keys.py, node #2943). Every point below is from the type docs strings:
scopesandexpires_in_secondsare both optional now, but at least one must be provided; omitted fields stay unchanged; neither acceptsnull; both changes are saved togetherscopesreplaces the key's scope restrictions using the same identifiers as the dashboard; an empty array means All permissions (subject to the owner's effective access) - not revoked access; read-only is["api.all.read"], and finer-grained examples look like["api.files.read"]- Scope changes do not change the owner's (user or service account) roles and do not grant admin permissions
- They follow the same authentication-cache propagation as dashboard edits, rather than taking effect instantly on every endpoint
The rest: python residency catch-up, deprecation annotations, and a WS refactor
- Regional processing residency: python's project residency enum adds
JP_STORAGE_PROCESSING,IN_STORAGE_PROCESSING, andAU_STORAGE_PROCESSING(#4081) - node shipped the feature in v7.34.0 (#2942) on 10-14, and python has now caught up. - ChatModel deprecation annotations: both packages mark gpt-5.4-nano and gpt-5.1 with Announced shutdown date: 2027-04-01, and fold the gpt-4.1 / gpt-4o families into a 2027-01-14 row (python's annotation includes the undated aliases; node lists only the dated snapshots). The official deprecations page already gives replacements: gpt-5.4-nano to gpt-6-luna; gpt-5.1 and gpt-5.3-codex to gpt-6-sol. For the wave-by-wave reading, see the companion piece OpenAI's October 2026 deprecation wave: GPT-4o and GPT-4.1 on 2027-01-14, TTS to gpt-realtime-2.1-mini.
- WebSocket refactor: python adds a shared
_websocket_connection.pymodule (#4084, share WebSocket connection handling); node has two matching refactors (#2947 share existing WebSocket send and open handling, #2953 share WebSocket connection lifecycle and generated bindings). Purely internal; neither CHANGELOG declares a behavior change.
Who benefits
- Teams building Live voice agents: fixtures add deterministic output inserts (chimes, confirmations, short promos) with a 30-second cap and a single-active-fixture rule that invites a playback queue; Decisions triggers mean compliance and QA scoring of every utterance no longer requires building your own transcript polling.
- Products that want custom voices in speech: prompt creation lowers the bar from recording samples and consent to writing a description - but note it is Live-only; TTS and Realtime still require the audio_sample path.
- Platform teams governing API keys: with scopes and expiry decoupled, rotating a key no longer forces resetting its expiry, and narrowing access no longer means deleting and recreating it.
- Teams running Decisions evaluations at volume: stable prefixes (review handbooks and the like) with
prompt_cache_keyplus explicit breakpoints cut repeated-input costs, under the same rules as Responses caching.
Next steps
- The previous SDK write-up: Browser and Computer Toolsets (1/4) Land in the OpenAI SDKs: BrowserToolset Turns Driver Methods into Function Tools.
- The Live API foundations: The Live API lands in the OpenAI SDK: gpt-live-1, dual WebRTC/WebSocket channels, and SIP call control.
- Prompt caching in depth (breakpoints, keys, diagnostics): openai-python 3.9/3.10 and openai-node 7.11/7.12: Prompt Cache Diagnostics, API Key Expiry, GPT Image 2.5 and OpenAI's Agents Optimization cookbook: a four-round playbook for cheaper support agents.
- The deprecation wave behind this release's annotations: OpenAI's October 2026 deprecation wave: GPT-4o and GPT-4.1 on 2027-01-14, TTS to gpt-realtime-2.1-mini.
Key points
- Six stable features landed in both SDKs the same day (2026-10-16 per each CHANGELOG; checked 2026-10-17): prompt-based voice creation (python #4091 / node #2955), Live audio fixtures (#4085/#2946), Decisions in Live sessions (#4088/#2951), Decisions prompt caching (python #4087 labeled [2/2] / node #2956), response error diagnostics and model notices (#4086/#2948), and python-side regional processing residency catch-up (#4081, node had it since v7.34.0)
- The boundary is written into the type docs string: Voices created from text prompts are supported only in Live, not in Realtime or the speech endpoint - the speech and Realtime voice configs repeat the same sentence, so prompt-created voices cannot be used for TTS or Realtime sessions
- Prompt variant parameters: name and prompt are required (prompt must not be whitespace-only), model is optional and defaults to auto with 2026-10-08 as the other literal, script_hint is optional - omit it and a script is generated from the prompt; scripts that are too short are rejected. The Voice object gains a prompt union member and an optional prompt field; the response includes no preview audio
- Live audio fixture session.output_audio.fixture.play: base64 raw mono PCM16 little-endian at 24 kHz, no container header, 30 seconds max; the whole payload is validated before model speech is interrupted and input is muted; only one fixture can be active; fixture.playing acknowledges acceptance, fixture.played reports server mixer drain, and neither is an exact transport-media boundary; input arriving during playback is dropped, not replayed
- Decisions in Live: session config gains triggers (at most one per transcript event type; event_type is session.input_transcript.delta or session.output_transcript.delta) with three question types - predicate, choice (2-255 unique options with typed string-or-boolean values), score (ordered levels); the delegation union gains a decisions target (model plus questions); decision.item.create/created/delete/deleted append or remove input items for future evaluations without touching voice context
- The Decisions API gets prompt caching: client.decisions.create gains prompt_cache_key and prompt_cache_options (gpt-5.6 and later; implicit or explicit mode, ttl only 30m, up to four breakpoints written per request, matching considers the latest 80 breakpoints); input_text and input_image blocks accept prompt_cache_breakpoint (mode always explicit, TTL inherited from the request, boundary not rounded to a token block)
- Diagnostics and governance: the error object on Responses, beta Responses, and videos gains nullable param and type fields; the Realtime response status error gains a nullable message; project API key update now treats scopes and expires_in_seconds as optional (provide at least one, omitted fields stay unchanged, neither accepts null) - an empty scopes array means All permissions, not no permissions
- Deprecation annotations updated with the release: both SDKs mark gpt-5.4-nano and gpt-5.1 with an announced shutdown date of 2027-04-01 (the official deprecations page gives replacements: nano to gpt-6-luna, 5.1 to gpt-6-sol); see the companion deprecation-wave article
Frequently asked questions
Official references
- Changelogopenai-python v3.32.0 release notes (GitHub Releases)
- Changelogopenai-node v7.35.0 release notes (GitHub Releases)
- Docssrc/openai/resources/audio/voices.py at v3.32.0 (prompt creation signature and docs strings)
- Docsopenai-python v3.31.0...v3.32.0 compare (Live types and error diagnostics)
- Docsopenai-node v7.34.0...v7.35.0 compare (voices.ts and decisions.ts)
- Changelogcommit 325da45 (add cache settings and key options [2/2])
- DocsOpenAI official deprecations page (2027-04-01 rows and replacements for gpt-5.4-nano / gpt-5.1)
Related articles
Browser and Computer Toolsets (1/4) Land in the OpenAI SDKs: BrowserToolset Turns Driver Methods into Function Tools
On 2026-10-14 the official SDKs shipped four releases: openai-python 3.30/3.31 and openai-node 7.33/7.34. The (1/4) browser and computer toolsets headline: BrowserToolset wraps a caller-supplied driver as ordinary function tools.
Read articleHosted agent environments surface in the OpenAI SDKs: prewarmed creation, idle suspension, expiration
Four releases in three days, October 9-11, 2026: openai-python 3.27-3.29 and openai-node 7.32 surface one agent environment API — prewarmed beta creation, idle suspension, expiration. Quoted from release notes and SDK source.
Read articleOpenAI API 429 Rate Limit Errors: RateLimitError and SDK Retries Explained
A 429 is two problems in one status: throughput limits vs quota exhaustion. The Python SDK already retries twice and honors Retry-After — this guide explains the mechanics from source.
Read articleSubscribe to GPTMap Weekly
One email every Monday: curated OpenAI updates, deep dives, and best practices. No ads, unsubscribe anytime.
Submitting opens Buttondown in a new tab to confirm your subscription.