Skip to content

Commit 0eb5c03

Browse files
authored
Merge pull request #623 from openai/release-please--branches--main--changes--next
release: 3.28.0
2 parents b6d8afc + 6ab1594 commit 0eb5c03

14 files changed

Lines changed: 262 additions & 98 deletions

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "3.27.0"
2+
".": "3.28.0"
33
}

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 139
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-3e207c26eea3b15837c78ef2fe0e1c68937708fd0763971ce749c0bdb7db6376.yml
3-
openapi_spec_hash: 626982004d5a594a822fa7883422efb4
4-
config_hash: 0dda4b3af379312c9c55467a5e1e1ec0
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai%2Fopenai-2ab0731e8c94b7c783b55939d2d2a46c2594c1da2ec444c543e17a9eea6d9164.yml
3+
openapi_spec_hash: 5557d4cd48565e8b98dfcb96a5804965
4+
config_hash: 1cb55f2105c291f6f4721d06655d40f0

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## 3.28.0 (2026-03-14)
4+
5+
Full Changelog: [v3.27.0...v3.28.0](https://github.com/openai/openai-go/compare/v3.27.0...v3.28.0)
6+
7+
### Features
8+
9+
* **api:** add /v1/videos endpoint option to batch ([7b2d67e](https://github.com/openai/openai-go/commit/7b2d67e3d65737572d89536d16ed81a3ce39688f))
10+
* **api:** add defer_loading field to function tools ([6d4b683](https://github.com/openai/openai-go/commit/6d4b6833e5b0b29a9b1d0c99062a231290e8b93f))
11+
* **api:** custom voices ([d00b782](https://github.com/openai/openai-go/commit/d00b782c32db4c953b8e39edc5a77504693c70f3))
12+
13+
### ⚠ BREAKING CHANGES
14+
15+
* **api:** The `voice` param and resouce has changed from a `string` to a `string | {id: string}`. This is a breaking change for Go.
16+
317
## 3.27.0 (2026-03-13)
418

519
Full Changelog: [v3.26.0...v3.27.0](https://github.com/openai/openai-go/compare/v3.26.0...v3.27.0)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Or to pin the version:
3030
<!-- x-release-please-start-version -->
3131

3232
```sh
33-
go get -u 'github.com/openai/openai-go/v3@v3.27.0'
33+
go get -u 'github.com/openai/openai-go/v3@v3.28.0'
3434
```
3535

3636
<!-- x-release-please-end -->

audiospeech.go

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ type AudioSpeechNewParams struct {
6262
Model SpeechModel `json:"model,omitzero" api:"required"`
6363
// The voice to use when generating the audio. Supported built-in voices are
6464
// `alloy`, `ash`, `ballad`, `coral`, `echo`, `fable`, `onyx`, `nova`, `sage`,
65-
// `shimmer`, `verse`, `marin`, and `cedar`. Previews of the voices are available
66-
// in the
65+
// `shimmer`, `verse`, `marin`, and `cedar`. You may also provide a custom voice
66+
// object with an `id`, for example `{ "id": "voice_1234" }`. Previews of the
67+
// voices are available in the
6768
// [Text to speech guide](https://platform.openai.com/docs/guides/text-to-speech#voice-options).
68-
Voice AudioSpeechNewParamsVoice `json:"voice,omitzero" api:"required"`
69+
Voice AudioSpeechNewParamsVoiceUnion `json:"voice,omitzero" api:"required"`
6970
// Control the voice of your generated audio with additional instructions. Does not
7071
// work with `tts-1` or `tts-1-hd`.
7172
Instructions param.Opt[string] `json:"instructions,omitzero"`
@@ -93,26 +94,68 @@ func (r *AudioSpeechNewParams) UnmarshalJSON(data []byte) error {
9394
return apijson.UnmarshalRoot(data, r)
9495
}
9596

96-
// The voice to use when generating the audio. Supported built-in voices are
97-
// `alloy`, `ash`, `ballad`, `coral`, `echo`, `fable`, `onyx`, `nova`, `sage`,
98-
// `shimmer`, `verse`, `marin`, and `cedar`. Previews of the voices are available
99-
// in the
100-
// [Text to speech guide](https://platform.openai.com/docs/guides/text-to-speech#voice-options).
101-
type AudioSpeechNewParamsVoice string
97+
// Only one field can be non-zero.
98+
//
99+
// Use [param.IsOmitted] to confirm if a field is set.
100+
type AudioSpeechNewParamsVoiceUnion struct {
101+
OfString param.Opt[string] `json:",omitzero,inline"`
102+
// Check if union is this variant with
103+
// !param.IsOmitted(union.OfAudioSpeechNewsVoiceString)
104+
OfAudioSpeechNewsVoiceString param.Opt[string] `json:",omitzero,inline"`
105+
OfAudioSpeechNewsVoiceID *AudioSpeechNewParamsVoiceID `json:",omitzero,inline"`
106+
paramUnion
107+
}
108+
109+
func (u AudioSpeechNewParamsVoiceUnion) MarshalJSON() ([]byte, error) {
110+
return param.MarshalUnion(u, u.OfString, u.OfAudioSpeechNewsVoiceString, u.OfAudioSpeechNewsVoiceID)
111+
}
112+
func (u *AudioSpeechNewParamsVoiceUnion) UnmarshalJSON(data []byte) error {
113+
return apijson.UnmarshalRoot(data, u)
114+
}
115+
116+
func (u *AudioSpeechNewParamsVoiceUnion) asAny() any {
117+
if !param.IsOmitted(u.OfString) {
118+
return &u.OfString.Value
119+
} else if !param.IsOmitted(u.OfAudioSpeechNewsVoiceString) {
120+
return &u.OfAudioSpeechNewsVoiceString
121+
} else if !param.IsOmitted(u.OfAudioSpeechNewsVoiceID) {
122+
return u.OfAudioSpeechNewsVoiceID
123+
}
124+
return nil
125+
}
126+
127+
type AudioSpeechNewParamsVoiceString string
102128

103129
const (
104-
AudioSpeechNewParamsVoiceAlloy AudioSpeechNewParamsVoice = "alloy"
105-
AudioSpeechNewParamsVoiceAsh AudioSpeechNewParamsVoice = "ash"
106-
AudioSpeechNewParamsVoiceBallad AudioSpeechNewParamsVoice = "ballad"
107-
AudioSpeechNewParamsVoiceCoral AudioSpeechNewParamsVoice = "coral"
108-
AudioSpeechNewParamsVoiceEcho AudioSpeechNewParamsVoice = "echo"
109-
AudioSpeechNewParamsVoiceSage AudioSpeechNewParamsVoice = "sage"
110-
AudioSpeechNewParamsVoiceShimmer AudioSpeechNewParamsVoice = "shimmer"
111-
AudioSpeechNewParamsVoiceVerse AudioSpeechNewParamsVoice = "verse"
112-
AudioSpeechNewParamsVoiceMarin AudioSpeechNewParamsVoice = "marin"
113-
AudioSpeechNewParamsVoiceCedar AudioSpeechNewParamsVoice = "cedar"
130+
AudioSpeechNewParamsVoiceStringAlloy AudioSpeechNewParamsVoiceString = "alloy"
131+
AudioSpeechNewParamsVoiceStringAsh AudioSpeechNewParamsVoiceString = "ash"
132+
AudioSpeechNewParamsVoiceStringBallad AudioSpeechNewParamsVoiceString = "ballad"
133+
AudioSpeechNewParamsVoiceStringCoral AudioSpeechNewParamsVoiceString = "coral"
134+
AudioSpeechNewParamsVoiceStringEcho AudioSpeechNewParamsVoiceString = "echo"
135+
AudioSpeechNewParamsVoiceStringSage AudioSpeechNewParamsVoiceString = "sage"
136+
AudioSpeechNewParamsVoiceStringShimmer AudioSpeechNewParamsVoiceString = "shimmer"
137+
AudioSpeechNewParamsVoiceStringVerse AudioSpeechNewParamsVoiceString = "verse"
138+
AudioSpeechNewParamsVoiceStringMarin AudioSpeechNewParamsVoiceString = "marin"
139+
AudioSpeechNewParamsVoiceStringCedar AudioSpeechNewParamsVoiceString = "cedar"
114140
)
115141

142+
// Custom voice reference.
143+
//
144+
// The property ID is required.
145+
type AudioSpeechNewParamsVoiceID struct {
146+
// The custom voice ID, e.g. `voice_1234`.
147+
ID string `json:"id" api:"required"`
148+
paramObj
149+
}
150+
151+
func (r AudioSpeechNewParamsVoiceID) MarshalJSON() (data []byte, err error) {
152+
type shadow AudioSpeechNewParamsVoiceID
153+
return param.MarshalObject(r, (*shadow)(&r))
154+
}
155+
func (r *AudioSpeechNewParamsVoiceID) UnmarshalJSON(data []byte) error {
156+
return apijson.UnmarshalRoot(data, r)
157+
}
158+
116159
// The format to audio in. Supported formats are `mp3`, `opus`, `aac`, `flac`,
117160
// `wav`, and `pcm`.
118161
type AudioSpeechNewParamsResponseFormat string

audiospeech_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ func TestAudioSpeechNewWithOptionalParams(t *testing.T) {
2727
option.WithAPIKey("My API Key"),
2828
)
2929
resp, err := client.Audio.Speech.New(context.TODO(), openai.AudioSpeechNewParams{
30-
Input: "input",
31-
Model: openai.SpeechModelTTS1,
32-
Voice: openai.AudioSpeechNewParamsVoiceAsh,
30+
Input: "input",
31+
Model: openai.SpeechModelTTS1,
32+
Voice: openai.AudioSpeechNewParamsVoiceUnion{
33+
OfString: openai.String("string"),
34+
},
3335
Instructions: openai.String("instructions"),
3436
ResponseFormat: openai.AudioSpeechNewParamsResponseFormatMP3,
3537
Speed: openai.Float(0.25),

batch.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,13 +351,14 @@ type BatchNewParams struct {
351351
CompletionWindow BatchNewParamsCompletionWindow `json:"completion_window,omitzero" api:"required"`
352352
// The endpoint to be used for all requests in the batch. Currently
353353
// `/v1/responses`, `/v1/chat/completions`, `/v1/embeddings`, `/v1/completions`,
354-
// `/v1/moderations`, `/v1/images/generations`, and `/v1/images/edits` are
355-
// supported. Note that `/v1/embeddings` batches are also restricted to a maximum
356-
// of 50,000 embedding inputs across all requests in the batch.
354+
// `/v1/moderations`, `/v1/images/generations`, `/v1/images/edits`, and
355+
// `/v1/videos` are supported. Note that `/v1/embeddings` batches are also
356+
// restricted to a maximum of 50,000 embedding inputs across all requests in the
357+
// batch.
357358
//
358359
// Any of "/v1/responses", "/v1/chat/completions", "/v1/embeddings",
359360
// "/v1/completions", "/v1/moderations", "/v1/images/generations",
360-
// "/v1/images/edits".
361+
// "/v1/images/edits", "/v1/videos".
361362
Endpoint BatchNewParamsEndpoint `json:"endpoint,omitzero" api:"required"`
362363
// The ID of an uploaded file that contains requests for the new batch.
363364
//
@@ -400,9 +401,10 @@ const (
400401

401402
// The endpoint to be used for all requests in the batch. Currently
402403
// `/v1/responses`, `/v1/chat/completions`, `/v1/embeddings`, `/v1/completions`,
403-
// `/v1/moderations`, `/v1/images/generations`, and `/v1/images/edits` are
404-
// supported. Note that `/v1/embeddings` batches are also restricted to a maximum
405-
// of 50,000 embedding inputs across all requests in the batch.
404+
// `/v1/moderations`, `/v1/images/generations`, `/v1/images/edits`, and
405+
// `/v1/videos` are supported. Note that `/v1/embeddings` batches are also
406+
// restricted to a maximum of 50,000 embedding inputs across all requests in the
407+
// batch.
406408
type BatchNewParamsEndpoint string
407409

408410
const (
@@ -413,6 +415,7 @@ const (
413415
BatchNewParamsEndpointV1Moderations BatchNewParamsEndpoint = "/v1/moderations"
414416
BatchNewParamsEndpointV1ImagesGenerations BatchNewParamsEndpoint = "/v1/images/generations"
415417
BatchNewParamsEndpointV1ImagesEdits BatchNewParamsEndpoint = "/v1/images/edits"
418+
BatchNewParamsEndpointV1Videos BatchNewParamsEndpoint = "/v1/videos"
416419
)
417420

418421
// The expiration policy for the output and/or error file that are generated for a

chatcompletion.go

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -545,8 +545,9 @@ type ChatCompletionAudioParam struct {
545545
Format ChatCompletionAudioParamFormat `json:"format,omitzero" api:"required"`
546546
// The voice the model uses to respond. Supported built-in voices are `alloy`,
547547
// `ash`, `ballad`, `coral`, `echo`, `fable`, `nova`, `onyx`, `sage`, `shimmer`,
548-
// `marin`, and `cedar`.
549-
Voice ChatCompletionAudioParamVoice `json:"voice,omitzero" api:"required"`
548+
// `marin`, and `cedar`. You may also provide a custom voice object with an `id`,
549+
// for example `{ "id": "voice_1234" }`.
550+
Voice ChatCompletionAudioParamVoiceUnion `json:"voice,omitzero" api:"required"`
550551
paramObj
551552
}
552553

@@ -571,24 +572,68 @@ const (
571572
ChatCompletionAudioParamFormatPcm16 ChatCompletionAudioParamFormat = "pcm16"
572573
)
573574

574-
// The voice the model uses to respond. Supported built-in voices are `alloy`,
575-
// `ash`, `ballad`, `coral`, `echo`, `fable`, `nova`, `onyx`, `sage`, `shimmer`,
576-
// `marin`, and `cedar`.
577-
type ChatCompletionAudioParamVoice string
575+
// Only one field can be non-zero.
576+
//
577+
// Use [param.IsOmitted] to confirm if a field is set.
578+
type ChatCompletionAudioParamVoiceUnion struct {
579+
OfString param.Opt[string] `json:",omitzero,inline"`
580+
// Check if union is this variant with
581+
// !param.IsOmitted(union.OfChatCompletionAudioVoiceString)
582+
OfChatCompletionAudioVoiceString param.Opt[string] `json:",omitzero,inline"`
583+
OfChatCompletionAudioVoiceID *ChatCompletionAudioParamVoiceID `json:",omitzero,inline"`
584+
paramUnion
585+
}
586+
587+
func (u ChatCompletionAudioParamVoiceUnion) MarshalJSON() ([]byte, error) {
588+
return param.MarshalUnion(u, u.OfString, u.OfChatCompletionAudioVoiceString, u.OfChatCompletionAudioVoiceID)
589+
}
590+
func (u *ChatCompletionAudioParamVoiceUnion) UnmarshalJSON(data []byte) error {
591+
return apijson.UnmarshalRoot(data, u)
592+
}
593+
594+
func (u *ChatCompletionAudioParamVoiceUnion) asAny() any {
595+
if !param.IsOmitted(u.OfString) {
596+
return &u.OfString.Value
597+
} else if !param.IsOmitted(u.OfChatCompletionAudioVoiceString) {
598+
return &u.OfChatCompletionAudioVoiceString
599+
} else if !param.IsOmitted(u.OfChatCompletionAudioVoiceID) {
600+
return u.OfChatCompletionAudioVoiceID
601+
}
602+
return nil
603+
}
604+
605+
type ChatCompletionAudioParamVoiceString string
578606

579607
const (
580-
ChatCompletionAudioParamVoiceAlloy ChatCompletionAudioParamVoice = "alloy"
581-
ChatCompletionAudioParamVoiceAsh ChatCompletionAudioParamVoice = "ash"
582-
ChatCompletionAudioParamVoiceBallad ChatCompletionAudioParamVoice = "ballad"
583-
ChatCompletionAudioParamVoiceCoral ChatCompletionAudioParamVoice = "coral"
584-
ChatCompletionAudioParamVoiceEcho ChatCompletionAudioParamVoice = "echo"
585-
ChatCompletionAudioParamVoiceSage ChatCompletionAudioParamVoice = "sage"
586-
ChatCompletionAudioParamVoiceShimmer ChatCompletionAudioParamVoice = "shimmer"
587-
ChatCompletionAudioParamVoiceVerse ChatCompletionAudioParamVoice = "verse"
588-
ChatCompletionAudioParamVoiceMarin ChatCompletionAudioParamVoice = "marin"
589-
ChatCompletionAudioParamVoiceCedar ChatCompletionAudioParamVoice = "cedar"
608+
ChatCompletionAudioParamVoiceStringAlloy ChatCompletionAudioParamVoiceString = "alloy"
609+
ChatCompletionAudioParamVoiceStringAsh ChatCompletionAudioParamVoiceString = "ash"
610+
ChatCompletionAudioParamVoiceStringBallad ChatCompletionAudioParamVoiceString = "ballad"
611+
ChatCompletionAudioParamVoiceStringCoral ChatCompletionAudioParamVoiceString = "coral"
612+
ChatCompletionAudioParamVoiceStringEcho ChatCompletionAudioParamVoiceString = "echo"
613+
ChatCompletionAudioParamVoiceStringSage ChatCompletionAudioParamVoiceString = "sage"
614+
ChatCompletionAudioParamVoiceStringShimmer ChatCompletionAudioParamVoiceString = "shimmer"
615+
ChatCompletionAudioParamVoiceStringVerse ChatCompletionAudioParamVoiceString = "verse"
616+
ChatCompletionAudioParamVoiceStringMarin ChatCompletionAudioParamVoiceString = "marin"
617+
ChatCompletionAudioParamVoiceStringCedar ChatCompletionAudioParamVoiceString = "cedar"
590618
)
591619

620+
// Custom voice reference.
621+
//
622+
// The property ID is required.
623+
type ChatCompletionAudioParamVoiceID struct {
624+
// The custom voice ID, e.g. `voice_1234`.
625+
ID string `json:"id" api:"required"`
626+
paramObj
627+
}
628+
629+
func (r ChatCompletionAudioParamVoiceID) MarshalJSON() (data []byte, err error) {
630+
type shadow ChatCompletionAudioParamVoiceID
631+
return param.MarshalObject(r, (*shadow)(&r))
632+
}
633+
func (r *ChatCompletionAudioParamVoiceID) UnmarshalJSON(data []byte) error {
634+
return apijson.UnmarshalRoot(data, r)
635+
}
636+
592637
// Represents a streamed chunk of a chat completion response returned by the model,
593638
// based on the provided input.
594639
// [Learn more](https://platform.openai.com/docs/guides/streaming-responses).

chatcompletion_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ func TestChatCompletionNewWithOptionalParams(t *testing.T) {
3838
Model: shared.ChatModelGPT5_4,
3939
Audio: openai.ChatCompletionAudioParam{
4040
Format: openai.ChatCompletionAudioParamFormatWAV,
41-
Voice: openai.ChatCompletionAudioParamVoiceAsh,
41+
Voice: openai.ChatCompletionAudioParamVoiceUnion{
42+
OfString: openai.String("string"),
43+
},
4244
},
4345
FrequencyPenalty: openai.Float(-2),
4446
FunctionCall: openai.ChatCompletionNewParamsFunctionCallUnion{

internal/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
package internal
44

5-
const PackageVersion = "3.27.0" // x-release-please-version
5+
const PackageVersion = "3.28.0" // x-release-please-version

0 commit comments

Comments
 (0)