Skip to content

Commit ffdc023

Browse files
feat(api): add prompt-based voice creation (#1205)
## Summary Create custom voices from text descriptions and read their original prompts. ## Changes - Add prompt-based voice creation with optional script hints and model selection. - Expose the original prompt on voice responses when available. Co-authored-by: marcuswood-oai <323319819+marcuswood-oai@users.noreply.github.com>
1 parent e17430d commit ffdc023

12 files changed

Lines changed: 716 additions & 82 deletions

File tree

‎.castiron.stats.yml‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
schema_version: 1
2-
generation_id: e71f55aa-cd36-4bcf-97b3-55096536ddeb
3-
openapi_spec_hash: 9f25e689946a326df6a67ecaccc90e48
4-
openapi_transformed_spec_hash: 7acc5250f436f644f74dd5f5c348741d
5-
config_hash: dda57991526f80e9f99d8f9621460eaa
6-
codegen_sha: 38f50c350df42e0de48ffd3b3111de9bc51dd733
7-
codegen_hash: 23c69e401abac115c537fc9ea4dc066687d188231c9eb4196e402273db798fb7
8-
public_codegen_sha: 680fa4655b6d09b9838ca751b503b521c9398e61
2+
generation_id: 8419511e-de94-4184-8866-c88383c29cc6
3+
openapi_spec_hash: 7ca9a258daebb3d2c04cf85a4c394f5a
4+
openapi_transformed_spec_hash: b23980060fc5ae2b16711bed7eadd3f3
5+
config_hash: 8f3e767a17693de466483ca638e0305f
6+
codegen_sha: acf19120b7fabd21b945246c46f26b8c7e132ff2
7+
codegen_hash: bd6e918e20d78d1ee682b4f0f00367d58ee6927ab27a2275a323c857f44f79e2
8+
public_codegen_sha: 37ee738014b603a10004bcfa66101c928f96c476

‎api_reference/openapi.transformed.yml‎

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,11 +1691,11 @@ paths:
16911691
- Audio
16921692
summary: Create voice
16931693
description: |
1694-
Create a custom voice you can use for audio output (for example, in Text-to-Speech and the Realtime API). This requires an audio sample and a previously uploaded consent recording.
1694+
Creates a voice from a text prompt or from a consent recording and an audio sample.
16951695

1696-
Send `name`, `audio_sample`, and the `consent` recording ID as multipart form data. The optional `type` defaults to `audio_sample`.
1696+
For prompt-based creation, send `type: "prompt"` with a `name` and `prompt` as JSON or multipart form data. For creation from an audio sample, send `type: "audio_sample"` with a `name`, `audio_sample`, and `consent` recording ID as multipart form data. The type defaults to `audio_sample` when omitted.
16971697

1698-
Returns the saved voice's metadata. See the [custom voices guide](https://developers.openai.com/api/docs/guides/text-to-speech#custom-voices) for requirements and best practices. Custom voices are limited to eligible customers.
1698+
Returns the saved voice's metadata. Voices created from text prompts are supported only in Live, not in Realtime or the speech endpoint. The response does not include preview audio.
16991699
requestBody:
17001700
required: true
17011701
content:
@@ -1710,7 +1710,7 @@ paths:
17101710
schema:
17111711
$ref: '#/components/schemas/VoiceResource'
17121712
'400':
1713-
description: Invalid voice request, consent recording, or audio sample.
1713+
description: Invalid voice request, prompt, script hint, model, consent recording, or audio sample.
17141714
content:
17151715
application/json:
17161716
schema:
@@ -1735,9 +1735,13 @@ paths:
17351735
curl https://api.openai.com/v1/audio/voices \
17361736
-X POST \
17371737
-H "Authorization: Bearer $OPENAI_API_KEY" \
1738-
-F "name=My new voice" \
1739-
-F "consent=cons_1234" \
1740-
-F "audio_sample=@audio_sample.wav;type=audio/x-wav"
1738+
-H "Content-Type: application/json" \
1739+
-d '{
1740+
"type": "prompt",
1741+
"name": "Warm narrator",
1742+
"prompt": "A warm, calm narrator with a clear, measured delivery.",
1743+
"model": "auto"
1744+
}'
17411745
/batches:
17421746
post:
17431747
summary: Create batch
@@ -41530,7 +41534,7 @@ components:
4153041534
`alloy`, `ash`, `ballad`, `coral`, `echo`, `fable`, `nova`, `onyx`,
4153141535
`sage`, `shimmer`, `marin`, and `cedar`. You may also provide a
4153241536
custom voice object with an `id`, for example `{ "id": "voice_1234" }`.
41533-
Custom voices must be created from audio samples.
41537+
Custom voices must be created from audio samples. Voices created from text prompts are supported only in Live.
4153441538
format:
4153541539
type: string
4153641540
enum:
@@ -44371,7 +44375,7 @@ components:
4437144375
description: Control the voice of your generated audio with additional instructions. Does not work with `tts-1` or `tts-1-hd`.
4437244376
maxLength: 4096
4437344377
voice:
44374-
description: 'The voice to use when generating the audio. Supported built-in voices are `alloy`, `ash`, `ballad`, `coral`, `echo`, `fable`, `onyx`, `nova`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. You may also provide a custom voice object with an `id`, for example `{ "id": "voice_1234" }`. Previews of the voices are available in the [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options). Custom voices must be created from audio samples.'
44378+
description: 'The voice to use when generating the audio. Supported built-in voices are `alloy`, `ash`, `ballad`, `coral`, `echo`, `fable`, `onyx`, `nova`, `sage`, `shimmer`, `verse`, `marin`, and `cedar`. You may also provide a custom voice object with an `id`, for example `{ "id": "voice_1234" }`. Previews of the voices are available in the [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options). Custom voices must be created from audio samples. Voices created from text prompts are supported only in Live.'
4437544379
title: Voice
4437644380
anyOf:
4437744381
- anyOf:
@@ -45263,9 +45267,11 @@ components:
4526345267
propertyName: type
4526445268
mapping:
4526545269
audio_sample: '#/components/schemas/CreateVoiceFromConsentRequest'
45270+
prompt: '#/components/schemas/CreateVoicePromptRequest'
4526645271
x-oai-default-discriminator-value: audio_sample
4526745272
anyOf:
4526845273
- $ref: '#/components/schemas/CreateVoiceFromConsentRequest'
45274+
- $ref: '#/components/schemas/CreateVoicePromptRequest'
4526945275
CustomToolCall:
4527045276
type: object
4527145277
title: Custom tool call
@@ -54892,7 +54898,7 @@ components:
5489254898
`marin`, and `cedar`. You may also provide a custom voice object with an
5489354899
`id`, for example `{ "id": "voice_1234" }`. Voice cannot be changed during
5489454900
the session once the model has responded with audio at least once.
54895-
Custom voices must be created from audio samples.
54901+
Custom voices must be created from audio samples. Voices created from text prompts are supported only in Live.
5489654902
output_audio_format:
5489754903
type: string
5489854904
enum:
@@ -58236,7 +58242,7 @@ components:
5823658242
`marin`, and `cedar`. You may also provide a custom voice object with
5823758243
an `id`, for example `{ "id": "voice_1234" }`. Voice cannot be changed
5823858244
during the session once the model has responded with audio at least once.
58239-
Custom voices must be created from audio samples.
58245+
Custom voices must be created from audio samples. Voices created from text prompts are supported only in Live.
5824058246
We recommend `marin` and `cedar` for best quality.
5824158247
tools:
5824258248
type: array
@@ -60809,7 +60815,7 @@ components:
6080960815
`marin`, and `cedar`. You may also provide a custom voice object with an
6081060816
`id`, for example `{ "id": "voice_1234" }`. Voice cannot be changed during
6081160817
the session once the model has responded with audio at least once.
60812-
Custom voices must be created from audio samples.
60818+
Custom voices must be created from audio samples. Voices created from text prompts are supported only in Live.
6081360819
input_audio_format:
6081460820
type: string
6081560821
description: |
@@ -61089,7 +61095,7 @@ components:
6108961095
`marin`, and `cedar`. You may also provide a custom voice object with
6109061096
an `id`, for example `{ "id": "voice_1234" }`. Voice cannot be changed
6109161097
during the session once the model has responded with audio at least once.
61092-
Custom voices must be created from audio samples.
61098+
Custom voices must be created from audio samples. Voices created from text prompts are supported only in Live.
6109361099
We recommend `marin` and `cedar` for best quality.
6109461100
speed:
6109561101
type: number
@@ -71723,7 +71729,7 @@ components:
7172371729
VoiceResource:
7172471730
type: object
7172571731
title: Voice
71726-
description: A custom voice that can be used for audio output.
71732+
description: A custom voice that can be used for audio output. Voices created from text prompts are supported only in Live.
7172771733
additionalProperties: false
7172871734
properties:
7172971735
object:
@@ -71740,6 +71746,10 @@ components:
7174071746
type: string
7174171747
enum:
7174271748
- audio_sample
71749+
- prompt
71750+
prompt:
71751+
type: string
71752+
description: The original text prompt used to create the voice. Present for prompt-generated voices with a stored prompt; omitted for audio-sample voices and older voices without a stored prompt.
7174371753
name:
7174471754
type: string
7174571755
description: The name of the voice.
@@ -106332,6 +106342,45 @@ components:
106332106342
- $ref: '#/components/schemas/BetaResponseCustomToolCallInputDoneEvent'
106333106343
discriminator:
106334106344
propertyName: type
106345+
CreateVoicePromptRequest:
106346+
type: object
106347+
title: Prompt
106348+
description: Creates a synthetic voice from a text description. Supports application/json or multipart/form-data.
106349+
additionalProperties: false
106350+
properties:
106351+
type:
106352+
type: string
106353+
enum:
106354+
- prompt
106355+
description: Set to `prompt` to create a voice from a text description.
106356+
name:
106357+
type: string
106358+
minLength: 1
106359+
maxLength: 256
106360+
description: The name of the new voice.
106361+
prompt:
106362+
type: string
106363+
minLength: 1
106364+
maxLength: 2000
106365+
description: A description of the desired voice. Must not contain only whitespace.
106366+
script_hint:
106367+
type: string
106368+
minLength: 1
106369+
maxLength: 2000
106370+
description: Optional text for the voice to speak during creation. If omitted, a script is generated from the prompt. Must not be blank after trimming whitespace; scripts that are too short are rejected.
106371+
model:
106372+
anyOf:
106373+
- type: string
106374+
- type: string
106375+
enum:
106376+
- auto
106377+
- 2026-10-08
106378+
default: auto
106379+
description: The voice creation model to use. Defaults to `auto`.
106380+
required:
106381+
- type
106382+
- name
106383+
- prompt
106335106384
OAuthErrorCode:
106336106385
anyOf:
106337106386
- enum:

‎openai-java-core/src/main/kotlin/com/openai/models/audio/speech/SpeechCreateParams.kt‎

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ private constructor(
6868
* `cedar`. You may also provide a custom voice object with an `id`, for example `{ "id":
6969
* "voice_1234" }`. Previews of the voices are available in the
7070
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
71-
* Custom voices must be created from audio samples.
71+
* Custom voices must be created from audio samples. Voices created from text prompts are
72+
* supported only in Live.
7273
*
7374
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is
7475
* unexpectedly missing or null (e.g. if the server responded with an unexpected value).
@@ -252,7 +253,8 @@ private constructor(
252253
* and `cedar`. You may also provide a custom voice object with an `id`, for example `{
253254
* "id": "voice_1234" }`. Previews of the voices are available in the
254255
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
255-
* Custom voices must be created from audio samples.
256+
* Custom voices must be created from audio samples. Voices created from text prompts are
257+
* supported only in Live.
256258
*/
257259
fun voice(voice: Voice) = apply { body.voice(voice) }
258260

@@ -548,7 +550,8 @@ private constructor(
548550
* and `cedar`. You may also provide a custom voice object with an `id`, for example `{
549551
* "id": "voice_1234" }`. Previews of the voices are available in the
550552
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
551-
* Custom voices must be created from audio samples.
553+
* Custom voices must be created from audio samples. Voices created from text prompts are
554+
* supported only in Live.
552555
*
553556
* @throws OpenAIInvalidDataException if the JSON field has an unexpected type or is
554557
* unexpectedly missing or null (e.g. if the server responded with an unexpected value).
@@ -745,7 +748,8 @@ private constructor(
745748
* `id`, for example `{ "id": "voice_1234" }`. Previews of the voices are available in
746749
* the
747750
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
748-
* Custom voices must be created from audio samples.
751+
* Custom voices must be created from audio samples. Voices created from text prompts
752+
* are supported only in Live.
749753
*/
750754
fun voice(voice: Voice) = voice(JsonField.of(voice))
751755

@@ -971,7 +975,8 @@ private constructor(
971975
* `cedar`. You may also provide a custom voice object with an `id`, for example `{ "id":
972976
* "voice_1234" }`. Previews of the voices are available in the
973977
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
974-
* Custom voices must be created from audio samples.
978+
* Custom voices must be created from audio samples. Voices created from text prompts are
979+
* supported only in Live.
975980
*/
976981
@JsonDeserialize(using = Voice.Deserializer::class)
977982
@JsonSerialize(using = Voice.Serializer::class)
@@ -991,7 +996,8 @@ private constructor(
991996
* and `cedar`. You may also provide a custom voice object with an `id`, for example `{
992997
* "id": "voice_1234" }`. Previews of the voices are available in the
993998
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
994-
* Custom voices must be created from audio samples.
999+
* Custom voices must be created from audio samples. Voices created from text prompts are
1000+
* supported only in Live.
9951001
*/
9961002
fun unionMember1(): Optional<UnionMember1> = Optional.ofNullable(unionMember1)
9971003

@@ -1012,7 +1018,8 @@ private constructor(
10121018
* and `cedar`. You may also provide a custom voice object with an `id`, for example `{
10131019
* "id": "voice_1234" }`. Previews of the voices are available in the
10141020
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
1015-
* Custom voices must be created from audio samples.
1021+
* Custom voices must be created from audio samples. Voices created from text prompts are
1022+
* supported only in Live.
10161023
*/
10171024
fun asUnionMember1(): UnionMember1 = unionMember1.getOrThrow("unionMember1")
10181025

@@ -1152,7 +1159,8 @@ private constructor(
11521159
* `id`, for example `{ "id": "voice_1234" }`. Previews of the voices are available in
11531160
* the
11541161
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
1155-
* Custom voices must be created from audio samples.
1162+
* Custom voices must be created from audio samples. Voices created from text prompts
1163+
* are supported only in Live.
11561164
*/
11571165
@JvmStatic
11581166
fun ofUnionMember1(unionMember1: UnionMember1) = Voice(unionMember1 = unionMember1)
@@ -1173,7 +1181,8 @@ private constructor(
11731181
* `id`, for example `{ "id": "voice_1234" }`. Previews of the voices are available in
11741182
* the
11751183
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
1176-
* Custom voices must be created from audio samples.
1184+
* Custom voices must be created from audio samples. Voices created from text prompts
1185+
* are supported only in Live.
11771186
*/
11781187
fun visitUnionMember1(unionMember1: UnionMember1): T
11791188

@@ -1251,7 +1260,8 @@ private constructor(
12511260
* and `cedar`. You may also provide a custom voice object with an `id`, for example `{
12521261
* "id": "voice_1234" }`. Previews of the voices are available in the
12531262
* [Text to speech guide](https://developers.openai.com/api/docs/guides/text-to-speech#voice-options).
1254-
* Custom voices must be created from audio samples.
1263+
* Custom voices must be created from audio samples. Voices created from text prompts are
1264+
* supported only in Live.
12551265
*/
12561266
class UnionMember1 @JsonCreator private constructor(private val value: JsonField<String>) :
12571267
Enum {

0 commit comments

Comments
 (0)