From 411894ea26cd10281d95d619feca4d50f7f57897 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 26 Feb 2026 14:32:30 +0000
Subject: [PATCH 1/5] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index d9cefbd2..6aaf0974 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 946
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx%2Ftelnyx-462166922656820a2c260496fa86ce259c51c8ad7aaa783e1975e16f05c08af7.yml
-openapi_spec_hash: bc16f6bdab2570564f73ece9ec24f57c
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx%2Ftelnyx-7508cbe75462245fb5cdf6935064e7342011990bf26539ae6590e9b65a65b826.yml
+openapi_spec_hash: 08ae3f68c700f1a6432feb1f3df446fd
config_hash: 86808d35d9648ffe4b87e3e5b858c17c
From f54a80e694595f81293ab50af4548f054b48df43 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 26 Feb 2026 15:17:35 +0000
Subject: [PATCH 2/5] codegen metadata
---
.stats.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 6aaf0974..cabca1cd 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 946
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx%2Ftelnyx-7508cbe75462245fb5cdf6935064e7342011990bf26539ae6590e9b65a65b826.yml
-openapi_spec_hash: 08ae3f68c700f1a6432feb1f3df446fd
-config_hash: 86808d35d9648ffe4b87e3e5b858c17c
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx%2Ftelnyx-f8ac3fc0b11c82c4504efdfd9719d069fb41ab1d977f8cb3de1ed1a53d8b2c24.yml
+openapi_spec_hash: b103646d1bc605319de9dc598af102a6
+config_hash: 5300e28459aea095deff56269a1d7e9e
From e30bc6fa5f91da4f8734564a66e8458d09422000 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 26 Feb 2026 15:35:34 +0000
Subject: [PATCH 3/5] codegen metadata
---
.stats.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index cabca1cd..1b8e2150 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 946
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx%2Ftelnyx-f8ac3fc0b11c82c4504efdfd9719d069fb41ab1d977f8cb3de1ed1a53d8b2c24.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx%2Ftelnyx-ba02fe79cc421415e64d1c7a406b6e9e7edd0735b0bd8ca60cc0cb2f65d71fe6.yml
openapi_spec_hash: b103646d1bc605319de9dc598af102a6
-config_hash: 5300e28459aea095deff56269a1d7e9e
+config_hash: a928849ebc1d9775bbdf265cf313c0f7
From f14db77cd98183ca8919771c2ba9d01c7f9dacfc Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 26 Feb 2026 17:58:48 +0000
Subject: [PATCH 4/5] feat(api): manual updates
---
.stats.yml | 6 +-
api.md | 2 +-
src/telnyx/resources/conferences/actions.py | 10 -
src/telnyx/resources/text_to_speech.py | 284 +++++++-----------
src/telnyx/types/__init__.py | 2 +-
.../conferences/action_record_start_params.py | 6 -
.../text_to_speech_generate_speech_params.py | 26 ++
.../types/text_to_speech_stream_params.py | 49 ---
.../api_resources/conferences/test_actions.py | 2 -
tests/api_resources/test_text_to_speech.py | 174 ++++++-----
10 files changed, 234 insertions(+), 327 deletions(-)
create mode 100644 src/telnyx/types/text_to_speech_generate_speech_params.py
delete mode 100644 src/telnyx/types/text_to_speech_stream_params.py
diff --git a/.stats.yml b/.stats.yml
index 1b8e2150..3984b45a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 946
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx%2Ftelnyx-ba02fe79cc421415e64d1c7a406b6e9e7edd0735b0bd8ca60cc0cb2f65d71fe6.yml
-openapi_spec_hash: b103646d1bc605319de9dc598af102a6
-config_hash: a928849ebc1d9775bbdf265cf313c0f7
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx%2Ftelnyx-e5b44768a2da327dbb88d2a4f97653388c6489365db2e873d1225d48280c1530.yml
+openapi_spec_hash: 515f3d122ed486daa3f9a90a252908c8
+config_hash: 147ed46e6f2c0900ee7716ce4dddb8e2
diff --git a/api.md b/api.md
index 1c0081a5..ffcc76d7 100644
--- a/api.md
+++ b/api.md
@@ -4464,8 +4464,8 @@ from telnyx.types import TextToSpeechListVoicesResponse
Methods:
+- client.text_to_speech.generate_speech(\*\*params) -> BinaryAPIResponse
- client.text_to_speech.list_voices(\*\*params) -> TextToSpeechListVoicesResponse
-- client.text_to_speech.stream(\*\*params) -> None
# UsageReports
diff --git a/src/telnyx/resources/conferences/actions.py b/src/telnyx/resources/conferences/actions.py
index c10db5ed..cbad915a 100644
--- a/src/telnyx/resources/conferences/actions.py
+++ b/src/telnyx/resources/conferences/actions.py
@@ -765,7 +765,6 @@ def record_start(
id: str,
*,
format: Literal["wav", "mp3"],
- channels: Literal["single", "dual"] | Omit = omit,
command_id: str | Omit = omit,
custom_file_name: str | Omit = omit,
play_beep: bool | Omit = omit,
@@ -791,9 +790,6 @@ def record_start(
format: The audio file format used when storing the conference recording. Can be either
`mp3` or `wav`.
- channels: When `dual`, final audio file will be stereo recorded with the conference
- creator on the first channel, and the rest on the second channel.
-
command_id: Use this field to avoid duplicate commands. Telnyx will ignore any command with
the same `command_id` for the same `conference_id`.
@@ -823,7 +819,6 @@ def record_start(
body=maybe_transform(
{
"format": format,
- "channels": channels,
"command_id": command_id,
"custom_file_name": custom_file_name,
"play_beep": play_beep,
@@ -1956,7 +1951,6 @@ async def record_start(
id: str,
*,
format: Literal["wav", "mp3"],
- channels: Literal["single", "dual"] | Omit = omit,
command_id: str | Omit = omit,
custom_file_name: str | Omit = omit,
play_beep: bool | Omit = omit,
@@ -1982,9 +1976,6 @@ async def record_start(
format: The audio file format used when storing the conference recording. Can be either
`mp3` or `wav`.
- channels: When `dual`, final audio file will be stereo recorded with the conference
- creator on the first channel, and the rest on the second channel.
-
command_id: Use this field to avoid duplicate commands. Telnyx will ignore any command with
the same `command_id` for the same `conference_id`.
@@ -2014,7 +2005,6 @@ async def record_start(
body=await async_maybe_transform(
{
"format": format,
- "channels": channels,
"command_id": command_id,
"custom_file_name": custom_file_name,
"play_beep": play_beep,
diff --git a/src/telnyx/resources/text_to_speech.py b/src/telnyx/resources/text_to_speech.py
index 4b9ff0e3..7e37a6f5 100644
--- a/src/telnyx/resources/text_to_speech.py
+++ b/src/telnyx/resources/text_to_speech.py
@@ -6,16 +6,24 @@
import httpx
-from ..types import text_to_speech_stream_params, text_to_speech_list_voices_params
-from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
+from ..types import text_to_speech_list_voices_params, text_to_speech_generate_speech_params
+from .._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
from .._utils import maybe_transform, async_maybe_transform
from .._compat import cached_property
from .._resource import SyncAPIResource, AsyncAPIResource
from .._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
+ to_custom_raw_response_wrapper,
async_to_streamed_response_wrapper,
+ to_custom_streamed_response_wrapper,
+ async_to_custom_raw_response_wrapper,
+ async_to_custom_streamed_response_wrapper,
)
from .._base_client import make_request_options
from ..types.text_to_speech_list_voices_response import TextToSpeechListVoicesResponse
@@ -43,25 +51,36 @@ def with_streaming_response(self) -> TextToSpeechResourceWithStreamingResponse:
"""
return TextToSpeechResourceWithStreamingResponse(self)
- def list_voices(
+ def generate_speech(
self,
*,
- elevenlabs_api_key_ref: str | Omit = omit,
- provider: Literal["aws", "azure", "elevenlabs", "telnyx"] | Omit = omit,
+ text: str,
+ voice: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> TextToSpeechListVoicesResponse:
+ ) -> BinaryAPIResponse:
"""
- Returns a list of voices that can be used with the text to speech commands.
+ Converts the provided text to speech using the specified voice and returns audio
+ data
Args:
- elevenlabs_api_key_ref: Reference to your ElevenLabs API key stored in the Telnyx Portal
+ text: The text to convert to speech
- provider: Filter voices by provider
+ voice: The voice ID in the format Provider.ModelId.VoiceId.
+
+ Examples:
+
+ - AWS.Polly.Joanna-Neural
+ - Azure.en-US-AvaMultilingualNeural
+ - ElevenLabs.eleven_multilingual_v2.Rachel
+ - Telnyx.KokoroTTS.af
+
+ Use the `GET /text-to-speech/voices` endpoint to get a complete list of
+ available voices.
extra_headers: Send extra headers
@@ -71,86 +90,41 @@ def list_voices(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return self._get(
- "/text-to-speech/voices",
+ extra_headers = {"Accept": "audio/mpeg", **(extra_headers or {})}
+ return self._post(
+ "/text-to-speech/speech",
+ body=maybe_transform(
+ {
+ "text": text,
+ "voice": voice,
+ },
+ text_to_speech_generate_speech_params.TextToSpeechGenerateSpeechParams,
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=maybe_transform(
- {
- "elevenlabs_api_key_ref": elevenlabs_api_key_ref,
- "provider": provider,
- },
- text_to_speech_list_voices_params.TextToSpeechListVoicesParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TextToSpeechListVoicesResponse,
+ cast_to=BinaryAPIResponse,
)
- def stream(
+ def list_voices(
self,
*,
- audio_format: Literal["pcm", "wav"] | Omit = omit,
- disable_cache: bool | Omit = omit,
- model_id: str | Omit = omit,
- provider: Literal["aws", "telnyx", "azure", "elevenlabs", "minimax", "murfai", "rime", "resemble"]
- | Omit = omit,
- socket_id: str | Omit = omit,
- voice: str | Omit = omit,
- voice_id: str | Omit = omit,
+ elevenlabs_api_key_ref: str | Omit = omit,
+ provider: Literal["aws", "azure", "elevenlabs", "telnyx"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
+ ) -> TextToSpeechListVoicesResponse:
"""
- Open a WebSocket connection to stream text and receive synthesized audio in real
- time. Authentication is provided via the standard
- `Authorization: Bearer ` header. Send JSON frames with text to
- synthesize; receive JSON frames containing base64-encoded audio chunks.
-
- Supported providers: `aws`, `telnyx`, `azure`, `murfai`, `minimax`, `rime`,
- `resemble`, `elevenlabs`.
-
- **Connection flow:**
-
- 1. Open WebSocket with query parameters specifying provider, voice, and model.
- 2. Send an initial handshake message `{"text": " "}` (single space) with
- optional `voice_settings` to initialize the session.
- 3. Send text messages as `{"text": "Hello world"}`.
- 4. Receive audio chunks as JSON frames with base64-encoded audio.
- 5. A final frame with `isFinal: true` indicates the end of audio for the current
- text.
-
- To interrupt and restart synthesis mid-stream, send `{"force": true}` — the
- current worker is stopped and a new one is started.
+ Returns a list of voices that can be used with the text to speech commands.
Args:
- audio_format: Audio output format override. Supported for Telnyx `Natural`/`NaturalHD` models
- only. Accepted values: `pcm`, `wav`.
-
- disable_cache: When `true`, bypass the audio cache and generate fresh audio.
-
- model_id: Model identifier for the chosen provider. Examples: `Natural`, `NaturalHD`
- (Telnyx); `Polly.Generative` (AWS).
-
- provider: TTS provider. Defaults to `telnyx` if not specified. Ignored when `voice` is
- provided.
-
- socket_id: Client-provided socket identifier for tracking. If not provided, one is
- generated server-side.
-
- voice: Voice identifier in the format `provider.model_id.voice_id` or
- `provider.voice_id` (e.g. `telnyx.NaturalHD.Telnyx_Alloy` or
- `azure.en-US-AvaMultilingualNeural`). When provided, the `provider`, `model_id`,
- and `voice_id` are extracted automatically. Takes precedence over individual
- `provider`/`model_id`/`voice_id` parameters.
+ elevenlabs_api_key_ref: Reference to your ElevenLabs API key stored in the Telnyx Portal
- voice_id: Voice identifier for the chosen provider.
+ provider: Filter voices by provider
extra_headers: Send extra headers
@@ -160,9 +134,8 @@ def stream(
timeout: Override the client-level default timeout for this request, in seconds
"""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._get(
- "/text-to-speech/speech",
+ "/text-to-speech/voices",
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -170,18 +143,13 @@ def stream(
timeout=timeout,
query=maybe_transform(
{
- "audio_format": audio_format,
- "disable_cache": disable_cache,
- "model_id": model_id,
+ "elevenlabs_api_key_ref": elevenlabs_api_key_ref,
"provider": provider,
- "socket_id": socket_id,
- "voice": voice,
- "voice_id": voice_id,
},
- text_to_speech_stream_params.TextToSpeechStreamParams,
+ text_to_speech_list_voices_params.TextToSpeechListVoicesParams,
),
),
- cast_to=NoneType,
+ cast_to=TextToSpeechListVoicesResponse,
)
@@ -205,25 +173,36 @@ def with_streaming_response(self) -> AsyncTextToSpeechResourceWithStreamingRespo
"""
return AsyncTextToSpeechResourceWithStreamingResponse(self)
- async def list_voices(
+ async def generate_speech(
self,
*,
- elevenlabs_api_key_ref: str | Omit = omit,
- provider: Literal["aws", "azure", "elevenlabs", "telnyx"] | Omit = omit,
+ text: str,
+ voice: str,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> TextToSpeechListVoicesResponse:
+ ) -> AsyncBinaryAPIResponse:
"""
- Returns a list of voices that can be used with the text to speech commands.
+ Converts the provided text to speech using the specified voice and returns audio
+ data
Args:
- elevenlabs_api_key_ref: Reference to your ElevenLabs API key stored in the Telnyx Portal
+ text: The text to convert to speech
- provider: Filter voices by provider
+ voice: The voice ID in the format Provider.ModelId.VoiceId.
+
+ Examples:
+
+ - AWS.Polly.Joanna-Neural
+ - Azure.en-US-AvaMultilingualNeural
+ - ElevenLabs.eleven_multilingual_v2.Rachel
+ - Telnyx.KokoroTTS.af
+
+ Use the `GET /text-to-speech/voices` endpoint to get a complete list of
+ available voices.
extra_headers: Send extra headers
@@ -233,86 +212,41 @@ async def list_voices(
timeout: Override the client-level default timeout for this request, in seconds
"""
- return await self._get(
- "/text-to-speech/voices",
+ extra_headers = {"Accept": "audio/mpeg", **(extra_headers or {})}
+ return await self._post(
+ "/text-to-speech/speech",
+ body=await async_maybe_transform(
+ {
+ "text": text,
+ "voice": voice,
+ },
+ text_to_speech_generate_speech_params.TextToSpeechGenerateSpeechParams,
+ ),
options=make_request_options(
- extra_headers=extra_headers,
- extra_query=extra_query,
- extra_body=extra_body,
- timeout=timeout,
- query=await async_maybe_transform(
- {
- "elevenlabs_api_key_ref": elevenlabs_api_key_ref,
- "provider": provider,
- },
- text_to_speech_list_voices_params.TextToSpeechListVoicesParams,
- ),
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=TextToSpeechListVoicesResponse,
+ cast_to=AsyncBinaryAPIResponse,
)
- async def stream(
+ async def list_voices(
self,
*,
- audio_format: Literal["pcm", "wav"] | Omit = omit,
- disable_cache: bool | Omit = omit,
- model_id: str | Omit = omit,
- provider: Literal["aws", "telnyx", "azure", "elevenlabs", "minimax", "murfai", "rime", "resemble"]
- | Omit = omit,
- socket_id: str | Omit = omit,
- voice: str | Omit = omit,
- voice_id: str | Omit = omit,
+ elevenlabs_api_key_ref: str | Omit = omit,
+ provider: Literal["aws", "azure", "elevenlabs", "telnyx"] | Omit = omit,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
+ ) -> TextToSpeechListVoicesResponse:
"""
- Open a WebSocket connection to stream text and receive synthesized audio in real
- time. Authentication is provided via the standard
- `Authorization: Bearer ` header. Send JSON frames with text to
- synthesize; receive JSON frames containing base64-encoded audio chunks.
-
- Supported providers: `aws`, `telnyx`, `azure`, `murfai`, `minimax`, `rime`,
- `resemble`, `elevenlabs`.
-
- **Connection flow:**
-
- 1. Open WebSocket with query parameters specifying provider, voice, and model.
- 2. Send an initial handshake message `{"text": " "}` (single space) with
- optional `voice_settings` to initialize the session.
- 3. Send text messages as `{"text": "Hello world"}`.
- 4. Receive audio chunks as JSON frames with base64-encoded audio.
- 5. A final frame with `isFinal: true` indicates the end of audio for the current
- text.
-
- To interrupt and restart synthesis mid-stream, send `{"force": true}` — the
- current worker is stopped and a new one is started.
+ Returns a list of voices that can be used with the text to speech commands.
Args:
- audio_format: Audio output format override. Supported for Telnyx `Natural`/`NaturalHD` models
- only. Accepted values: `pcm`, `wav`.
-
- disable_cache: When `true`, bypass the audio cache and generate fresh audio.
-
- model_id: Model identifier for the chosen provider. Examples: `Natural`, `NaturalHD`
- (Telnyx); `Polly.Generative` (AWS).
-
- provider: TTS provider. Defaults to `telnyx` if not specified. Ignored when `voice` is
- provided.
-
- socket_id: Client-provided socket identifier for tracking. If not provided, one is
- generated server-side.
-
- voice: Voice identifier in the format `provider.model_id.voice_id` or
- `provider.voice_id` (e.g. `telnyx.NaturalHD.Telnyx_Alloy` or
- `azure.en-US-AvaMultilingualNeural`). When provided, the `provider`, `model_id`,
- and `voice_id` are extracted automatically. Takes precedence over individual
- `provider`/`model_id`/`voice_id` parameters.
+ elevenlabs_api_key_ref: Reference to your ElevenLabs API key stored in the Telnyx Portal
- voice_id: Voice identifier for the chosen provider.
+ provider: Filter voices by provider
extra_headers: Send extra headers
@@ -322,9 +256,8 @@ async def stream(
timeout: Override the client-level default timeout for this request, in seconds
"""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._get(
- "/text-to-speech/speech",
+ "/text-to-speech/voices",
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -332,18 +265,13 @@ async def stream(
timeout=timeout,
query=await async_maybe_transform(
{
- "audio_format": audio_format,
- "disable_cache": disable_cache,
- "model_id": model_id,
+ "elevenlabs_api_key_ref": elevenlabs_api_key_ref,
"provider": provider,
- "socket_id": socket_id,
- "voice": voice,
- "voice_id": voice_id,
},
- text_to_speech_stream_params.TextToSpeechStreamParams,
+ text_to_speech_list_voices_params.TextToSpeechListVoicesParams,
),
),
- cast_to=NoneType,
+ cast_to=TextToSpeechListVoicesResponse,
)
@@ -351,45 +279,49 @@ class TextToSpeechResourceWithRawResponse:
def __init__(self, text_to_speech: TextToSpeechResource) -> None:
self._text_to_speech = text_to_speech
+ self.generate_speech = to_custom_raw_response_wrapper(
+ text_to_speech.generate_speech,
+ BinaryAPIResponse,
+ )
self.list_voices = to_raw_response_wrapper(
text_to_speech.list_voices,
)
- self.stream = to_raw_response_wrapper(
- text_to_speech.stream,
- )
class AsyncTextToSpeechResourceWithRawResponse:
def __init__(self, text_to_speech: AsyncTextToSpeechResource) -> None:
self._text_to_speech = text_to_speech
+ self.generate_speech = async_to_custom_raw_response_wrapper(
+ text_to_speech.generate_speech,
+ AsyncBinaryAPIResponse,
+ )
self.list_voices = async_to_raw_response_wrapper(
text_to_speech.list_voices,
)
- self.stream = async_to_raw_response_wrapper(
- text_to_speech.stream,
- )
class TextToSpeechResourceWithStreamingResponse:
def __init__(self, text_to_speech: TextToSpeechResource) -> None:
self._text_to_speech = text_to_speech
+ self.generate_speech = to_custom_streamed_response_wrapper(
+ text_to_speech.generate_speech,
+ StreamedBinaryAPIResponse,
+ )
self.list_voices = to_streamed_response_wrapper(
text_to_speech.list_voices,
)
- self.stream = to_streamed_response_wrapper(
- text_to_speech.stream,
- )
class AsyncTextToSpeechResourceWithStreamingResponse:
def __init__(self, text_to_speech: AsyncTextToSpeechResource) -> None:
self._text_to_speech = text_to_speech
+ self.generate_speech = async_to_custom_streamed_response_wrapper(
+ text_to_speech.generate_speech,
+ AsyncStreamedBinaryAPIResponse,
+ )
self.list_voices = async_to_streamed_response_wrapper(
text_to_speech.list_voices,
)
- self.stream = async_to_streamed_response_wrapper(
- text_to_speech.stream,
- )
diff --git a/src/telnyx/types/__init__.py b/src/telnyx/types/__init__.py
index d6801488..10f0b762 100644
--- a/src/telnyx/types/__init__.py
+++ b/src/telnyx/types/__init__.py
@@ -437,7 +437,6 @@
from .sim_card_group_update_params import SimCardGroupUpdateParams as SimCardGroupUpdateParams
from .sim_card_order_create_params import SimCardOrderCreateParams as SimCardOrderCreateParams
from .sub_number_order_list_params import SubNumberOrderListParams as SubNumberOrderListParams
-from .text_to_speech_stream_params import TextToSpeechStreamParams as TextToSpeechStreamParams
from .url_shortener_settings_param import URLShortenerSettingsParam as URLShortenerSettingsParam
from .user_address_create_response import UserAddressCreateResponse as UserAddressCreateResponse
from .verified_number_data_wrapper import VerifiedNumberDataWrapper as VerifiedNumberDataWrapper
@@ -831,6 +830,7 @@
)
from .sim_card_get_activation_code_response import SimCardGetActivationCodeResponse as SimCardGetActivationCodeResponse
from .sim_card_order_preview_preview_params import SimCardOrderPreviewPreviewParams as SimCardOrderPreviewPreviewParams
+from .text_to_speech_generate_speech_params import TextToSpeechGenerateSpeechParams as TextToSpeechGenerateSpeechParams
from .verification_trigger_flashcall_params import (
VerificationTriggerFlashcallParams as VerificationTriggerFlashcallParams,
)
diff --git a/src/telnyx/types/conferences/action_record_start_params.py b/src/telnyx/types/conferences/action_record_start_params.py
index d568dc16..09c21496 100644
--- a/src/telnyx/types/conferences/action_record_start_params.py
+++ b/src/telnyx/types/conferences/action_record_start_params.py
@@ -14,12 +14,6 @@ class ActionRecordStartParams(TypedDict, total=False):
Can be either `mp3` or `wav`.
"""
- channels: Literal["single", "dual"]
- """
- When `dual`, final audio file will be stereo recorded with the conference
- creator on the first channel, and the rest on the second channel.
- """
-
command_id: str
"""Use this field to avoid duplicate commands.
diff --git a/src/telnyx/types/text_to_speech_generate_speech_params.py b/src/telnyx/types/text_to_speech_generate_speech_params.py
new file mode 100644
index 00000000..95b43e53
--- /dev/null
+++ b/src/telnyx/types/text_to_speech_generate_speech_params.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["TextToSpeechGenerateSpeechParams"]
+
+
+class TextToSpeechGenerateSpeechParams(TypedDict, total=False):
+ text: Required[str]
+ """The text to convert to speech"""
+
+ voice: Required[str]
+ """The voice ID in the format Provider.ModelId.VoiceId.
+
+ Examples:
+
+ - AWS.Polly.Joanna-Neural
+ - Azure.en-US-AvaMultilingualNeural
+ - ElevenLabs.eleven_multilingual_v2.Rachel
+ - Telnyx.KokoroTTS.af
+
+ Use the `GET /text-to-speech/voices` endpoint to get a complete list of
+ available voices.
+ """
diff --git a/src/telnyx/types/text_to_speech_stream_params.py b/src/telnyx/types/text_to_speech_stream_params.py
deleted file mode 100644
index 9a4aac90..00000000
--- a/src/telnyx/types/text_to_speech_stream_params.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, TypedDict
-
-__all__ = ["TextToSpeechStreamParams"]
-
-
-class TextToSpeechStreamParams(TypedDict, total=False):
- audio_format: Literal["pcm", "wav"]
- """Audio output format override.
-
- Supported for Telnyx `Natural`/`NaturalHD` models only. Accepted values: `pcm`,
- `wav`.
- """
-
- disable_cache: bool
- """When `true`, bypass the audio cache and generate fresh audio."""
-
- model_id: str
- """Model identifier for the chosen provider.
-
- Examples: `Natural`, `NaturalHD` (Telnyx); `Polly.Generative` (AWS).
- """
-
- provider: Literal["aws", "telnyx", "azure", "elevenlabs", "minimax", "murfai", "rime", "resemble"]
- """TTS provider.
-
- Defaults to `telnyx` if not specified. Ignored when `voice` is provided.
- """
-
- socket_id: str
- """Client-provided socket identifier for tracking.
-
- If not provided, one is generated server-side.
- """
-
- voice: str
- """
- Voice identifier in the format `provider.model_id.voice_id` or
- `provider.voice_id` (e.g. `telnyx.NaturalHD.Telnyx_Alloy` or
- `azure.en-US-AvaMultilingualNeural`). When provided, the `provider`, `model_id`,
- and `voice_id` are extracted automatically. Takes precedence over individual
- `provider`/`model_id`/`voice_id` parameters.
- """
-
- voice_id: str
- """Voice identifier for the chosen provider."""
diff --git a/tests/api_resources/conferences/test_actions.py b/tests/api_resources/conferences/test_actions.py
index 1ea4ee48..c628fcaa 100644
--- a/tests/api_resources/conferences/test_actions.py
+++ b/tests/api_resources/conferences/test_actions.py
@@ -633,7 +633,6 @@ def test_method_record_start_with_all_params(self, client: Telnyx) -> None:
action = client.conferences.actions.record_start(
id="id",
format="wav",
- channels="dual",
command_id="891510ac-f3e4-11e8-af5b-de00688a4901",
custom_file_name="my_recording_file_name",
play_beep=True,
@@ -1624,7 +1623,6 @@ async def test_method_record_start_with_all_params(self, async_client: AsyncTeln
action = await async_client.conferences.actions.record_start(
id="id",
format="wav",
- channels="dual",
command_id="891510ac-f3e4-11e8-af5b-de00688a4901",
custom_file_name="my_recording_file_name",
play_beep=True,
diff --git a/tests/api_resources/test_text_to_speech.py b/tests/api_resources/test_text_to_speech.py
index 19825e23..2db1196b 100644
--- a/tests/api_resources/test_text_to_speech.py
+++ b/tests/api_resources/test_text_to_speech.py
@@ -5,11 +5,21 @@
import os
from typing import Any, cast
+import httpx
import pytest
+from respx import MockRouter
from telnyx import Telnyx, AsyncTelnyx
from tests.utils import assert_matches_type
-from telnyx.types import TextToSpeechListVoicesResponse
+from telnyx.types import (
+ TextToSpeechListVoicesResponse,
+)
+from telnyx._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -17,6 +27,51 @@
class TestTextToSpeech:
parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_generate_speech(self, client: Telnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/text-to-speech/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ text_to_speech = client.text_to_speech.generate_speech(
+ text="text",
+ voice="voice",
+ )
+ assert text_to_speech.is_closed
+ assert text_to_speech.json() == {"foo": "bar"}
+ assert cast(Any, text_to_speech.is_closed) is True
+ assert isinstance(text_to_speech, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_raw_response_generate_speech(self, client: Telnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/text-to-speech/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+
+ text_to_speech = client.text_to_speech.with_raw_response.generate_speech(
+ text="text",
+ voice="voice",
+ )
+
+ assert text_to_speech.is_closed is True
+ assert text_to_speech.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert text_to_speech.json() == {"foo": "bar"}
+ assert isinstance(text_to_speech, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_streaming_response_generate_speech(self, client: Telnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/text-to-speech/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ with client.text_to_speech.with_streaming_response.generate_speech(
+ text="text",
+ voice="voice",
+ ) as text_to_speech:
+ assert not text_to_speech.is_closed
+ assert text_to_speech.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert text_to_speech.json() == {"foo": "bar"}
+ assert cast(Any, text_to_speech.is_closed) is True
+ assert isinstance(text_to_speech, StreamedBinaryAPIResponse)
+
+ assert cast(Any, text_to_speech.is_closed) is True
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_list_voices(self, client: Telnyx) -> None:
@@ -54,53 +109,56 @@ def test_streaming_response_list_voices(self, client: Telnyx) -> None:
assert cast(Any, response.is_closed) is True
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_method_stream(self, client: Telnyx) -> None:
- text_to_speech = client.text_to_speech.stream()
- assert text_to_speech is None
- @pytest.mark.skip(reason="Mock server tests are disabled")
+class TestAsyncTextToSpeech:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
@parametrize
- def test_method_stream_with_all_params(self, client: Telnyx) -> None:
- text_to_speech = client.text_to_speech.stream(
- audio_format="pcm",
- disable_cache=True,
- model_id="model_id",
- provider="aws",
- socket_id="socket_id",
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_generate_speech(self, async_client: AsyncTelnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/text-to-speech/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ text_to_speech = await async_client.text_to_speech.generate_speech(
+ text="text",
voice="voice",
- voice_id="voice_id",
)
- assert text_to_speech is None
+ assert text_to_speech.is_closed
+ assert await text_to_speech.json() == {"foo": "bar"}
+ assert cast(Any, text_to_speech.is_closed) is True
+ assert isinstance(text_to_speech, AsyncBinaryAPIResponse)
- @pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
- def test_raw_response_stream(self, client: Telnyx) -> None:
- response = client.text_to_speech.with_raw_response.stream()
+ @pytest.mark.respx(base_url=base_url)
+ async def test_raw_response_generate_speech(self, async_client: AsyncTelnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/text-to-speech/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- text_to_speech = response.parse()
- assert text_to_speech is None
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- def test_streaming_response_stream(self, client: Telnyx) -> None:
- with client.text_to_speech.with_streaming_response.stream() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ text_to_speech = await async_client.text_to_speech.with_raw_response.generate_speech(
+ text="text",
+ voice="voice",
+ )
- text_to_speech = response.parse()
- assert text_to_speech is None
+ assert text_to_speech.is_closed is True
+ assert text_to_speech.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert await text_to_speech.json() == {"foo": "bar"}
+ assert isinstance(text_to_speech, AsyncBinaryAPIResponse)
- assert cast(Any, response.is_closed) is True
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_streaming_response_generate_speech(self, async_client: AsyncTelnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/text-to-speech/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"}))
+ async with async_client.text_to_speech.with_streaming_response.generate_speech(
+ text="text",
+ voice="voice",
+ ) as text_to_speech:
+ assert not text_to_speech.is_closed
+ assert text_to_speech.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert await text_to_speech.json() == {"foo": "bar"}
+ assert cast(Any, text_to_speech.is_closed) is True
+ assert isinstance(text_to_speech, AsyncStreamedBinaryAPIResponse)
-class TestAsyncTextToSpeech:
- parametrize = pytest.mark.parametrize(
- "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
- )
+ assert cast(Any, text_to_speech.is_closed) is True
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -138,45 +196,3 @@ async def test_streaming_response_list_voices(self, async_client: AsyncTelnyx) -
assert_matches_type(TextToSpeechListVoicesResponse, text_to_speech, path=["response"])
assert cast(Any, response.is_closed) is True
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_stream(self, async_client: AsyncTelnyx) -> None:
- text_to_speech = await async_client.text_to_speech.stream()
- assert text_to_speech is None
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_method_stream_with_all_params(self, async_client: AsyncTelnyx) -> None:
- text_to_speech = await async_client.text_to_speech.stream(
- audio_format="pcm",
- disable_cache=True,
- model_id="model_id",
- provider="aws",
- socket_id="socket_id",
- voice="voice",
- voice_id="voice_id",
- )
- assert text_to_speech is None
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_raw_response_stream(self, async_client: AsyncTelnyx) -> None:
- response = await async_client.text_to_speech.with_raw_response.stream()
-
- assert response.is_closed is True
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
- text_to_speech = await response.parse()
- assert text_to_speech is None
-
- @pytest.mark.skip(reason="Mock server tests are disabled")
- @parametrize
- async def test_streaming_response_stream(self, async_client: AsyncTelnyx) -> None:
- async with async_client.text_to_speech.with_streaming_response.stream() as response:
- assert not response.is_closed
- assert response.http_request.headers.get("X-Stainless-Lang") == "python"
-
- text_to_speech = await response.parse()
- assert text_to_speech is None
-
- assert cast(Any, response.is_closed) is True
From ef54d1bf9e80441af3a43b33aa0b850ec48b1750 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 26 Feb 2026 17:59:58 +0000
Subject: [PATCH 5/5] release: 4.53.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 8 ++++++++
pyproject.toml | 2 +-
src/telnyx/_version.py | 2 +-
4 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 04014e1d..9b75df70 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.52.0"
+ ".": "4.53.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55998159..169435af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 4.53.0 (2026-02-26)
+
+Full Changelog: [v4.52.0...v4.53.0](https://github.com/team-telnyx/telnyx-python/compare/v4.52.0...v4.53.0)
+
+### Features
+
+* **api:** manual updates ([f14db77](https://github.com/team-telnyx/telnyx-python/commit/f14db77cd98183ca8919771c2ba9d01c7f9dacfc))
+
## 4.52.0 (2026-02-26)
Full Changelog: [v4.51.0...v4.52.0](https://github.com/team-telnyx/telnyx-python/compare/v4.51.0...v4.52.0)
diff --git a/pyproject.toml b/pyproject.toml
index 5cefb405..08504cd6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "telnyx"
-version = "4.52.0"
+version = "4.53.0"
description = "Telnyx API SDK for global Voice, SMS, MMS, WhatsApp, Fax, Wireless IoT, SIP Trunking, and Call Control."
dynamic = ["readme"]
license = "MIT"
diff --git a/src/telnyx/_version.py b/src/telnyx/_version.py
index 4011b841..2592ed1b 100644
--- a/src/telnyx/_version.py
+++ b/src/telnyx/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "telnyx"
-__version__ = "4.52.0" # x-release-please-version
+__version__ = "4.53.0" # x-release-please-version