diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index baecb9848..28a64b708 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.179.0"
+ ".": "4.180.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 0a0068803..d0e375fdc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 1249
+configured_endpoints: 1256
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 41553a83b..4fc124d9a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [4.180.0](https://github.com/team-telnyx/telnyx-python/compare/v4.179.0...v4.180.0) (2026-09-13)
+
+
+### Features
+
+* promote from staging 938aa9b ([fb184dc](https://github.com/team-telnyx/telnyx-python/commit/fb184dc2e4b0c9abecc4aba606fd8d66b25f5e73))
+
## [4.179.0](https://github.com/team-telnyx/telnyx-python/compare/v4.178.0...v4.179.0) (2026-09-07)
diff --git a/api.md b/api.md
index 7efee71e9..e1e4fdd12 100644
--- a/api.md
+++ b/api.md
@@ -330,6 +330,8 @@ from telnyx.types import (
OutboundMessage,
ReplacedLinkClick,
Transcription,
+ WhatsappAccountUpdate,
+ WhatsappMessageEcho,
CallAIGatherEndedWebhookEvent,
CallAIGatherMessageHistoryUpdatedWebhookEvent,
CallAIGatherPartialResultsWebhookEvent,
@@ -606,6 +608,7 @@ Types:
from telnyx.types.ai import (
ArithmeticExpression,
Assistant,
+ AssistantA2AAgent,
AssistantIntegration,
AssistantMcpServer,
AssistantTool,
@@ -2790,6 +2793,7 @@ Types:
from telnyx.types import (
MessagingMessagingProfile,
MessagingProfile,
+ MessagingProfileFeatures,
NumberPoolSettings,
URLShortenerSettings,
MessagingProfileCreateResponse,
@@ -5737,6 +5741,7 @@ from telnyx.types.whatsapp import (
PhoneNumberListResponse,
PhoneNumberGetResponse,
PhoneNumberRetrieveConversationWindowResponse,
+ PhoneNumberRetrievePhoneNumberResponse,
)
```
@@ -5747,6 +5752,7 @@ Methods:
- client.whatsapp.phone_numbers.get(\*\*params) -> PhoneNumberGetResponse
- client.whatsapp.phone_numbers.resend_verification(phone_number, \*\*params) -> None
- client.whatsapp.phone_numbers.retrieve_conversation_window(phone_number, \*\*params) -> PhoneNumberRetrieveConversationWindowResponse
+- client.whatsapp.phone_numbers.retrieve_phone_number(phone_number) -> PhoneNumberRetrievePhoneNumberResponse
- client.whatsapp.phone_numbers.verify(phone_number, \*\*params) -> None
### CallingSettings
@@ -5856,8 +5862,21 @@ from telnyx.types.x402 import CreditAccountCreateQuoteResponse, CreditAccountSet
Methods:
-- client.x402.credit_account.create_quote(\*\*params) -> CreditAccountCreateQuoteResponse
-- client.x402.credit_account.settle(\*\*params) -> CreditAccountSettleResponse
+- client.x402.credit_account.create_quote(\*\*params) -> CreditAccountCreateQuoteResponse
+- client.x402.credit_account.settle(\*\*params) -> CreditAccountSettleResponse
+
+### Payments
+
+Types:
+
+```python
+from telnyx.types.x402.credit_account import X402TransactionRecord, PaymentRetrieveResponse
+```
+
+Methods:
+
+- client.x402.credit_account.payments.retrieve(id) -> PaymentRetrieveResponse
+- client.x402.credit_account.payments.list(\*\*params) -> SyncDefaultFlatPagination[X402TransactionRecord]
# VoiceClones
@@ -6787,3 +6806,27 @@ Methods:
- client.external_requirements.sub_number_orders.retrieve(sub_number_order_id, \*, regulatory_requirement_id) -> SubNumberOrderRetrieveResponse
- client.external_requirements.sub_number_orders.update(sub_number_order_id, \*, regulatory_requirement_id, \*\*params) -> SubNumberOrderUpdateResponse
+
+# Compute
+
+## Funcs
+
+Types:
+
+```python
+from telnyx.types.compute import (
+ FunctionsObservabilityPaginationMeta,
+ LogsMeta,
+ FuncRetrieveLogsResponse,
+ FuncRetrieveMetricAggregatesResponse,
+ FuncRetrieveRevisionsResponse,
+ FuncRetrieveShipInspectionResponse,
+)
+```
+
+Methods:
+
+- client.compute.funcs.retrieve_logs(id, \*\*params) -> FuncRetrieveLogsResponse
+- client.compute.funcs.retrieve_metric_aggregates(id, \*\*params) -> FuncRetrieveMetricAggregatesResponse
+- client.compute.funcs.retrieve_revisions(id, \*\*params) -> FuncRetrieveRevisionsResponse
+- client.compute.funcs.retrieve_ship_inspection(id) -> FuncRetrieveShipInspectionResponse
diff --git a/pyproject.toml b/pyproject.toml
index 17b258e1e..ab8d35410 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "telnyx"
-version = "4.179.0"
+version = "4.180.0"
description = "The official Python library for the telnyx API"
dynamic = ["readme"]
license = "MIT"
diff --git a/src/telnyx/_client.py b/src/telnyx/_client.py
index ab28b8024..11c29ae54 100644
--- a/src/telnyx/_client.py
+++ b/src/telnyx/_client.py
@@ -55,6 +55,7 @@
queues,
actions,
balance,
+ compute,
payment,
porting,
pricing,
@@ -271,6 +272,7 @@
from .resources.actions.actions import ActionsResource, AsyncActionsResource
from .resources.advanced_orders import AdvancedOrdersResource, AsyncAdvancedOrdersResource
from .resources.charges_summary import ChargesSummaryResource, AsyncChargesSummaryResource
+ from .resources.compute.compute import ComputeResource, AsyncComputeResource
from .resources.email_templates import EmailTemplatesResource, AsyncEmailTemplatesResource
from .resources.global_ip_usage import GlobalIPUsageResource, AsyncGlobalIPUsageResource
from .resources.payment.payment import PaymentResource, AsyncPaymentResource
@@ -1850,6 +1852,12 @@ def external_requirements(self) -> ExternalRequirementsResource:
return ExternalRequirementsResource(self)
+ @cached_property
+ def compute(self) -> ComputeResource:
+ from .resources.compute import ComputeResource
+
+ return ComputeResource(self)
+
@cached_property
def with_raw_response(self) -> TelnyxWithRawResponse:
return TelnyxWithRawResponse(self)
@@ -3348,6 +3356,12 @@ def external_requirements(self) -> AsyncExternalRequirementsResource:
return AsyncExternalRequirementsResource(self)
+ @cached_property
+ def compute(self) -> AsyncComputeResource:
+ from .resources.compute import AsyncComputeResource
+
+ return AsyncComputeResource(self)
+
@cached_property
def with_raw_response(self) -> AsyncTelnyxWithRawResponse:
return AsyncTelnyxWithRawResponse(self)
@@ -4782,6 +4796,12 @@ def external_requirements(self) -> external_requirements.ExternalRequirementsRes
return ExternalRequirementsResourceWithRawResponse(self._client.external_requirements)
+ @cached_property
+ def compute(self) -> compute.ComputeResourceWithRawResponse:
+ from .resources.compute import ComputeResourceWithRawResponse
+
+ return ComputeResourceWithRawResponse(self._client.compute)
+
class AsyncTelnyxWithRawResponse:
_client: AsyncTelnyx
@@ -6087,6 +6107,12 @@ def external_requirements(self) -> external_requirements.AsyncExternalRequiremen
return AsyncExternalRequirementsResourceWithRawResponse(self._client.external_requirements)
+ @cached_property
+ def compute(self) -> compute.AsyncComputeResourceWithRawResponse:
+ from .resources.compute import AsyncComputeResourceWithRawResponse
+
+ return AsyncComputeResourceWithRawResponse(self._client.compute)
+
class TelnyxWithStreamedResponse:
_client: Telnyx
@@ -7394,6 +7420,12 @@ def external_requirements(self) -> external_requirements.ExternalRequirementsRes
return ExternalRequirementsResourceWithStreamingResponse(self._client.external_requirements)
+ @cached_property
+ def compute(self) -> compute.ComputeResourceWithStreamingResponse:
+ from .resources.compute import ComputeResourceWithStreamingResponse
+
+ return ComputeResourceWithStreamingResponse(self._client.compute)
+
class AsyncTelnyxWithStreamedResponse:
_client: AsyncTelnyx
@@ -8749,6 +8781,12 @@ def external_requirements(self) -> external_requirements.AsyncExternalRequiremen
return AsyncExternalRequirementsResourceWithStreamingResponse(self._client.external_requirements)
+ @cached_property
+ def compute(self) -> compute.AsyncComputeResourceWithStreamingResponse:
+ from .resources.compute import AsyncComputeResourceWithStreamingResponse
+
+ return AsyncComputeResourceWithStreamingResponse(self._client.compute)
+
Client = Telnyx
diff --git a/src/telnyx/_version.py b/src/telnyx/_version.py
index bd4f52a53..2c5801666 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.179.0" # x-release-please-version
+__version__ = "4.180.0" # x-release-please-version
diff --git a/src/telnyx/resources/__init__.py b/src/telnyx/resources/__init__.py
index cc508b0c9..7595ed0ba 100644
--- a/src/telnyx/resources/__init__.py
+++ b/src/telnyx/resources/__init__.py
@@ -144,6 +144,14 @@
BalanceResourceWithStreamingResponse,
AsyncBalanceResourceWithStreamingResponse,
)
+from .compute import (
+ ComputeResource,
+ AsyncComputeResource,
+ ComputeResourceWithRawResponse,
+ AsyncComputeResourceWithRawResponse,
+ ComputeResourceWithStreamingResponse,
+ AsyncComputeResourceWithStreamingResponse,
+)
from .payment import (
PaymentResource,
AsyncPaymentResource,
@@ -2539,4 +2547,10 @@
"AsyncExternalRequirementsResourceWithRawResponse",
"ExternalRequirementsResourceWithStreamingResponse",
"AsyncExternalRequirementsResourceWithStreamingResponse",
+ "ComputeResource",
+ "AsyncComputeResource",
+ "ComputeResourceWithRawResponse",
+ "AsyncComputeResourceWithRawResponse",
+ "ComputeResourceWithStreamingResponse",
+ "AsyncComputeResourceWithStreamingResponse",
]
diff --git a/src/telnyx/resources/ai/assistants/assistants.py b/src/telnyx/resources/ai/assistants/assistants.py
index f83186f94..62e44f416 100644
--- a/src/telnyx/resources/ai/assistants/assistants.py
+++ b/src/telnyx/resources/ai/assistants/assistants.py
@@ -97,6 +97,7 @@
from ....types.ai.telephony_settings_param import TelephonySettingsParam
from ....types.ai.assistant_delete_response import AssistantDeleteResponse
from ....types.ai.fallback_config_req_param import FallbackConfigReqParam
+from ....types.ai.assistant_a2_a_agent_param import AssistantA2AAgentParam
from ....types.ai.assistant_mcp_server_param import AssistantMcpServerParam
from ....types.ai.assistant_integration_param import AssistantIntegrationParam
from ....types.ai.assistant_send_sms_response import AssistantSendSMSResponse
@@ -170,6 +171,7 @@ def create(
*,
instructions: str,
name: str,
+ a2a_agents: Iterable[AssistantA2AAgentParam] | Omit = omit,
conversation_flow: ConversationFlowReqParam | Omit = omit,
description: str | Omit = omit,
dynamic_variables: Dict[str, object] | Omit = omit,
@@ -212,6 +214,15 @@ def create(
instructions: System instructions for the assistant. These may be templated with
[dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables)
+ a2a_agents: A2A agents this assistant can delegate to. Tools are not stored here: at the
+ start of every conversation each agent's card is fetched and one tool is derived
+ per skill the card advertises, named `a2a__`. The following
+ limits are not enforced when the assistant is saved, and anything past them is
+ dropped when the conversation starts: 64 agents per assistant, 64 skills per
+ card, 128 derived tools per assistant, and a 6 second budget for all card
+ fetches combined. An agent whose card cannot be fetched costs the assistant that
+ capability for the conversation; it does not fail the call.
+
conversation_flow: Conversation flow as supplied by API clients (create / update).
A directed graph of `FlowNodeReq` connected by `FlowEdge`s. Validation enforces
@@ -303,6 +314,7 @@ def create(
{
"instructions": instructions,
"name": name,
+ "a2a_agents": a2a_agents,
"conversation_flow": conversation_flow,
"description": description,
"dynamic_variables": dynamic_variables,
@@ -399,6 +411,7 @@ def update(
self,
assistant_id: str,
*,
+ a2a_agents: Iterable[AssistantA2AAgentParam] | Omit = omit,
conversation_flow: ConversationFlowReqParam | Omit = omit,
description: str | Omit = omit,
dynamic_variables: Dict[str, object] | Omit = omit,
@@ -442,6 +455,16 @@ def update(
assistant versions.
Args:
+ a2a_agents: A2A agents this assistant can delegate to. Tools are not stored here: at the
+ start of every conversation each agent's card is fetched and one tool is derived
+ per skill the card advertises, named `a2a__`. The following
+ limits are not enforced when the assistant is saved, and anything past them is
+ dropped when the conversation starts: 64 agents per assistant, 64 skills per
+ card, 128 derived tools per assistant, and a 6 second budget for all card
+ fetches combined. An agent whose card cannot be fetched costs the assistant that
+ capability for the conversation; it does not fail the call. Omit this field to
+ leave the assistant's agents unchanged; send an empty array to remove them all.
+
conversation_flow: Conversation flow as supplied by API clients (create / update).
A directed graph of `FlowNodeReq` connected by `FlowEdge`s. Validation enforces
@@ -540,6 +563,7 @@ def update(
path_template("/ai/assistants/{assistant_id}", assistant_id=assistant_id),
body=maybe_transform(
{
+ "a2a_agents": a2a_agents,
"conversation_flow": conversation_flow,
"description": description,
"dynamic_variables": dynamic_variables,
@@ -944,6 +968,7 @@ async def create(
*,
instructions: str,
name: str,
+ a2a_agents: Iterable[AssistantA2AAgentParam] | Omit = omit,
conversation_flow: ConversationFlowReqParam | Omit = omit,
description: str | Omit = omit,
dynamic_variables: Dict[str, object] | Omit = omit,
@@ -986,6 +1011,15 @@ async def create(
instructions: System instructions for the assistant. These may be templated with
[dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables)
+ a2a_agents: A2A agents this assistant can delegate to. Tools are not stored here: at the
+ start of every conversation each agent's card is fetched and one tool is derived
+ per skill the card advertises, named `a2a__`. The following
+ limits are not enforced when the assistant is saved, and anything past them is
+ dropped when the conversation starts: 64 agents per assistant, 64 skills per
+ card, 128 derived tools per assistant, and a 6 second budget for all card
+ fetches combined. An agent whose card cannot be fetched costs the assistant that
+ capability for the conversation; it does not fail the call.
+
conversation_flow: Conversation flow as supplied by API clients (create / update).
A directed graph of `FlowNodeReq` connected by `FlowEdge`s. Validation enforces
@@ -1077,6 +1111,7 @@ async def create(
{
"instructions": instructions,
"name": name,
+ "a2a_agents": a2a_agents,
"conversation_flow": conversation_flow,
"description": description,
"dynamic_variables": dynamic_variables,
@@ -1173,6 +1208,7 @@ async def update(
self,
assistant_id: str,
*,
+ a2a_agents: Iterable[AssistantA2AAgentParam] | Omit = omit,
conversation_flow: ConversationFlowReqParam | Omit = omit,
description: str | Omit = omit,
dynamic_variables: Dict[str, object] | Omit = omit,
@@ -1216,6 +1252,16 @@ async def update(
assistant versions.
Args:
+ a2a_agents: A2A agents this assistant can delegate to. Tools are not stored here: at the
+ start of every conversation each agent's card is fetched and one tool is derived
+ per skill the card advertises, named `a2a__`. The following
+ limits are not enforced when the assistant is saved, and anything past them is
+ dropped when the conversation starts: 64 agents per assistant, 64 skills per
+ card, 128 derived tools per assistant, and a 6 second budget for all card
+ fetches combined. An agent whose card cannot be fetched costs the assistant that
+ capability for the conversation; it does not fail the call. Omit this field to
+ leave the assistant's agents unchanged; send an empty array to remove them all.
+
conversation_flow: Conversation flow as supplied by API clients (create / update).
A directed graph of `FlowNodeReq` connected by `FlowEdge`s. Validation enforces
@@ -1314,6 +1360,7 @@ async def update(
path_template("/ai/assistants/{assistant_id}", assistant_id=assistant_id),
body=await async_maybe_transform(
{
+ "a2a_agents": a2a_agents,
"conversation_flow": conversation_flow,
"description": description,
"dynamic_variables": dynamic_variables,
diff --git a/src/telnyx/resources/ai/assistants/versions.py b/src/telnyx/resources/ai/assistants/versions.py
index 53fe4dbbe..33af21060 100644
--- a/src/telnyx/resources/ai/assistants/versions.py
+++ b/src/telnyx/resources/ai/assistants/versions.py
@@ -31,6 +31,7 @@
from ....types.ai.messaging_settings_param import MessagingSettingsParam
from ....types.ai.telephony_settings_param import TelephonySettingsParam
from ....types.ai.fallback_config_req_param import FallbackConfigReqParam
+from ....types.ai.assistant_a2_a_agent_param import AssistantA2AAgentParam
from ....types.ai.assistant_mcp_server_param import AssistantMcpServerParam
from ....types.ai.assistant_integration_param import AssistantIntegrationParam
from ....types.ai.conversation_flow_req_param import ConversationFlowReqParam
@@ -115,6 +116,7 @@ def update(
version_id: str,
*,
assistant_id: str,
+ a2a_agents: Iterable[AssistantA2AAgentParam] | Omit = omit,
conversation_flow: ConversationFlowReqParam | Omit = omit,
description: str | Omit = omit,
dynamic_variables: Dict[str, object] | Omit = omit,
@@ -157,6 +159,16 @@ def update(
version
Args:
+ a2a_agents: A2A agents this assistant can delegate to. Tools are not stored here: at the
+ start of every conversation each agent's card is fetched and one tool is derived
+ per skill the card advertises, named `a2a__`. The following
+ limits are not enforced when the assistant is saved, and anything past them is
+ dropped when the conversation starts: 64 agents per assistant, 64 skills per
+ card, 128 derived tools per assistant, and a 6 second budget for all card
+ fetches combined. An agent whose card cannot be fetched costs the assistant that
+ capability for the conversation; it does not fail the call. Omit this field to
+ leave the assistant's agents unchanged; send an empty array to remove them all.
+
conversation_flow: Conversation flow as supplied by API clients (create / update).
A directed graph of `FlowNodeReq` connected by `FlowEdge`s. Validation enforces
@@ -256,6 +268,7 @@ def update(
),
body=maybe_transform(
{
+ "a2a_agents": a2a_agents,
"conversation_flow": conversation_flow,
"description": description,
"dynamic_variables": dynamic_variables,
@@ -486,6 +499,7 @@ async def update(
version_id: str,
*,
assistant_id: str,
+ a2a_agents: Iterable[AssistantA2AAgentParam] | Omit = omit,
conversation_flow: ConversationFlowReqParam | Omit = omit,
description: str | Omit = omit,
dynamic_variables: Dict[str, object] | Omit = omit,
@@ -528,6 +542,16 @@ async def update(
version
Args:
+ a2a_agents: A2A agents this assistant can delegate to. Tools are not stored here: at the
+ start of every conversation each agent's card is fetched and one tool is derived
+ per skill the card advertises, named `a2a__`. The following
+ limits are not enforced when the assistant is saved, and anything past them is
+ dropped when the conversation starts: 64 agents per assistant, 64 skills per
+ card, 128 derived tools per assistant, and a 6 second budget for all card
+ fetches combined. An agent whose card cannot be fetched costs the assistant that
+ capability for the conversation; it does not fail the call. Omit this field to
+ leave the assistant's agents unchanged; send an empty array to remove them all.
+
conversation_flow: Conversation flow as supplied by API clients (create / update).
A directed graph of `FlowNodeReq` connected by `FlowEdge`s. Validation enforces
@@ -627,6 +651,7 @@ async def update(
),
body=await async_maybe_transform(
{
+ "a2a_agents": a2a_agents,
"conversation_flow": conversation_flow,
"description": description,
"dynamic_variables": dynamic_variables,
diff --git a/src/telnyx/resources/ai/openai/chat.py b/src/telnyx/resources/ai/openai/chat.py
index c2ee67886..5de789c19 100644
--- a/src/telnyx/resources/ai/openai/chat.py
+++ b/src/telnyx/resources/ai/openai/chat.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import Dict, Union, Iterable
+from typing import Union, Iterable
from typing_extensions import Literal
import httpx
@@ -53,9 +53,6 @@ def create_completion(
early_stopping: bool | Omit = omit,
enable_thinking: bool | Omit = omit,
frequency_penalty: float | Omit = omit,
- guided_choice: SequenceNotStr[str] | Omit = omit,
- guided_json: Dict[str, object] | Omit = omit,
- guided_regex: str | Omit = omit,
length_penalty: float | Omit = omit,
logprobs: bool | Omit = omit,
max_tokens: int | Omit = omit,
@@ -112,13 +109,6 @@ def create_completion(
frequency_penalty: Higher values will penalize the model from repeating the same output tokens.
- guided_choice: If specified, the output will be exactly one of the choices.
-
- guided_json: Must be a valid JSON schema. If specified, the output will follow the JSON
- schema.
-
- guided_regex: If specified, the output will follow the regex pattern.
-
length_penalty: This is used with `use_beam_search` to prefer shorter or longer completions.
logprobs: Whether to return log probabilities of the output tokens or not. If true,
@@ -155,8 +145,10 @@ def create_completion(
provider never passes through Telnyx model routing, so a region cannot be
enforced for it. Omit for today's latency-based routing.
- response_format: Use this is you want to guarantee a JSON output without defining a schema. For
- control over the schema, use `guided_json`.
+ response_format: Controls the format of the model output. `json_object` guarantees valid JSON
+ output without defining a schema; `json_schema` constrains the output to the
+ JSON schema you supply via the `json_schema` property and is the supported way
+ to get guaranteed structured output on Telnyx-hosted models.
seed: If specified, the system will make a best effort to sample deterministically,
such that repeated requests with the same `seed` and parameters should return
@@ -210,9 +202,6 @@ def create_completion(
"early_stopping": early_stopping,
"enable_thinking": enable_thinking,
"frequency_penalty": frequency_penalty,
- "guided_choice": guided_choice,
- "guided_json": guided_json,
- "guided_regex": guided_regex,
"length_penalty": length_penalty,
"logprobs": logprobs,
"max_tokens": max_tokens,
@@ -273,9 +262,6 @@ async def create_completion(
early_stopping: bool | Omit = omit,
enable_thinking: bool | Omit = omit,
frequency_penalty: float | Omit = omit,
- guided_choice: SequenceNotStr[str] | Omit = omit,
- guided_json: Dict[str, object] | Omit = omit,
- guided_regex: str | Omit = omit,
length_penalty: float | Omit = omit,
logprobs: bool | Omit = omit,
max_tokens: int | Omit = omit,
@@ -332,13 +318,6 @@ async def create_completion(
frequency_penalty: Higher values will penalize the model from repeating the same output tokens.
- guided_choice: If specified, the output will be exactly one of the choices.
-
- guided_json: Must be a valid JSON schema. If specified, the output will follow the JSON
- schema.
-
- guided_regex: If specified, the output will follow the regex pattern.
-
length_penalty: This is used with `use_beam_search` to prefer shorter or longer completions.
logprobs: Whether to return log probabilities of the output tokens or not. If true,
@@ -375,8 +354,10 @@ async def create_completion(
provider never passes through Telnyx model routing, so a region cannot be
enforced for it. Omit for today's latency-based routing.
- response_format: Use this is you want to guarantee a JSON output without defining a schema. For
- control over the schema, use `guided_json`.
+ response_format: Controls the format of the model output. `json_object` guarantees valid JSON
+ output without defining a schema; `json_schema` constrains the output to the
+ JSON schema you supply via the `json_schema` property and is the supported way
+ to get guaranteed structured output on Telnyx-hosted models.
seed: If specified, the system will make a best effort to sample deterministically,
such that repeated requests with the same `seed` and parameters should return
@@ -430,9 +411,6 @@ async def create_completion(
"early_stopping": early_stopping,
"enable_thinking": enable_thinking,
"frequency_penalty": frequency_penalty,
- "guided_choice": guided_choice,
- "guided_json": guided_json,
- "guided_regex": guided_regex,
"length_penalty": length_penalty,
"logprobs": logprobs,
"max_tokens": max_tokens,
diff --git a/src/telnyx/resources/compute/__init__.py b/src/telnyx/resources/compute/__init__.py
new file mode 100644
index 000000000..d3f382ac7
--- /dev/null
+++ b/src/telnyx/resources/compute/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .funcs import (
+ FuncsResource,
+ AsyncFuncsResource,
+ FuncsResourceWithRawResponse,
+ AsyncFuncsResourceWithRawResponse,
+ FuncsResourceWithStreamingResponse,
+ AsyncFuncsResourceWithStreamingResponse,
+)
+from .compute import (
+ ComputeResource,
+ AsyncComputeResource,
+ ComputeResourceWithRawResponse,
+ AsyncComputeResourceWithRawResponse,
+ ComputeResourceWithStreamingResponse,
+ AsyncComputeResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "FuncsResource",
+ "AsyncFuncsResource",
+ "FuncsResourceWithRawResponse",
+ "AsyncFuncsResourceWithRawResponse",
+ "FuncsResourceWithStreamingResponse",
+ "AsyncFuncsResourceWithStreamingResponse",
+ "ComputeResource",
+ "AsyncComputeResource",
+ "ComputeResourceWithRawResponse",
+ "AsyncComputeResourceWithRawResponse",
+ "ComputeResourceWithStreamingResponse",
+ "AsyncComputeResourceWithStreamingResponse",
+]
diff --git a/src/telnyx/resources/compute/compute.py b/src/telnyx/resources/compute/compute.py
new file mode 100644
index 000000000..5a77c3552
--- /dev/null
+++ b/src/telnyx/resources/compute/compute.py
@@ -0,0 +1,102 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .funcs import (
+ FuncsResource,
+ AsyncFuncsResource,
+ FuncsResourceWithRawResponse,
+ AsyncFuncsResourceWithRawResponse,
+ FuncsResourceWithStreamingResponse,
+ AsyncFuncsResourceWithStreamingResponse,
+)
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+
+__all__ = ["ComputeResource", "AsyncComputeResource"]
+
+
+class ComputeResource(SyncAPIResource):
+ @cached_property
+ def funcs(self) -> FuncsResource:
+ return FuncsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> ComputeResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#accessing-raw-response-data-eg-headers
+ """
+ return ComputeResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> ComputeResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#with_streaming_response
+ """
+ return ComputeResourceWithStreamingResponse(self)
+
+
+class AsyncComputeResource(AsyncAPIResource):
+ @cached_property
+ def funcs(self) -> AsyncFuncsResource:
+ return AsyncFuncsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncComputeResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncComputeResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncComputeResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#with_streaming_response
+ """
+ return AsyncComputeResourceWithStreamingResponse(self)
+
+
+class ComputeResourceWithRawResponse:
+ def __init__(self, compute: ComputeResource) -> None:
+ self._compute = compute
+
+ @cached_property
+ def funcs(self) -> FuncsResourceWithRawResponse:
+ return FuncsResourceWithRawResponse(self._compute.funcs)
+
+
+class AsyncComputeResourceWithRawResponse:
+ def __init__(self, compute: AsyncComputeResource) -> None:
+ self._compute = compute
+
+ @cached_property
+ def funcs(self) -> AsyncFuncsResourceWithRawResponse:
+ return AsyncFuncsResourceWithRawResponse(self._compute.funcs)
+
+
+class ComputeResourceWithStreamingResponse:
+ def __init__(self, compute: ComputeResource) -> None:
+ self._compute = compute
+
+ @cached_property
+ def funcs(self) -> FuncsResourceWithStreamingResponse:
+ return FuncsResourceWithStreamingResponse(self._compute.funcs)
+
+
+class AsyncComputeResourceWithStreamingResponse:
+ def __init__(self, compute: AsyncComputeResource) -> None:
+ self._compute = compute
+
+ @cached_property
+ def funcs(self) -> AsyncFuncsResourceWithStreamingResponse:
+ return AsyncFuncsResourceWithStreamingResponse(self._compute.funcs)
diff --git a/src/telnyx/resources/compute/funcs.py b/src/telnyx/resources/compute/funcs.py
new file mode 100644
index 000000000..512b8839d
--- /dev/null
+++ b/src/telnyx/resources/compute/funcs.py
@@ -0,0 +1,566 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Any, Union, cast
+from datetime import datetime
+from typing_extensions import Literal
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import path_template, maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.compute import (
+ func_retrieve_logs_params,
+ func_retrieve_revisions_params,
+ func_retrieve_metric_aggregates_params,
+)
+from ...types.compute.func_retrieve_logs_response import FuncRetrieveLogsResponse
+from ...types.compute.func_retrieve_revisions_response import FuncRetrieveRevisionsResponse
+from ...types.compute.func_retrieve_ship_inspection_response import FuncRetrieveShipInspectionResponse
+from ...types.compute.func_retrieve_metric_aggregates_response import FuncRetrieveMetricAggregatesResponse
+
+__all__ = ["FuncsResource", "AsyncFuncsResource"]
+
+
+class FuncsResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> FuncsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#accessing-raw-response-data-eg-headers
+ """
+ return FuncsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> FuncsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#with_streaming_response
+ """
+ return FuncsResourceWithStreamingResponse(self)
+
+ def retrieve_logs(
+ self,
+ id: str,
+ *,
+ end_time: Union[str, datetime] | Omit = omit,
+ limit: int | Omit = omit,
+ start_time: Union[str, datetime] | Omit = omit,
+ type: Literal["runtime", "invocations"] | 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,
+ ) -> FuncRetrieveLogsResponse:
+ """Returns logs oldest first.
+
+ `type=runtime` (default) returns function
+ stdout/stderr. `type=invocations` returns one platform-generated record per HTTP
+ request served.
+
+ Args:
+ end_time: Return records at or before this RFC 3339 timestamp.
+
+ limit: Maximum records to return.
+
+ start_time: Return records at or after this RFC 3339 timestamp.
+
+ type: Log stream to return.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return cast(
+ FuncRetrieveLogsResponse,
+ self._get(
+ path_template("/compute/funcs/{id}/logs", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "end_time": end_time,
+ "limit": limit,
+ "start_time": start_time,
+ "type": type,
+ },
+ func_retrieve_logs_params.FuncRetrieveLogsParams,
+ ),
+ ),
+ cast_to=cast(
+ Any, FuncRetrieveLogsResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ def retrieve_metric_aggregates(
+ self,
+ id: str,
+ *,
+ end_time: Union[str, datetime],
+ start_time: Union[str, datetime],
+ filter_edge_site: str | Omit = omit,
+ filter_namespace: str | Omit = omit,
+ page_number: int | Omit = omit,
+ page_size: int | 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,
+ ) -> FuncRetrieveMetricAggregatesResponse:
+ """
+ Returns aggregate request, latency, CPU, memory, and resource-limit metrics for
+ a function over the requested window.
+
+ Args:
+ end_time: Exclusive window end, UTC ISO 8601 with milliseconds
+
+ start_time: Inclusive window start, UTC ISO 8601 with milliseconds
+
+ filter_edge_site: Edge site filter
+
+ filter_namespace: Kubernetes namespace filter
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ path_template("/compute/funcs/{id}/metric_aggregates", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "end_time": end_time,
+ "start_time": start_time,
+ "filter_edge_site": filter_edge_site,
+ "filter_namespace": filter_namespace,
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ func_retrieve_metric_aggregates_params.FuncRetrieveMetricAggregatesParams,
+ ),
+ ),
+ cast_to=FuncRetrieveMetricAggregatesResponse,
+ )
+
+ def retrieve_revisions(
+ self,
+ id: str,
+ *,
+ page_number: int | Omit = omit,
+ page_size: int | 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,
+ ) -> FuncRetrieveRevisionsResponse:
+ """
+ Lists a function's ship history newest first, including per-ship failure stage
+ and reason when recorded.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ path_template("/compute/funcs/{id}/revisions", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ func_retrieve_revisions_params.FuncRetrieveRevisionsParams,
+ ),
+ ),
+ cast_to=FuncRetrieveRevisionsResponse,
+ )
+
+ def retrieve_ship_inspection(
+ self,
+ id: 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,
+ ) -> FuncRetrieveShipInspectionResponse:
+ """Returns the latest ship outcome.
+
+ The stage is `none` on success, `pending` while
+ building, or a failure stage such as `build`, `platform`, `pre_build`, `deploy`,
+ or `security_review`. This stage-neutral customer-facing path is an alias over
+ the same inspection resource as `build_log_inspection`.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ path_template("/compute/funcs/{id}/ship_inspection", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=FuncRetrieveShipInspectionResponse,
+ )
+
+
+class AsyncFuncsResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncFuncsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncFuncsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncFuncsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#with_streaming_response
+ """
+ return AsyncFuncsResourceWithStreamingResponse(self)
+
+ async def retrieve_logs(
+ self,
+ id: str,
+ *,
+ end_time: Union[str, datetime] | Omit = omit,
+ limit: int | Omit = omit,
+ start_time: Union[str, datetime] | Omit = omit,
+ type: Literal["runtime", "invocations"] | 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,
+ ) -> FuncRetrieveLogsResponse:
+ """Returns logs oldest first.
+
+ `type=runtime` (default) returns function
+ stdout/stderr. `type=invocations` returns one platform-generated record per HTTP
+ request served.
+
+ Args:
+ end_time: Return records at or before this RFC 3339 timestamp.
+
+ limit: Maximum records to return.
+
+ start_time: Return records at or after this RFC 3339 timestamp.
+
+ type: Log stream to return.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return cast(
+ FuncRetrieveLogsResponse,
+ await self._get(
+ path_template("/compute/funcs/{id}/logs", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "end_time": end_time,
+ "limit": limit,
+ "start_time": start_time,
+ "type": type,
+ },
+ func_retrieve_logs_params.FuncRetrieveLogsParams,
+ ),
+ ),
+ cast_to=cast(
+ Any, FuncRetrieveLogsResponse
+ ), # Union types cannot be passed in as arguments in the type system
+ ),
+ )
+
+ async def retrieve_metric_aggregates(
+ self,
+ id: str,
+ *,
+ end_time: Union[str, datetime],
+ start_time: Union[str, datetime],
+ filter_edge_site: str | Omit = omit,
+ filter_namespace: str | Omit = omit,
+ page_number: int | Omit = omit,
+ page_size: int | 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,
+ ) -> FuncRetrieveMetricAggregatesResponse:
+ """
+ Returns aggregate request, latency, CPU, memory, and resource-limit metrics for
+ a function over the requested window.
+
+ Args:
+ end_time: Exclusive window end, UTC ISO 8601 with milliseconds
+
+ start_time: Inclusive window start, UTC ISO 8601 with milliseconds
+
+ filter_edge_site: Edge site filter
+
+ filter_namespace: Kubernetes namespace filter
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ path_template("/compute/funcs/{id}/metric_aggregates", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "end_time": end_time,
+ "start_time": start_time,
+ "filter_edge_site": filter_edge_site,
+ "filter_namespace": filter_namespace,
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ func_retrieve_metric_aggregates_params.FuncRetrieveMetricAggregatesParams,
+ ),
+ ),
+ cast_to=FuncRetrieveMetricAggregatesResponse,
+ )
+
+ async def retrieve_revisions(
+ self,
+ id: str,
+ *,
+ page_number: int | Omit = omit,
+ page_size: int | 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,
+ ) -> FuncRetrieveRevisionsResponse:
+ """
+ Lists a function's ship history newest first, including per-ship failure stage
+ and reason when recorded.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ path_template("/compute/funcs/{id}/revisions", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ func_retrieve_revisions_params.FuncRetrieveRevisionsParams,
+ ),
+ ),
+ cast_to=FuncRetrieveRevisionsResponse,
+ )
+
+ async def retrieve_ship_inspection(
+ self,
+ id: 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,
+ ) -> FuncRetrieveShipInspectionResponse:
+ """Returns the latest ship outcome.
+
+ The stage is `none` on success, `pending` while
+ building, or a failure stage such as `build`, `platform`, `pre_build`, `deploy`,
+ or `security_review`. This stage-neutral customer-facing path is an alias over
+ the same inspection resource as `build_log_inspection`.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ path_template("/compute/funcs/{id}/ship_inspection", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=FuncRetrieveShipInspectionResponse,
+ )
+
+
+class FuncsResourceWithRawResponse:
+ def __init__(self, funcs: FuncsResource) -> None:
+ self._funcs = funcs
+
+ self.retrieve_logs = to_raw_response_wrapper(
+ funcs.retrieve_logs,
+ )
+ self.retrieve_metric_aggregates = to_raw_response_wrapper(
+ funcs.retrieve_metric_aggregates,
+ )
+ self.retrieve_revisions = to_raw_response_wrapper(
+ funcs.retrieve_revisions,
+ )
+ self.retrieve_ship_inspection = to_raw_response_wrapper(
+ funcs.retrieve_ship_inspection,
+ )
+
+
+class AsyncFuncsResourceWithRawResponse:
+ def __init__(self, funcs: AsyncFuncsResource) -> None:
+ self._funcs = funcs
+
+ self.retrieve_logs = async_to_raw_response_wrapper(
+ funcs.retrieve_logs,
+ )
+ self.retrieve_metric_aggregates = async_to_raw_response_wrapper(
+ funcs.retrieve_metric_aggregates,
+ )
+ self.retrieve_revisions = async_to_raw_response_wrapper(
+ funcs.retrieve_revisions,
+ )
+ self.retrieve_ship_inspection = async_to_raw_response_wrapper(
+ funcs.retrieve_ship_inspection,
+ )
+
+
+class FuncsResourceWithStreamingResponse:
+ def __init__(self, funcs: FuncsResource) -> None:
+ self._funcs = funcs
+
+ self.retrieve_logs = to_streamed_response_wrapper(
+ funcs.retrieve_logs,
+ )
+ self.retrieve_metric_aggregates = to_streamed_response_wrapper(
+ funcs.retrieve_metric_aggregates,
+ )
+ self.retrieve_revisions = to_streamed_response_wrapper(
+ funcs.retrieve_revisions,
+ )
+ self.retrieve_ship_inspection = to_streamed_response_wrapper(
+ funcs.retrieve_ship_inspection,
+ )
+
+
+class AsyncFuncsResourceWithStreamingResponse:
+ def __init__(self, funcs: AsyncFuncsResource) -> None:
+ self._funcs = funcs
+
+ self.retrieve_logs = async_to_streamed_response_wrapper(
+ funcs.retrieve_logs,
+ )
+ self.retrieve_metric_aggregates = async_to_streamed_response_wrapper(
+ funcs.retrieve_metric_aggregates,
+ )
+ self.retrieve_revisions = async_to_streamed_response_wrapper(
+ funcs.retrieve_revisions,
+ )
+ self.retrieve_ship_inspection = async_to_streamed_response_wrapper(
+ funcs.retrieve_ship_inspection,
+ )
diff --git a/src/telnyx/resources/email_messages/email_messages.py b/src/telnyx/resources/email_messages/email_messages.py
index 41a7d1549..c8d444293 100644
--- a/src/telnyx/resources/email_messages/email_messages.py
+++ b/src/telnyx/resources/email_messages/email_messages.py
@@ -382,10 +382,17 @@ def batch(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> EmailMessageBatchResponse:
- """
- Creates up to 50 email messages in a single request.
+ """Creates up to 1,000 email messages in a single request.
+
+ Each message is
+ validated and sent independently; per-message failures do not affect other
+ messages in the batch. All responses use 207 Multi-Status.
Args:
+ messages: Array of email messages to send. Up to 1,000 messages per batch request. Each
+ message is validated and sent independently; per-message failures do not affect
+ other messages in the batch.
+
sandbox_mode: Applies sandbox mode to all messages in the batch. Overrides any per-message
sandbox_mode in the messages array.
@@ -882,10 +889,17 @@ async def batch(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> EmailMessageBatchResponse:
- """
- Creates up to 50 email messages in a single request.
+ """Creates up to 1,000 email messages in a single request.
+
+ Each message is
+ validated and sent independently; per-message failures do not affect other
+ messages in the batch. All responses use 207 Multi-Status.
Args:
+ messages: Array of email messages to send. Up to 1,000 messages per batch request. Each
+ message is validated and sent independently; per-message failures do not affect
+ other messages in the batch.
+
sandbox_mode: Applies sandbox mode to all messages in the batch. Overrides any per-message
sandbox_mode in the messages array.
diff --git a/src/telnyx/resources/messaging_profiles/messaging_profiles.py b/src/telnyx/resources/messaging_profiles/messaging_profiles.py
index f3d1e2cc0..f92aebf80 100644
--- a/src/telnyx/resources/messaging_profiles/messaging_profiles.py
+++ b/src/telnyx/resources/messaging_profiles/messaging_profiles.py
@@ -51,6 +51,7 @@
from ...types.messaging_messaging_profile import MessagingMessagingProfile
from ...types.messaging_metrics_time_frame import MessagingMetricsTimeFrame
from ...types.url_shortener_settings_param import URLShortenerSettingsParam
+from ...types.messaging_profile_features_param import MessagingProfileFeaturesParam
from ...types.messaging_profile_create_response import MessagingProfileCreateResponse
from ...types.messaging_profile_delete_response import MessagingProfileDeleteResponse
from ...types.messaging_profile_update_response import MessagingProfileUpdateResponse
@@ -100,6 +101,7 @@ def create(
daily_spend_limit: str | Omit = omit,
daily_spend_limit_enabled: bool | Omit = omit,
enabled: bool | Omit = omit,
+ features: Optional[MessagingProfileFeaturesParam] | Omit = omit,
health_webhook_url: Optional[str] | Omit = omit,
mms_fall_back_to_sms: bool | Omit = omit,
mms_transcoding: bool | Omit = omit,
@@ -141,6 +143,10 @@ def create(
enabled: Specifies whether the messaging profile is enabled or not.
+ features: Telnyx product features the messaging customer can enable on the messaging
+ profile. Keys map to individual feature flags; unknown keys are accepted and
+ preserved for forward compatibility with rolling deployments.
+
health_webhook_url: A URL to receive health check webhooks for numbers in this profile.
mms_fall_back_to_sms: enables SMS fallback for MMS messages.
@@ -196,6 +202,7 @@ def create(
"daily_spend_limit": daily_spend_limit,
"daily_spend_limit_enabled": daily_spend_limit_enabled,
"enabled": enabled,
+ "features": features,
"health_webhook_url": health_webhook_url,
"mms_fall_back_to_sms": mms_fall_back_to_sms,
"mms_transcoding": mms_transcoding,
@@ -261,6 +268,7 @@ def update(
daily_spend_limit: str | Omit = omit,
daily_spend_limit_enabled: bool | Omit = omit,
enabled: bool | Omit = omit,
+ features: Optional[MessagingProfileFeaturesParam] | Omit = omit,
mms_fall_back_to_sms: bool | Omit = omit,
mms_transcoding: bool | Omit = omit,
mobile_only: bool | Omit = omit,
@@ -300,6 +308,10 @@ def update(
enabled: Specifies whether the messaging profile is enabled or not.
+ features: Telnyx product features the messaging customer can enable on the messaging
+ profile. Keys map to individual feature flags; unknown keys are accepted and
+ preserved for forward compatibility with rolling deployments.
+
mms_fall_back_to_sms: enables SMS fallback for MMS messages.
mms_transcoding: enables automated resizing of MMS media.
@@ -372,6 +384,7 @@ def update(
"daily_spend_limit": daily_spend_limit,
"daily_spend_limit_enabled": daily_spend_limit_enabled,
"enabled": enabled,
+ "features": features,
"mms_fall_back_to_sms": mms_fall_back_to_sms,
"mms_transcoding": mms_transcoding,
"mobile_only": mobile_only,
@@ -724,6 +737,7 @@ async def create(
daily_spend_limit: str | Omit = omit,
daily_spend_limit_enabled: bool | Omit = omit,
enabled: bool | Omit = omit,
+ features: Optional[MessagingProfileFeaturesParam] | Omit = omit,
health_webhook_url: Optional[str] | Omit = omit,
mms_fall_back_to_sms: bool | Omit = omit,
mms_transcoding: bool | Omit = omit,
@@ -765,6 +779,10 @@ async def create(
enabled: Specifies whether the messaging profile is enabled or not.
+ features: Telnyx product features the messaging customer can enable on the messaging
+ profile. Keys map to individual feature flags; unknown keys are accepted and
+ preserved for forward compatibility with rolling deployments.
+
health_webhook_url: A URL to receive health check webhooks for numbers in this profile.
mms_fall_back_to_sms: enables SMS fallback for MMS messages.
@@ -820,6 +838,7 @@ async def create(
"daily_spend_limit": daily_spend_limit,
"daily_spend_limit_enabled": daily_spend_limit_enabled,
"enabled": enabled,
+ "features": features,
"health_webhook_url": health_webhook_url,
"mms_fall_back_to_sms": mms_fall_back_to_sms,
"mms_transcoding": mms_transcoding,
@@ -885,6 +904,7 @@ async def update(
daily_spend_limit: str | Omit = omit,
daily_spend_limit_enabled: bool | Omit = omit,
enabled: bool | Omit = omit,
+ features: Optional[MessagingProfileFeaturesParam] | Omit = omit,
mms_fall_back_to_sms: bool | Omit = omit,
mms_transcoding: bool | Omit = omit,
mobile_only: bool | Omit = omit,
@@ -924,6 +944,10 @@ async def update(
enabled: Specifies whether the messaging profile is enabled or not.
+ features: Telnyx product features the messaging customer can enable on the messaging
+ profile. Keys map to individual feature flags; unknown keys are accepted and
+ preserved for forward compatibility with rolling deployments.
+
mms_fall_back_to_sms: enables SMS fallback for MMS messages.
mms_transcoding: enables automated resizing of MMS media.
@@ -996,6 +1020,7 @@ async def update(
"daily_spend_limit": daily_spend_limit,
"daily_spend_limit_enabled": daily_spend_limit_enabled,
"enabled": enabled,
+ "features": features,
"mms_fall_back_to_sms": mms_fall_back_to_sms,
"mms_transcoding": mms_transcoding,
"mobile_only": mobile_only,
diff --git a/src/telnyx/resources/whatsapp/phone_numbers/phone_numbers.py b/src/telnyx/resources/whatsapp/phone_numbers/phone_numbers.py
index 4f57df715..08a1c24ac 100644
--- a/src/telnyx/resources/whatsapp/phone_numbers/phone_numbers.py
+++ b/src/telnyx/resources/whatsapp/phone_numbers/phone_numbers.py
@@ -51,6 +51,7 @@
)
from ....types.whatsapp.phone_number_get_response import PhoneNumberGetResponse
from ....types.whatsapp.phone_number_list_response import PhoneNumberListResponse
+from ....types.whatsapp.phone_number_retrieve_phone_number_response import PhoneNumberRetrievePhoneNumberResponse
from ....types.whatsapp.phone_number_retrieve_conversation_window_response import (
PhoneNumberRetrieveConversationWindowResponse,
)
@@ -298,6 +299,41 @@ def retrieve_conversation_window(
cast_to=PhoneNumberRetrieveConversationWindowResponse,
)
+ def retrieve_phone_number(
+ self,
+ phone_number: 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,
+ ) -> PhoneNumberRetrievePhoneNumberResponse:
+ """
+ Returns one WhatsApp phone number linked to the authenticated Telnyx account.
+ For a coexistence number in the `syncing` state, the response includes
+ `sync_progress`.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not phone_number:
+ raise ValueError(f"Expected a non-empty value for `phone_number` but received {phone_number!r}")
+ return self._get(
+ path_template("/whatsapp/phone_numbers/{phone_number}", phone_number=phone_number),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PhoneNumberRetrievePhoneNumberResponse,
+ )
+
def verify(
self,
phone_number: str,
@@ -575,6 +611,41 @@ async def retrieve_conversation_window(
cast_to=PhoneNumberRetrieveConversationWindowResponse,
)
+ async def retrieve_phone_number(
+ self,
+ phone_number: 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,
+ ) -> PhoneNumberRetrievePhoneNumberResponse:
+ """
+ Returns one WhatsApp phone number linked to the authenticated Telnyx account.
+ For a coexistence number in the `syncing` state, the response includes
+ `sync_progress`.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not phone_number:
+ raise ValueError(f"Expected a non-empty value for `phone_number` but received {phone_number!r}")
+ return await self._get(
+ path_template("/whatsapp/phone_numbers/{phone_number}", phone_number=phone_number),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PhoneNumberRetrievePhoneNumberResponse,
+ )
+
async def verify(
self,
phone_number: str,
@@ -631,6 +702,9 @@ def __init__(self, phone_numbers: PhoneNumbersResource) -> None:
self.retrieve_conversation_window = to_raw_response_wrapper(
phone_numbers.retrieve_conversation_window,
)
+ self.retrieve_phone_number = to_raw_response_wrapper(
+ phone_numbers.retrieve_phone_number,
+ )
self.verify = to_raw_response_wrapper(
phone_numbers.verify,
)
@@ -670,6 +744,9 @@ def __init__(self, phone_numbers: AsyncPhoneNumbersResource) -> None:
self.retrieve_conversation_window = async_to_raw_response_wrapper(
phone_numbers.retrieve_conversation_window,
)
+ self.retrieve_phone_number = async_to_raw_response_wrapper(
+ phone_numbers.retrieve_phone_number,
+ )
self.verify = async_to_raw_response_wrapper(
phone_numbers.verify,
)
@@ -709,6 +786,9 @@ def __init__(self, phone_numbers: PhoneNumbersResource) -> None:
self.retrieve_conversation_window = to_streamed_response_wrapper(
phone_numbers.retrieve_conversation_window,
)
+ self.retrieve_phone_number = to_streamed_response_wrapper(
+ phone_numbers.retrieve_phone_number,
+ )
self.verify = to_streamed_response_wrapper(
phone_numbers.verify,
)
@@ -748,6 +828,9 @@ def __init__(self, phone_numbers: AsyncPhoneNumbersResource) -> None:
self.retrieve_conversation_window = async_to_streamed_response_wrapper(
phone_numbers.retrieve_conversation_window,
)
+ self.retrieve_phone_number = async_to_streamed_response_wrapper(
+ phone_numbers.retrieve_phone_number,
+ )
self.verify = async_to_streamed_response_wrapper(
phone_numbers.verify,
)
diff --git a/src/telnyx/resources/x402/credit_account/__init__.py b/src/telnyx/resources/x402/credit_account/__init__.py
new file mode 100644
index 000000000..2bfff4bb2
--- /dev/null
+++ b/src/telnyx/resources/x402/credit_account/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .payments import (
+ PaymentsResource,
+ AsyncPaymentsResource,
+ PaymentsResourceWithRawResponse,
+ AsyncPaymentsResourceWithRawResponse,
+ PaymentsResourceWithStreamingResponse,
+ AsyncPaymentsResourceWithStreamingResponse,
+)
+from .credit_account import (
+ CreditAccountResource,
+ AsyncCreditAccountResource,
+ CreditAccountResourceWithRawResponse,
+ AsyncCreditAccountResourceWithRawResponse,
+ CreditAccountResourceWithStreamingResponse,
+ AsyncCreditAccountResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "PaymentsResource",
+ "AsyncPaymentsResource",
+ "PaymentsResourceWithRawResponse",
+ "AsyncPaymentsResourceWithRawResponse",
+ "PaymentsResourceWithStreamingResponse",
+ "AsyncPaymentsResourceWithStreamingResponse",
+ "CreditAccountResource",
+ "AsyncCreditAccountResource",
+ "CreditAccountResourceWithRawResponse",
+ "AsyncCreditAccountResourceWithRawResponse",
+ "CreditAccountResourceWithStreamingResponse",
+ "AsyncCreditAccountResourceWithStreamingResponse",
+]
diff --git a/src/telnyx/resources/x402/credit_account.py b/src/telnyx/resources/x402/credit_account/credit_account.py
similarity index 79%
rename from src/telnyx/resources/x402/credit_account.py
rename to src/telnyx/resources/x402/credit_account/credit_account.py
index 21c3256d3..0d4926905 100644
--- a/src/telnyx/resources/x402/credit_account.py
+++ b/src/telnyx/resources/x402/credit_account/credit_account.py
@@ -4,20 +4,28 @@
import httpx
-from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
-from ..._utils import maybe_transform, strip_not_given, async_maybe_transform
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
+from .payments import (
+ PaymentsResource,
+ AsyncPaymentsResource,
+ PaymentsResourceWithRawResponse,
+ AsyncPaymentsResourceWithRawResponse,
+ PaymentsResourceWithStreamingResponse,
+ AsyncPaymentsResourceWithStreamingResponse,
+)
+from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ...._utils import maybe_transform, strip_not_given, async_maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ...types.x402 import credit_account_settle_params, credit_account_create_quote_params
-from ..._base_client import make_request_options
-from ...types.x402.credit_account_settle_response import CreditAccountSettleResponse
-from ...types.x402.credit_account_create_quote_response import CreditAccountCreateQuoteResponse
+from ....types.x402 import credit_account_settle_params, credit_account_create_quote_params
+from ...._base_client import make_request_options
+from ....types.x402.credit_account_settle_response import CreditAccountSettleResponse
+from ....types.x402.credit_account_create_quote_response import CreditAccountCreateQuoteResponse
__all__ = ["CreditAccountResource", "AsyncCreditAccountResource"]
@@ -28,6 +36,14 @@ class CreditAccountResource(SyncAPIResource):
Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
"""
+ @cached_property
+ def payments(self) -> PaymentsResource:
+ """Operations for x402 cryptocurrency payment transactions.
+
+ Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
+ """
+ return PaymentsResource(self._client)
+
@cached_property
def with_raw_response(self) -> CreditAccountResourceWithRawResponse:
"""
@@ -76,7 +92,7 @@ def create_quote(
timeout: Override the client-level default timeout for this request, in seconds
"""
return self._post(
- "/v2/x402/credit_account/quote",
+ "/x402/credit_account/quote",
body=maybe_transform(
{"amount_usd": amount_usd}, credit_account_create_quote_params.CreditAccountCreateQuoteParams
),
@@ -121,7 +137,7 @@ def settle(
"""
extra_headers = {**strip_not_given({"PAYMENT-SIGNATURE": header_payment_signature}), **(extra_headers or {})}
return self._post(
- "/v2/x402/credit_account",
+ "/x402/credit_account",
body=maybe_transform(
{
"id": id,
@@ -142,6 +158,14 @@ class AsyncCreditAccountResource(AsyncAPIResource):
Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
"""
+ @cached_property
+ def payments(self) -> AsyncPaymentsResource:
+ """Operations for x402 cryptocurrency payment transactions.
+
+ Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
+ """
+ return AsyncPaymentsResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncCreditAccountResourceWithRawResponse:
"""
@@ -190,7 +214,7 @@ async def create_quote(
timeout: Override the client-level default timeout for this request, in seconds
"""
return await self._post(
- "/v2/x402/credit_account/quote",
+ "/x402/credit_account/quote",
body=await async_maybe_transform(
{"amount_usd": amount_usd}, credit_account_create_quote_params.CreditAccountCreateQuoteParams
),
@@ -235,7 +259,7 @@ async def settle(
"""
extra_headers = {**strip_not_given({"PAYMENT-SIGNATURE": header_payment_signature}), **(extra_headers or {})}
return await self._post(
- "/v2/x402/credit_account",
+ "/x402/credit_account",
body=await async_maybe_transform(
{
"id": id,
@@ -261,6 +285,14 @@ def __init__(self, credit_account: CreditAccountResource) -> None:
credit_account.settle,
)
+ @cached_property
+ def payments(self) -> PaymentsResourceWithRawResponse:
+ """Operations for x402 cryptocurrency payment transactions.
+
+ Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
+ """
+ return PaymentsResourceWithRawResponse(self._credit_account.payments)
+
class AsyncCreditAccountResourceWithRawResponse:
def __init__(self, credit_account: AsyncCreditAccountResource) -> None:
@@ -273,6 +305,14 @@ def __init__(self, credit_account: AsyncCreditAccountResource) -> None:
credit_account.settle,
)
+ @cached_property
+ def payments(self) -> AsyncPaymentsResourceWithRawResponse:
+ """Operations for x402 cryptocurrency payment transactions.
+
+ Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
+ """
+ return AsyncPaymentsResourceWithRawResponse(self._credit_account.payments)
+
class CreditAccountResourceWithStreamingResponse:
def __init__(self, credit_account: CreditAccountResource) -> None:
@@ -285,6 +325,14 @@ def __init__(self, credit_account: CreditAccountResource) -> None:
credit_account.settle,
)
+ @cached_property
+ def payments(self) -> PaymentsResourceWithStreamingResponse:
+ """Operations for x402 cryptocurrency payment transactions.
+
+ Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
+ """
+ return PaymentsResourceWithStreamingResponse(self._credit_account.payments)
+
class AsyncCreditAccountResourceWithStreamingResponse:
def __init__(self, credit_account: AsyncCreditAccountResource) -> None:
@@ -296,3 +344,11 @@ def __init__(self, credit_account: AsyncCreditAccountResource) -> None:
self.settle = async_to_streamed_response_wrapper(
credit_account.settle,
)
+
+ @cached_property
+ def payments(self) -> AsyncPaymentsResourceWithStreamingResponse:
+ """Operations for x402 cryptocurrency payment transactions.
+
+ Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
+ """
+ return AsyncPaymentsResourceWithStreamingResponse(self._credit_account.payments)
diff --git a/src/telnyx/resources/x402/credit_account/payments.py b/src/telnyx/resources/x402/credit_account/payments.py
new file mode 100644
index 000000000..5d4528fb5
--- /dev/null
+++ b/src/telnyx/resources/x402/credit_account/payments.py
@@ -0,0 +1,295 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ...._utils import path_template, maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ....pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.x402.credit_account import payment_list_params
+from ....types.x402.credit_account.x402_transaction_record import X402TransactionRecord
+from ....types.x402.credit_account.payment_retrieve_response import PaymentRetrieveResponse
+
+__all__ = ["PaymentsResource", "AsyncPaymentsResource"]
+
+
+class PaymentsResource(SyncAPIResource):
+ """Operations for x402 cryptocurrency payment transactions.
+
+ Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> PaymentsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#accessing-raw-response-data-eg-headers
+ """
+ return PaymentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> PaymentsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#with_streaming_response
+ """
+ return PaymentsResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ id: 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,
+ ) -> PaymentRetrieveResponse:
+ """Returns a single x402 payment transaction by ID.
+
+ The transaction must belong to
+ the authenticated user; organization sub-users must have read permission on
+ transactions. Returns 404 if the transaction does not exist or belongs to
+ another user.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._get(
+ path_template("/x402/credit_account/payments/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PaymentRetrieveResponse,
+ )
+
+ def list(
+ self,
+ *,
+ page_number: int | Omit = omit,
+ page_size: int | 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,
+ ) -> SyncDefaultFlatPagination[X402TransactionRecord]:
+ """
+ Returns a paginated list of the authenticated user's x402 payment transactions,
+ newest first. Organization sub-users must have read permission on transactions;
+ without it the list is empty.
+
+ Args:
+ page_number: The page number to load.
+
+ page_size: The size of the page.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get_api_list(
+ "/x402/credit_account/payments",
+ page=SyncDefaultFlatPagination[X402TransactionRecord],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ payment_list_params.PaymentListParams,
+ ),
+ ),
+ model=X402TransactionRecord,
+ )
+
+
+class AsyncPaymentsResource(AsyncAPIResource):
+ """Operations for x402 cryptocurrency payment transactions.
+
+ Fund your Telnyx account using USDC stablecoin payments via the x402 protocol.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncPaymentsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncPaymentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncPaymentsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/team-telnyx/telnyx-python#with_streaming_response
+ """
+ return AsyncPaymentsResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ id: 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,
+ ) -> PaymentRetrieveResponse:
+ """Returns a single x402 payment transaction by ID.
+
+ The transaction must belong to
+ the authenticated user; organization sub-users must have read permission on
+ transactions. Returns 404 if the transaction does not exist or belongs to
+ another user.
+
+ Args:
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._get(
+ path_template("/x402/credit_account/payments/{id}", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PaymentRetrieveResponse,
+ )
+
+ def list(
+ self,
+ *,
+ page_number: int | Omit = omit,
+ page_size: int | 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,
+ ) -> AsyncPaginator[X402TransactionRecord, AsyncDefaultFlatPagination[X402TransactionRecord]]:
+ """
+ Returns a paginated list of the authenticated user's x402 payment transactions,
+ newest first. Organization sub-users must have read permission on transactions;
+ without it the list is empty.
+
+ Args:
+ page_number: The page number to load.
+
+ page_size: The size of the page.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._get_api_list(
+ "/x402/credit_account/payments",
+ page=AsyncDefaultFlatPagination[X402TransactionRecord],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ payment_list_params.PaymentListParams,
+ ),
+ ),
+ model=X402TransactionRecord,
+ )
+
+
+class PaymentsResourceWithRawResponse:
+ def __init__(self, payments: PaymentsResource) -> None:
+ self._payments = payments
+
+ self.retrieve = to_raw_response_wrapper(
+ payments.retrieve,
+ )
+ self.list = to_raw_response_wrapper(
+ payments.list,
+ )
+
+
+class AsyncPaymentsResourceWithRawResponse:
+ def __init__(self, payments: AsyncPaymentsResource) -> None:
+ self._payments = payments
+
+ self.retrieve = async_to_raw_response_wrapper(
+ payments.retrieve,
+ )
+ self.list = async_to_raw_response_wrapper(
+ payments.list,
+ )
+
+
+class PaymentsResourceWithStreamingResponse:
+ def __init__(self, payments: PaymentsResource) -> None:
+ self._payments = payments
+
+ self.retrieve = to_streamed_response_wrapper(
+ payments.retrieve,
+ )
+ self.list = to_streamed_response_wrapper(
+ payments.list,
+ )
+
+
+class AsyncPaymentsResourceWithStreamingResponse:
+ def __init__(self, payments: AsyncPaymentsResource) -> None:
+ self._payments = payments
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ payments.retrieve,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ payments.list,
+ )
diff --git a/src/telnyx/resources/x402/x402.py b/src/telnyx/resources/x402/x402.py
index 456197384..160daf9be 100644
--- a/src/telnyx/resources/x402/x402.py
+++ b/src/telnyx/resources/x402/x402.py
@@ -4,7 +4,7 @@
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
-from .credit_account import (
+from .credit_account.credit_account import (
CreditAccountResource,
AsyncCreditAccountResource,
CreditAccountResourceWithRawResponse,
diff --git a/src/telnyx/types/__init__.py b/src/telnyx/types/__init__.py
index 7b01c411d..8b22e9ea8 100644
--- a/src/telnyx/types/__init__.py
+++ b/src/telnyx/types/__init__.py
@@ -313,6 +313,7 @@
from .uac_internal_settings import UacInternalSettings as UacInternalSettings
from .voice_design_response import VoiceDesignResponse as VoiceDesignResponse
from .voice_sdk_call_report import VoiceSDKCallReport as VoiceSDKCallReport
+from .whatsapp_message_echo import WhatsappMessageEcho as WhatsappMessageEcho
from .alphanumeric_sender_id import AlphanumericSenderID as AlphanumericSenderID
from .call_event_list_params import CallEventListParams as CallEventListParams
from .call_streaming_started import CallStreamingStarted as CallStreamingStarted
@@ -397,6 +398,7 @@
from .transcribe_client_event import TranscribeClientEvent as TranscribeClientEvent
from .transcribe_server_event import TranscribeServerEvent as TranscribeServerEvent
from .voice_clone_list_params import VoiceCloneListParams as VoiceCloneListParams
+from .whatsapp_account_update import WhatsappAccountUpdate as WhatsappAccountUpdate
from .whatsapp_location_param import WhatsappLocationParam as WhatsappLocationParam
from .whatsapp_reaction_param import WhatsappReactionParam as WhatsappReactionParam
from .attachment_request_param import AttachmentRequestParam as AttachmentRequestParam
@@ -501,6 +503,7 @@
from .infringement_claim_wrapped import InfringementClaimWrapped as InfringementClaimWrapped
from .list_retrieve_all_response import ListRetrieveAllResponse as ListRetrieveAllResponse
from .messaging_error_0b38e7044b import MessagingError0b38e7044b as MessagingError0b38e7044b
+from .messaging_profile_features import MessagingProfileFeatures as MessagingProfileFeatures
from .number_order_create_params import NumberOrderCreateParams as NumberOrderCreateParams
from .number_order_list_response import NumberOrderListResponse as NumberOrderListResponse
from .number_order_update_params import NumberOrderUpdateParams as NumberOrderUpdateParams
@@ -792,6 +795,7 @@
from .integration_secret_create_params import IntegrationSecretCreateParams as IntegrationSecretCreateParams
from .inventory_coverage_list_response import InventoryCoverageListResponse as InventoryCoverageListResponse
from .message_send_short_code_response import MessageSendShortCodeResponse as MessageSendShortCodeResponse
+from .messaging_profile_features_param import MessagingProfileFeaturesParam as MessagingProfileFeaturesParam
from .messaging_url_domain_list_params import MessagingURLDomainListParams as MessagingURLDomainListParams
from .network_list_interfaces_response import NetworkListInterfacesResponse as NetworkListInterfacesResponse
from .notification_channel_list_params import NotificationChannelListParams as NotificationChannelListParams
diff --git a/src/telnyx/types/ai/__init__.py b/src/telnyx/types/ai/__init__.py
index e5dceb21b..bbd64274b 100644
--- a/src/telnyx/types/ai/__init__.py
+++ b/src/telnyx/types/ai/__init__.py
@@ -60,6 +60,7 @@
from .assistant_send_sms_params import AssistantSendSMSParams as AssistantSendSMSParams
from .fallback_config_req_param import FallbackConfigReqParam as FallbackConfigReqParam
from .start_speaking_plan_param import StartSpeakingPlanParam as StartSpeakingPlanParam
+from .assistant_a2_a_agent_param import AssistantA2AAgentParam as AssistantA2AAgentParam
from .assistant_mcp_server_param import AssistantMcpServerParam as AssistantMcpServerParam
from .cluster_fetch_graph_params import ClusterFetchGraphParams as ClusterFetchGraphParams
from .conversation_create_params import ConversationCreateParams as ConversationCreateParams
@@ -122,6 +123,7 @@
from .collection_envelope import CollectionEnvelope as CollectionEnvelope
from .inference_embedding import InferenceEmbedding as InferenceEmbedding
from .start_speaking_plan import StartSpeakingPlan as StartSpeakingPlan
+ from .assistant_a2_a_agent import AssistantA2AAgent as AssistantA2AAgent
from .assistant_mcp_server import AssistantMcpServer as AssistantMcpServer
from .events_list_response import EventsListResponse as EventsListResponse
from .shared_tool_response import SharedToolResponse as SharedToolResponse
@@ -162,6 +164,10 @@
def __getattr__(name: str) -> Any:
+ if name == "AssistantA2AAgent":
+ from .assistant_a2_a_agent import AssistantA2AAgent
+
+ return AssistantA2AAgent
if name == "AssistantIntegration":
from .assistant_integration import AssistantIntegration
diff --git a/src/telnyx/types/ai/assistant_a2_a_agent.py b/src/telnyx/types/ai/assistant_a2_a_agent.py
new file mode 100644
index 000000000..8155830a9
--- /dev/null
+++ b/src/telnyx/types/ai/assistant_a2_a_agent.py
@@ -0,0 +1,130 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List, Union, Optional
+from typing_extensions import Literal, TypeAlias
+
+from pydantic import Field as FieldInfo
+
+from ..._models import BaseModel
+
+__all__ = [
+ "AssistantA2AAgent",
+ "Header",
+ "Message",
+ "MessageA2AAgentRequestStartMessage",
+ "MessageA2AAgentRequestResponseDelayedMessage",
+]
+
+
+class Header(BaseModel):
+ """
+ A header sent when fetching an A2A agent's card and on every call made to that agent.
+ """
+
+ name: str
+ """HTTP header name.
+
+ May only contain alphanumeric characters, hyphens, and underscores, or a
+ `{{dynamic_variable}}` placeholder surrounded by those characters.
+ """
+
+ value: str
+ """Header value, stored exactly as written.
+
+ It may be a literal, a `{{dynamic_variable}}`, or an
+ `{{#integration_secret}}identifier{{/integration_secret}}` section that resolves
+ to a stored integration secret when the conversation starts. Control characters
+ are not allowed. The encrypted `{{variable | encryption_secret_ref}}` form used
+ for per-caller credentials is not resolved here and is rejected when the
+ assistant is saved.
+ """
+
+
+class MessageA2AAgentRequestStartMessage(BaseModel):
+ content: str
+ """The text the assistant speaks."""
+
+ type: Literal["request_start"]
+ """Speak the filler message immediately when the call to the agent begins."""
+
+ timing_ms: Optional[int] = None
+ """An optional delay value. This value is ignored for `request_start` messages."""
+
+
+class MessageA2AAgentRequestResponseDelayedMessage(BaseModel):
+ content: str
+ """The text the assistant speaks."""
+
+ timing_ms: int
+ """How long to wait, in milliseconds, before speaking this message."""
+
+ type: Literal["request_response_delayed"]
+ """
+ Speak the filler message only if the agent has not answered yet after
+ `timing_ms`.
+ """
+
+
+Message: TypeAlias = Union[MessageA2AAgentRequestStartMessage, MessageA2AAgentRequestResponseDelayedMessage]
+
+
+class AssistantA2AAgent(BaseModel):
+ """
+ A remote agent, reachable over the A2A (Agent2Agent) protocol, that an assistant can delegate to. Tools are not configured here: at the start of every conversation the agent's card is fetched and one tool is derived per skill the card advertises.
+ """
+
+ name: str
+ """
+ Identifies the agent and seeds the names of the tools derived from its card
+ (`a2a__`). Characters outside `[A-Za-z0-9_]` are replaced with
+ `_` before the tool name is built, so two agents whose names differ only in
+ punctuation collide and are rejected.
+ """
+
+ url: str
+ """The agent's base URL, or the URL of its agent card.
+
+ At most 2,048 bytes once UTF-8 encoded. `/.well-known/agent-card.json` is
+ appended to the path unless it already ends in `.json`. Must be an `http://` or
+ `https://` URL for an externally reachable host: internal destinations
+ (`localhost`, private and reserved IP ranges, `.local` domains) are rejected,
+ and the hostname may not contain a `{{...}}` placeholder. Placeholders in the
+ path are allowed.
+ """
+
+ async_: Optional[bool] = FieldInfo(alias="async", default=None)
+ """
+ When `true`, the assistant hands the turn straight back to the model and the
+ agent's answer is delivered into the conversation once it arrives, instead of
+ the caller waiting for it in silence.
+ """
+
+ headers: Optional[List[Header]] = None
+ """Headers sent when fetching this agent's card and on every call made to it.
+
+ Use them to authenticate to the agent.
+ """
+
+ messages: Optional[List[Message]] = None
+ """Filler messages spoken while a call to this agent is in progress.
+
+ `request_start` messages are spoken immediately when the call begins.
+ `request_response_delayed` messages are spoken after `timing_ms` has elapsed
+ only if the agent has not answered yet. Filler messages are not used when
+ `async` is `true`.
+ """
+
+ poll_interval_ms: Optional[int] = None
+ """How often, in milliseconds, to poll an agent task that has not finished yet.
+
+ Defaults to 500.
+ """
+
+ timeout_ms: Optional[int] = None
+ """
+ Total budget, in milliseconds, for one call to this agent, including any time
+ spent polling a task that is still running. Omit to inherit the assistant's tool
+ timeout.
+ """
diff --git a/src/telnyx/types/ai/assistant_a2_a_agent_param.py b/src/telnyx/types/ai/assistant_a2_a_agent_param.py
new file mode 100644
index 000000000..29bcd9b77
--- /dev/null
+++ b/src/telnyx/types/ai/assistant_a2_a_agent_param.py
@@ -0,0 +1,127 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Iterable
+from typing_extensions import Literal, Required, TypeAlias, TypedDict
+
+__all__ = [
+ "AssistantA2AAgentParam",
+ "Header",
+ "Message",
+ "MessageA2AAgentRequestStartMessage",
+ "MessageA2AAgentRequestResponseDelayedMessage",
+]
+
+
+class Header(TypedDict, total=False):
+ """
+ A header sent when fetching an A2A agent's card and on every call made to that agent.
+ """
+
+ name: Required[str]
+ """HTTP header name.
+
+ May only contain alphanumeric characters, hyphens, and underscores, or a
+ `{{dynamic_variable}}` placeholder surrounded by those characters.
+ """
+
+ value: Required[str]
+ """Header value, stored exactly as written.
+
+ It may be a literal, a `{{dynamic_variable}}`, or an
+ `{{#integration_secret}}identifier{{/integration_secret}}` section that resolves
+ to a stored integration secret when the conversation starts. Control characters
+ are not allowed. The encrypted `{{variable | encryption_secret_ref}}` form used
+ for per-caller credentials is not resolved here and is rejected when the
+ assistant is saved.
+ """
+
+
+class MessageA2AAgentRequestStartMessage(TypedDict, total=False):
+ content: Required[str]
+ """The text the assistant speaks."""
+
+ type: Required[Literal["request_start"]]
+ """Speak the filler message immediately when the call to the agent begins."""
+
+ timing_ms: int
+ """An optional delay value. This value is ignored for `request_start` messages."""
+
+
+class MessageA2AAgentRequestResponseDelayedMessage(TypedDict, total=False):
+ content: Required[str]
+ """The text the assistant speaks."""
+
+ timing_ms: Required[int]
+ """How long to wait, in milliseconds, before speaking this message."""
+
+ type: Required[Literal["request_response_delayed"]]
+ """
+ Speak the filler message only if the agent has not answered yet after
+ `timing_ms`.
+ """
+
+
+Message: TypeAlias = Union[MessageA2AAgentRequestStartMessage, MessageA2AAgentRequestResponseDelayedMessage]
+
+_AssistantA2AAgentParamReservedKeywords = TypedDict(
+ "_AssistantA2AAgentParamReservedKeywords",
+ {
+ "async": bool,
+ },
+ total=False,
+)
+
+
+class AssistantA2AAgentParam(_AssistantA2AAgentParamReservedKeywords, total=False):
+ """
+ A remote agent, reachable over the A2A (Agent2Agent) protocol, that an assistant can delegate to. Tools are not configured here: at the start of every conversation the agent's card is fetched and one tool is derived per skill the card advertises.
+ """
+
+ name: Required[str]
+ """
+ Identifies the agent and seeds the names of the tools derived from its card
+ (`a2a__`). Characters outside `[A-Za-z0-9_]` are replaced with
+ `_` before the tool name is built, so two agents whose names differ only in
+ punctuation collide and are rejected.
+ """
+
+ url: Required[str]
+ """The agent's base URL, or the URL of its agent card.
+
+ At most 2,048 bytes once UTF-8 encoded. `/.well-known/agent-card.json` is
+ appended to the path unless it already ends in `.json`. Must be an `http://` or
+ `https://` URL for an externally reachable host: internal destinations
+ (`localhost`, private and reserved IP ranges, `.local` domains) are rejected,
+ and the hostname may not contain a `{{...}}` placeholder. Placeholders in the
+ path are allowed.
+ """
+
+ headers: Iterable[Header]
+ """Headers sent when fetching this agent's card and on every call made to it.
+
+ Use them to authenticate to the agent.
+ """
+
+ messages: Iterable[Message]
+ """Filler messages spoken while a call to this agent is in progress.
+
+ `request_start` messages are spoken immediately when the call begins.
+ `request_response_delayed` messages are spoken after `timing_ms` has elapsed
+ only if the agent has not answered yet. Filler messages are not used when
+ `async` is `true`.
+ """
+
+ poll_interval_ms: int
+ """How often, in milliseconds, to poll an agent task that has not finished yet.
+
+ Defaults to 500.
+ """
+
+ timeout_ms: int
+ """
+ Total budget, in milliseconds, for one call to this agent, including any time
+ spent polling a task that is still running. Omit to inherit the assistant's tool
+ timeout.
+ """
diff --git a/src/telnyx/types/ai/assistant_create_params.py b/src/telnyx/types/ai/assistant_create_params.py
index 670ae88ef..e579df2d1 100644
--- a/src/telnyx/types/ai/assistant_create_params.py
+++ b/src/telnyx/types/ai/assistant_create_params.py
@@ -18,6 +18,7 @@
from .messaging_settings_param import MessagingSettingsParam
from .telephony_settings_param import TelephonySettingsParam
from .fallback_config_req_param import FallbackConfigReqParam
+from .assistant_a2_a_agent_param import AssistantA2AAgentParam
from .assistant_mcp_server_param import AssistantMcpServerParam
from .assistant_integration_param import AssistantIntegrationParam
from .conversation_flow_req_param import ConversationFlowReqParam
@@ -38,6 +39,19 @@ class AssistantCreateParams(TypedDict, total=False):
name: Required[str]
+ a2a_agents: Iterable[AssistantA2AAgentParam]
+ """A2A agents this assistant can delegate to.
+
+ Tools are not stored here: at the start of every conversation each agent's card
+ is fetched and one tool is derived per skill the card advertises, named
+ `a2a__`. The following limits are not enforced when the
+ assistant is saved, and anything past them is dropped when the conversation
+ starts: 64 agents per assistant, 64 skills per card, 128 derived tools per
+ assistant, and a 6 second budget for all card fetches combined. An agent whose
+ card cannot be fetched costs the assistant that capability for the conversation;
+ it does not fail the call.
+ """
+
conversation_flow: ConversationFlowReqParam
"""Conversation flow as supplied by API clients (create / update).
diff --git a/src/telnyx/types/ai/assistant_update_params.py b/src/telnyx/types/ai/assistant_update_params.py
index 09633fe25..0ea5158a4 100644
--- a/src/telnyx/types/ai/assistant_update_params.py
+++ b/src/telnyx/types/ai/assistant_update_params.py
@@ -17,6 +17,7 @@
from .messaging_settings_param import MessagingSettingsParam
from .telephony_settings_param import TelephonySettingsParam
from .fallback_config_req_param import FallbackConfigReqParam
+from .assistant_a2_a_agent_param import AssistantA2AAgentParam
from .assistant_mcp_server_param import AssistantMcpServerParam
from .assistant_integration_param import AssistantIntegrationParam
from .conversation_flow_req_param import ConversationFlowReqParam
@@ -28,6 +29,20 @@
class AssistantUpdateParams(TypedDict, total=False):
+ a2a_agents: Iterable[AssistantA2AAgentParam]
+ """A2A agents this assistant can delegate to.
+
+ Tools are not stored here: at the start of every conversation each agent's card
+ is fetched and one tool is derived per skill the card advertises, named
+ `a2a__`. The following limits are not enforced when the
+ assistant is saved, and anything past them is dropped when the conversation
+ starts: 64 agents per assistant, 64 skills per card, 128 derived tools per
+ assistant, and a 6 second budget for all card fetches combined. An agent whose
+ card cannot be fetched costs the assistant that capability for the conversation;
+ it does not fail the call. Omit this field to leave the assistant's agents
+ unchanged; send an empty array to remove them all.
+ """
+
conversation_flow: ConversationFlowReqParam
"""Conversation flow as supplied by API clients (create / update).
diff --git a/src/telnyx/types/ai/assistants/version_update_params.py b/src/telnyx/types/ai/assistants/version_update_params.py
index 1aea2a2dc..66a52f5b6 100644
--- a/src/telnyx/types/ai/assistants/version_update_params.py
+++ b/src/telnyx/types/ai/assistants/version_update_params.py
@@ -17,6 +17,7 @@
from ..messaging_settings_param import MessagingSettingsParam
from ..telephony_settings_param import TelephonySettingsParam
from ..fallback_config_req_param import FallbackConfigReqParam
+from ..assistant_a2_a_agent_param import AssistantA2AAgentParam
from ..assistant_mcp_server_param import AssistantMcpServerParam
from ..assistant_integration_param import AssistantIntegrationParam
from ..conversation_flow_req_param import ConversationFlowReqParam
@@ -30,6 +31,20 @@
class VersionUpdateParams(TypedDict, total=False):
assistant_id: Required[str]
+ a2a_agents: Iterable[AssistantA2AAgentParam]
+ """A2A agents this assistant can delegate to.
+
+ Tools are not stored here: at the start of every conversation each agent's card
+ is fetched and one tool is derived per skill the card advertises, named
+ `a2a__`. The following limits are not enforced when the
+ assistant is saved, and anything past them is dropped when the conversation
+ starts: 64 agents per assistant, 64 skills per card, 128 derived tools per
+ assistant, and a 6 second budget for all card fetches combined. An agent whose
+ card cannot be fetched costs the assistant that capability for the conversation;
+ it does not fail the call. Omit this field to leave the assistant's agents
+ unchanged; send an empty array to remove them all.
+ """
+
conversation_flow: ConversationFlowReqParam
"""Conversation flow as supplied by API clients (create / update).
diff --git a/src/telnyx/types/ai/inference_embedding.py b/src/telnyx/types/ai/inference_embedding.py
index 65d1659cf..373c03b9e 100644
--- a/src/telnyx/types/ai/inference_embedding.py
+++ b/src/telnyx/types/ai/inference_embedding.py
@@ -19,6 +19,7 @@
from .conversation_flow import ConversationFlow
from .messaging_settings import MessagingSettings
from .telephony_settings import TelephonySettings
+from .assistant_a2_a_agent import AssistantA2AAgent
from .assistant_mcp_server import AssistantMcpServer
from .assistant_integration import AssistantIntegration
from .transcription_settings import TranscriptionSettings
@@ -52,6 +53,19 @@ class InferenceEmbedding(BaseModel):
name: str
+ a2a_agents: Optional[List[AssistantA2AAgent]] = None
+ """A2A agents this assistant can delegate to.
+
+ Tools are not stored here: at the start of every conversation each agent's card
+ is fetched and one tool is derived per skill the card advertises, named
+ `a2a__`. The following limits are not enforced when the
+ assistant is saved, and anything past them is dropped when the conversation
+ starts: 64 agents per assistant, 64 skills per card, 128 derived tools per
+ assistant, and a 6 second budget for all card fetches combined. An agent whose
+ card cannot be fetched costs the assistant that capability for the conversation;
+ it does not fail the call.
+ """
+
conversation_flow: Optional[ConversationFlow] = None
"""Conversation flow as returned by the API."""
diff --git a/src/telnyx/types/ai/openai/chat_create_completion_params.py b/src/telnyx/types/ai/openai/chat_create_completion_params.py
index 051918210..4570e5a4d 100644
--- a/src/telnyx/types/ai/openai/chat_create_completion_params.py
+++ b/src/telnyx/types/ai/openai/chat_create_completion_params.py
@@ -13,6 +13,10 @@
"Message",
"MessageContentTextAndImageArray",
"ResponseFormat",
+ "ResponseFormatResponseFormatText",
+ "ResponseFormatResponseFormatJsonObject",
+ "ResponseFormatResponseFormatJsonSchemaParam",
+ "ResponseFormatResponseFormatJsonSchemaParamJsonSchema",
"Tool",
"ToolFunction",
"ToolFunctionFunction",
@@ -56,18 +60,6 @@ class ChatCreateCompletionParams(TypedDict, total=False):
frequency_penalty: float
"""Higher values will penalize the model from repeating the same output tokens."""
- guided_choice: SequenceNotStr[str]
- """If specified, the output will be exactly one of the choices."""
-
- guided_json: Dict[str, object]
- """Must be a valid JSON schema.
-
- If specified, the output will follow the JSON schema.
- """
-
- guided_regex: str
- """If specified, the output will follow the regex pattern."""
-
length_penalty: float
"""This is used with `use_beam_search` to prefer shorter or longer completions."""
@@ -126,9 +118,12 @@ class ChatCreateCompletionParams(TypedDict, total=False):
"""
response_format: ResponseFormat
- """Use this is you want to guarantee a JSON output without defining a schema.
+ """Controls the format of the model output.
- For control over the schema, use `guided_json`.
+ `json_object` guarantees valid JSON output without defining a schema;
+ `json_schema` constrains the output to the JSON schema you supply via the
+ `json_schema` property and is the supported way to get guaranteed structured
+ output on Telnyx-hosted models.
"""
seed: int
@@ -207,13 +202,69 @@ class Message(TypedDict, total=False):
role: Required[Literal["system", "user", "assistant", "tool"]]
-class ResponseFormat(TypedDict, total=False):
- """Use this is you want to guarantee a JSON output without defining a schema.
+class ResponseFormatResponseFormatText(TypedDict, total=False):
+ """Plain text output."""
+
+ type: Required[Literal["text"]]
+
+
+class ResponseFormatResponseFormatJsonObject(TypedDict, total=False):
+ """JSON mode: the model output is valid JSON, without a schema."""
+
+ type: Required[Literal["json_object"]]
- For control over the schema, use `guided_json`.
+
+class ResponseFormatResponseFormatJsonSchemaParamJsonSchema(TypedDict, total=False):
+ """The JSON schema configuration, required when `type` is `json_schema`.
+
+ Matches the [OpenAI structured outputs](https://platform.openai.com/docs/guides/structured-outputs) `json_schema` response format.
+ """
+
+ name: Required[str]
+ """The name of the response format. Used for clarity only."""
+
+ description: str
+ """
+ A description of what the response format is for, typically used to guide the
+ model.
"""
- type: Required[Literal["text", "json_object"]]
+ schema: Dict[str, object]
+ """The JSON schema the model output must conform to.
+
+ A valid [JSON Schema](https://json-schema.org) object, e.g. a Pydantic
+ `model_json_schema()` export.
+ """
+
+ strict: bool
+ """Enables strict schema adherence when supported by the model.
+
+ If the generated output does not match the provided schema, the request fails
+ instead of returning non-conformant output.
+ """
+
+
+class ResponseFormatResponseFormatJsonSchemaParam(TypedDict, total=False):
+ """
+ Structured output: the model output is constrained to the JSON schema supplied in `json_schema`.
+ """
+
+ json_schema: Required[ResponseFormatResponseFormatJsonSchemaParamJsonSchema]
+ """The JSON schema configuration, required when `type` is `json_schema`.
+
+ Matches the
+ [OpenAI structured outputs](https://platform.openai.com/docs/guides/structured-outputs)
+ `json_schema` response format.
+ """
+
+ type: Required[Literal["json_schema"]]
+
+
+ResponseFormat: TypeAlias = Union[
+ ResponseFormatResponseFormatText,
+ ResponseFormatResponseFormatJsonObject,
+ ResponseFormatResponseFormatJsonSchemaParam,
+]
class ToolFunctionFunction(TypedDict, total=False):
diff --git a/src/telnyx/types/ai/telephony_settings.py b/src/telnyx/types/ai/telephony_settings.py
index 44137d173..5e64f5302 100644
--- a/src/telnyx/types/ai/telephony_settings.py
+++ b/src/telnyx/types/ai/telephony_settings.py
@@ -116,6 +116,17 @@ class TelephonySettings(BaseModel):
the main tool array or on any workflow node — enforced at write time.
"""
+ fallback_destination: Optional[str] = None
+ """
+ Destination number or SIP URI to transfer the caller to when the AI conversation
+ ends abnormally, for example because of an assistant-side error, so the caller
+ is not left in dead air. This only fires for abnormal ends: it does not fire
+ when the conversation ends on purpose (the caller hung up, the assistant
+ completed normally, the caller hung up after a relay handoff, or voicemail was
+ detected), and it does not fire when the assistant already transferred or
+ bridged the call.
+ """
+
noise_suppression: Optional[Literal["krisp", "deepfilternet", "disabled"]] = None
"""The noise suppression engine to use.
diff --git a/src/telnyx/types/ai/telephony_settings_param.py b/src/telnyx/types/ai/telephony_settings_param.py
index ce37701ca..24348ded3 100644
--- a/src/telnyx/types/ai/telephony_settings_param.py
+++ b/src/telnyx/types/ai/telephony_settings_param.py
@@ -113,6 +113,17 @@ class TelephonySettingsParam(TypedDict, total=False):
the main tool array or on any workflow node — enforced at write time.
"""
+ fallback_destination: str
+ """
+ Destination number or SIP URI to transfer the caller to when the AI conversation
+ ends abnormally, for example because of an assistant-side error, so the caller
+ is not left in dead air. This only fires for abnormal ends: it does not fire
+ when the conversation ends on purpose (the caller hung up, the assistant
+ completed normally, the caller hung up after a relay handoff, or voicemail was
+ detected), and it does not fire when the assistant already transferred or
+ bridged the call.
+ """
+
noise_suppression: Literal["krisp", "deepfilternet", "disabled"]
"""The noise suppression engine to use.
diff --git a/src/telnyx/types/compute/__init__.py b/src/telnyx/types/compute/__init__.py
new file mode 100644
index 000000000..f8c6e7d70
--- /dev/null
+++ b/src/telnyx/types/compute/__init__.py
@@ -0,0 +1,49 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any
+
+from .func_retrieve_logs_params import FuncRetrieveLogsParams as FuncRetrieveLogsParams
+from .func_retrieve_logs_response import FuncRetrieveLogsResponse as FuncRetrieveLogsResponse
+from .func_retrieve_revisions_params import FuncRetrieveRevisionsParams as FuncRetrieveRevisionsParams
+from .func_retrieve_metric_aggregates_params import (
+ FuncRetrieveMetricAggregatesParams as FuncRetrieveMetricAggregatesParams,
+)
+
+if TYPE_CHECKING:
+ from .logs_meta import LogsMeta as LogsMeta
+ from .func_retrieve_revisions_response import FuncRetrieveRevisionsResponse as FuncRetrieveRevisionsResponse
+ from .func_retrieve_ship_inspection_response import (
+ FuncRetrieveShipInspectionResponse as FuncRetrieveShipInspectionResponse,
+ )
+ from .functions_observability_pagination_meta import (
+ FunctionsObservabilityPaginationMeta as FunctionsObservabilityPaginationMeta,
+ )
+ from .func_retrieve_metric_aggregates_response import (
+ FuncRetrieveMetricAggregatesResponse as FuncRetrieveMetricAggregatesResponse,
+ )
+
+
+def __getattr__(name: str) -> Any:
+ if name == "FunctionsObservabilityPaginationMeta":
+ from .functions_observability_pagination_meta import FunctionsObservabilityPaginationMeta
+
+ return FunctionsObservabilityPaginationMeta
+ if name == "LogsMeta":
+ from .logs_meta import LogsMeta
+
+ return LogsMeta
+ if name == "FuncRetrieveMetricAggregatesResponse":
+ from .func_retrieve_metric_aggregates_response import FuncRetrieveMetricAggregatesResponse
+
+ return FuncRetrieveMetricAggregatesResponse
+ if name == "FuncRetrieveRevisionsResponse":
+ from .func_retrieve_revisions_response import FuncRetrieveRevisionsResponse
+
+ return FuncRetrieveRevisionsResponse
+ if name == "FuncRetrieveShipInspectionResponse":
+ from .func_retrieve_ship_inspection_response import FuncRetrieveShipInspectionResponse
+
+ return FuncRetrieveShipInspectionResponse
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
diff --git a/src/telnyx/types/compute/func_retrieve_logs_params.py b/src/telnyx/types/compute/func_retrieve_logs_params.py
new file mode 100644
index 000000000..9f6801f19
--- /dev/null
+++ b/src/telnyx/types/compute/func_retrieve_logs_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Literal, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["FuncRetrieveLogsParams"]
+
+
+class FuncRetrieveLogsParams(TypedDict, total=False):
+ end_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """Return records at or before this RFC 3339 timestamp."""
+
+ limit: int
+ """Maximum records to return."""
+
+ start_time: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """Return records at or after this RFC 3339 timestamp."""
+
+ type: Literal["runtime", "invocations"]
+ """Log stream to return."""
diff --git a/src/telnyx/types/compute/func_retrieve_logs_response.py b/src/telnyx/types/compute/func_retrieve_logs_response.py
new file mode 100644
index 000000000..8759be2c5
--- /dev/null
+++ b/src/telnyx/types/compute/func_retrieve_logs_response.py
@@ -0,0 +1,63 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List, Union, Optional
+from datetime import datetime
+from typing_extensions import Literal, TypeAlias
+
+from ..._models import BaseModel
+from .logs_meta import LogsMeta
+
+__all__ = [
+ "FuncRetrieveLogsResponse",
+ "FuncRuntimeLogsResponse",
+ "FuncRuntimeLogsResponseData",
+ "FuncInvocationLogsResponse",
+ "FuncInvocationLogsResponseData",
+]
+
+
+class FuncRuntimeLogsResponseData(BaseModel):
+ level: Optional[str] = None
+
+ message: Optional[str] = None
+
+ record_type: Optional[Literal["compute_func_runtime_log"]] = None
+
+ timestamp: Optional[datetime] = None
+
+
+class FuncRuntimeLogsResponse(BaseModel):
+ data: Optional[List[FuncRuntimeLogsResponseData]] = None
+
+ meta: Optional[LogsMeta] = None
+
+
+class FuncInvocationLogsResponseData(BaseModel):
+ duration_ms: Optional[float] = None
+
+ method: Optional[str] = None
+
+ path: Optional[str] = None
+
+ record_type: Optional[Literal["compute_func_invocation_log"]] = None
+
+ region: Optional[str] = None
+
+ request_size_bytes: Optional[int] = None
+
+ response_size_bytes: Optional[int] = None
+
+ status_code: Optional[int] = None
+
+ timestamp: Optional[datetime] = None
+
+
+class FuncInvocationLogsResponse(BaseModel):
+ data: Optional[List[FuncInvocationLogsResponseData]] = None
+
+ meta: Optional[LogsMeta] = None
+
+
+FuncRetrieveLogsResponse: TypeAlias = Union[FuncRuntimeLogsResponse, FuncInvocationLogsResponse]
diff --git a/src/telnyx/types/compute/func_retrieve_metric_aggregates_params.py b/src/telnyx/types/compute/func_retrieve_metric_aggregates_params.py
new file mode 100644
index 000000000..f26bac5f4
--- /dev/null
+++ b/src/telnyx/types/compute/func_retrieve_metric_aggregates_params.py
@@ -0,0 +1,29 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Required, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["FuncRetrieveMetricAggregatesParams"]
+
+
+class FuncRetrieveMetricAggregatesParams(TypedDict, total=False):
+ end_time: Required[Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]]
+ """Exclusive window end, UTC ISO 8601 with milliseconds"""
+
+ start_time: Required[Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]]
+ """Inclusive window start, UTC ISO 8601 with milliseconds"""
+
+ filter_edge_site: Annotated[str, PropertyInfo(alias="filter[edge_site]")]
+ """Edge site filter"""
+
+ filter_namespace: Annotated[str, PropertyInfo(alias="filter[namespace]")]
+ """Kubernetes namespace filter"""
+
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
diff --git a/src/telnyx/types/compute/func_retrieve_metric_aggregates_response.py b/src/telnyx/types/compute/func_retrieve_metric_aggregates_response.py
new file mode 100644
index 000000000..d8f6578b5
--- /dev/null
+++ b/src/telnyx/types/compute/func_retrieve_metric_aggregates_response.py
@@ -0,0 +1,55 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from datetime import datetime
+
+from ..._models import BaseModel
+from .functions_observability_pagination_meta import FunctionsObservabilityPaginationMeta
+
+__all__ = ["FuncRetrieveMetricAggregatesResponse", "Data"]
+
+
+class Data(BaseModel):
+ cpu_used_cores_avg: Optional[float] = None
+
+ cpu_used_cores_max: Optional[float] = None
+
+ end_time: Optional[datetime] = None
+
+ function_id: Optional[str] = None
+
+ function_name: Optional[str] = None
+
+ memory_used_bytes_avg: Optional[float] = None
+
+ memory_used_bytes_max: Optional[float] = None
+
+ product: Optional[str] = None
+
+ record_type: Optional[str] = None
+
+ request_client_error_rate: Optional[float] = None
+
+ request_count: Optional[float] = None
+
+ request_error_rate: Optional[float] = None
+
+ request_latency_avg_ms: Optional[float] = None
+
+ request_latency_p50_ms: Optional[float] = None
+
+ request_latency_p95_ms: Optional[float] = None
+
+ request_latency_p99_ms: Optional[float] = None
+
+ request_success_rate: Optional[float] = None
+
+ start_time: Optional[datetime] = None
+
+
+class FuncRetrieveMetricAggregatesResponse(BaseModel):
+ data: Optional[List[Data]] = None
+
+ meta: Optional[FunctionsObservabilityPaginationMeta] = None
diff --git a/src/telnyx/types/compute/func_retrieve_revisions_params.py b/src/telnyx/types/compute/func_retrieve_revisions_params.py
new file mode 100644
index 000000000..7414dd84f
--- /dev/null
+++ b/src/telnyx/types/compute/func_retrieve_revisions_params.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["FuncRetrieveRevisionsParams"]
+
+
+class FuncRetrieveRevisionsParams(TypedDict, total=False):
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
diff --git a/src/telnyx/types/compute/func_retrieve_revisions_response.py b/src/telnyx/types/compute/func_retrieve_revisions_response.py
new file mode 100644
index 000000000..27e37975f
--- /dev/null
+++ b/src/telnyx/types/compute/func_retrieve_revisions_response.py
@@ -0,0 +1,43 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from datetime import datetime
+
+from ..._models import BaseModel
+from .functions_observability_pagination_meta import FunctionsObservabilityPaginationMeta
+
+__all__ = ["FuncRetrieveRevisionsResponse", "Data"]
+
+
+class Data(BaseModel):
+ active: Optional[bool] = None
+
+ build_ok_at: Optional[datetime] = None
+
+ build_status: Optional[str] = None
+
+ commit_sha: Optional[str] = None
+
+ deploy_status: Optional[str] = None
+
+ failure_reason: Optional[str] = None
+
+ failure_stage: Optional[str] = None
+
+ image: Optional[str] = None
+
+ record_type: Optional[str] = None
+
+ revision_id: Optional[str] = None
+
+ shipped_at: Optional[datetime] = None
+
+ shipped_by: Optional[str] = None
+
+
+class FuncRetrieveRevisionsResponse(BaseModel):
+ data: Optional[List[Data]] = None
+
+ meta: Optional[FunctionsObservabilityPaginationMeta] = None
diff --git a/src/telnyx/types/compute/func_retrieve_ship_inspection_response.py b/src/telnyx/types/compute/func_retrieve_ship_inspection_response.py
new file mode 100644
index 000000000..f464d8fc2
--- /dev/null
+++ b/src/telnyx/types/compute/func_retrieve_ship_inspection_response.py
@@ -0,0 +1,30 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["FuncRetrieveShipInspectionResponse", "Data"]
+
+
+class Data(BaseModel):
+ created_at: Optional[datetime] = None
+
+ reason: Optional[str] = None
+
+ record_type: Optional[Literal["build_log_inspection"]] = None
+ """Stable record type retained by both inspection path aliases."""
+
+ runtime: Optional[str] = None
+
+ snippet: Optional[str] = None
+
+ stage: Optional[Literal["build", "platform", "pre_build", "deploy", "security_review", "none", "pending"]] = None
+
+
+class FuncRetrieveShipInspectionResponse(BaseModel):
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/compute/functions_observability_pagination_meta.py b/src/telnyx/types/compute/functions_observability_pagination_meta.py
new file mode 100644
index 000000000..6217d57ed
--- /dev/null
+++ b/src/telnyx/types/compute/functions_observability_pagination_meta.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+
+from ..._models import BaseModel
+
+__all__ = ["FunctionsObservabilityPaginationMeta"]
+
+
+class FunctionsObservabilityPaginationMeta(BaseModel):
+ page_number: Optional[int] = None
+
+ page_size: Optional[int] = None
+
+ total_pages: Optional[int] = None
+
+ total_results: Optional[int] = None
diff --git a/src/telnyx/types/compute/logs_meta.py b/src/telnyx/types/compute/logs_meta.py
new file mode 100644
index 000000000..db984ecb2
--- /dev/null
+++ b/src/telnyx/types/compute/logs_meta.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+
+from ..._models import BaseModel
+
+__all__ = ["LogsMeta"]
+
+
+class LogsMeta(BaseModel):
+ has_more: Optional[bool] = None
+
+ partial: Optional[bool] = None
diff --git a/src/telnyx/types/credential_connection.py b/src/telnyx/types/credential_connection.py
index 71a65d68a..ea5953cb7 100644
--- a/src/telnyx/types/credential_connection.py
+++ b/src/telnyx/types/credential_connection.py
@@ -120,7 +120,10 @@ class CredentialConnection(BaseModel):
password: Optional[str] = None
"""The password to be used as part of the credentials.
- Must be 8 to 128 characters long.
+ Must be 8 to 128 characters long. For primary accounts created on or after
+ September 8, 2026, this password is returned as `********`. The password is
+ returned in full on create, and on update only when that update changed the
+ password. Accounts created before September 8, 2026 are unaffected.
"""
record_type: Optional[str] = None
diff --git a/src/telnyx/types/email_inboxes/email_message.py b/src/telnyx/types/email_inboxes/email_message.py
index 9b6361b2e..6dfe80ac1 100644
--- a/src/telnyx/types/email_inboxes/email_message.py
+++ b/src/telnyx/types/email_inboxes/email_message.py
@@ -11,6 +11,7 @@
from ..._models import BaseModel
from .email_address import EmailAddress
from ..message_event import MessageEvent
+from ..suppressed_recipient import SuppressedRecipient
__all__ = ["EmailMessage", "Attachment"]
@@ -113,3 +114,12 @@ class EmailMessage(BaseModel):
Persists even after the scheduled send has been processed or cancelled.
"""
+
+ suppressed: Optional[List[SuppressedRecipient]] = None
+ """Recipients excluded from delivery by suppression checks, with reasons.
+
+ On batch items, present when that item had suppressed recipients; all other
+ recipients of the item still receive the message. For single sends this
+ information appears at the top level of the response instead (see
+ EmailMessageResponse.suppressed).
+ """
diff --git a/src/telnyx/types/email_message_batch_params.py b/src/telnyx/types/email_message_batch_params.py
index 2aa883e22..b78cd9cae 100644
--- a/src/telnyx/types/email_message_batch_params.py
+++ b/src/telnyx/types/email_message_batch_params.py
@@ -17,6 +17,11 @@
class EmailMessageBatchParams(TypedDict, total=False):
messages: Required[Iterable[Message]]
+ """Array of email messages to send.
+
+ Up to 1,000 messages per batch request. Each message is validated and sent
+ independently; per-message failures do not affect other messages in the batch.
+ """
sandbox_mode: bool
"""Applies sandbox mode to all messages in the batch.
diff --git a/src/telnyx/types/email_message_batch_response.py b/src/telnyx/types/email_message_batch_response.py
index aa23e1e97..a4485ee04 100644
--- a/src/telnyx/types/email_message_batch_response.py
+++ b/src/telnyx/types/email_message_batch_response.py
@@ -17,6 +17,7 @@ class Error(BaseModel):
"not_found",
"forbidden",
"service_unavailable",
+ "unprocessable_entity",
"validation_error",
"recipient_suppressed",
"reputation_suspended",
diff --git a/src/telnyx/types/fqdn_connection.py b/src/telnyx/types/fqdn_connection.py
index 679bc8e05..874826a47 100644
--- a/src/telnyx/types/fqdn_connection.py
+++ b/src/telnyx/types/fqdn_connection.py
@@ -135,7 +135,13 @@ class FqdnConnection(BaseModel):
outbound: Optional[OutboundFqdn] = None
password: Optional[str] = None
- """The password for the FQDN connection."""
+ """The password for the FQDN connection.
+
+ For primary accounts created on or after September 8, 2026, this password is
+ returned as `********`. The password is returned in full on create, and on
+ update only when that update changed the password. Accounts created before
+ September 8, 2026 are unaffected.
+ """
record_type: Optional[str] = None
"""Identifies the type of the resource."""
diff --git a/src/telnyx/types/fqdn_connections/fqdn_authentication.py b/src/telnyx/types/fqdn_connections/fqdn_authentication.py
index f2755af55..9a7d529fa 100644
--- a/src/telnyx/types/fqdn_connections/fqdn_authentication.py
+++ b/src/telnyx/types/fqdn_connections/fqdn_authentication.py
@@ -30,7 +30,13 @@ class FqdnAuthentication(BaseModel):
"""Whether the connection is a Microsoft Teams SBC."""
password: Optional[str] = None
- """The password for authentication."""
+ """The password for authentication.
+
+ For primary accounts created on or after September 8, 2026, this password is
+ returned as `********`. The password is returned in full on create, and on
+ update only when that update changed the password. Accounts created before
+ September 8, 2026 are unaffected.
+ """
record_type: Optional[str] = None
"""Identifies the type of the resource."""
diff --git a/src/telnyx/types/messaging_inbound_message_payload.py b/src/telnyx/types/messaging_inbound_message_payload.py
index c06dbe415..0cdf0c60e 100644
--- a/src/telnyx/types/messaging_inbound_message_payload.py
+++ b/src/telnyx/types/messaging_inbound_message_payload.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from typing import List, Optional
+from typing import TYPE_CHECKING, Dict, List, Union, Optional
from datetime import datetime
from typing_extensions import Literal
@@ -13,6 +13,9 @@
__all__ = [
"MessagingInboundMessagePayload",
+ "Body",
+ "BodyEdit",
+ "BodyRevoke",
"Cc",
"Cost",
"CostBreakdown",
@@ -20,10 +23,76 @@
"CostBreakdownRate",
"From",
"Media",
- "To",
+ "ToUnionMember0",
]
+class BodyEdit(BaseModel):
+ """Details for an edited WhatsApp message."""
+
+ message: Dict[str, object]
+ """Replacement WhatsApp message content. Its shape depends on the message type."""
+
+ original_message_id: str
+ """
+ Telnyx message ID when a mapping exists, otherwise the original Meta WhatsApp
+ message ID. Treat this value as opaque.
+ """
+
+
+class BodyRevoke(BaseModel):
+ """Details for a revoked WhatsApp message."""
+
+ original_message_id: str
+ """
+ Telnyx message ID when a mapping exists, otherwise the original Meta WhatsApp
+ message ID. Treat this value as opaque.
+ """
+
+
+class Body(BaseModel):
+ """WhatsApp message body.
+
+ For message edits and revocations, inspect `type` and the corresponding `edit` or `revoke` object.
+ """
+
+ id: Optional[str] = None
+ """Telnyx identifier for this webhook message."""
+
+ edit: Optional[BodyEdit] = None
+ """Details for an edited WhatsApp message."""
+
+ foreign_id: Optional[str] = None
+ """Meta WhatsApp message identifier for this webhook event."""
+
+ from_: Optional[str] = FieldInfo(alias="from", default=None)
+ """WhatsApp sender in E.164 format."""
+
+ revoke: Optional[BodyRevoke] = None
+ """Details for a revoked WhatsApp message."""
+
+ timestamp: Optional[str] = None
+ """Unix timestamp supplied by Meta."""
+
+ type: Optional[str] = None
+ """WhatsApp message body type.
+
+ Edit and revoke events use `edit` and `revoke`, respectively.
+ """
+
+ if TYPE_CHECKING:
+ # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a
+ # value to this field, so for compatibility we avoid doing it at runtime.
+ __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride]
+
+ # Stub to indicate that arbitrary properties are accepted.
+ # To access properties that are not valid identifiers you can use `getattr`, e.g.
+ # `getattr(obj, '$type')`
+ def __getattr__(self, attr: str) -> object: ...
+ else:
+ __pydantic_extra__: Dict[str, object]
+
+
class Cc(BaseModel):
carrier: Optional[str] = None
"""The carrier of the receiver."""
@@ -101,7 +170,7 @@ class Media(BaseModel):
"""The url of the media requested to be sent."""
-class To(BaseModel):
+class ToUnionMember0(BaseModel):
carrier: Optional[str] = None
"""The carrier of the receiver."""
@@ -129,6 +198,13 @@ class MessagingInboundMessagePayload(BaseModel):
id: Optional[str] = None
"""Identifies the type of resource."""
+ body: Optional[Body] = None
+ """WhatsApp message body.
+
+ For message edits and revocations, inspect `type` and the corresponding `edit`
+ or `revoke` object.
+ """
+
cc: Optional[List[Cc]] = None
completed_at: Optional[datetime] = None
@@ -200,10 +276,15 @@ class MessagingInboundMessagePayload(BaseModel):
**Required for SMS**
"""
- to: Optional[List[To]] = None
+ to: Union[List[ToUnionMember0], str, None] = None
+ """Receiving address.
+
+ SMS and MMS webhooks use an array of recipients. WhatsApp webhooks use one E.164
+ phone number.
+ """
- type: Optional[Literal["SMS", "MMS"]] = None
- """The type of message. This value can be either 'sms' or 'mms'."""
+ type: Optional[Literal["SMS", "MMS", "WHATSAPP"]] = None
+ """The messaging channel used for the message."""
valid_until: Optional[datetime] = None
"""Not used for inbound messages."""
diff --git a/src/telnyx/types/messaging_messaging_profile.py b/src/telnyx/types/messaging_messaging_profile.py
index c650f12fb..ff57665b6 100644
--- a/src/telnyx/types/messaging_messaging_profile.py
+++ b/src/telnyx/types/messaging_messaging_profile.py
@@ -9,6 +9,7 @@
from .._models import BaseModel
from .number_pool_settings import NumberPoolSettings
from .url_shortener_settings import URLShortenerSettings
+from .messaging_profile_features import MessagingProfileFeatures
__all__ = ["MessagingMessagingProfile"]
@@ -41,6 +42,13 @@ class MessagingMessagingProfile(BaseModel):
enabled: Optional[bool] = None
"""Specifies whether the messaging profile is enabled or not."""
+ features: Optional[MessagingProfileFeatures] = None
+ """
+ Telnyx product features the messaging customer can enable on the messaging
+ profile. Keys map to individual feature flags; unknown keys are accepted and
+ preserved for forward compatibility with rolling deployments.
+ """
+
health_webhook_url: Optional[str] = None
"""DEPRECATED: health check url service checking"""
diff --git a/src/telnyx/types/messaging_profile_create_params.py b/src/telnyx/types/messaging_profile_create_params.py
index 12b2c6ef5..badd3edc5 100644
--- a/src/telnyx/types/messaging_profile_create_params.py
+++ b/src/telnyx/types/messaging_profile_create_params.py
@@ -8,6 +8,7 @@
from .._types import SequenceNotStr
from .number_pool_settings_param import NumberPoolSettingsParam
from .url_shortener_settings_param import URLShortenerSettingsParam
+from .messaging_profile_features_param import MessagingProfileFeaturesParam
__all__ = ["MessagingProfileCreateParams"]
@@ -44,6 +45,13 @@ class MessagingProfileCreateParams(TypedDict, total=False):
enabled: bool
"""Specifies whether the messaging profile is enabled or not."""
+ features: Optional[MessagingProfileFeaturesParam]
+ """
+ Telnyx product features the messaging customer can enable on the messaging
+ profile. Keys map to individual feature flags; unknown keys are accepted and
+ preserved for forward compatibility with rolling deployments.
+ """
+
health_webhook_url: Optional[str]
"""A URL to receive health check webhooks for numbers in this profile."""
diff --git a/src/telnyx/types/messaging_profile_features.py b/src/telnyx/types/messaging_profile_features.py
new file mode 100644
index 000000000..2e27c79da
--- /dev/null
+++ b/src/telnyx/types/messaging_profile_features.py
@@ -0,0 +1,37 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Dict, Optional
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+
+__all__ = ["MessagingProfileFeatures"]
+
+
+class MessagingProfileFeatures(BaseModel):
+ """
+ Telnyx product features the messaging customer can enable on the messaging profile. Keys map to individual feature flags; unknown keys are accepted and preserved for forward compatibility with rolling deployments.
+ """
+
+ ai_opt_out_detection_enabled: Optional[bool] = None
+ """
+ Enables AI detection of inbound opt-out messages that do not follow the standard
+ STOP/UNSTOP/HELP opt-out keyword pattern. When enabled, the messaging platform
+ applies an AI model to identify non-standard opt-out requests (e.g.
+ natural-language phrases) and treats them as opt-outs.
+ """
+
+ if TYPE_CHECKING:
+ # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a
+ # value to this field, so for compatibility we avoid doing it at runtime.
+ __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride]
+
+ # Stub to indicate that arbitrary properties are accepted.
+ # To access properties that are not valid identifiers you can use `getattr`, e.g.
+ # `getattr(obj, '$type')`
+ def __getattr__(self, attr: str) -> object: ...
+ else:
+ __pydantic_extra__: Dict[str, object]
diff --git a/src/telnyx/types/messaging_profile_features_param.py b/src/telnyx/types/messaging_profile_features_param.py
new file mode 100644
index 000000000..39cd7c236
--- /dev/null
+++ b/src/telnyx/types/messaging_profile_features_param.py
@@ -0,0 +1,21 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+__all__ = ["MessagingProfileFeaturesParam"]
+
+
+class MessagingProfileFeaturesParam(TypedDict, total=False, extra_items=object): # type: ignore[call-arg]
+ """
+ Telnyx product features the messaging customer can enable on the messaging profile. Keys map to individual feature flags; unknown keys are accepted and preserved for forward compatibility with rolling deployments.
+ """
+
+ ai_opt_out_detection_enabled: bool
+ """
+ Enables AI detection of inbound opt-out messages that do not follow the standard
+ STOP/UNSTOP/HELP opt-out keyword pattern. When enabled, the messaging platform
+ applies an AI model to identify non-standard opt-out requests (e.g.
+ natural-language phrases) and treats them as opt-outs.
+ """
diff --git a/src/telnyx/types/messaging_profile_update_params.py b/src/telnyx/types/messaging_profile_update_params.py
index fa101a778..dcfdbb2e4 100644
--- a/src/telnyx/types/messaging_profile_update_params.py
+++ b/src/telnyx/types/messaging_profile_update_params.py
@@ -8,6 +8,7 @@
from .._types import SequenceNotStr
from .number_pool_settings_param import NumberPoolSettingsParam
from .url_shortener_settings_param import URLShortenerSettingsParam
+from .messaging_profile_features_param import MessagingProfileFeaturesParam
__all__ = ["MessagingProfileUpdateParams"]
@@ -34,6 +35,13 @@ class MessagingProfileUpdateParams(TypedDict, total=False):
enabled: bool
"""Specifies whether the messaging profile is enabled or not."""
+ features: Optional[MessagingProfileFeaturesParam]
+ """
+ Telnyx product features the messaging customer can enable on the messaging
+ profile. Keys map to individual feature flags; unknown keys are accepted and
+ preserved for forward compatibility with rolling deployments.
+ """
+
mms_fall_back_to_sms: bool
"""enables SMS fallback for MMS messages."""
diff --git a/src/telnyx/types/uac_connection.py b/src/telnyx/types/uac_connection.py
index 24a336e9d..c8aa17df5 100644
--- a/src/telnyx/types/uac_connection.py
+++ b/src/telnyx/types/uac_connection.py
@@ -141,7 +141,10 @@ class UacConnection(BaseModel):
password: Optional[str] = None
"""The password to be used as part of the credentials.
- Must be 8 to 128 characters long.
+ Must be 8 to 128 characters long. For primary accounts created on or after
+ September 8, 2026, this password is returned as `********`. The password is
+ returned in full on create, and on update only when that update changed the
+ password. Accounts created before September 8, 2026 are unaffected.
"""
record_type: Optional[str] = None
diff --git a/src/telnyx/types/uac_external_settings.py b/src/telnyx/types/uac_external_settings.py
index 765d8e4b2..ad1cc60a2 100644
--- a/src/telnyx/types/uac_external_settings.py
+++ b/src/telnyx/types/uac_external_settings.py
@@ -40,7 +40,13 @@ class UacExternalSettings(BaseModel):
"""
password: Optional[str] = None
- """The SIP password used for digest authentication with the external SIP peer."""
+ """The SIP password used for digest authentication with the external SIP peer.
+
+ For primary accounts created on or after September 8, 2026, this password is
+ returned as `********`. The password is returned in full on create, and on
+ update only when that update changed the password. Accounts created before
+ September 8, 2026 are unaffected.
+ """
proxy: Optional[str] = None
"""
diff --git a/src/telnyx/types/uac_external_settings_param.py b/src/telnyx/types/uac_external_settings_param.py
index 7e7c83d51..4a9e99064 100644
--- a/src/telnyx/types/uac_external_settings_param.py
+++ b/src/telnyx/types/uac_external_settings_param.py
@@ -38,7 +38,13 @@ class UacExternalSettingsParam(TypedDict, total=False):
"""
password: str
- """The SIP password used for digest authentication with the external SIP peer."""
+ """The SIP password used for digest authentication with the external SIP peer.
+
+ For primary accounts created on or after September 8, 2026, this password is
+ returned as `********`. The password is returned in full on create, and on
+ update only when that update changed the password. Accounts created before
+ September 8, 2026 are unaffected.
+ """
proxy: str
"""
diff --git a/src/telnyx/types/unsafe_unwrap_webhook_event.py b/src/telnyx/types/unsafe_unwrap_webhook_event.py
index 858d8f248..6ff39948c 100644
--- a/src/telnyx/types/unsafe_unwrap_webhook_event.py
+++ b/src/telnyx/types/unsafe_unwrap_webhook_event.py
@@ -10,9 +10,11 @@
from .fax_delivered import FaxDelivered
from .fax_media_processed import FaxMediaProcessed
from .fax_sending_started import FaxSendingStarted
+from .whatsapp_message_echo import WhatsappMessageEcho
from .campaign_status_update import CampaignStatusUpdate
from .call_cost_webhook_event import CallCostWebhookEvent
from .call_hold_webhook_event import CallHoldWebhookEvent
+from .whatsapp_account_update import WhatsappAccountUpdate
from .conference_floor_changed import ConferenceFloorChanged
from .call_hangup_webhook_event import CallHangupWebhookEvent
from .call_unhold_webhook_event import CallUnholdWebhookEvent
@@ -155,4 +157,6 @@
SessionStatusChangedWebhookEvent,
TranscriptCompletedWebhookEvent,
TranscriptionWebhookEvent,
+ WhatsappAccountUpdate,
+ WhatsappMessageEcho,
]
diff --git a/src/telnyx/types/unwrap_webhook_event.py b/src/telnyx/types/unwrap_webhook_event.py
index 1747cbc40..d3faec93e 100644
--- a/src/telnyx/types/unwrap_webhook_event.py
+++ b/src/telnyx/types/unwrap_webhook_event.py
@@ -10,9 +10,11 @@
from .fax_delivered import FaxDelivered
from .fax_media_processed import FaxMediaProcessed
from .fax_sending_started import FaxSendingStarted
+from .whatsapp_message_echo import WhatsappMessageEcho
from .campaign_status_update import CampaignStatusUpdate
from .call_cost_webhook_event import CallCostWebhookEvent
from .call_hold_webhook_event import CallHoldWebhookEvent
+from .whatsapp_account_update import WhatsappAccountUpdate
from .conference_floor_changed import ConferenceFloorChanged
from .call_hangup_webhook_event import CallHangupWebhookEvent
from .call_unhold_webhook_event import CallUnholdWebhookEvent
@@ -155,4 +157,6 @@
SessionStatusChangedWebhookEvent,
TranscriptCompletedWebhookEvent,
TranscriptionWebhookEvent,
+ WhatsappAccountUpdate,
+ WhatsappMessageEcho,
]
diff --git a/src/telnyx/types/whatsapp/__init__.py b/src/telnyx/types/whatsapp/__init__.py
index a9f8b7965..8756522d5 100644
--- a/src/telnyx/types/whatsapp/__init__.py
+++ b/src/telnyx/types/whatsapp/__init__.py
@@ -42,6 +42,9 @@
from .user_data_retrieve_response import UserDataRetrieveResponse as UserDataRetrieveResponse
from .business_account_list_response import BusinessAccountListResponse as BusinessAccountListResponse
from .business_account_retrieve_response import BusinessAccountRetrieveResponse as BusinessAccountRetrieveResponse
+ from .phone_number_retrieve_phone_number_response import (
+ PhoneNumberRetrievePhoneNumberResponse as PhoneNumberRetrievePhoneNumberResponse,
+ )
from .phone_number_retrieve_conversation_window_response import (
PhoneNumberRetrieveConversationWindowResponse as PhoneNumberRetrieveConversationWindowResponse,
)
@@ -72,6 +75,10 @@ def __getattr__(name: str) -> Any:
from .phone_number_retrieve_conversation_window_response import PhoneNumberRetrieveConversationWindowResponse
return PhoneNumberRetrieveConversationWindowResponse
+ if name == "PhoneNumberRetrievePhoneNumberResponse":
+ from .phone_number_retrieve_phone_number_response import PhoneNumberRetrievePhoneNumberResponse
+
+ return PhoneNumberRetrievePhoneNumberResponse
if name == "WhatsappUserData":
from .whatsapp_user_data import WhatsappUserData
diff --git a/src/telnyx/types/whatsapp/business_accounts/phone_number_list_response.py b/src/telnyx/types/whatsapp/business_accounts/phone_number_list_response.py
index 2696da1af..50b736454 100644
--- a/src/telnyx/types/whatsapp/business_accounts/phone_number_list_response.py
+++ b/src/telnyx/types/whatsapp/business_accounts/phone_number_list_response.py
@@ -4,21 +4,63 @@
from typing import Optional
from datetime import datetime
+from typing_extensions import Literal
from ...._models import BaseModel
-__all__ = ["PhoneNumberListResponse"]
+__all__ = ["PhoneNumberListResponse", "SyncProgress"]
+
+
+class SyncProgress(BaseModel):
+ """Synchronization progress.
+
+ This object is returned only while a coexistence number is synchronizing.
+ """
+
+ contacts_status: Optional[str] = None
+
+ history_chunk_order: Optional[int] = None
+
+ history_phase: Optional[int] = None
+
+ history_progress: Optional[int] = None
+
+ history_status: Optional[str] = None
class PhoneNumberListResponse(BaseModel):
calling_enabled: Optional[bool] = None
+ coexistence_state: Optional[
+ Literal[
+ "pending_onboarding",
+ "sync_pending",
+ "syncing",
+ "sync_complete",
+ "active",
+ "history_declined",
+ "sync_deadline_expired",
+ "offboarded",
+ "disconnected",
+ ]
+ ] = None
+ """Current lifecycle state for a coexistence number.
+
+ This is null for a standard Cloud API number.
+ """
+
created_at: Optional[datetime] = None
display_name: Optional[str] = None
enabled: Optional[bool] = None
+ is_on_biz_app: Optional[bool] = None
+ """
+ Indicates whether the number is connected to both the WhatsApp Business app and
+ Cloud API through WhatsApp Coexistence.
+ """
+
phone_number: Optional[str] = None
"""Phone number in E164 format"""
@@ -32,6 +74,18 @@ class PhoneNumberListResponse(BaseModel):
status: Optional[str] = None
+ sync_deadline: Optional[datetime] = None
+ """Deadline for initiating the current coexistence synchronization cycle.
+
+ This is null when no deadline applies.
+ """
+
+ sync_progress: Optional[SyncProgress] = None
+ """Synchronization progress.
+
+ This object is returned only while a coexistence number is synchronizing.
+ """
+
user_id: Optional[str] = None
"""User ID"""
diff --git a/src/telnyx/types/whatsapp/phone_number_get_response.py b/src/telnyx/types/whatsapp/phone_number_get_response.py
index 7123ef8dc..e1caf5441 100644
--- a/src/telnyx/types/whatsapp/phone_number_get_response.py
+++ b/src/telnyx/types/whatsapp/phone_number_get_response.py
@@ -4,22 +4,64 @@
from typing import List, Optional
from datetime import datetime
+from typing_extensions import Literal
from ..._models import BaseModel
from ..shared.messaging_pagination_meta import MessagingPaginationMeta
-__all__ = ["PhoneNumberGetResponse", "Data"]
+__all__ = ["PhoneNumberGetResponse", "Data", "DataSyncProgress"]
+
+
+class DataSyncProgress(BaseModel):
+ """Synchronization progress.
+
+ This object is returned only while a coexistence number is synchronizing.
+ """
+
+ contacts_status: Optional[str] = None
+
+ history_chunk_order: Optional[int] = None
+
+ history_phase: Optional[int] = None
+
+ history_progress: Optional[int] = None
+
+ history_status: Optional[str] = None
class Data(BaseModel):
calling_enabled: Optional[bool] = None
+ coexistence_state: Optional[
+ Literal[
+ "pending_onboarding",
+ "sync_pending",
+ "syncing",
+ "sync_complete",
+ "active",
+ "history_declined",
+ "sync_deadline_expired",
+ "offboarded",
+ "disconnected",
+ ]
+ ] = None
+ """Current lifecycle state for a coexistence number.
+
+ This is null for a standard Cloud API number.
+ """
+
created_at: Optional[datetime] = None
display_name: Optional[str] = None
enabled: Optional[bool] = None
+ is_on_biz_app: Optional[bool] = None
+ """
+ Indicates whether the number is connected to both the WhatsApp Business app and
+ Cloud API through WhatsApp Coexistence.
+ """
+
phone_number: Optional[str] = None
"""Phone number in E164 format"""
@@ -33,6 +75,18 @@ class Data(BaseModel):
status: Optional[str] = None
+ sync_deadline: Optional[datetime] = None
+ """Deadline for initiating the current coexistence synchronization cycle.
+
+ This is null when no deadline applies.
+ """
+
+ sync_progress: Optional[DataSyncProgress] = None
+ """Synchronization progress.
+
+ This object is returned only while a coexistence number is synchronizing.
+ """
+
user_id: Optional[str] = None
"""User ID"""
diff --git a/src/telnyx/types/whatsapp/phone_number_list_response.py b/src/telnyx/types/whatsapp/phone_number_list_response.py
index 6aefd3146..0d8e59fcf 100644
--- a/src/telnyx/types/whatsapp/phone_number_list_response.py
+++ b/src/telnyx/types/whatsapp/phone_number_list_response.py
@@ -4,21 +4,63 @@
from typing import Optional
from datetime import datetime
+from typing_extensions import Literal
from ..._models import BaseModel
-__all__ = ["PhoneNumberListResponse"]
+__all__ = ["PhoneNumberListResponse", "SyncProgress"]
+
+
+class SyncProgress(BaseModel):
+ """Synchronization progress.
+
+ This object is returned only while a coexistence number is synchronizing.
+ """
+
+ contacts_status: Optional[str] = None
+
+ history_chunk_order: Optional[int] = None
+
+ history_phase: Optional[int] = None
+
+ history_progress: Optional[int] = None
+
+ history_status: Optional[str] = None
class PhoneNumberListResponse(BaseModel):
calling_enabled: Optional[bool] = None
+ coexistence_state: Optional[
+ Literal[
+ "pending_onboarding",
+ "sync_pending",
+ "syncing",
+ "sync_complete",
+ "active",
+ "history_declined",
+ "sync_deadline_expired",
+ "offboarded",
+ "disconnected",
+ ]
+ ] = None
+ """Current lifecycle state for a coexistence number.
+
+ This is null for a standard Cloud API number.
+ """
+
created_at: Optional[datetime] = None
display_name: Optional[str] = None
enabled: Optional[bool] = None
+ is_on_biz_app: Optional[bool] = None
+ """
+ Indicates whether the number is connected to both the WhatsApp Business app and
+ Cloud API through WhatsApp Coexistence.
+ """
+
phone_number: Optional[str] = None
"""Phone number in E164 format"""
@@ -32,6 +74,18 @@ class PhoneNumberListResponse(BaseModel):
status: Optional[str] = None
+ sync_deadline: Optional[datetime] = None
+ """Deadline for initiating the current coexistence synchronization cycle.
+
+ This is null when no deadline applies.
+ """
+
+ sync_progress: Optional[SyncProgress] = None
+ """Synchronization progress.
+
+ This object is returned only while a coexistence number is synchronizing.
+ """
+
user_id: Optional[str] = None
"""User ID"""
diff --git a/src/telnyx/types/whatsapp/phone_number_retrieve_phone_number_response.py b/src/telnyx/types/whatsapp/phone_number_retrieve_phone_number_response.py
new file mode 100644
index 000000000..1bc577231
--- /dev/null
+++ b/src/telnyx/types/whatsapp/phone_number_retrieve_phone_number_response.py
@@ -0,0 +1,97 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["PhoneNumberRetrievePhoneNumberResponse", "Data", "DataSyncProgress"]
+
+
+class DataSyncProgress(BaseModel):
+ """Synchronization progress.
+
+ This object is returned only while a coexistence number is synchronizing.
+ """
+
+ contacts_status: Optional[str] = None
+
+ history_chunk_order: Optional[int] = None
+
+ history_phase: Optional[int] = None
+
+ history_progress: Optional[int] = None
+
+ history_status: Optional[str] = None
+
+
+class Data(BaseModel):
+ calling_enabled: Optional[bool] = None
+
+ coexistence_state: Optional[
+ Literal[
+ "pending_onboarding",
+ "sync_pending",
+ "syncing",
+ "sync_complete",
+ "active",
+ "history_declined",
+ "sync_deadline_expired",
+ "offboarded",
+ "disconnected",
+ ]
+ ] = None
+ """Current lifecycle state for a coexistence number.
+
+ This is null for a standard Cloud API number.
+ """
+
+ created_at: Optional[datetime] = None
+
+ display_name: Optional[str] = None
+
+ enabled: Optional[bool] = None
+
+ is_on_biz_app: Optional[bool] = None
+ """
+ Indicates whether the number is connected to both the WhatsApp Business app and
+ Cloud API through WhatsApp Coexistence.
+ """
+
+ phone_number: Optional[str] = None
+ """Phone number in E164 format"""
+
+ phone_number_id: Optional[str] = None
+ """Whatsapp phone number ID"""
+
+ quality_rating: Optional[str] = None
+ """Whatsapp quality rating"""
+
+ record_type: Optional[str] = None
+
+ status: Optional[str] = None
+
+ sync_deadline: Optional[datetime] = None
+ """Deadline for initiating the current coexistence synchronization cycle.
+
+ This is null when no deadline applies.
+ """
+
+ sync_progress: Optional[DataSyncProgress] = None
+ """Synchronization progress.
+
+ This object is returned only while a coexistence number is synchronizing.
+ """
+
+ user_id: Optional[str] = None
+ """User ID"""
+
+ waba_id: Optional[str] = None
+ """WABA ID of Whatsapp business account"""
+
+
+class PhoneNumberRetrievePhoneNumberResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/whatsapp_account_update.py b/src/telnyx/types/whatsapp_account_update.py
new file mode 100644
index 000000000..9ef28e4f6
--- /dev/null
+++ b/src/telnyx/types/whatsapp_account_update.py
@@ -0,0 +1,41 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["WhatsappAccountUpdate", "Data", "DataPayload"]
+
+
+class DataPayload(BaseModel):
+ event: str
+ """Account event reported by Meta.
+
+ Coexistence lifecycle values include `ACCOUNT_OFFBOARDED`,
+ `ACCOUNT_RECONNECTED`, and `PARTNER_REMOVED`. Preserve unknown values for
+ forward compatibility.
+ """
+
+ record_type: Literal["whatsapp_account"]
+
+ waba_id: str
+ """Meta WhatsApp Business Account identifier."""
+
+
+class Data(BaseModel):
+ id: str
+
+ event_type: Literal["whatsapp.account.update"]
+
+ occurred_at: datetime
+
+ payload: DataPayload
+
+ record_type: Literal["event"]
+
+
+class WhatsappAccountUpdate(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/whatsapp_message_echo.py b/src/telnyx/types/whatsapp_message_echo.py
new file mode 100644
index 000000000..d0dc010bb
--- /dev/null
+++ b/src/telnyx/types/whatsapp_message_echo.py
@@ -0,0 +1,127 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Dict, List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from pydantic import Field as FieldInfo
+
+from .._models import BaseModel
+from .messaging_error_0b38e7044b import MessagingError0b38e7044b
+
+__all__ = ["WhatsappMessageEcho", "Data", "DataPayload", "DataPayloadBody", "DataPayloadCost", "DataPayloadFrom"]
+
+
+class DataPayloadBody(BaseModel):
+ """Mirrored WhatsApp message content.
+
+ The content property matches the value of `type`.
+ """
+
+ id: str
+ """Telnyx identifier for the mirrored message."""
+
+ foreign_id: str
+ """Meta WhatsApp message identifier, also known as a wamid."""
+
+ timestamp: str
+ """Unix timestamp supplied by Meta."""
+
+ type: str
+ """WhatsApp message content type."""
+
+ from_: Optional[str] = FieldInfo(alias="from", default=None)
+ """WhatsApp user who received the message."""
+
+ from_user_id: Optional[str] = None
+ """Opaque recipient identifier when Meta does not supply a phone number."""
+
+ if TYPE_CHECKING:
+ # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a
+ # value to this field, so for compatibility we avoid doing it at runtime.
+ __pydantic_extra__: Dict[str, object] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride]
+
+ # Stub to indicate that arbitrary properties are accepted.
+ # To access properties that are not valid identifiers you can use `getattr`, e.g.
+ # `getattr(obj, '$type')`
+ def __getattr__(self, attr: str) -> object: ...
+ else:
+ __pydantic_extra__: Dict[str, object]
+
+
+class DataPayloadCost(BaseModel):
+ """No charge is created for a Business app message echo."""
+
+ amount: Optional[str] = None
+
+ currency: Optional[str] = None
+
+
+class DataPayloadFrom(BaseModel):
+ phone_number: str
+ """Coexistence-enabled business phone number in E.164 format."""
+
+ carrier: Optional[str] = None
+
+ line_type: Optional[str] = None
+
+
+class DataPayload(BaseModel):
+ id: str
+ """Telnyx identifier for the mirrored message."""
+
+ body: DataPayloadBody
+ """Mirrored WhatsApp message content.
+
+ The content property matches the value of `type`.
+ """
+
+ cost: DataPayloadCost
+ """No charge is created for a Business app message echo."""
+
+ direction: Literal["outbound"]
+ """Indicates that the business sent the message to the WhatsApp user."""
+
+ errors: List[MessagingError0b38e7044b]
+
+ from_: DataPayloadFrom = FieldInfo(alias="from")
+
+ messaging_profile_id: str
+
+ organization_id: str
+
+ origin: Literal["whatsapp_business_app"]
+ """Identifies the WhatsApp Business app as the source of the message."""
+
+ record_type: Literal["message"]
+
+ to: str
+ """WhatsApp user who received the Business app message."""
+
+ type: Literal["WHATSAPP"]
+
+ received_at: Optional[datetime] = None
+
+ tags: Optional[List[str]] = None
+
+ webhook_failover_url: Optional[str] = None
+
+ webhook_url: Optional[str] = None
+
+
+class Data(BaseModel):
+ id: str
+
+ event_type: Literal["message.echo"]
+
+ occurred_at: datetime
+
+ payload: DataPayload
+
+ record_type: Literal["event"]
+
+
+class WhatsappMessageEcho(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/x402/credit_account/__init__.py b/src/telnyx/types/x402/credit_account/__init__.py
new file mode 100644
index 000000000..aaf3d85aa
--- /dev/null
+++ b/src/telnyx/types/x402/credit_account/__init__.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any
+
+from .payment_list_params import PaymentListParams as PaymentListParams
+
+if TYPE_CHECKING:
+ from .x402_transaction_record import X402TransactionRecord as X402TransactionRecord
+ from .payment_retrieve_response import PaymentRetrieveResponse as PaymentRetrieveResponse
+
+
+def __getattr__(name: str) -> Any:
+ if name == "X402TransactionRecord":
+ from .x402_transaction_record import X402TransactionRecord
+
+ return X402TransactionRecord
+ if name == "PaymentRetrieveResponse":
+ from .payment_retrieve_response import PaymentRetrieveResponse
+
+ return PaymentRetrieveResponse
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
diff --git a/src/telnyx/types/x402/credit_account/payment_list_params.py b/src/telnyx/types/x402/credit_account/payment_list_params.py
new file mode 100644
index 000000000..f697acd85
--- /dev/null
+++ b/src/telnyx/types/x402/credit_account/payment_list_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["PaymentListParams"]
+
+
+class PaymentListParams(TypedDict, total=False):
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """The page number to load."""
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """The size of the page."""
diff --git a/src/telnyx/types/x402/credit_account/payment_retrieve_response.py b/src/telnyx/types/x402/credit_account/payment_retrieve_response.py
new file mode 100644
index 000000000..07fd68868
--- /dev/null
+++ b/src/telnyx/types/x402/credit_account/payment_retrieve_response.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+
+from ...._models import BaseModel
+from .x402_transaction_record import X402TransactionRecord
+
+__all__ = ["PaymentRetrieveResponse"]
+
+
+class PaymentRetrieveResponse(BaseModel):
+ data: Optional[X402TransactionRecord] = None
+ """An x402 payment transaction."""
diff --git a/src/telnyx/types/x402/credit_account/x402_transaction_record.py b/src/telnyx/types/x402/credit_account/x402_transaction_record.py
new file mode 100644
index 000000000..bf5fa80b7
--- /dev/null
+++ b/src/telnyx/types/x402/credit_account/x402_transaction_record.py
@@ -0,0 +1,45 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["X402TransactionRecord"]
+
+
+class X402TransactionRecord(BaseModel):
+ """An x402 payment transaction."""
+
+ id: Optional[str] = None
+ """Unique transaction identifier."""
+
+ amount: Optional[str] = None
+ """The transaction amount in the specified currency."""
+
+ created_at: Optional[datetime] = None
+ """ISO 8601 timestamp when the transaction was created."""
+
+ currency: Optional[str] = None
+ """The currency of the transaction amount (e.g. USD)."""
+
+ quote_id: Optional[str] = None
+ """The original quote ID associated with this transaction."""
+
+ record_type: Optional[Literal["x402_transaction"]] = None
+
+ status: Optional[Literal["settled"]] = None
+ """The settlement status of the transaction.
+
+ x402 transactions are created after successful on-chain settlement, so the
+ status is `settled`.
+ """
+
+ tx_hash: Optional[str] = None
+ """The on-chain transaction hash, if available."""
+
+ updated_at: Optional[datetime] = None
+ """ISO 8601 timestamp when the transaction was last updated."""
diff --git a/tests/api_resources/ai/assistants/test_versions.py b/tests/api_resources/ai/assistants/test_versions.py
index dca4e6a1c..76f1f978b 100644
--- a/tests/api_resources/ai/assistants/test_versions.py
+++ b/tests/api_resources/ai/assistants/test_versions.py
@@ -97,6 +97,28 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None:
version = client.ai.assistants.versions.update(
version_id="version_id",
assistant_id="assistant_id",
+ a2a_agents=[
+ {
+ "name": "billing_agent",
+ "url": "https://agents.example.com",
+ "async": True,
+ "headers": [
+ {
+ "name": "X-Api-Key",
+ "value": "{{#integration_secret}}my_agent_api_key{{/integration_secret}}",
+ }
+ ],
+ "messages": [
+ {
+ "content": "x",
+ "type": "request_start",
+ "timing_ms": 100,
+ }
+ ],
+ "poll_interval_ms": 500,
+ "timeout_ms": 30000,
+ }
+ ],
conversation_flow={
"nodes": [
{
@@ -337,6 +359,7 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None:
telephony_settings={
"default_texml_app_id": "default_texml_app_id",
"disable_dtmf": True,
+ "fallback_destination": "fallback_destination",
"noise_suppression": "krisp",
"noise_suppression_config": {
"attenuation_limit": 0,
@@ -760,6 +783,28 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) ->
version = await async_client.ai.assistants.versions.update(
version_id="version_id",
assistant_id="assistant_id",
+ a2a_agents=[
+ {
+ "name": "billing_agent",
+ "url": "https://agents.example.com",
+ "async": True,
+ "headers": [
+ {
+ "name": "X-Api-Key",
+ "value": "{{#integration_secret}}my_agent_api_key{{/integration_secret}}",
+ }
+ ],
+ "messages": [
+ {
+ "content": "x",
+ "type": "request_start",
+ "timing_ms": 100,
+ }
+ ],
+ "poll_interval_ms": 500,
+ "timeout_ms": 30000,
+ }
+ ],
conversation_flow={
"nodes": [
{
@@ -1000,6 +1045,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) ->
telephony_settings={
"default_texml_app_id": "default_texml_app_id",
"disable_dtmf": True,
+ "fallback_destination": "fallback_destination",
"noise_suppression": "krisp",
"noise_suppression_config": {
"attenuation_limit": 0,
diff --git a/tests/api_resources/ai/openai/test_chat.py b/tests/api_resources/ai/openai/test_chat.py
index fb94da2bb..bde11e416 100644
--- a/tests/api_resources/ai/openai/test_chat.py
+++ b/tests/api_resources/ai/openai/test_chat.py
@@ -53,9 +53,6 @@ def test_method_create_completion_with_all_params(self, client: Telnyx) -> None:
early_stopping=True,
enable_thinking=True,
frequency_penalty=0,
- guided_choice=["string"],
- guided_json={"foo": "bar"},
- guided_regex="guided_regex",
length_penalty=0,
logprobs=True,
max_tokens=0,
@@ -175,9 +172,6 @@ async def test_method_create_completion_with_all_params(self, async_client: Asyn
early_stopping=True,
enable_thinking=True,
frequency_penalty=0,
- guided_choice=["string"],
- guided_json={"foo": "bar"},
- guided_regex="guided_regex",
length_penalty=0,
logprobs=True,
max_tokens=0,
diff --git a/tests/api_resources/ai/test_assistants.py b/tests/api_resources/ai/test_assistants.py
index 7b2e66ed1..4a7420ec0 100644
--- a/tests/api_resources/ai/test_assistants.py
+++ b/tests/api_resources/ai/test_assistants.py
@@ -38,6 +38,28 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None:
assistant = client.ai.assistants.create(
instructions="instructions",
name="name",
+ a2a_agents=[
+ {
+ "name": "billing_agent",
+ "url": "https://agents.example.com",
+ "async": True,
+ "headers": [
+ {
+ "name": "X-Api-Key",
+ "value": "{{#integration_secret}}my_agent_api_key{{/integration_secret}}",
+ }
+ ],
+ "messages": [
+ {
+ "content": "x",
+ "type": "request_start",
+ "timing_ms": 100,
+ }
+ ],
+ "poll_interval_ms": 500,
+ "timeout_ms": 30000,
+ }
+ ],
conversation_flow={
"nodes": [
{
@@ -276,6 +298,7 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None:
telephony_settings={
"default_texml_app_id": "default_texml_app_id",
"disable_dtmf": True,
+ "fallback_destination": "fallback_destination",
"noise_suppression": "krisp",
"noise_suppression_config": {
"attenuation_limit": 0,
@@ -522,6 +545,28 @@ def test_method_update(self, client: Telnyx) -> None:
def test_method_update_with_all_params(self, client: Telnyx) -> None:
assistant = client.ai.assistants.update(
assistant_id="assistant_id",
+ a2a_agents=[
+ {
+ "name": "billing_agent",
+ "url": "https://agents.example.com",
+ "async": True,
+ "headers": [
+ {
+ "name": "X-Api-Key",
+ "value": "{{#integration_secret}}my_agent_api_key{{/integration_secret}}",
+ }
+ ],
+ "messages": [
+ {
+ "content": "x",
+ "type": "request_start",
+ "timing_ms": 100,
+ }
+ ],
+ "poll_interval_ms": 500,
+ "timeout_ms": 30000,
+ }
+ ],
conversation_flow={
"nodes": [
{
@@ -763,6 +808,7 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None:
telephony_settings={
"default_texml_app_id": "default_texml_app_id",
"disable_dtmf": True,
+ "fallback_destination": "fallback_destination",
"noise_suppression": "krisp",
"noise_suppression_config": {
"attenuation_limit": 0,
@@ -1306,6 +1352,28 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) ->
assistant = await async_client.ai.assistants.create(
instructions="instructions",
name="name",
+ a2a_agents=[
+ {
+ "name": "billing_agent",
+ "url": "https://agents.example.com",
+ "async": True,
+ "headers": [
+ {
+ "name": "X-Api-Key",
+ "value": "{{#integration_secret}}my_agent_api_key{{/integration_secret}}",
+ }
+ ],
+ "messages": [
+ {
+ "content": "x",
+ "type": "request_start",
+ "timing_ms": 100,
+ }
+ ],
+ "poll_interval_ms": 500,
+ "timeout_ms": 30000,
+ }
+ ],
conversation_flow={
"nodes": [
{
@@ -1544,6 +1612,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) ->
telephony_settings={
"default_texml_app_id": "default_texml_app_id",
"disable_dtmf": True,
+ "fallback_destination": "fallback_destination",
"noise_suppression": "krisp",
"noise_suppression_config": {
"attenuation_limit": 0,
@@ -1790,6 +1859,28 @@ async def test_method_update(self, async_client: AsyncTelnyx) -> None:
async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> None:
assistant = await async_client.ai.assistants.update(
assistant_id="assistant_id",
+ a2a_agents=[
+ {
+ "name": "billing_agent",
+ "url": "https://agents.example.com",
+ "async": True,
+ "headers": [
+ {
+ "name": "X-Api-Key",
+ "value": "{{#integration_secret}}my_agent_api_key{{/integration_secret}}",
+ }
+ ],
+ "messages": [
+ {
+ "content": "x",
+ "type": "request_start",
+ "timing_ms": 100,
+ }
+ ],
+ "poll_interval_ms": 500,
+ "timeout_ms": 30000,
+ }
+ ],
conversation_flow={
"nodes": [
{
@@ -2031,6 +2122,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) ->
telephony_settings={
"default_texml_app_id": "default_texml_app_id",
"disable_dtmf": True,
+ "fallback_destination": "fallback_destination",
"noise_suppression": "krisp",
"noise_suppression_config": {
"attenuation_limit": 0,
diff --git a/tests/api_resources/compute/__init__.py b/tests/api_resources/compute/__init__.py
new file mode 100644
index 000000000..fd8019a9a
--- /dev/null
+++ b/tests/api_resources/compute/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/compute/test_funcs.py b/tests/api_resources/compute/test_funcs.py
new file mode 100644
index 000000000..286d348ce
--- /dev/null
+++ b/tests/api_resources/compute/test_funcs.py
@@ -0,0 +1,454 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from telnyx import Telnyx, AsyncTelnyx
+from tests.utils import assert_matches_type
+from telnyx._utils import parse_datetime
+from telnyx.types.compute import (
+ FuncRetrieveLogsResponse,
+ FuncRetrieveRevisionsResponse,
+ FuncRetrieveShipInspectionResponse,
+ FuncRetrieveMetricAggregatesResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestFuncs:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_logs(self, client: Telnyx) -> None:
+ func = client.compute.funcs.retrieve_logs(
+ id="id",
+ )
+ assert_matches_type(FuncRetrieveLogsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_logs_with_all_params(self, client: Telnyx) -> None:
+ func = client.compute.funcs.retrieve_logs(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ limit=1,
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ type="runtime",
+ )
+ assert_matches_type(FuncRetrieveLogsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve_logs(self, client: Telnyx) -> None:
+ response = client.compute.funcs.with_raw_response.retrieve_logs(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ func = response.parse()
+ assert_matches_type(FuncRetrieveLogsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve_logs(self, client: Telnyx) -> None:
+ with client.compute.funcs.with_streaming_response.retrieve_logs(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ func = response.parse()
+ assert_matches_type(FuncRetrieveLogsResponse, func, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve_logs(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.compute.funcs.with_raw_response.retrieve_logs(
+ id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_metric_aggregates(self, client: Telnyx) -> None:
+ func = client.compute.funcs.retrieve_metric_aggregates(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(FuncRetrieveMetricAggregatesResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_metric_aggregates_with_all_params(self, client: Telnyx) -> None:
+ func = client.compute.funcs.retrieve_metric_aggregates(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ filter_edge_site="filter[edge_site]",
+ filter_namespace="filter[namespace]",
+ page_number=0,
+ page_size=1,
+ )
+ assert_matches_type(FuncRetrieveMetricAggregatesResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve_metric_aggregates(self, client: Telnyx) -> None:
+ response = client.compute.funcs.with_raw_response.retrieve_metric_aggregates(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ func = response.parse()
+ assert_matches_type(FuncRetrieveMetricAggregatesResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve_metric_aggregates(self, client: Telnyx) -> None:
+ with client.compute.funcs.with_streaming_response.retrieve_metric_aggregates(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ func = response.parse()
+ assert_matches_type(FuncRetrieveMetricAggregatesResponse, func, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve_metric_aggregates(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.compute.funcs.with_raw_response.retrieve_metric_aggregates(
+ id="",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_revisions(self, client: Telnyx) -> None:
+ func = client.compute.funcs.retrieve_revisions(
+ id="id",
+ )
+ assert_matches_type(FuncRetrieveRevisionsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_revisions_with_all_params(self, client: Telnyx) -> None:
+ func = client.compute.funcs.retrieve_revisions(
+ id="id",
+ page_number=1,
+ page_size=1,
+ )
+ assert_matches_type(FuncRetrieveRevisionsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve_revisions(self, client: Telnyx) -> None:
+ response = client.compute.funcs.with_raw_response.retrieve_revisions(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ func = response.parse()
+ assert_matches_type(FuncRetrieveRevisionsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve_revisions(self, client: Telnyx) -> None:
+ with client.compute.funcs.with_streaming_response.retrieve_revisions(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ func = response.parse()
+ assert_matches_type(FuncRetrieveRevisionsResponse, func, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve_revisions(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.compute.funcs.with_raw_response.retrieve_revisions(
+ id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_ship_inspection(self, client: Telnyx) -> None:
+ func = client.compute.funcs.retrieve_ship_inspection(
+ "id",
+ )
+ assert_matches_type(FuncRetrieveShipInspectionResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve_ship_inspection(self, client: Telnyx) -> None:
+ response = client.compute.funcs.with_raw_response.retrieve_ship_inspection(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ func = response.parse()
+ assert_matches_type(FuncRetrieveShipInspectionResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve_ship_inspection(self, client: Telnyx) -> None:
+ with client.compute.funcs.with_streaming_response.retrieve_ship_inspection(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ func = response.parse()
+ assert_matches_type(FuncRetrieveShipInspectionResponse, func, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve_ship_inspection(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.compute.funcs.with_raw_response.retrieve_ship_inspection(
+ "",
+ )
+
+
+class TestAsyncFuncs:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_logs(self, async_client: AsyncTelnyx) -> None:
+ func = await async_client.compute.funcs.retrieve_logs(
+ id="id",
+ )
+ assert_matches_type(FuncRetrieveLogsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_logs_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ func = await async_client.compute.funcs.retrieve_logs(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ limit=1,
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ type="runtime",
+ )
+ assert_matches_type(FuncRetrieveLogsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve_logs(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.compute.funcs.with_raw_response.retrieve_logs(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ func = await response.parse()
+ assert_matches_type(FuncRetrieveLogsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve_logs(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.compute.funcs.with_streaming_response.retrieve_logs(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ func = await response.parse()
+ assert_matches_type(FuncRetrieveLogsResponse, func, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_retrieve_logs(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.compute.funcs.with_raw_response.retrieve_logs(
+ id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_metric_aggregates(self, async_client: AsyncTelnyx) -> None:
+ func = await async_client.compute.funcs.retrieve_metric_aggregates(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+ assert_matches_type(FuncRetrieveMetricAggregatesResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_metric_aggregates_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ func = await async_client.compute.funcs.retrieve_metric_aggregates(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ filter_edge_site="filter[edge_site]",
+ filter_namespace="filter[namespace]",
+ page_number=0,
+ page_size=1,
+ )
+ assert_matches_type(FuncRetrieveMetricAggregatesResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve_metric_aggregates(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.compute.funcs.with_raw_response.retrieve_metric_aggregates(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ func = await response.parse()
+ assert_matches_type(FuncRetrieveMetricAggregatesResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve_metric_aggregates(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.compute.funcs.with_streaming_response.retrieve_metric_aggregates(
+ id="id",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ func = await response.parse()
+ assert_matches_type(FuncRetrieveMetricAggregatesResponse, func, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_retrieve_metric_aggregates(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.compute.funcs.with_raw_response.retrieve_metric_aggregates(
+ id="",
+ end_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ start_time=parse_datetime("2019-12-27T18:11:19.117Z"),
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_revisions(self, async_client: AsyncTelnyx) -> None:
+ func = await async_client.compute.funcs.retrieve_revisions(
+ id="id",
+ )
+ assert_matches_type(FuncRetrieveRevisionsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_revisions_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ func = await async_client.compute.funcs.retrieve_revisions(
+ id="id",
+ page_number=1,
+ page_size=1,
+ )
+ assert_matches_type(FuncRetrieveRevisionsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve_revisions(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.compute.funcs.with_raw_response.retrieve_revisions(
+ id="id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ func = await response.parse()
+ assert_matches_type(FuncRetrieveRevisionsResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve_revisions(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.compute.funcs.with_streaming_response.retrieve_revisions(
+ id="id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ func = await response.parse()
+ assert_matches_type(FuncRetrieveRevisionsResponse, func, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_retrieve_revisions(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.compute.funcs.with_raw_response.retrieve_revisions(
+ id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_ship_inspection(self, async_client: AsyncTelnyx) -> None:
+ func = await async_client.compute.funcs.retrieve_ship_inspection(
+ "id",
+ )
+ assert_matches_type(FuncRetrieveShipInspectionResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve_ship_inspection(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.compute.funcs.with_raw_response.retrieve_ship_inspection(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ func = await response.parse()
+ assert_matches_type(FuncRetrieveShipInspectionResponse, func, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve_ship_inspection(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.compute.funcs.with_streaming_response.retrieve_ship_inspection(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ func = await response.parse()
+ assert_matches_type(FuncRetrieveShipInspectionResponse, func, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_retrieve_ship_inspection(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.compute.funcs.with_raw_response.retrieve_ship_inspection(
+ "",
+ )
diff --git a/tests/api_resources/test_messaging_profiles.py b/tests/api_resources/test_messaging_profiles.py
index 0b5a166b6..dad0260e9 100644
--- a/tests/api_resources/test_messaging_profiles.py
+++ b/tests/api_resources/test_messaging_profiles.py
@@ -47,6 +47,7 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None:
daily_spend_limit="269125115713",
daily_spend_limit_enabled=True,
enabled=True,
+ features={"ai_opt_out_detection_enabled": True},
health_webhook_url="health_webhook_url",
mms_fall_back_to_sms=True,
mms_transcoding=True,
@@ -160,6 +161,7 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None:
daily_spend_limit="269125115713",
daily_spend_limit_enabled=True,
enabled=True,
+ features={"ai_opt_out_detection_enabled": True},
mms_fall_back_to_sms=True,
mms_transcoding=True,
mobile_only=True,
@@ -547,6 +549,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) ->
daily_spend_limit="269125115713",
daily_spend_limit_enabled=True,
enabled=True,
+ features={"ai_opt_out_detection_enabled": True},
health_webhook_url="health_webhook_url",
mms_fall_back_to_sms=True,
mms_transcoding=True,
@@ -660,6 +663,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) ->
daily_spend_limit="269125115713",
daily_spend_limit_enabled=True,
enabled=True,
+ features={"ai_opt_out_detection_enabled": True},
mms_fall_back_to_sms=True,
mms_transcoding=True,
mobile_only=True,
diff --git a/tests/api_resources/whatsapp/test_phone_numbers.py b/tests/api_resources/whatsapp/test_phone_numbers.py
index 9c7d71ace..e96722396 100644
--- a/tests/api_resources/whatsapp/test_phone_numbers.py
+++ b/tests/api_resources/whatsapp/test_phone_numbers.py
@@ -13,6 +13,7 @@
from telnyx.types.whatsapp import (
PhoneNumberGetResponse,
PhoneNumberListResponse,
+ PhoneNumberRetrievePhoneNumberResponse,
PhoneNumberRetrieveConversationWindowResponse,
)
@@ -235,6 +236,48 @@ def test_path_params_retrieve_conversation_window(self, client: Telnyx) -> None:
destination_number="+353894650851",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve_phone_number(self, client: Telnyx) -> None:
+ phone_number = client.whatsapp.phone_numbers.retrieve_phone_number(
+ "phone_number",
+ )
+ assert_matches_type(PhoneNumberRetrievePhoneNumberResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve_phone_number(self, client: Telnyx) -> None:
+ response = client.whatsapp.phone_numbers.with_raw_response.retrieve_phone_number(
+ "phone_number",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number = response.parse()
+ assert_matches_type(PhoneNumberRetrievePhoneNumberResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve_phone_number(self, client: Telnyx) -> None:
+ with client.whatsapp.phone_numbers.with_streaming_response.retrieve_phone_number(
+ "phone_number",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number = response.parse()
+ assert_matches_type(PhoneNumberRetrievePhoneNumberResponse, phone_number, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve_phone_number(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `phone_number` but received ''"):
+ client.whatsapp.phone_numbers.with_raw_response.retrieve_phone_number(
+ "",
+ )
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_verify(self, client: Telnyx) -> None:
@@ -500,6 +543,48 @@ async def test_path_params_retrieve_conversation_window(self, async_client: Asyn
destination_number="+353894650851",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve_phone_number(self, async_client: AsyncTelnyx) -> None:
+ phone_number = await async_client.whatsapp.phone_numbers.retrieve_phone_number(
+ "phone_number",
+ )
+ assert_matches_type(PhoneNumberRetrievePhoneNumberResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve_phone_number(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.whatsapp.phone_numbers.with_raw_response.retrieve_phone_number(
+ "phone_number",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number = await response.parse()
+ assert_matches_type(PhoneNumberRetrievePhoneNumberResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve_phone_number(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.whatsapp.phone_numbers.with_streaming_response.retrieve_phone_number(
+ "phone_number",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number = await response.parse()
+ assert_matches_type(PhoneNumberRetrievePhoneNumberResponse, phone_number, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_retrieve_phone_number(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `phone_number` but received ''"):
+ await async_client.whatsapp.phone_numbers.with_raw_response.retrieve_phone_number(
+ "",
+ )
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_verify(self, async_client: AsyncTelnyx) -> None:
diff --git a/tests/api_resources/x402/credit_account/__init__.py b/tests/api_resources/x402/credit_account/__init__.py
new file mode 100644
index 000000000..fd8019a9a
--- /dev/null
+++ b/tests/api_resources/x402/credit_account/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/x402/credit_account/test_payments.py b/tests/api_resources/x402/credit_account/test_payments.py
new file mode 100644
index 000000000..74748ba5d
--- /dev/null
+++ b/tests/api_resources/x402/credit_account/test_payments.py
@@ -0,0 +1,183 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from telnyx import Telnyx, AsyncTelnyx
+from tests.utils import assert_matches_type
+from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+from telnyx.types.x402.credit_account import X402TransactionRecord, PaymentRetrieveResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestPayments:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve(self, client: Telnyx) -> None:
+ payment = client.x402.credit_account.payments.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(PaymentRetrieveResponse, payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: Telnyx) -> None:
+ response = client.x402.credit_account.payments.with_raw_response.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ payment = response.parse()
+ assert_matches_type(PaymentRetrieveResponse, payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Telnyx) -> None:
+ with client.x402.credit_account.payments.with_streaming_response.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ payment = response.parse()
+ assert_matches_type(PaymentRetrieveResponse, payment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_retrieve(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.x402.credit_account.payments.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Telnyx) -> None:
+ payment = client.x402.credit_account.payments.list()
+ assert_matches_type(SyncDefaultFlatPagination[X402TransactionRecord], payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Telnyx) -> None:
+ payment = client.x402.credit_account.payments.list(
+ page_number=1,
+ page_size=1,
+ )
+ assert_matches_type(SyncDefaultFlatPagination[X402TransactionRecord], payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Telnyx) -> None:
+ response = client.x402.credit_account.payments.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ payment = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[X402TransactionRecord], payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Telnyx) -> None:
+ with client.x402.credit_account.payments.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ payment = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[X402TransactionRecord], payment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncPayments:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
+ payment = await async_client.x402.credit_account.payments.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(PaymentRetrieveResponse, payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.x402.credit_account.payments.with_raw_response.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ payment = await response.parse()
+ assert_matches_type(PaymentRetrieveResponse, payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.x402.credit_account.payments.with_streaming_response.retrieve(
+ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ payment = await response.parse()
+ assert_matches_type(PaymentRetrieveResponse, payment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_retrieve(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.x402.credit_account.payments.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncTelnyx) -> None:
+ payment = await async_client.x402.credit_account.payments.list()
+ assert_matches_type(AsyncDefaultFlatPagination[X402TransactionRecord], payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ payment = await async_client.x402.credit_account.payments.list(
+ page_number=1,
+ page_size=1,
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[X402TransactionRecord], payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.x402.credit_account.payments.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ payment = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[X402TransactionRecord], payment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.x402.credit_account.payments.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ payment = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[X402TransactionRecord], payment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True