diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index e7dafb47..195f950f 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "4.151.0"
+ ".": "4.152.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index e1653505..bbfd6264 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 1047
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx/telnyx-f0b674236fbd66f50b5a1706fafd8cb681459cf05379967fd1f043d38d6d476d.yml
-openapi_spec_hash: 7ae2cfe4f10fc24e4376fd15cd3455e8
-config_hash: da8cae8a6100e4d90af920e222524d09
+configured_endpoints: 1076
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/telnyx/telnyx-7b8d117e2646843c69453ee88c0f30b7384c3764fbbc72c69f10a2b362bc0b44.yml
+openapi_spec_hash: c1cb5e3e98c7a71c43fa94dc87635d25
+config_hash: 5ce01cd30f63029e0b785a241c80bae4
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3aac0bfb..e4a7a581 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 4.152.0 (2026-06-05)
+
+Full Changelog: [v4.151.0...v4.152.0](https://github.com/team-telnyx/telnyx-python/compare/v4.151.0...v4.152.0)
+
+### Features
+
+* NUM-6470: Add branded-calling-v2 OpenAPI specs (external + internal) ([a2c999f](https://github.com/team-telnyx/telnyx-python/commit/a2c999f01668f86406e50c6a32fbefc099ae938b))
+
## 4.151.0 (2026-06-05)
Full Changelog: [v4.150.0...v4.151.0](https://github.com/team-telnyx/telnyx-python/compare/v4.150.0...v4.151.0)
diff --git a/api.md b/api.md
index ed55ffb2..f8e9a358 100644
--- a/api.md
+++ b/api.md
@@ -23,7 +23,6 @@ from telnyx.types import (
MessagingFeatureSet,
MessagingHostedNumberOrder,
MessagingPaginationMeta,
- MetaInfo,
Metadata,
MinimaxVoiceSettings,
NetappsLocation,
@@ -34,7 +33,6 @@ from telnyx.types import (
PortingOrdersExceptionType,
RegionInformation,
ReputationData,
- ReputationPhoneNumberWithReputationData,
ResembleVoiceSettings,
RimeVoiceSettings,
RoomParticipant,
@@ -43,7 +41,6 @@ from telnyx.types import (
SimpleSimCard,
SubNumberOrderRegulatoryRequirementWithValue,
WhatsappTemplateData,
- XaiVoiceSettings,
)
```
@@ -573,7 +570,6 @@ Types:
```python
from telnyx.types import (
- ModelMetadata,
AICreateResponseDeprecatedResponse,
AIRetrieveModelsResponse,
AISummarizeResponse,
@@ -593,33 +589,22 @@ Types:
```python
from telnyx.types.ai import (
Assistant,
- AssistantIntegration,
- AssistantMcpServer,
AssistantTool,
AssistantsList,
AudioVisualizerConfig,
EnabledFeatures,
- ExternalLlm,
- ExternalLlmReq,
- FallbackConfig,
- FallbackConfigReq,
HangupTool,
HangupToolParams,
ImportMetadata,
InferenceEmbedding,
- InferenceEmbeddingInterruptionSettings,
InferenceEmbeddingWebhookToolParams,
InsightSettings,
MessagingSettings,
Observability,
ObservabilityReq,
- PostConversationSettings,
- PostConversationSettingsReq,
PrivacySettings,
RetrievalTool,
- StartSpeakingPlan,
TelephonySettings,
- TranscriptionEndpointingPlan,
TranscriptionSettings,
TranscriptionSettingsConfig,
TransferTool,
@@ -710,15 +695,7 @@ Methods:
Types:
```python
-from telnyx.types.ai.assistants import (
- CanaryDeploy,
- CanaryDeployResponse,
- Clause,
- RolloutSlot,
- RuleInput,
- RuleOutput,
- Serve,
-)
+from telnyx.types.ai.assistants import CanaryDeploy, CanaryDeployResponse
```
Methods:
@@ -1453,13 +1430,11 @@ from telnyx.types.calls import (
TelnyxVoiceSettings,
TranscriptionConfig,
TranscriptionEngineAConfig,
- TranscriptionEngineAssemblyaiConfig,
TranscriptionEngineAzureConfig,
TranscriptionEngineBConfig,
TranscriptionEngineDeepgramConfig,
TranscriptionEngineGoogleConfig,
TranscriptionEngineTelnyxConfig,
- TranscriptionEngineXaiConfig,
TranscriptionStartRequest,
ActionAddAIAssistantMessagesResponse,
ActionAnswerResponse,
@@ -3710,9 +3685,9 @@ Types:
from telnyx.types import (
NetworkInterface,
NetworkInterfaceRegion,
- PublicInternetGatewayRead,
PublicInternetGatewayCreateResponse,
PublicInternetGatewayRetrieveResponse,
+ PublicInternetGatewayListResponse,
PublicInternetGatewayDeleteResponse,
)
```
@@ -3721,7 +3696,7 @@ Methods:
- client.public_internet_gateways.create(\*\*params) -> PublicInternetGatewayCreateResponse
- client.public_internet_gateways.retrieve(id) -> PublicInternetGatewayRetrieveResponse
-- client.public_internet_gateways.list(\*\*params) -> SyncDefaultFlatPagination[PublicInternetGatewayRead]
+- client.public_internet_gateways.list(\*\*params) -> SyncDefaultFlatPagination[PublicInternetGatewayListResponse]
- client.public_internet_gateways.delete(id) -> PublicInternetGatewayDeleteResponse
# Queues
@@ -4806,10 +4781,10 @@ Types:
```python
from telnyx.types import (
- VirtualCrossConnectCombined,
VirtualCrossConnectCreateResponse,
VirtualCrossConnectRetrieveResponse,
VirtualCrossConnectUpdateResponse,
+ VirtualCrossConnectListResponse,
VirtualCrossConnectDeleteResponse,
)
```
@@ -4819,7 +4794,7 @@ Methods:
- client.virtual_cross_connects.create(\*\*params) -> VirtualCrossConnectCreateResponse
- client.virtual_cross_connects.retrieve(id) -> VirtualCrossConnectRetrieveResponse
- client.virtual_cross_connects.update(id, \*\*params) -> VirtualCrossConnectUpdateResponse
-- client.virtual_cross_connects.list(\*\*params) -> SyncDefaultFlatPagination[VirtualCrossConnectCombined]
+- client.virtual_cross_connects.list(\*\*params) -> SyncDefaultFlatPagination[VirtualCrossConnectListResponse]
- client.virtual_cross_connects.delete(id) -> VirtualCrossConnectDeleteResponse
# VirtualCrossConnectsCoverage
@@ -4853,9 +4828,9 @@ Types:
```python
from telnyx.types import (
- WireguardInterfaceRead,
WireguardInterfaceCreateResponse,
WireguardInterfaceRetrieveResponse,
+ WireguardInterfaceListResponse,
WireguardInterfaceDeleteResponse,
)
```
@@ -4864,7 +4839,7 @@ Methods:
- client.wireguard_interfaces.create(\*\*params) -> WireguardInterfaceCreateResponse
- client.wireguard_interfaces.retrieve(id) -> WireguardInterfaceRetrieveResponse
-- client.wireguard_interfaces.list(\*\*params) -> SyncDefaultFlatPagination[WireguardInterfaceRead]
+- client.wireguard_interfaces.list(\*\*params) -> SyncDefaultFlatPagination[WireguardInterfaceListResponse]
- client.wireguard_interfaces.delete(id) -> WireguardInterfaceDeleteResponse
# WireguardPeers
@@ -5590,6 +5565,7 @@ from telnyx.types import (
EnterpriseCreateResponse,
EnterpriseRetrieveResponse,
EnterpriseUpdateResponse,
+ EnterpriseActivateBrandedCallingResponse,
)
```
@@ -5600,6 +5576,7 @@ Methods:
- client.enterprises.update(enterprise_id, \*\*params) -> EnterpriseUpdateResponse
- client.enterprises.list(\*\*params) -> SyncDefaultFlatPagination[EnterprisePublic]
- client.enterprises.delete(enterprise_id) -> None
+- client.enterprises.activate_branded_calling(enterprise_id) -> EnterpriseActivateBrandedCallingResponse
## Reputation
@@ -5626,15 +5603,47 @@ Methods:
Types:
```python
-from telnyx.types.enterprises.reputation import NumberRetrieveResponse, NumberAssociateResponse
+from telnyx.types.enterprises.reputation import (
+ NumberRetrieveResponse,
+ NumberListResponse,
+ NumberAssociateResponse,
+ NumberRefreshResponse,
+)
```
Methods:
- client.enterprises.reputation.numbers.retrieve(phone_number, \*, enterprise_id, \*\*params) -> NumberRetrieveResponse
-- client.enterprises.reputation.numbers.list(enterprise_id, \*\*params) -> SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData]
+- client.enterprises.reputation.numbers.list(enterprise_id, \*\*params) -> SyncDefaultFlatPagination[NumberListResponse]
- client.enterprises.reputation.numbers.associate(enterprise_id, \*\*params) -> NumberAssociateResponse
- client.enterprises.reputation.numbers.disassociate(phone_number, \*, enterprise_id) -> None
+- client.enterprises.reputation.numbers.refresh(enterprise_id, \*\*params) -> NumberRefreshResponse
+
+### Loa
+
+Types:
+
+```python
+from telnyx.types.enterprises.reputation import LoaUpdateResponse
+```
+
+Methods:
+
+- client.enterprises.reputation.loa.update(enterprise_id, \*\*params) -> LoaUpdateResponse
+- client.enterprises.reputation.loa.render(enterprise_id, \*\*params) -> BinaryAPIResponse
+
+## Dir
+
+Types:
+
+```python
+from telnyx.types.enterprises import DirCreateResponse, DirListResponse
+```
+
+Methods:
+
+- client.enterprises.dir.create(enterprise_id, \*\*params) -> DirCreateResponse
+- client.enterprises.dir.list(enterprise_id, \*\*params) -> SyncDefaultFlatPagination[DirListResponse]
# Reputation
@@ -5643,22 +5652,63 @@ Methods:
Types:
```python
-from telnyx.types.reputation import NumberRetrieveResponse
+from telnyx.types.reputation import NumberRetrieveResponse, NumberListResponse
```
Methods:
- client.reputation.numbers.retrieve(phone_number, \*\*params) -> NumberRetrieveResponse
-- client.reputation.numbers.list(\*\*params) -> SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData]
+- client.reputation.numbers.list(\*\*params) -> SyncDefaultFlatPagination[NumberListResponse]
- client.reputation.numbers.delete(phone_number) -> None
# TermsOfService
+Types:
+
+```python
+from telnyx.types import TermsOfServiceStatusResponse
+```
+
+Methods:
+
+- client.terms_of_service.status(\*\*params) -> TermsOfServiceStatusResponse
+
## NumberReputation
+Types:
+
+```python
+from telnyx.types.terms_of_service import NumberReputationAgreeResponse
+```
+
+Methods:
+
+- client.terms_of_service.number_reputation.agree() -> NumberReputationAgreeResponse
+
+## Agreements
+
+Types:
+
+```python
+from telnyx.types.terms_of_service import AgreementRetrieveResponse, AgreementListResponse
+```
+
+Methods:
+
+- client.terms_of_service.agreements.retrieve(agreement_id) -> AgreementRetrieveResponse
+- client.terms_of_service.agreements.list(\*\*params) -> SyncDefaultFlatPagination[AgreementListResponse]
+
+## BrandedCalling
+
+Types:
+
+```python
+from telnyx.types.terms_of_service import BrandedCallingAgreeResponse
+```
+
Methods:
-- client.terms_of_service.number_reputation.agree() -> None
+- client.terms_of_service.branded_calling.agree() -> BrandedCallingAgreeResponse
# PronunciationDicts
@@ -5683,20 +5733,113 @@ Methods:
- client.pronunciation_dicts.list(\*\*params) -> SyncDefaultFlatPagination[PronunciationDictData]
- client.pronunciation_dicts.delete(id) -> None
+# CallReasons
+
+Types:
+
+```python
+from telnyx.types import CallReasonListResponse, CallReasonValidateResponse
+```
+
+Methods:
+
+- client.call_reasons.list(\*\*params) -> SyncDefaultFlatPagination[CallReasonListResponse]
+- client.call_reasons.validate(\*\*params) -> CallReasonValidateResponse
+
+# Dir
+
+Types:
+
+```python
+from telnyx.types import (
+ DirRetrieveResponse,
+ DirUpdateResponse,
+ DirListResponse,
+ DirListDocumentTypesResponse,
+ DirListInfringementClaimsResponse,
+ DirSubmitResponse,
+ DirUpdateInfringementResponse,
+)
+```
+
+Methods:
+
+- client.dir.retrieve(dir_id) -> DirRetrieveResponse
+- client.dir.update(dir_id, \*\*params) -> DirUpdateResponse
+- client.dir.list(\*\*params) -> SyncDefaultFlatPagination[DirListResponse]
+- client.dir.delete(dir_id) -> None
+- client.dir.list_document_types() -> DirListDocumentTypesResponse
+- client.dir.list_infringement_claims(dir_id, \*\*params) -> SyncDefaultFlatPagination[DirListInfringementClaimsResponse]
+- client.dir.submit(dir_id) -> DirSubmitResponse
+- client.dir.update_infringement(dir_id, \*\*params) -> DirUpdateInfringementResponse
+
+## Comments
+
+Types:
+
+```python
+from telnyx.types.dir import CommentCreateResponse, CommentListResponse
+```
+
+Methods:
+
+- client.dir.comments.create(dir_id, \*\*params) -> CommentCreateResponse
+- client.dir.comments.list(dir_id, \*\*params) -> SyncDefaultFlatPagination[CommentListResponse]
+
+## PhoneNumberBatches
+
+Types:
+
+```python
+from telnyx.types.dir import PhoneNumberBatchRetrieveResponse, PhoneNumberBatchListResponse
+```
+
+Methods:
+
+- client.dir.phone_number_batches.retrieve(batch_id, \*, dir_id) -> PhoneNumberBatchRetrieveResponse
+- client.dir.phone_number_batches.list(dir_id, \*\*params) -> SyncDefaultFlatPagination[PhoneNumberBatchListResponse]
+
+## PhoneNumbers
+
+Types:
+
+```python
+from telnyx.types.dir import (
+ PhoneNumberListResponse,
+ PhoneNumberAddResponse,
+ PhoneNumberRemoveResponse,
+)
+```
+
+Methods:
+
+- client.dir.phone_numbers.list(dir_id, \*\*params) -> SyncDefaultFlatPagination[PhoneNumberListResponse]
+- client.dir.phone_numbers.add(dir_id, \*\*params) -> PhoneNumberAddResponse
+- client.dir.phone_numbers.remove(dir_id, \*\*params) -> PhoneNumberRemoveResponse
+
+# InfringementClaims
+
+Types:
+
+```python
+from telnyx.types import InfringementClaimRetrieveResponse, InfringementClaimContestResponse
+```
+
+Methods:
+
+- client.infringement_claims.retrieve(claim_id) -> InfringementClaimRetrieveResponse
+- client.infringement_claims.contest(claim_id, \*\*params) -> InfringementClaimContestResponse
+
# UacConnections
Types:
```python
from telnyx.types import (
- UacConnection,
- UacExternalSettings,
- UacInbound,
- UacInternalSettings,
- UacOutbound,
UacConnectionCreateResponse,
UacConnectionRetrieveResponse,
UacConnectionUpdateResponse,
+ UacConnectionListResponse,
UacConnectionDeleteResponse,
)
```
@@ -5706,7 +5849,7 @@ Methods:
- client.uac_connections.create(\*\*params) -> UacConnectionCreateResponse
- client.uac_connections.retrieve(id) -> UacConnectionRetrieveResponse
- client.uac_connections.update(id, \*\*params) -> UacConnectionUpdateResponse
-- client.uac_connections.list(\*\*params) -> SyncDefaultFlatPagination[UacConnection]
+- client.uac_connections.list(\*\*params) -> SyncDefaultFlatPagination[UacConnectionListResponse]
- client.uac_connections.delete(id) -> UacConnectionDeleteResponse
## Actions
diff --git a/pyproject.toml b/pyproject.toml
index 14022cae..17245305 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "telnyx"
-version = "4.151.0"
+version = "4.152.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 405a4042..3bf5e231 100644
--- a/src/telnyx/_client.py
+++ b/src/telnyx/_client.py
@@ -38,6 +38,7 @@
if TYPE_CHECKING:
from .resources import (
ai,
+ dir,
ips,
list,
seti,
@@ -81,6 +82,7 @@
ota_updates,
short_codes,
audit_events,
+ call_reasons,
oauth_grants,
requirements,
voice_clones,
@@ -141,6 +143,7 @@
texml_applications,
webhook_deliveries,
global_ip_protocols,
+ infringement_claims,
integration_secrets,
notification_events,
number_block_orders,
@@ -211,6 +214,7 @@
from .resources.media import MediaResource, AsyncMediaResource
from .resources.oauth import OAuthResource, AsyncOAuthResource
from .resources.balance import BalanceResource, AsyncBalanceResource
+ from .resources.dir.dir import DirResource, AsyncDirResource
from .resources.regions import RegionsResource, AsyncRegionsResource
from .resources.comments import CommentsResource, AsyncCommentsResource
from .resources.invoices import InvoicesResource, AsyncInvoicesResource
@@ -229,6 +233,7 @@
from .resources.short_codes import ShortCodesResource, AsyncShortCodesResource
from .resources.texml.texml import TexmlResource, AsyncTexmlResource
from .resources.audit_events import AuditEventsResource, AsyncAuditEventsResource
+ from .resources.call_reasons import CallReasonsResource, AsyncCallReasonsResource
from .resources.oauth_grants import OAuthGrantsResource, AsyncOAuthGrantsResource
from .resources.requirements import RequirementsResource, AsyncRequirementsResource
from .resources.voice_clones import VoiceClonesResource, AsyncVoiceClonesResource
@@ -287,6 +292,7 @@
from .resources.webhook_deliveries import WebhookDeliveriesResource, AsyncWebhookDeliveriesResource
from .resources.addresses.addresses import AddressesResource, AsyncAddressesResource
from .resources.global_ip_protocols import GlobalIPProtocolsResource, AsyncGlobalIPProtocolsResource
+ from .resources.infringement_claims import InfringementClaimsResource, AsyncInfringementClaimsResource
from .resources.integration_secrets import IntegrationSecretsResource, AsyncIntegrationSecretsResource
from .resources.messaging.messaging import MessagingResource, AsyncMessagingResource
from .resources.notification_events import NotificationEventsResource, AsyncNotificationEventsResource
@@ -1637,7 +1643,7 @@ def traffic_policy_profiles(self) -> TrafficPolicyProfilesResource:
@cached_property
def enterprises(self) -> EnterprisesResource:
- """Enterprise management for Branded Calling and Number Reputation services"""
+ """Manage the legal-entity record that owns your DIRs and phone numbers."""
from .resources.enterprises import EnterprisesResource
return EnterprisesResource(self)
@@ -1650,6 +1656,9 @@ def reputation(self) -> ReputationResource:
@cached_property
def terms_of_service(self) -> TermsOfServiceResource:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
from .resources.terms_of_service import TermsOfServiceResource
return TermsOfServiceResource(self)
@@ -1664,6 +1673,31 @@ def pronunciation_dicts(self) -> PronunciationDictsResource:
return PronunciationDictsResource(self)
+ @cached_property
+ def call_reasons(self) -> CallReasonsResource:
+ """
+ Static reference values the API accepts: call reasons, document types, rejection types.
+ """
+ from .resources.call_reasons import CallReasonsResource
+
+ return CallReasonsResource(self)
+
+ @cached_property
+ def dir(self) -> DirResource:
+ from .resources.dir import DirResource
+
+ return DirResource(self)
+
+ @cached_property
+ def infringement_claims(self) -> InfringementClaimsResource:
+ """Trademark or impersonation claims filed against your DIR.
+
+ Customers may contest a claim with supporting evidence.
+ """
+ from .resources.infringement_claims import InfringementClaimsResource
+
+ return InfringementClaimsResource(self)
+
@cached_property
def uac_connections(self) -> UacConnectionsResource:
"""UAC connection operations"""
@@ -3017,7 +3051,7 @@ def traffic_policy_profiles(self) -> AsyncTrafficPolicyProfilesResource:
@cached_property
def enterprises(self) -> AsyncEnterprisesResource:
- """Enterprise management for Branded Calling and Number Reputation services"""
+ """Manage the legal-entity record that owns your DIRs and phone numbers."""
from .resources.enterprises import AsyncEnterprisesResource
return AsyncEnterprisesResource(self)
@@ -3030,6 +3064,9 @@ def reputation(self) -> AsyncReputationResource:
@cached_property
def terms_of_service(self) -> AsyncTermsOfServiceResource:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
from .resources.terms_of_service import AsyncTermsOfServiceResource
return AsyncTermsOfServiceResource(self)
@@ -3044,6 +3081,31 @@ def pronunciation_dicts(self) -> AsyncPronunciationDictsResource:
return AsyncPronunciationDictsResource(self)
+ @cached_property
+ def call_reasons(self) -> AsyncCallReasonsResource:
+ """
+ Static reference values the API accepts: call reasons, document types, rejection types.
+ """
+ from .resources.call_reasons import AsyncCallReasonsResource
+
+ return AsyncCallReasonsResource(self)
+
+ @cached_property
+ def dir(self) -> AsyncDirResource:
+ from .resources.dir import AsyncDirResource
+
+ return AsyncDirResource(self)
+
+ @cached_property
+ def infringement_claims(self) -> AsyncInfringementClaimsResource:
+ """Trademark or impersonation claims filed against your DIR.
+
+ Customers may contest a claim with supporting evidence.
+ """
+ from .resources.infringement_claims import AsyncInfringementClaimsResource
+
+ return AsyncInfringementClaimsResource(self)
+
@cached_property
def uac_connections(self) -> AsyncUacConnectionsResource:
"""UAC connection operations"""
@@ -4333,7 +4395,7 @@ def traffic_policy_profiles(self) -> traffic_policy_profiles.TrafficPolicyProfil
@cached_property
def enterprises(self) -> enterprises.EnterprisesResourceWithRawResponse:
- """Enterprise management for Branded Calling and Number Reputation services"""
+ """Manage the legal-entity record that owns your DIRs and phone numbers."""
from .resources.enterprises import EnterprisesResourceWithRawResponse
return EnterprisesResourceWithRawResponse(self._client.enterprises)
@@ -4346,6 +4408,9 @@ def reputation(self) -> reputation.ReputationResourceWithRawResponse:
@cached_property
def terms_of_service(self) -> terms_of_service.TermsOfServiceResourceWithRawResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
from .resources.terms_of_service import TermsOfServiceResourceWithRawResponse
return TermsOfServiceResourceWithRawResponse(self._client.terms_of_service)
@@ -4360,6 +4425,31 @@ def pronunciation_dicts(self) -> pronunciation_dicts.PronunciationDictsResourceW
return PronunciationDictsResourceWithRawResponse(self._client.pronunciation_dicts)
+ @cached_property
+ def call_reasons(self) -> call_reasons.CallReasonsResourceWithRawResponse:
+ """
+ Static reference values the API accepts: call reasons, document types, rejection types.
+ """
+ from .resources.call_reasons import CallReasonsResourceWithRawResponse
+
+ return CallReasonsResourceWithRawResponse(self._client.call_reasons)
+
+ @cached_property
+ def dir(self) -> dir.DirResourceWithRawResponse:
+ from .resources.dir import DirResourceWithRawResponse
+
+ return DirResourceWithRawResponse(self._client.dir)
+
+ @cached_property
+ def infringement_claims(self) -> infringement_claims.InfringementClaimsResourceWithRawResponse:
+ """Trademark or impersonation claims filed against your DIR.
+
+ Customers may contest a claim with supporting evidence.
+ """
+ from .resources.infringement_claims import InfringementClaimsResourceWithRawResponse
+
+ return InfringementClaimsResourceWithRawResponse(self._client.infringement_claims)
+
@cached_property
def uac_connections(self) -> uac_connections.UacConnectionsResourceWithRawResponse:
"""UAC connection operations"""
@@ -5520,7 +5610,7 @@ def traffic_policy_profiles(self) -> traffic_policy_profiles.AsyncTrafficPolicyP
@cached_property
def enterprises(self) -> enterprises.AsyncEnterprisesResourceWithRawResponse:
- """Enterprise management for Branded Calling and Number Reputation services"""
+ """Manage the legal-entity record that owns your DIRs and phone numbers."""
from .resources.enterprises import AsyncEnterprisesResourceWithRawResponse
return AsyncEnterprisesResourceWithRawResponse(self._client.enterprises)
@@ -5533,6 +5623,9 @@ def reputation(self) -> reputation.AsyncReputationResourceWithRawResponse:
@cached_property
def terms_of_service(self) -> terms_of_service.AsyncTermsOfServiceResourceWithRawResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
from .resources.terms_of_service import AsyncTermsOfServiceResourceWithRawResponse
return AsyncTermsOfServiceResourceWithRawResponse(self._client.terms_of_service)
@@ -5547,6 +5640,31 @@ def pronunciation_dicts(self) -> pronunciation_dicts.AsyncPronunciationDictsReso
return AsyncPronunciationDictsResourceWithRawResponse(self._client.pronunciation_dicts)
+ @cached_property
+ def call_reasons(self) -> call_reasons.AsyncCallReasonsResourceWithRawResponse:
+ """
+ Static reference values the API accepts: call reasons, document types, rejection types.
+ """
+ from .resources.call_reasons import AsyncCallReasonsResourceWithRawResponse
+
+ return AsyncCallReasonsResourceWithRawResponse(self._client.call_reasons)
+
+ @cached_property
+ def dir(self) -> dir.AsyncDirResourceWithRawResponse:
+ from .resources.dir import AsyncDirResourceWithRawResponse
+
+ return AsyncDirResourceWithRawResponse(self._client.dir)
+
+ @cached_property
+ def infringement_claims(self) -> infringement_claims.AsyncInfringementClaimsResourceWithRawResponse:
+ """Trademark or impersonation claims filed against your DIR.
+
+ Customers may contest a claim with supporting evidence.
+ """
+ from .resources.infringement_claims import AsyncInfringementClaimsResourceWithRawResponse
+
+ return AsyncInfringementClaimsResourceWithRawResponse(self._client.infringement_claims)
+
@cached_property
def uac_connections(self) -> uac_connections.AsyncUacConnectionsResourceWithRawResponse:
"""UAC connection operations"""
@@ -6709,7 +6827,7 @@ def traffic_policy_profiles(self) -> traffic_policy_profiles.TrafficPolicyProfil
@cached_property
def enterprises(self) -> enterprises.EnterprisesResourceWithStreamingResponse:
- """Enterprise management for Branded Calling and Number Reputation services"""
+ """Manage the legal-entity record that owns your DIRs and phone numbers."""
from .resources.enterprises import EnterprisesResourceWithStreamingResponse
return EnterprisesResourceWithStreamingResponse(self._client.enterprises)
@@ -6722,6 +6840,9 @@ def reputation(self) -> reputation.ReputationResourceWithStreamingResponse:
@cached_property
def terms_of_service(self) -> terms_of_service.TermsOfServiceResourceWithStreamingResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
from .resources.terms_of_service import TermsOfServiceResourceWithStreamingResponse
return TermsOfServiceResourceWithStreamingResponse(self._client.terms_of_service)
@@ -6736,6 +6857,31 @@ def pronunciation_dicts(self) -> pronunciation_dicts.PronunciationDictsResourceW
return PronunciationDictsResourceWithStreamingResponse(self._client.pronunciation_dicts)
+ @cached_property
+ def call_reasons(self) -> call_reasons.CallReasonsResourceWithStreamingResponse:
+ """
+ Static reference values the API accepts: call reasons, document types, rejection types.
+ """
+ from .resources.call_reasons import CallReasonsResourceWithStreamingResponse
+
+ return CallReasonsResourceWithStreamingResponse(self._client.call_reasons)
+
+ @cached_property
+ def dir(self) -> dir.DirResourceWithStreamingResponse:
+ from .resources.dir import DirResourceWithStreamingResponse
+
+ return DirResourceWithStreamingResponse(self._client.dir)
+
+ @cached_property
+ def infringement_claims(self) -> infringement_claims.InfringementClaimsResourceWithStreamingResponse:
+ """Trademark or impersonation claims filed against your DIR.
+
+ Customers may contest a claim with supporting evidence.
+ """
+ from .resources.infringement_claims import InfringementClaimsResourceWithStreamingResponse
+
+ return InfringementClaimsResourceWithStreamingResponse(self._client.infringement_claims)
+
@cached_property
def uac_connections(self) -> uac_connections.UacConnectionsResourceWithStreamingResponse:
"""UAC connection operations"""
@@ -7944,7 +8090,7 @@ def traffic_policy_profiles(
@cached_property
def enterprises(self) -> enterprises.AsyncEnterprisesResourceWithStreamingResponse:
- """Enterprise management for Branded Calling and Number Reputation services"""
+ """Manage the legal-entity record that owns your DIRs and phone numbers."""
from .resources.enterprises import AsyncEnterprisesResourceWithStreamingResponse
return AsyncEnterprisesResourceWithStreamingResponse(self._client.enterprises)
@@ -7957,6 +8103,9 @@ def reputation(self) -> reputation.AsyncReputationResourceWithStreamingResponse:
@cached_property
def terms_of_service(self) -> terms_of_service.AsyncTermsOfServiceResourceWithStreamingResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
from .resources.terms_of_service import AsyncTermsOfServiceResourceWithStreamingResponse
return AsyncTermsOfServiceResourceWithStreamingResponse(self._client.terms_of_service)
@@ -7971,6 +8120,31 @@ def pronunciation_dicts(self) -> pronunciation_dicts.AsyncPronunciationDictsReso
return AsyncPronunciationDictsResourceWithStreamingResponse(self._client.pronunciation_dicts)
+ @cached_property
+ def call_reasons(self) -> call_reasons.AsyncCallReasonsResourceWithStreamingResponse:
+ """
+ Static reference values the API accepts: call reasons, document types, rejection types.
+ """
+ from .resources.call_reasons import AsyncCallReasonsResourceWithStreamingResponse
+
+ return AsyncCallReasonsResourceWithStreamingResponse(self._client.call_reasons)
+
+ @cached_property
+ def dir(self) -> dir.AsyncDirResourceWithStreamingResponse:
+ from .resources.dir import AsyncDirResourceWithStreamingResponse
+
+ return AsyncDirResourceWithStreamingResponse(self._client.dir)
+
+ @cached_property
+ def infringement_claims(self) -> infringement_claims.AsyncInfringementClaimsResourceWithStreamingResponse:
+ """Trademark or impersonation claims filed against your DIR.
+
+ Customers may contest a claim with supporting evidence.
+ """
+ from .resources.infringement_claims import AsyncInfringementClaimsResourceWithStreamingResponse
+
+ return AsyncInfringementClaimsResourceWithStreamingResponse(self._client.infringement_claims)
+
@cached_property
def uac_connections(self) -> uac_connections.AsyncUacConnectionsResourceWithStreamingResponse:
"""UAC connection operations"""
diff --git a/src/telnyx/_version.py b/src/telnyx/_version.py
index 5841a80c..c99502a1 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.151.0" # x-release-please-version
+__version__ = "4.152.0" # x-release-please-version
diff --git a/src/telnyx/resources/__init__.py b/src/telnyx/resources/__init__.py
index 0c2e32ee..0fde60a8 100644
--- a/src/telnyx/resources/__init__.py
+++ b/src/telnyx/resources/__init__.py
@@ -8,6 +8,14 @@
AIResourceWithStreamingResponse,
AsyncAIResourceWithStreamingResponse,
)
+from .dir import (
+ DirResource,
+ AsyncDirResource,
+ DirResourceWithRawResponse,
+ AsyncDirResourceWithRawResponse,
+ DirResourceWithStreamingResponse,
+ AsyncDirResourceWithStreamingResponse,
+)
from .ips import (
IPsResource,
AsyncIPsResource,
@@ -353,6 +361,14 @@
AuditEventsResourceWithStreamingResponse,
AsyncAuditEventsResourceWithStreamingResponse,
)
+from .call_reasons import (
+ CallReasonsResource,
+ AsyncCallReasonsResource,
+ CallReasonsResourceWithRawResponse,
+ AsyncCallReasonsResourceWithRawResponse,
+ CallReasonsResourceWithStreamingResponse,
+ AsyncCallReasonsResourceWithStreamingResponse,
+)
from .oauth_grants import (
OAuthGrantsResource,
AsyncOAuthGrantsResource,
@@ -833,6 +849,14 @@
GlobalIPProtocolsResourceWithStreamingResponse,
AsyncGlobalIPProtocolsResourceWithStreamingResponse,
)
+from .infringement_claims import (
+ InfringementClaimsResource,
+ AsyncInfringementClaimsResource,
+ InfringementClaimsResourceWithRawResponse,
+ AsyncInfringementClaimsResourceWithRawResponse,
+ InfringementClaimsResourceWithStreamingResponse,
+ AsyncInfringementClaimsResourceWithStreamingResponse,
+)
from .integration_secrets import (
IntegrationSecretsResource,
AsyncIntegrationSecretsResource,
@@ -2291,6 +2315,24 @@
"AsyncPronunciationDictsResourceWithRawResponse",
"PronunciationDictsResourceWithStreamingResponse",
"AsyncPronunciationDictsResourceWithStreamingResponse",
+ "CallReasonsResource",
+ "AsyncCallReasonsResource",
+ "CallReasonsResourceWithRawResponse",
+ "AsyncCallReasonsResourceWithRawResponse",
+ "CallReasonsResourceWithStreamingResponse",
+ "AsyncCallReasonsResourceWithStreamingResponse",
+ "DirResource",
+ "AsyncDirResource",
+ "DirResourceWithRawResponse",
+ "AsyncDirResourceWithRawResponse",
+ "DirResourceWithStreamingResponse",
+ "AsyncDirResourceWithStreamingResponse",
+ "InfringementClaimsResource",
+ "AsyncInfringementClaimsResource",
+ "InfringementClaimsResourceWithRawResponse",
+ "AsyncInfringementClaimsResourceWithRawResponse",
+ "InfringementClaimsResourceWithStreamingResponse",
+ "AsyncInfringementClaimsResourceWithStreamingResponse",
"UacConnectionsResource",
"AsyncUacConnectionsResource",
"UacConnectionsResourceWithRawResponse",
diff --git a/src/telnyx/resources/ai/assistants/assistants.py b/src/telnyx/resources/ai/assistants/assistants.py
index 86b35421..b6e2875c 100644
--- a/src/telnyx/resources/ai/assistants/assistants.py
+++ b/src/telnyx/resources/ai/assistants/assistants.py
@@ -80,7 +80,6 @@
from ....types.ai.assistant_tool_param import AssistantToolParam
from ....types.ai.voice_settings_param import VoiceSettingsParam
from ....types.ai.widget_settings_param import WidgetSettingsParam
-from ....types.ai.external_llm_req_param import ExternalLlmReqParam
from ....types.ai.insight_settings_param import InsightSettingsParam
from ....types.ai.privacy_settings_param import PrivacySettingsParam
from ....types.ai.assistant_chat_response import AssistantChatResponse
@@ -88,13 +87,8 @@
from ....types.ai.messaging_settings_param import MessagingSettingsParam
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_mcp_server_param import AssistantMcpServerParam
-from ....types.ai.assistant_integration_param import AssistantIntegrationParam
from ....types.ai.assistant_send_sms_response import AssistantSendSMSResponse
from ....types.ai.transcription_settings_param import TranscriptionSettingsParam
-from ....types.ai.post_conversation_settings_req_param import PostConversationSettingsReqParam
-from ....types.ai.inference_embedding_interruption_settings_param import InferenceEmbeddingInterruptionSettingsParam
__all__ = ["AssistantsResource", "AsyncAssistantsResource"]
@@ -162,18 +156,18 @@ def create(
dynamic_variables_webhook_timeout_ms: int | Omit = omit,
dynamic_variables_webhook_url: str | Omit = omit,
enabled_features: List[EnabledFeatures] | Omit = omit,
- external_llm: ExternalLlmReqParam | Omit = omit,
- fallback_config: FallbackConfigReqParam | Omit = omit,
+ external_llm: assistant_create_params.ExternalLlm | Omit = omit,
+ fallback_config: assistant_create_params.FallbackConfig | Omit = omit,
greeting: str | Omit = omit,
insight_settings: InsightSettingsParam | Omit = omit,
- integrations: Iterable[AssistantIntegrationParam] | Omit = omit,
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam | Omit = omit,
+ integrations: Iterable[assistant_create_params.Integration] | Omit = omit,
+ interruption_settings: assistant_create_params.InterruptionSettings | Omit = omit,
llm_api_key_ref: str | Omit = omit,
- mcp_servers: Iterable[AssistantMcpServerParam] | Omit = omit,
+ mcp_servers: Iterable[assistant_create_params.McpServer] | Omit = omit,
messaging_settings: MessagingSettingsParam | Omit = omit,
model: str | Omit = omit,
observability_settings: ObservabilityReqParam | Omit = omit,
- post_conversation_settings: PostConversationSettingsReqParam | Omit = omit,
+ post_conversation_settings: assistant_create_params.PostConversationSettings | Omit = omit,
privacy_settings: PrivacySettingsParam | Omit = omit,
tags: SequenceNotStr[str] | Omit = omit,
telephony_settings: TelephonySettingsParam | Omit = omit,
@@ -380,20 +374,20 @@ def update(
dynamic_variables_webhook_timeout_ms: int | Omit = omit,
dynamic_variables_webhook_url: str | Omit = omit,
enabled_features: List[EnabledFeatures] | Omit = omit,
- external_llm: ExternalLlmReqParam | Omit = omit,
- fallback_config: FallbackConfigReqParam | Omit = omit,
+ external_llm: assistant_update_params.ExternalLlm | Omit = omit,
+ fallback_config: assistant_update_params.FallbackConfig | Omit = omit,
greeting: str | Omit = omit,
insight_settings: InsightSettingsParam | Omit = omit,
instructions: str | Omit = omit,
- integrations: Iterable[AssistantIntegrationParam] | Omit = omit,
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam | Omit = omit,
+ integrations: Iterable[assistant_update_params.Integration] | Omit = omit,
+ interruption_settings: assistant_update_params.InterruptionSettings | Omit = omit,
llm_api_key_ref: str | Omit = omit,
- mcp_servers: Iterable[AssistantMcpServerParam] | Omit = omit,
+ mcp_servers: Iterable[assistant_update_params.McpServer] | Omit = omit,
messaging_settings: MessagingSettingsParam | Omit = omit,
model: str | Omit = omit,
name: str | Omit = omit,
observability_settings: ObservabilityReqParam | Omit = omit,
- post_conversation_settings: PostConversationSettingsReqParam | Omit = omit,
+ post_conversation_settings: assistant_update_params.PostConversationSettings | Omit = omit,
privacy_settings: PrivacySettingsParam | Omit = omit,
promote_to_main: bool | Omit = omit,
tags: SequenceNotStr[str] | Omit = omit,
@@ -903,18 +897,18 @@ async def create(
dynamic_variables_webhook_timeout_ms: int | Omit = omit,
dynamic_variables_webhook_url: str | Omit = omit,
enabled_features: List[EnabledFeatures] | Omit = omit,
- external_llm: ExternalLlmReqParam | Omit = omit,
- fallback_config: FallbackConfigReqParam | Omit = omit,
+ external_llm: assistant_create_params.ExternalLlm | Omit = omit,
+ fallback_config: assistant_create_params.FallbackConfig | Omit = omit,
greeting: str | Omit = omit,
insight_settings: InsightSettingsParam | Omit = omit,
- integrations: Iterable[AssistantIntegrationParam] | Omit = omit,
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam | Omit = omit,
+ integrations: Iterable[assistant_create_params.Integration] | Omit = omit,
+ interruption_settings: assistant_create_params.InterruptionSettings | Omit = omit,
llm_api_key_ref: str | Omit = omit,
- mcp_servers: Iterable[AssistantMcpServerParam] | Omit = omit,
+ mcp_servers: Iterable[assistant_create_params.McpServer] | Omit = omit,
messaging_settings: MessagingSettingsParam | Omit = omit,
model: str | Omit = omit,
observability_settings: ObservabilityReqParam | Omit = omit,
- post_conversation_settings: PostConversationSettingsReqParam | Omit = omit,
+ post_conversation_settings: assistant_create_params.PostConversationSettings | Omit = omit,
privacy_settings: PrivacySettingsParam | Omit = omit,
tags: SequenceNotStr[str] | Omit = omit,
telephony_settings: TelephonySettingsParam | Omit = omit,
@@ -1121,20 +1115,20 @@ async def update(
dynamic_variables_webhook_timeout_ms: int | Omit = omit,
dynamic_variables_webhook_url: str | Omit = omit,
enabled_features: List[EnabledFeatures] | Omit = omit,
- external_llm: ExternalLlmReqParam | Omit = omit,
- fallback_config: FallbackConfigReqParam | Omit = omit,
+ external_llm: assistant_update_params.ExternalLlm | Omit = omit,
+ fallback_config: assistant_update_params.FallbackConfig | Omit = omit,
greeting: str | Omit = omit,
insight_settings: InsightSettingsParam | Omit = omit,
instructions: str | Omit = omit,
- integrations: Iterable[AssistantIntegrationParam] | Omit = omit,
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam | Omit = omit,
+ integrations: Iterable[assistant_update_params.Integration] | Omit = omit,
+ interruption_settings: assistant_update_params.InterruptionSettings | Omit = omit,
llm_api_key_ref: str | Omit = omit,
- mcp_servers: Iterable[AssistantMcpServerParam] | Omit = omit,
+ mcp_servers: Iterable[assistant_update_params.McpServer] | Omit = omit,
messaging_settings: MessagingSettingsParam | Omit = omit,
model: str | Omit = omit,
name: str | Omit = omit,
observability_settings: ObservabilityReqParam | Omit = omit,
- post_conversation_settings: PostConversationSettingsReqParam | Omit = omit,
+ post_conversation_settings: assistant_update_params.PostConversationSettings | Omit = omit,
privacy_settings: PrivacySettingsParam | Omit = omit,
promote_to_main: bool | Omit = omit,
tags: SequenceNotStr[str] | Omit = omit,
diff --git a/src/telnyx/resources/ai/assistants/canary_deploys.py b/src/telnyx/resources/ai/assistants/canary_deploys.py
index baf62939..09412a23 100644
--- a/src/telnyx/resources/ai/assistants/canary_deploys.py
+++ b/src/telnyx/resources/ai/assistants/canary_deploys.py
@@ -18,7 +18,6 @@
)
from ...._base_client import make_request_options
from ....types.ai.assistants import canary_deploy_create_params, canary_deploy_update_params
-from ....types.ai.assistants.rule_input_param import RuleInputParam
from ....types.ai.assistants.canary_deploy_response import CanaryDeployResponse
__all__ = ["CanaryDeploysResource", "AsyncCanaryDeploysResource"]
@@ -50,7 +49,7 @@ def create(
self,
assistant_id: str,
*,
- rules: Iterable[RuleInputParam] | Omit = omit,
+ rules: Iterable[canary_deploy_create_params.Rule] | 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,
@@ -124,7 +123,7 @@ def update(
self,
assistant_id: str,
*,
- rules: Iterable[RuleInputParam] | Omit = omit,
+ rules: Iterable[canary_deploy_update_params.Rule] | 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,
@@ -222,7 +221,7 @@ async def create(
self,
assistant_id: str,
*,
- rules: Iterable[RuleInputParam] | Omit = omit,
+ rules: Iterable[canary_deploy_create_params.Rule] | 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,
@@ -296,7 +295,7 @@ async def update(
self,
assistant_id: str,
*,
- rules: Iterable[RuleInputParam] | Omit = omit,
+ rules: Iterable[canary_deploy_update_params.Rule] | 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,
diff --git a/src/telnyx/resources/ai/assistants/versions.py b/src/telnyx/resources/ai/assistants/versions.py
index 270a7c10..a9bcfeb5 100644
--- a/src/telnyx/resources/ai/assistants/versions.py
+++ b/src/telnyx/resources/ai/assistants/versions.py
@@ -24,18 +24,12 @@
from ....types.ai.assistant_tool_param import AssistantToolParam
from ....types.ai.voice_settings_param import VoiceSettingsParam
from ....types.ai.widget_settings_param import WidgetSettingsParam
-from ....types.ai.external_llm_req_param import ExternalLlmReqParam
from ....types.ai.insight_settings_param import InsightSettingsParam
from ....types.ai.privacy_settings_param import PrivacySettingsParam
from ....types.ai.observability_req_param import ObservabilityReqParam
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_mcp_server_param import AssistantMcpServerParam
-from ....types.ai.assistant_integration_param import AssistantIntegrationParam
from ....types.ai.transcription_settings_param import TranscriptionSettingsParam
-from ....types.ai.post_conversation_settings_req_param import PostConversationSettingsReqParam
-from ....types.ai.inference_embedding_interruption_settings_param import InferenceEmbeddingInterruptionSettingsParam
__all__ = ["VersionsResource", "AsyncVersionsResource"]
@@ -118,20 +112,20 @@ def update(
dynamic_variables_webhook_timeout_ms: int | Omit = omit,
dynamic_variables_webhook_url: str | Omit = omit,
enabled_features: List[EnabledFeatures] | Omit = omit,
- external_llm: ExternalLlmReqParam | Omit = omit,
- fallback_config: FallbackConfigReqParam | Omit = omit,
+ external_llm: version_update_params.ExternalLlm | Omit = omit,
+ fallback_config: version_update_params.FallbackConfig | Omit = omit,
greeting: str | Omit = omit,
insight_settings: InsightSettingsParam | Omit = omit,
instructions: str | Omit = omit,
- integrations: Iterable[AssistantIntegrationParam] | Omit = omit,
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam | Omit = omit,
+ integrations: Iterable[version_update_params.Integration] | Omit = omit,
+ interruption_settings: version_update_params.InterruptionSettings | Omit = omit,
llm_api_key_ref: str | Omit = omit,
- mcp_servers: Iterable[AssistantMcpServerParam] | Omit = omit,
+ mcp_servers: Iterable[version_update_params.McpServer] | Omit = omit,
messaging_settings: MessagingSettingsParam | Omit = omit,
model: str | Omit = omit,
name: str | Omit = omit,
observability_settings: ObservabilityReqParam | Omit = omit,
- post_conversation_settings: PostConversationSettingsReqParam | Omit = omit,
+ post_conversation_settings: version_update_params.PostConversationSettings | Omit = omit,
privacy_settings: PrivacySettingsParam | Omit = omit,
tags: SequenceNotStr[str] | Omit = omit,
telephony_settings: TelephonySettingsParam | Omit = omit,
@@ -487,20 +481,20 @@ async def update(
dynamic_variables_webhook_timeout_ms: int | Omit = omit,
dynamic_variables_webhook_url: str | Omit = omit,
enabled_features: List[EnabledFeatures] | Omit = omit,
- external_llm: ExternalLlmReqParam | Omit = omit,
- fallback_config: FallbackConfigReqParam | Omit = omit,
+ external_llm: version_update_params.ExternalLlm | Omit = omit,
+ fallback_config: version_update_params.FallbackConfig | Omit = omit,
greeting: str | Omit = omit,
insight_settings: InsightSettingsParam | Omit = omit,
instructions: str | Omit = omit,
- integrations: Iterable[AssistantIntegrationParam] | Omit = omit,
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam | Omit = omit,
+ integrations: Iterable[version_update_params.Integration] | Omit = omit,
+ interruption_settings: version_update_params.InterruptionSettings | Omit = omit,
llm_api_key_ref: str | Omit = omit,
- mcp_servers: Iterable[AssistantMcpServerParam] | Omit = omit,
+ mcp_servers: Iterable[version_update_params.McpServer] | Omit = omit,
messaging_settings: MessagingSettingsParam | Omit = omit,
model: str | Omit = omit,
name: str | Omit = omit,
observability_settings: ObservabilityReqParam | Omit = omit,
- post_conversation_settings: PostConversationSettingsReqParam | Omit = omit,
+ post_conversation_settings: version_update_params.PostConversationSettings | Omit = omit,
privacy_settings: PrivacySettingsParam | Omit = omit,
tags: SequenceNotStr[str] | Omit = omit,
telephony_settings: TelephonySettingsParam | Omit = omit,
diff --git a/src/telnyx/resources/call_reasons.py b/src/telnyx/resources/call_reasons.py
new file mode 100644
index 00000000..bc104c32
--- /dev/null
+++ b/src/telnyx/resources/call_reasons.py
@@ -0,0 +1,307 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..types import call_reason_list_params
+from .._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from .._utils import 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 ..pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+from .._base_client import AsyncPaginator, make_request_options
+from ..types.call_reason_list_response import CallReasonListResponse
+from ..types.call_reason_validate_response import CallReasonValidateResponse
+
+__all__ = ["CallReasonsResource", "AsyncCallReasonsResource"]
+
+
+class CallReasonsResource(SyncAPIResource):
+ """
+ Static reference values the API accepts: call reasons, document types, rejection types.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> CallReasonsResourceWithRawResponse:
+ """
+ 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 CallReasonsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> CallReasonsResourceWithStreamingResponse:
+ """
+ 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 CallReasonsResourceWithStreamingResponse(self)
+
+ 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[CallReasonListResponse]:
+ """Telnyx maintains a library of pre-vetted call-reason phrases (e.g.
+
+ "Appointment
+ reminders", "Billing inquiries") that carry through DIR vetting smoothly. You
+ can use any string that fits your use case in `DirCreateRequest.call_reasons`,
+ but matching one of these reduces the chance the vetting team flags the phrasing
+ for clarification.
+
+ Args:
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Default `100` for this endpoint (the call-reason library is
+ small and most callers want the whole list in one call). Maximum 250; values
+ above are clamped to 250.
+
+ 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(
+ "/call_reasons",
+ page=SyncDefaultFlatPagination[CallReasonListResponse],
+ 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,
+ },
+ call_reason_list_params.CallReasonListParams,
+ ),
+ ),
+ model=CallReasonListResponse,
+ )
+
+ def validate(
+ self,
+ *,
+ body: SequenceNotStr[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,
+ ) -> CallReasonValidateResponse:
+ """
+ Check up to 10 candidate `call_reasons` strings against Telnyx's vetting
+ heuristics before sending them on a DIR create or update. The endpoint flags
+ strings that are likely to be rejected during vetting (too generic, banned
+ phrases, length issues, etc.) so you can fix them up front.
+
+ Args:
+ body: **Bare JSON array** of candidate call-reason strings (NOT an object — there is
+ no top-level `call_reasons` key on this endpoint). 1–10 strings, each ≤64
+ characters.
+
+ 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._post(
+ "/call_reasons/validate",
+ body=maybe_transform(body, SequenceNotStr[str]),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CallReasonValidateResponse,
+ )
+
+
+class AsyncCallReasonsResource(AsyncAPIResource):
+ """
+ Static reference values the API accepts: call reasons, document types, rejection types.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncCallReasonsResourceWithRawResponse:
+ """
+ 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 AsyncCallReasonsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncCallReasonsResourceWithStreamingResponse:
+ """
+ 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 AsyncCallReasonsResourceWithStreamingResponse(self)
+
+ 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[CallReasonListResponse, AsyncDefaultFlatPagination[CallReasonListResponse]]:
+ """Telnyx maintains a library of pre-vetted call-reason phrases (e.g.
+
+ "Appointment
+ reminders", "Billing inquiries") that carry through DIR vetting smoothly. You
+ can use any string that fits your use case in `DirCreateRequest.call_reasons`,
+ but matching one of these reduces the chance the vetting team flags the phrasing
+ for clarification.
+
+ Args:
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Default `100` for this endpoint (the call-reason library is
+ small and most callers want the whole list in one call). Maximum 250; values
+ above are clamped to 250.
+
+ 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(
+ "/call_reasons",
+ page=AsyncDefaultFlatPagination[CallReasonListResponse],
+ 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,
+ },
+ call_reason_list_params.CallReasonListParams,
+ ),
+ ),
+ model=CallReasonListResponse,
+ )
+
+ async def validate(
+ self,
+ *,
+ body: SequenceNotStr[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,
+ ) -> CallReasonValidateResponse:
+ """
+ Check up to 10 candidate `call_reasons` strings against Telnyx's vetting
+ heuristics before sending them on a DIR create or update. The endpoint flags
+ strings that are likely to be rejected during vetting (too generic, banned
+ phrases, length issues, etc.) so you can fix them up front.
+
+ Args:
+ body: **Bare JSON array** of candidate call-reason strings (NOT an object — there is
+ no top-level `call_reasons` key on this endpoint). 1–10 strings, each ≤64
+ characters.
+
+ 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 await self._post(
+ "/call_reasons/validate",
+ body=await async_maybe_transform(body, SequenceNotStr[str]),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CallReasonValidateResponse,
+ )
+
+
+class CallReasonsResourceWithRawResponse:
+ def __init__(self, call_reasons: CallReasonsResource) -> None:
+ self._call_reasons = call_reasons
+
+ self.list = to_raw_response_wrapper(
+ call_reasons.list,
+ )
+ self.validate = to_raw_response_wrapper(
+ call_reasons.validate,
+ )
+
+
+class AsyncCallReasonsResourceWithRawResponse:
+ def __init__(self, call_reasons: AsyncCallReasonsResource) -> None:
+ self._call_reasons = call_reasons
+
+ self.list = async_to_raw_response_wrapper(
+ call_reasons.list,
+ )
+ self.validate = async_to_raw_response_wrapper(
+ call_reasons.validate,
+ )
+
+
+class CallReasonsResourceWithStreamingResponse:
+ def __init__(self, call_reasons: CallReasonsResource) -> None:
+ self._call_reasons = call_reasons
+
+ self.list = to_streamed_response_wrapper(
+ call_reasons.list,
+ )
+ self.validate = to_streamed_response_wrapper(
+ call_reasons.validate,
+ )
+
+
+class AsyncCallReasonsResourceWithStreamingResponse:
+ def __init__(self, call_reasons: AsyncCallReasonsResource) -> None:
+ self._call_reasons = call_reasons
+
+ self.list = async_to_streamed_response_wrapper(
+ call_reasons.list,
+ )
+ self.validate = async_to_streamed_response_wrapper(
+ call_reasons.validate,
+ )
diff --git a/src/telnyx/resources/dir/__init__.py b/src/telnyx/resources/dir/__init__.py
new file mode 100644
index 00000000..df97b4f5
--- /dev/null
+++ b/src/telnyx/resources/dir/__init__.py
@@ -0,0 +1,61 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .dir import (
+ DirResource,
+ AsyncDirResource,
+ DirResourceWithRawResponse,
+ AsyncDirResourceWithRawResponse,
+ DirResourceWithStreamingResponse,
+ AsyncDirResourceWithStreamingResponse,
+)
+from .comments import (
+ CommentsResource,
+ AsyncCommentsResource,
+ CommentsResourceWithRawResponse,
+ AsyncCommentsResourceWithRawResponse,
+ CommentsResourceWithStreamingResponse,
+ AsyncCommentsResourceWithStreamingResponse,
+)
+from .phone_numbers import (
+ PhoneNumbersResource,
+ AsyncPhoneNumbersResource,
+ PhoneNumbersResourceWithRawResponse,
+ AsyncPhoneNumbersResourceWithRawResponse,
+ PhoneNumbersResourceWithStreamingResponse,
+ AsyncPhoneNumbersResourceWithStreamingResponse,
+)
+from .phone_number_batches import (
+ PhoneNumberBatchesResource,
+ AsyncPhoneNumberBatchesResource,
+ PhoneNumberBatchesResourceWithRawResponse,
+ AsyncPhoneNumberBatchesResourceWithRawResponse,
+ PhoneNumberBatchesResourceWithStreamingResponse,
+ AsyncPhoneNumberBatchesResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "CommentsResource",
+ "AsyncCommentsResource",
+ "CommentsResourceWithRawResponse",
+ "AsyncCommentsResourceWithRawResponse",
+ "CommentsResourceWithStreamingResponse",
+ "AsyncCommentsResourceWithStreamingResponse",
+ "PhoneNumberBatchesResource",
+ "AsyncPhoneNumberBatchesResource",
+ "PhoneNumberBatchesResourceWithRawResponse",
+ "AsyncPhoneNumberBatchesResourceWithRawResponse",
+ "PhoneNumberBatchesResourceWithStreamingResponse",
+ "AsyncPhoneNumberBatchesResourceWithStreamingResponse",
+ "PhoneNumbersResource",
+ "AsyncPhoneNumbersResource",
+ "PhoneNumbersResourceWithRawResponse",
+ "AsyncPhoneNumbersResourceWithRawResponse",
+ "PhoneNumbersResourceWithStreamingResponse",
+ "AsyncPhoneNumbersResourceWithStreamingResponse",
+ "DirResource",
+ "AsyncDirResource",
+ "DirResourceWithRawResponse",
+ "AsyncDirResourceWithRawResponse",
+ "DirResourceWithStreamingResponse",
+ "AsyncDirResourceWithStreamingResponse",
+]
diff --git a/src/telnyx/resources/dir/comments.py b/src/telnyx/resources/dir/comments.py
new file mode 100644
index 00000000..89094488
--- /dev/null
+++ b/src/telnyx/resources/dir/comments.py
@@ -0,0 +1,355 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+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 ...types.dir import comment_list_params, comment_create_params
+from ...pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.dir.comment_list_response import CommentListResponse
+from ...types.dir.comment_create_response import CommentCreateResponse
+
+__all__ = ["CommentsResource", "AsyncCommentsResource"]
+
+
+class CommentsResource(SyncAPIResource):
+ """
+ Read messages from the Telnyx vetting team and reply with clarifying information.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> CommentsResourceWithRawResponse:
+ """
+ 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 CommentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> CommentsResourceWithStreamingResponse:
+ """
+ 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 CommentsResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ dir_id: str,
+ *,
+ content: str,
+ parent_comment_id: str | 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,
+ ) -> CommentCreateResponse:
+ """
+ Post a customer comment on a DIR (for example, to respond to reviewer notes).
+ Send only `content` (1–5000 chars) and an optional `parent_comment_id`; the
+ server sets the comment type, visibility, and author automatically. The
+ enterprise is resolved server-side from the DIR id.
+
+ Args:
+ content: Comment body. 1–5000 characters.
+
+ parent_comment_id: Optional parent comment id to thread this reply under.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._post(
+ path_template("/dir/{dir_id}/comments", dir_id=dir_id),
+ body=maybe_transform(
+ {
+ "content": content,
+ "parent_comment_id": parent_comment_id,
+ },
+ comment_create_params.CommentCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CommentCreateResponse,
+ )
+
+ def list(
+ self,
+ dir_id: str,
+ *,
+ comment_type: Literal[
+ "vetting_comment",
+ "rejection_reason",
+ "internal_note",
+ "notification",
+ "status_update",
+ "customer_inquiry",
+ "admin_response",
+ ]
+ | 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,
+ ) -> SyncDefaultFlatPagination[CommentListResponse]:
+ """List the comments on a DIR.
+
+ The enterprise is resolved server-side from the DIR
+ id.
+
+ Args:
+ comment_type:
+ Restrict to comments of this category. Customer-visible categories only:
+ internal-only comments are filtered out regardless of this filter.
+
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get_api_list(
+ path_template("/dir/{dir_id}/comments", dir_id=dir_id),
+ page=SyncDefaultFlatPagination[CommentListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "comment_type": comment_type,
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ comment_list_params.CommentListParams,
+ ),
+ ),
+ model=CommentListResponse,
+ )
+
+
+class AsyncCommentsResource(AsyncAPIResource):
+ """
+ Read messages from the Telnyx vetting team and reply with clarifying information.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncCommentsResourceWithRawResponse:
+ """
+ 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 AsyncCommentsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncCommentsResourceWithStreamingResponse:
+ """
+ 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 AsyncCommentsResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ dir_id: str,
+ *,
+ content: str,
+ parent_comment_id: str | 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,
+ ) -> CommentCreateResponse:
+ """
+ Post a customer comment on a DIR (for example, to respond to reviewer notes).
+ Send only `content` (1–5000 chars) and an optional `parent_comment_id`; the
+ server sets the comment type, visibility, and author automatically. The
+ enterprise is resolved server-side from the DIR id.
+
+ Args:
+ content: Comment body. 1–5000 characters.
+
+ parent_comment_id: Optional parent comment id to thread this reply under.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return await self._post(
+ path_template("/dir/{dir_id}/comments", dir_id=dir_id),
+ body=await async_maybe_transform(
+ {
+ "content": content,
+ "parent_comment_id": parent_comment_id,
+ },
+ comment_create_params.CommentCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CommentCreateResponse,
+ )
+
+ def list(
+ self,
+ dir_id: str,
+ *,
+ comment_type: Literal[
+ "vetting_comment",
+ "rejection_reason",
+ "internal_note",
+ "notification",
+ "status_update",
+ "customer_inquiry",
+ "admin_response",
+ ]
+ | 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,
+ ) -> AsyncPaginator[CommentListResponse, AsyncDefaultFlatPagination[CommentListResponse]]:
+ """List the comments on a DIR.
+
+ The enterprise is resolved server-side from the DIR
+ id.
+
+ Args:
+ comment_type:
+ Restrict to comments of this category. Customer-visible categories only:
+ internal-only comments are filtered out regardless of this filter.
+
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get_api_list(
+ path_template("/dir/{dir_id}/comments", dir_id=dir_id),
+ page=AsyncDefaultFlatPagination[CommentListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "comment_type": comment_type,
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ comment_list_params.CommentListParams,
+ ),
+ ),
+ model=CommentListResponse,
+ )
+
+
+class CommentsResourceWithRawResponse:
+ def __init__(self, comments: CommentsResource) -> None:
+ self._comments = comments
+
+ self.create = to_raw_response_wrapper(
+ comments.create,
+ )
+ self.list = to_raw_response_wrapper(
+ comments.list,
+ )
+
+
+class AsyncCommentsResourceWithRawResponse:
+ def __init__(self, comments: AsyncCommentsResource) -> None:
+ self._comments = comments
+
+ self.create = async_to_raw_response_wrapper(
+ comments.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ comments.list,
+ )
+
+
+class CommentsResourceWithStreamingResponse:
+ def __init__(self, comments: CommentsResource) -> None:
+ self._comments = comments
+
+ self.create = to_streamed_response_wrapper(
+ comments.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ comments.list,
+ )
+
+
+class AsyncCommentsResourceWithStreamingResponse:
+ def __init__(self, comments: AsyncCommentsResource) -> None:
+ self._comments = comments
+
+ self.create = async_to_streamed_response_wrapper(
+ comments.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ comments.list,
+ )
diff --git a/src/telnyx/resources/dir/dir.py b/src/telnyx/resources/dir/dir.py
new file mode 100644
index 00000000..c57fd8d4
--- /dev/null
+++ b/src/telnyx/resources/dir/dir.py
@@ -0,0 +1,1227 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Iterable, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+import httpx
+
+from ...types import (
+ dir_list_params,
+ dir_update_params,
+ dir_update_infringement_params,
+ dir_list_infringement_claims_params,
+)
+from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
+from ..._utils import path_template, maybe_transform, async_maybe_transform
+from .comments import (
+ CommentsResource,
+ AsyncCommentsResource,
+ CommentsResourceWithRawResponse,
+ AsyncCommentsResourceWithRawResponse,
+ CommentsResourceWithStreamingResponse,
+ AsyncCommentsResourceWithStreamingResponse,
+)
+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 .phone_numbers import (
+ PhoneNumbersResource,
+ AsyncPhoneNumbersResource,
+ PhoneNumbersResourceWithRawResponse,
+ AsyncPhoneNumbersResourceWithRawResponse,
+ PhoneNumbersResourceWithStreamingResponse,
+ AsyncPhoneNumbersResourceWithStreamingResponse,
+)
+from ..._base_client import AsyncPaginator, make_request_options
+from .phone_number_batches import (
+ PhoneNumberBatchesResource,
+ AsyncPhoneNumberBatchesResource,
+ PhoneNumberBatchesResourceWithRawResponse,
+ AsyncPhoneNumberBatchesResourceWithRawResponse,
+ PhoneNumberBatchesResourceWithStreamingResponse,
+ AsyncPhoneNumberBatchesResourceWithStreamingResponse,
+)
+from ...types.dir_list_response import DirListResponse
+from ...types.dir_submit_response import DirSubmitResponse
+from ...types.dir_update_response import DirUpdateResponse
+from ...types.dir_retrieve_response import DirRetrieveResponse
+from ...types.dir_list_document_types_response import DirListDocumentTypesResponse
+from ...types.dir_update_infringement_response import DirUpdateInfringementResponse
+from ...types.dir_list_infringement_claims_response import DirListInfringementClaimsResponse
+
+__all__ = ["DirResource", "AsyncDirResource"]
+
+
+class DirResource(SyncAPIResource):
+ @cached_property
+ def comments(self) -> CommentsResource:
+ """
+ Read messages from the Telnyx vetting team and reply with clarifying information.
+ """
+ return CommentsResource(self._client)
+
+ @cached_property
+ def phone_number_batches(self) -> PhoneNumberBatchesResource:
+ """Phone numbers are submitted to Telnyx for vetting in batches.
+
+ Batches group all numbers added in a single request under the same Letter of Authorization.
+ """
+ return PhoneNumberBatchesResource(self._client)
+
+ @cached_property
+ def phone_numbers(self) -> PhoneNumbersResource:
+ """
+ Associate phone numbers with a verified DIR so calls from those numbers carry the DIR's display identity.
+ """
+ return PhoneNumbersResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> DirResourceWithRawResponse:
+ """
+ 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 DirResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DirResourceWithStreamingResponse:
+ """
+ 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 DirResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ dir_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,
+ ) -> DirRetrieveResponse:
+ """Returns a single DIR by id.
+
+ The enterprise is resolved server-side from the DIR
+ id. Returns `404` if the DIR does not exist or is not yours.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get(
+ path_template("/dir/{dir_id}", dir_id=dir_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirRetrieveResponse,
+ )
+
+ def update(
+ self,
+ dir_id: str,
+ *,
+ authorizer_email: str | Omit = omit,
+ authorizer_name: str | Omit = omit,
+ call_reasons: SequenceNotStr[str] | Omit = omit,
+ display_name: str | Omit = omit,
+ logo_url: str | Omit = omit,
+ reselling: bool | 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,
+ ) -> DirUpdateResponse:
+ """Edit a DIR.
+
+ Only DIRs in `draft`, `rejected`, `unsuccessful`, or `suspended` are
+ editable. PATCH is a pure edit — `status` is never changed by this endpoint. To
+ re-vet after editing, call `POST /v2/dir/{dir_id}/submit` explicitly.
+
+ Args:
+ authorizer_email: Contact email of the authorizer. Telnyx may send verification or infringement
+ notices here.
+
+ authorizer_name: Name of the person at your enterprise authorizing this DIR. Must be a real
+ individual.
+
+ call_reasons: 1–10 reasons your business calls customers. Validate phrasing against
+ `POST /call_reasons/validate`.
+
+ display_name: Name shown to call recipients. 1–35 characters, no emoji, not whitespace-only.
+
+ logo_url: Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB).
+
+ reselling: Set to true if your organization places calls on behalf of other enterprises
+ (BPO/reseller). Updating this triggers re-vetting on next submit.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._patch(
+ path_template("/dir/{dir_id}", dir_id=dir_id),
+ body=maybe_transform(
+ {
+ "authorizer_email": authorizer_email,
+ "authorizer_name": authorizer_name,
+ "call_reasons": call_reasons,
+ "display_name": display_name,
+ "logo_url": logo_url,
+ "reselling": reselling,
+ },
+ dir_update_params.DirUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirUpdateResponse,
+ )
+
+ def list(
+ self,
+ *,
+ enterprise_id: str | Omit = omit,
+ filter_expiring_at_gte: Union[str, datetime] | Omit = omit,
+ filter_expiring_at_lte: Union[str, datetime] | Omit = omit,
+ page_number: int | Omit = omit,
+ page_size: int | Omit = omit,
+ search: str | Omit = omit,
+ sort: Literal[
+ "created_at",
+ "-created_at",
+ "updated_at",
+ "-updated_at",
+ "display_name",
+ "-display_name",
+ "status",
+ "-status",
+ ]
+ | Omit = omit,
+ status: Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ | 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[DirListResponse]:
+ """
+ Convenience endpoint that returns every DIR you own without scoping to a
+ specific enterprise. Equivalent to calling
+ `GET /v2/enterprises/{enterprise_id}/dir` for each enterprise and concatenating
+ the results, but server-side and paginated as a single list.
+
+ Args:
+ enterprise_id: Restrict results to a single enterprise.
+
+ filter_expiring_at_gte: Return only DIRs whose `expiring_at` is at or after this ISO-8601 timestamp.
+ Pairs with the `[lte]` variant to build renewal-window dashboards.
+
+ filter_expiring_at_lte: Return only DIRs whose `expiring_at` is at or before this ISO-8601 timestamp.
+
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ search: Case-insensitive partial match on `display_name` or call reason.
+
+ sort: Sort field. Allowed values: `created_at`, `updated_at`, `display_name`,
+ `status`. Prefix with `-` for descending. Default `-created_at`.
+
+ status: Filter by DIR status.
+
+ 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(
+ "/dir",
+ page=SyncDefaultFlatPagination[DirListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "enterprise_id": enterprise_id,
+ "filter_expiring_at_gte": filter_expiring_at_gte,
+ "filter_expiring_at_lte": filter_expiring_at_lte,
+ "page_number": page_number,
+ "page_size": page_size,
+ "search": search,
+ "sort": sort,
+ "status": status,
+ },
+ dir_list_params.DirListParams,
+ ),
+ ),
+ model=DirListResponse,
+ )
+
+ def delete(
+ self,
+ dir_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,
+ ) -> None:
+ """Delete a DIR.
+
+ Failure modes: `400` if a child phone number is in a non-deletable
+ status, `409` if the DIR has an unresolved infringement claim, `404` if the DIR
+ is not yours.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return self._delete(
+ path_template("/dir/{dir_id}", dir_id=dir_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ def list_document_types(
+ self,
+ *,
+ # 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,
+ ) -> DirListDocumentTypesResponse:
+ """
+ Reference list of `document_type` values accepted by
+ `DirCreateRequest.documents[].document_type` and the infringement-contest
+ endpoint. Each entry has a stable `short_name` (used in API calls) and a
+ customer-facing description.
+ """
+ return self._get(
+ "/dir/document_types",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirListDocumentTypesResponse,
+ )
+
+ def list_infringement_claims(
+ self,
+ dir_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,
+ ) -> SyncDefaultFlatPagination[DirListInfringementClaimsResponse]:
+ """Return the trademark or copyright claims filed against this DIR.
+
+ Each claim's
+ `status` is `pending` (newly filed; DIR auto-suspended), `contested` (you have
+ submitted contest evidence; awaiting resolution), or `resolved` (final).
+ Resolution outcomes: `upheld` (claim accepted; DIR stays
+ suspended/permanently_rejected), `rejected` (claim dismissed; DIR restored to
+ `verified`), `modified` (partial outcome).
+
+ Args:
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get_api_list(
+ path_template("/dir/{dir_id}/infringement_claims", dir_id=dir_id),
+ page=SyncDefaultFlatPagination[DirListInfringementClaimsResponse],
+ 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,
+ },
+ dir_list_infringement_claims_params.DirListInfringementClaimsParams,
+ ),
+ ),
+ model=DirListInfringementClaimsResponse,
+ )
+
+ def submit(
+ self,
+ dir_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,
+ ) -> DirSubmitResponse:
+ """Submit a DIR for vetting.
+
+ Sends the DIR back through the vetting cycle from any
+ non-terminal status. When re-submitting from `suspended` or `expired`, the DIR's
+ previous Branded Calling registration is torn down transactionally and its phone
+ numbers flip back to `submitted`. When re-submitting from `verified`, the
+ existing registration stays live throughout the new vetting cycle.
+
+ Returns `400` from `submitted`/`in_review`/`permanently_rejected`. Returns `409`
+ if the DIR has an unresolved infringement claim.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._post(
+ path_template("/dir/{dir_id}/submit", dir_id=dir_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirSubmitResponse,
+ )
+
+ def update_infringement(
+ self,
+ dir_id: str,
+ *,
+ certify_brand_is_accurate: Literal[True],
+ certify_ip_ownership: Literal[True],
+ certify_no_infringement: Literal[True],
+ certify_no_shaft_content: Literal[True],
+ infringement_resolution_notes: str,
+ call_reasons: Optional[SequenceNotStr[str]] | Omit = omit,
+ display_name: Optional[str] | Omit = omit,
+ documents: Optional[Iterable[dir_update_infringement_params.Document]] | Omit = omit,
+ logo_url: Optional[str] | 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,
+ ) -> DirUpdateInfringementResponse:
+ """
+ Push a fix for a DIR that is `suspended` with an open infringement claim back
+ into vetting. `POST /dir/{dir_id}/submit` is blocked while a claim is open, so
+ this is the customer-callable path to update the DIR's content and re-certify
+ before Telnyx adjudicates the claim. All four certification booleans must be
+ `true`. Optional content fields (`display_name`, `logo_url`, `call_reasons`,
+ `documents`) update the DIR; documents are append-only.
+
+ Args:
+ certify_brand_is_accurate: Must be `true`.
+
+ certify_ip_ownership: Must be `true`.
+
+ certify_no_infringement: Must be `true`.
+
+ certify_no_shaft_content: Must be `true`.
+
+ infringement_resolution_notes: Explanation of how the infringement concern was addressed.
+
+ documents: Append-only supporting documents.
+
+ logo_url: Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB).
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._put(
+ path_template("/dir/{dir_id}/infringement_update", dir_id=dir_id),
+ body=maybe_transform(
+ {
+ "certify_brand_is_accurate": certify_brand_is_accurate,
+ "certify_ip_ownership": certify_ip_ownership,
+ "certify_no_infringement": certify_no_infringement,
+ "certify_no_shaft_content": certify_no_shaft_content,
+ "infringement_resolution_notes": infringement_resolution_notes,
+ "call_reasons": call_reasons,
+ "display_name": display_name,
+ "documents": documents,
+ "logo_url": logo_url,
+ },
+ dir_update_infringement_params.DirUpdateInfringementParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirUpdateInfringementResponse,
+ )
+
+
+class AsyncDirResource(AsyncAPIResource):
+ @cached_property
+ def comments(self) -> AsyncCommentsResource:
+ """
+ Read messages from the Telnyx vetting team and reply with clarifying information.
+ """
+ return AsyncCommentsResource(self._client)
+
+ @cached_property
+ def phone_number_batches(self) -> AsyncPhoneNumberBatchesResource:
+ """Phone numbers are submitted to Telnyx for vetting in batches.
+
+ Batches group all numbers added in a single request under the same Letter of Authorization.
+ """
+ return AsyncPhoneNumberBatchesResource(self._client)
+
+ @cached_property
+ def phone_numbers(self) -> AsyncPhoneNumbersResource:
+ """
+ Associate phone numbers with a verified DIR so calls from those numbers carry the DIR's display identity.
+ """
+ return AsyncPhoneNumbersResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncDirResourceWithRawResponse:
+ """
+ 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 AsyncDirResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDirResourceWithStreamingResponse:
+ """
+ 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 AsyncDirResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ dir_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,
+ ) -> DirRetrieveResponse:
+ """Returns a single DIR by id.
+
+ The enterprise is resolved server-side from the DIR
+ id. Returns `404` if the DIR does not exist or is not yours.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return await self._get(
+ path_template("/dir/{dir_id}", dir_id=dir_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirRetrieveResponse,
+ )
+
+ async def update(
+ self,
+ dir_id: str,
+ *,
+ authorizer_email: str | Omit = omit,
+ authorizer_name: str | Omit = omit,
+ call_reasons: SequenceNotStr[str] | Omit = omit,
+ display_name: str | Omit = omit,
+ logo_url: str | Omit = omit,
+ reselling: bool | 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,
+ ) -> DirUpdateResponse:
+ """Edit a DIR.
+
+ Only DIRs in `draft`, `rejected`, `unsuccessful`, or `suspended` are
+ editable. PATCH is a pure edit — `status` is never changed by this endpoint. To
+ re-vet after editing, call `POST /v2/dir/{dir_id}/submit` explicitly.
+
+ Args:
+ authorizer_email: Contact email of the authorizer. Telnyx may send verification or infringement
+ notices here.
+
+ authorizer_name: Name of the person at your enterprise authorizing this DIR. Must be a real
+ individual.
+
+ call_reasons: 1–10 reasons your business calls customers. Validate phrasing against
+ `POST /call_reasons/validate`.
+
+ display_name: Name shown to call recipients. 1–35 characters, no emoji, not whitespace-only.
+
+ logo_url: Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB).
+
+ reselling: Set to true if your organization places calls on behalf of other enterprises
+ (BPO/reseller). Updating this triggers re-vetting on next submit.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return await self._patch(
+ path_template("/dir/{dir_id}", dir_id=dir_id),
+ body=await async_maybe_transform(
+ {
+ "authorizer_email": authorizer_email,
+ "authorizer_name": authorizer_name,
+ "call_reasons": call_reasons,
+ "display_name": display_name,
+ "logo_url": logo_url,
+ "reselling": reselling,
+ },
+ dir_update_params.DirUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirUpdateResponse,
+ )
+
+ def list(
+ self,
+ *,
+ enterprise_id: str | Omit = omit,
+ filter_expiring_at_gte: Union[str, datetime] | Omit = omit,
+ filter_expiring_at_lte: Union[str, datetime] | Omit = omit,
+ page_number: int | Omit = omit,
+ page_size: int | Omit = omit,
+ search: str | Omit = omit,
+ sort: Literal[
+ "created_at",
+ "-created_at",
+ "updated_at",
+ "-updated_at",
+ "display_name",
+ "-display_name",
+ "status",
+ "-status",
+ ]
+ | Omit = omit,
+ status: Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ | 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[DirListResponse, AsyncDefaultFlatPagination[DirListResponse]]:
+ """
+ Convenience endpoint that returns every DIR you own without scoping to a
+ specific enterprise. Equivalent to calling
+ `GET /v2/enterprises/{enterprise_id}/dir` for each enterprise and concatenating
+ the results, but server-side and paginated as a single list.
+
+ Args:
+ enterprise_id: Restrict results to a single enterprise.
+
+ filter_expiring_at_gte: Return only DIRs whose `expiring_at` is at or after this ISO-8601 timestamp.
+ Pairs with the `[lte]` variant to build renewal-window dashboards.
+
+ filter_expiring_at_lte: Return only DIRs whose `expiring_at` is at or before this ISO-8601 timestamp.
+
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ search: Case-insensitive partial match on `display_name` or call reason.
+
+ sort: Sort field. Allowed values: `created_at`, `updated_at`, `display_name`,
+ `status`. Prefix with `-` for descending. Default `-created_at`.
+
+ status: Filter by DIR status.
+
+ 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(
+ "/dir",
+ page=AsyncDefaultFlatPagination[DirListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "enterprise_id": enterprise_id,
+ "filter_expiring_at_gte": filter_expiring_at_gte,
+ "filter_expiring_at_lte": filter_expiring_at_lte,
+ "page_number": page_number,
+ "page_size": page_size,
+ "search": search,
+ "sort": sort,
+ "status": status,
+ },
+ dir_list_params.DirListParams,
+ ),
+ ),
+ model=DirListResponse,
+ )
+
+ async def delete(
+ self,
+ dir_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,
+ ) -> None:
+ """Delete a DIR.
+
+ Failure modes: `400` if a child phone number is in a non-deletable
+ status, `409` if the DIR has an unresolved infringement claim, `404` if the DIR
+ is not yours.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ extra_headers = {"Accept": "*/*", **(extra_headers or {})}
+ return await self._delete(
+ path_template("/dir/{dir_id}", dir_id=dir_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NoneType,
+ )
+
+ async def list_document_types(
+ self,
+ *,
+ # 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,
+ ) -> DirListDocumentTypesResponse:
+ """
+ Reference list of `document_type` values accepted by
+ `DirCreateRequest.documents[].document_type` and the infringement-contest
+ endpoint. Each entry has a stable `short_name` (used in API calls) and a
+ customer-facing description.
+ """
+ return await self._get(
+ "/dir/document_types",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirListDocumentTypesResponse,
+ )
+
+ def list_infringement_claims(
+ self,
+ dir_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,
+ ) -> AsyncPaginator[
+ DirListInfringementClaimsResponse, AsyncDefaultFlatPagination[DirListInfringementClaimsResponse]
+ ]:
+ """Return the trademark or copyright claims filed against this DIR.
+
+ Each claim's
+ `status` is `pending` (newly filed; DIR auto-suspended), `contested` (you have
+ submitted contest evidence; awaiting resolution), or `resolved` (final).
+ Resolution outcomes: `upheld` (claim accepted; DIR stays
+ suspended/permanently_rejected), `rejected` (claim dismissed; DIR restored to
+ `verified`), `modified` (partial outcome).
+
+ Args:
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get_api_list(
+ path_template("/dir/{dir_id}/infringement_claims", dir_id=dir_id),
+ page=AsyncDefaultFlatPagination[DirListInfringementClaimsResponse],
+ 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,
+ },
+ dir_list_infringement_claims_params.DirListInfringementClaimsParams,
+ ),
+ ),
+ model=DirListInfringementClaimsResponse,
+ )
+
+ async def submit(
+ self,
+ dir_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,
+ ) -> DirSubmitResponse:
+ """Submit a DIR for vetting.
+
+ Sends the DIR back through the vetting cycle from any
+ non-terminal status. When re-submitting from `suspended` or `expired`, the DIR's
+ previous Branded Calling registration is torn down transactionally and its phone
+ numbers flip back to `submitted`. When re-submitting from `verified`, the
+ existing registration stays live throughout the new vetting cycle.
+
+ Returns `400` from `submitted`/`in_review`/`permanently_rejected`. Returns `409`
+ if the DIR has an unresolved infringement claim.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return await self._post(
+ path_template("/dir/{dir_id}/submit", dir_id=dir_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirSubmitResponse,
+ )
+
+ async def update_infringement(
+ self,
+ dir_id: str,
+ *,
+ certify_brand_is_accurate: Literal[True],
+ certify_ip_ownership: Literal[True],
+ certify_no_infringement: Literal[True],
+ certify_no_shaft_content: Literal[True],
+ infringement_resolution_notes: str,
+ call_reasons: Optional[SequenceNotStr[str]] | Omit = omit,
+ display_name: Optional[str] | Omit = omit,
+ documents: Optional[Iterable[dir_update_infringement_params.Document]] | Omit = omit,
+ logo_url: Optional[str] | 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,
+ ) -> DirUpdateInfringementResponse:
+ """
+ Push a fix for a DIR that is `suspended` with an open infringement claim back
+ into vetting. `POST /dir/{dir_id}/submit` is blocked while a claim is open, so
+ this is the customer-callable path to update the DIR's content and re-certify
+ before Telnyx adjudicates the claim. All four certification booleans must be
+ `true`. Optional content fields (`display_name`, `logo_url`, `call_reasons`,
+ `documents`) update the DIR; documents are append-only.
+
+ Args:
+ certify_brand_is_accurate: Must be `true`.
+
+ certify_ip_ownership: Must be `true`.
+
+ certify_no_infringement: Must be `true`.
+
+ certify_no_shaft_content: Must be `true`.
+
+ infringement_resolution_notes: Explanation of how the infringement concern was addressed.
+
+ documents: Append-only supporting documents.
+
+ logo_url: Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB).
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return await self._put(
+ path_template("/dir/{dir_id}/infringement_update", dir_id=dir_id),
+ body=await async_maybe_transform(
+ {
+ "certify_brand_is_accurate": certify_brand_is_accurate,
+ "certify_ip_ownership": certify_ip_ownership,
+ "certify_no_infringement": certify_no_infringement,
+ "certify_no_shaft_content": certify_no_shaft_content,
+ "infringement_resolution_notes": infringement_resolution_notes,
+ "call_reasons": call_reasons,
+ "display_name": display_name,
+ "documents": documents,
+ "logo_url": logo_url,
+ },
+ dir_update_infringement_params.DirUpdateInfringementParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirUpdateInfringementResponse,
+ )
+
+
+class DirResourceWithRawResponse:
+ def __init__(self, dir: DirResource) -> None:
+ self._dir = dir
+
+ self.retrieve = to_raw_response_wrapper(
+ dir.retrieve,
+ )
+ self.update = to_raw_response_wrapper(
+ dir.update,
+ )
+ self.list = to_raw_response_wrapper(
+ dir.list,
+ )
+ self.delete = to_raw_response_wrapper(
+ dir.delete,
+ )
+ self.list_document_types = to_raw_response_wrapper(
+ dir.list_document_types,
+ )
+ self.list_infringement_claims = to_raw_response_wrapper(
+ dir.list_infringement_claims,
+ )
+ self.submit = to_raw_response_wrapper(
+ dir.submit,
+ )
+ self.update_infringement = to_raw_response_wrapper(
+ dir.update_infringement,
+ )
+
+ @cached_property
+ def comments(self) -> CommentsResourceWithRawResponse:
+ """
+ Read messages from the Telnyx vetting team and reply with clarifying information.
+ """
+ return CommentsResourceWithRawResponse(self._dir.comments)
+
+ @cached_property
+ def phone_number_batches(self) -> PhoneNumberBatchesResourceWithRawResponse:
+ """Phone numbers are submitted to Telnyx for vetting in batches.
+
+ Batches group all numbers added in a single request under the same Letter of Authorization.
+ """
+ return PhoneNumberBatchesResourceWithRawResponse(self._dir.phone_number_batches)
+
+ @cached_property
+ def phone_numbers(self) -> PhoneNumbersResourceWithRawResponse:
+ """
+ Associate phone numbers with a verified DIR so calls from those numbers carry the DIR's display identity.
+ """
+ return PhoneNumbersResourceWithRawResponse(self._dir.phone_numbers)
+
+
+class AsyncDirResourceWithRawResponse:
+ def __init__(self, dir: AsyncDirResource) -> None:
+ self._dir = dir
+
+ self.retrieve = async_to_raw_response_wrapper(
+ dir.retrieve,
+ )
+ self.update = async_to_raw_response_wrapper(
+ dir.update,
+ )
+ self.list = async_to_raw_response_wrapper(
+ dir.list,
+ )
+ self.delete = async_to_raw_response_wrapper(
+ dir.delete,
+ )
+ self.list_document_types = async_to_raw_response_wrapper(
+ dir.list_document_types,
+ )
+ self.list_infringement_claims = async_to_raw_response_wrapper(
+ dir.list_infringement_claims,
+ )
+ self.submit = async_to_raw_response_wrapper(
+ dir.submit,
+ )
+ self.update_infringement = async_to_raw_response_wrapper(
+ dir.update_infringement,
+ )
+
+ @cached_property
+ def comments(self) -> AsyncCommentsResourceWithRawResponse:
+ """
+ Read messages from the Telnyx vetting team and reply with clarifying information.
+ """
+ return AsyncCommentsResourceWithRawResponse(self._dir.comments)
+
+ @cached_property
+ def phone_number_batches(self) -> AsyncPhoneNumberBatchesResourceWithRawResponse:
+ """Phone numbers are submitted to Telnyx for vetting in batches.
+
+ Batches group all numbers added in a single request under the same Letter of Authorization.
+ """
+ return AsyncPhoneNumberBatchesResourceWithRawResponse(self._dir.phone_number_batches)
+
+ @cached_property
+ def phone_numbers(self) -> AsyncPhoneNumbersResourceWithRawResponse:
+ """
+ Associate phone numbers with a verified DIR so calls from those numbers carry the DIR's display identity.
+ """
+ return AsyncPhoneNumbersResourceWithRawResponse(self._dir.phone_numbers)
+
+
+class DirResourceWithStreamingResponse:
+ def __init__(self, dir: DirResource) -> None:
+ self._dir = dir
+
+ self.retrieve = to_streamed_response_wrapper(
+ dir.retrieve,
+ )
+ self.update = to_streamed_response_wrapper(
+ dir.update,
+ )
+ self.list = to_streamed_response_wrapper(
+ dir.list,
+ )
+ self.delete = to_streamed_response_wrapper(
+ dir.delete,
+ )
+ self.list_document_types = to_streamed_response_wrapper(
+ dir.list_document_types,
+ )
+ self.list_infringement_claims = to_streamed_response_wrapper(
+ dir.list_infringement_claims,
+ )
+ self.submit = to_streamed_response_wrapper(
+ dir.submit,
+ )
+ self.update_infringement = to_streamed_response_wrapper(
+ dir.update_infringement,
+ )
+
+ @cached_property
+ def comments(self) -> CommentsResourceWithStreamingResponse:
+ """
+ Read messages from the Telnyx vetting team and reply with clarifying information.
+ """
+ return CommentsResourceWithStreamingResponse(self._dir.comments)
+
+ @cached_property
+ def phone_number_batches(self) -> PhoneNumberBatchesResourceWithStreamingResponse:
+ """Phone numbers are submitted to Telnyx for vetting in batches.
+
+ Batches group all numbers added in a single request under the same Letter of Authorization.
+ """
+ return PhoneNumberBatchesResourceWithStreamingResponse(self._dir.phone_number_batches)
+
+ @cached_property
+ def phone_numbers(self) -> PhoneNumbersResourceWithStreamingResponse:
+ """
+ Associate phone numbers with a verified DIR so calls from those numbers carry the DIR's display identity.
+ """
+ return PhoneNumbersResourceWithStreamingResponse(self._dir.phone_numbers)
+
+
+class AsyncDirResourceWithStreamingResponse:
+ def __init__(self, dir: AsyncDirResource) -> None:
+ self._dir = dir
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ dir.retrieve,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ dir.update,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ dir.list,
+ )
+ self.delete = async_to_streamed_response_wrapper(
+ dir.delete,
+ )
+ self.list_document_types = async_to_streamed_response_wrapper(
+ dir.list_document_types,
+ )
+ self.list_infringement_claims = async_to_streamed_response_wrapper(
+ dir.list_infringement_claims,
+ )
+ self.submit = async_to_streamed_response_wrapper(
+ dir.submit,
+ )
+ self.update_infringement = async_to_streamed_response_wrapper(
+ dir.update_infringement,
+ )
+
+ @cached_property
+ def comments(self) -> AsyncCommentsResourceWithStreamingResponse:
+ """
+ Read messages from the Telnyx vetting team and reply with clarifying information.
+ """
+ return AsyncCommentsResourceWithStreamingResponse(self._dir.comments)
+
+ @cached_property
+ def phone_number_batches(self) -> AsyncPhoneNumberBatchesResourceWithStreamingResponse:
+ """Phone numbers are submitted to Telnyx for vetting in batches.
+
+ Batches group all numbers added in a single request under the same Letter of Authorization.
+ """
+ return AsyncPhoneNumberBatchesResourceWithStreamingResponse(self._dir.phone_number_batches)
+
+ @cached_property
+ def phone_numbers(self) -> AsyncPhoneNumbersResourceWithStreamingResponse:
+ """
+ Associate phone numbers with a verified DIR so calls from those numbers carry the DIR's display identity.
+ """
+ return AsyncPhoneNumbersResourceWithStreamingResponse(self._dir.phone_numbers)
diff --git a/src/telnyx/resources/dir/phone_number_batches.py b/src/telnyx/resources/dir/phone_number_batches.py
new file mode 100644
index 00000000..3dbb75e6
--- /dev/null
+++ b/src/telnyx/resources/dir/phone_number_batches.py
@@ -0,0 +1,319 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+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
+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.dir import phone_number_batch_list_params
+from ...pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.dir.phone_number_batch_list_response import PhoneNumberBatchListResponse
+from ...types.dir.phone_number_batch_retrieve_response import PhoneNumberBatchRetrieveResponse
+
+__all__ = ["PhoneNumberBatchesResource", "AsyncPhoneNumberBatchesResource"]
+
+
+class PhoneNumberBatchesResource(SyncAPIResource):
+ """Phone numbers are submitted to Telnyx for vetting in batches.
+
+ Batches group all numbers added in a single request under the same Letter of Authorization.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> PhoneNumberBatchesResourceWithRawResponse:
+ """
+ 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 PhoneNumberBatchesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> PhoneNumberBatchesResourceWithStreamingResponse:
+ """
+ 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 PhoneNumberBatchesResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ batch_id: str,
+ *,
+ dir_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,
+ ) -> PhoneNumberBatchRetrieveResponse:
+ """Get a single phone-number batch by id.
+
+ The enterprise is resolved server-side
+ from the DIR id.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ if not batch_id:
+ raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
+ return self._get(
+ path_template("/dir/{dir_id}/phone_number_batches/{batch_id}", dir_id=dir_id, batch_id=batch_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PhoneNumberBatchRetrieveResponse,
+ )
+
+ def list(
+ self,
+ dir_id: str,
+ *,
+ filter_status: Literal[
+ "submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"
+ ]
+ | 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,
+ ) -> SyncDefaultFlatPagination[PhoneNumberBatchListResponse]:
+ """List the phone-number batches submitted under a DIR.
+
+ The enterprise is resolved
+ server-side from the DIR id.
+
+ Args:
+ filter_status: Restrict to batches whose aggregate status equals this value.
+
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get_api_list(
+ path_template("/dir/{dir_id}/phone_number_batches", dir_id=dir_id),
+ page=SyncDefaultFlatPagination[PhoneNumberBatchListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "filter_status": filter_status,
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ phone_number_batch_list_params.PhoneNumberBatchListParams,
+ ),
+ ),
+ model=PhoneNumberBatchListResponse,
+ )
+
+
+class AsyncPhoneNumberBatchesResource(AsyncAPIResource):
+ """Phone numbers are submitted to Telnyx for vetting in batches.
+
+ Batches group all numbers added in a single request under the same Letter of Authorization.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncPhoneNumberBatchesResourceWithRawResponse:
+ """
+ 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 AsyncPhoneNumberBatchesResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncPhoneNumberBatchesResourceWithStreamingResponse:
+ """
+ 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 AsyncPhoneNumberBatchesResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ batch_id: str,
+ *,
+ dir_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,
+ ) -> PhoneNumberBatchRetrieveResponse:
+ """Get a single phone-number batch by id.
+
+ The enterprise is resolved server-side
+ from the DIR id.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ if not batch_id:
+ raise ValueError(f"Expected a non-empty value for `batch_id` but received {batch_id!r}")
+ return await self._get(
+ path_template("/dir/{dir_id}/phone_number_batches/{batch_id}", dir_id=dir_id, batch_id=batch_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PhoneNumberBatchRetrieveResponse,
+ )
+
+ def list(
+ self,
+ dir_id: str,
+ *,
+ filter_status: Literal[
+ "submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"
+ ]
+ | 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,
+ ) -> AsyncPaginator[PhoneNumberBatchListResponse, AsyncDefaultFlatPagination[PhoneNumberBatchListResponse]]:
+ """List the phone-number batches submitted under a DIR.
+
+ The enterprise is resolved
+ server-side from the DIR id.
+
+ Args:
+ filter_status: Restrict to batches whose aggregate status equals this value.
+
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get_api_list(
+ path_template("/dir/{dir_id}/phone_number_batches", dir_id=dir_id),
+ page=AsyncDefaultFlatPagination[PhoneNumberBatchListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "filter_status": filter_status,
+ "page_number": page_number,
+ "page_size": page_size,
+ },
+ phone_number_batch_list_params.PhoneNumberBatchListParams,
+ ),
+ ),
+ model=PhoneNumberBatchListResponse,
+ )
+
+
+class PhoneNumberBatchesResourceWithRawResponse:
+ def __init__(self, phone_number_batches: PhoneNumberBatchesResource) -> None:
+ self._phone_number_batches = phone_number_batches
+
+ self.retrieve = to_raw_response_wrapper(
+ phone_number_batches.retrieve,
+ )
+ self.list = to_raw_response_wrapper(
+ phone_number_batches.list,
+ )
+
+
+class AsyncPhoneNumberBatchesResourceWithRawResponse:
+ def __init__(self, phone_number_batches: AsyncPhoneNumberBatchesResource) -> None:
+ self._phone_number_batches = phone_number_batches
+
+ self.retrieve = async_to_raw_response_wrapper(
+ phone_number_batches.retrieve,
+ )
+ self.list = async_to_raw_response_wrapper(
+ phone_number_batches.list,
+ )
+
+
+class PhoneNumberBatchesResourceWithStreamingResponse:
+ def __init__(self, phone_number_batches: PhoneNumberBatchesResource) -> None:
+ self._phone_number_batches = phone_number_batches
+
+ self.retrieve = to_streamed_response_wrapper(
+ phone_number_batches.retrieve,
+ )
+ self.list = to_streamed_response_wrapper(
+ phone_number_batches.list,
+ )
+
+
+class AsyncPhoneNumberBatchesResourceWithStreamingResponse:
+ def __init__(self, phone_number_batches: AsyncPhoneNumberBatchesResource) -> None:
+ self._phone_number_batches = phone_number_batches
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ phone_number_batches.retrieve,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ phone_number_batches.list,
+ )
diff --git a/src/telnyx/resources/dir/phone_numbers.py b/src/telnyx/resources/dir/phone_numbers.py
new file mode 100644
index 00000000..e728afab
--- /dev/null
+++ b/src/telnyx/resources/dir/phone_numbers.py
@@ -0,0 +1,445 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Literal
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, 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 ...types.dir import phone_number_add_params, phone_number_list_params, phone_number_remove_params
+from ...pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.dir.phone_number_add_response import PhoneNumberAddResponse
+from ...types.dir.phone_number_list_response import PhoneNumberListResponse
+from ...types.dir.phone_number_remove_response import PhoneNumberRemoveResponse
+
+__all__ = ["PhoneNumbersResource", "AsyncPhoneNumbersResource"]
+
+
+class PhoneNumbersResource(SyncAPIResource):
+ """
+ Associate phone numbers with a verified DIR so calls from those numbers carry the DIR's display identity.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> PhoneNumbersResourceWithRawResponse:
+ """
+ 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 PhoneNumbersResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> PhoneNumbersResourceWithStreamingResponse:
+ """
+ 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 PhoneNumbersResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ dir_id: str,
+ *,
+ page_number: int | Omit = omit,
+ page_size: int | Omit = omit,
+ status: Literal[
+ "submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"
+ ]
+ | 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[PhoneNumberListResponse]:
+ """List the phone numbers registered under a DIR.
+
+ The enterprise is resolved
+ server-side from the DIR id.
+
+ Args:
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ status: Filter by phone-number status.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get_api_list(
+ path_template("/dir/{dir_id}/phone_numbers", dir_id=dir_id),
+ page=SyncDefaultFlatPagination[PhoneNumberListResponse],
+ 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,
+ "status": status,
+ },
+ phone_number_list_params.PhoneNumberListParams,
+ ),
+ ),
+ model=PhoneNumberListResponse,
+ )
+
+ def add(
+ self,
+ dir_id: str,
+ *,
+ documents: Iterable[phone_number_add_params.Document],
+ phone_numbers: SequenceNotStr[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,
+ ) -> PhoneNumberAddResponse:
+ """Register phone numbers under a DIR.
+
+ The enterprise is resolved server-side from
+ the DIR id. Same body, failure modes, and batch semantics whichever path form
+ you use.
+
+ **Pricing:** This is a billable action. See https://telnyx.com/pricing/numbers
+ for current pricing.
+
+ Args:
+ documents: Supporting documents covering this batch. At least one entry with
+ `document_type: letter_of_authorization` is required — the LOA authorises Telnyx
+ to register these numbers under the DIR. Each `document_id` must come from the
+ Telnyx Documents API. Additional document types (e.g. business registration) may
+ be included alongside the LOA.
+
+ phone_numbers: 1–15 phone numbers in E.164 format. 10-digit US numbers are auto-prefixed with
+ `1`.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._post(
+ path_template("/dir/{dir_id}/phone_numbers", dir_id=dir_id),
+ body=maybe_transform(
+ {
+ "documents": documents,
+ "phone_numbers": phone_numbers,
+ },
+ phone_number_add_params.PhoneNumberAddParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PhoneNumberAddResponse,
+ )
+
+ def remove(
+ self,
+ dir_id: str,
+ *,
+ phone_numbers: SequenceNotStr[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,
+ ) -> PhoneNumberRemoveResponse:
+ """Deregister phone numbers from a DIR.
+
+ The enterprise is resolved server-side from
+ the DIR id. Returns a partial-success envelope.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._delete(
+ path_template("/dir/{dir_id}/phone_numbers", dir_id=dir_id),
+ body=maybe_transform({"phone_numbers": phone_numbers}, phone_number_remove_params.PhoneNumberRemoveParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PhoneNumberRemoveResponse,
+ )
+
+
+class AsyncPhoneNumbersResource(AsyncAPIResource):
+ """
+ Associate phone numbers with a verified DIR so calls from those numbers carry the DIR's display identity.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncPhoneNumbersResourceWithRawResponse:
+ """
+ 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 AsyncPhoneNumbersResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncPhoneNumbersResourceWithStreamingResponse:
+ """
+ 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 AsyncPhoneNumbersResourceWithStreamingResponse(self)
+
+ def list(
+ self,
+ dir_id: str,
+ *,
+ page_number: int | Omit = omit,
+ page_size: int | Omit = omit,
+ status: Literal[
+ "submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"
+ ]
+ | 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[PhoneNumberListResponse, AsyncDefaultFlatPagination[PhoneNumberListResponse]]:
+ """List the phone numbers registered under a DIR.
+
+ The enterprise is resolved
+ server-side from the DIR id.
+
+ Args:
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ status: Filter by phone-number status.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return self._get_api_list(
+ path_template("/dir/{dir_id}/phone_numbers", dir_id=dir_id),
+ page=AsyncDefaultFlatPagination[PhoneNumberListResponse],
+ 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,
+ "status": status,
+ },
+ phone_number_list_params.PhoneNumberListParams,
+ ),
+ ),
+ model=PhoneNumberListResponse,
+ )
+
+ async def add(
+ self,
+ dir_id: str,
+ *,
+ documents: Iterable[phone_number_add_params.Document],
+ phone_numbers: SequenceNotStr[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,
+ ) -> PhoneNumberAddResponse:
+ """Register phone numbers under a DIR.
+
+ The enterprise is resolved server-side from
+ the DIR id. Same body, failure modes, and batch semantics whichever path form
+ you use.
+
+ **Pricing:** This is a billable action. See https://telnyx.com/pricing/numbers
+ for current pricing.
+
+ Args:
+ documents: Supporting documents covering this batch. At least one entry with
+ `document_type: letter_of_authorization` is required — the LOA authorises Telnyx
+ to register these numbers under the DIR. Each `document_id` must come from the
+ Telnyx Documents API. Additional document types (e.g. business registration) may
+ be included alongside the LOA.
+
+ phone_numbers: 1–15 phone numbers in E.164 format. 10-digit US numbers are auto-prefixed with
+ `1`.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return await self._post(
+ path_template("/dir/{dir_id}/phone_numbers", dir_id=dir_id),
+ body=await async_maybe_transform(
+ {
+ "documents": documents,
+ "phone_numbers": phone_numbers,
+ },
+ phone_number_add_params.PhoneNumberAddParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PhoneNumberAddResponse,
+ )
+
+ async def remove(
+ self,
+ dir_id: str,
+ *,
+ phone_numbers: SequenceNotStr[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,
+ ) -> PhoneNumberRemoveResponse:
+ """Deregister phone numbers from a DIR.
+
+ The enterprise is resolved server-side from
+ the DIR id. Returns a partial-success envelope.
+
+ 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 dir_id:
+ raise ValueError(f"Expected a non-empty value for `dir_id` but received {dir_id!r}")
+ return await self._delete(
+ path_template("/dir/{dir_id}/phone_numbers", dir_id=dir_id),
+ body=await async_maybe_transform(
+ {"phone_numbers": phone_numbers}, phone_number_remove_params.PhoneNumberRemoveParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PhoneNumberRemoveResponse,
+ )
+
+
+class PhoneNumbersResourceWithRawResponse:
+ def __init__(self, phone_numbers: PhoneNumbersResource) -> None:
+ self._phone_numbers = phone_numbers
+
+ self.list = to_raw_response_wrapper(
+ phone_numbers.list,
+ )
+ self.add = to_raw_response_wrapper(
+ phone_numbers.add,
+ )
+ self.remove = to_raw_response_wrapper(
+ phone_numbers.remove,
+ )
+
+
+class AsyncPhoneNumbersResourceWithRawResponse:
+ def __init__(self, phone_numbers: AsyncPhoneNumbersResource) -> None:
+ self._phone_numbers = phone_numbers
+
+ self.list = async_to_raw_response_wrapper(
+ phone_numbers.list,
+ )
+ self.add = async_to_raw_response_wrapper(
+ phone_numbers.add,
+ )
+ self.remove = async_to_raw_response_wrapper(
+ phone_numbers.remove,
+ )
+
+
+class PhoneNumbersResourceWithStreamingResponse:
+ def __init__(self, phone_numbers: PhoneNumbersResource) -> None:
+ self._phone_numbers = phone_numbers
+
+ self.list = to_streamed_response_wrapper(
+ phone_numbers.list,
+ )
+ self.add = to_streamed_response_wrapper(
+ phone_numbers.add,
+ )
+ self.remove = to_streamed_response_wrapper(
+ phone_numbers.remove,
+ )
+
+
+class AsyncPhoneNumbersResourceWithStreamingResponse:
+ def __init__(self, phone_numbers: AsyncPhoneNumbersResource) -> None:
+ self._phone_numbers = phone_numbers
+
+ self.list = async_to_streamed_response_wrapper(
+ phone_numbers.list,
+ )
+ self.add = async_to_streamed_response_wrapper(
+ phone_numbers.add,
+ )
+ self.remove = async_to_streamed_response_wrapper(
+ phone_numbers.remove,
+ )
diff --git a/src/telnyx/resources/enterprises/__init__.py b/src/telnyx/resources/enterprises/__init__.py
index 86b4aea1..f3f33c7f 100644
--- a/src/telnyx/resources/enterprises/__init__.py
+++ b/src/telnyx/resources/enterprises/__init__.py
@@ -1,5 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from .dir import (
+ DirResource,
+ AsyncDirResource,
+ DirResourceWithRawResponse,
+ AsyncDirResourceWithRawResponse,
+ DirResourceWithStreamingResponse,
+ AsyncDirResourceWithStreamingResponse,
+)
from .reputation import (
ReputationResource,
AsyncReputationResource,
@@ -24,6 +32,12 @@
"AsyncReputationResourceWithRawResponse",
"ReputationResourceWithStreamingResponse",
"AsyncReputationResourceWithStreamingResponse",
+ "DirResource",
+ "AsyncDirResource",
+ "DirResourceWithRawResponse",
+ "AsyncDirResourceWithRawResponse",
+ "DirResourceWithStreamingResponse",
+ "AsyncDirResourceWithStreamingResponse",
"EnterprisesResource",
"AsyncEnterprisesResource",
"EnterprisesResourceWithRawResponse",
diff --git a/src/telnyx/resources/enterprises/dir.py b/src/telnyx/resources/enterprises/dir.py
new file mode 100644
index 00000000..a7fc76ad
--- /dev/null
+++ b/src/telnyx/resources/enterprises/dir.py
@@ -0,0 +1,571 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union, Iterable
+from datetime import datetime
+from typing_extensions import Literal
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, 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 ...pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+from ..._base_client import AsyncPaginator, make_request_options
+from ...types.enterprises import dir_list_params, dir_create_params
+from ...types.enterprises.dir_list_response import DirListResponse
+from ...types.enterprises.dir_create_response import DirCreateResponse
+
+__all__ = ["DirResource", "AsyncDirResource"]
+
+
+class DirResource(SyncAPIResource):
+ """
+ A Display Identity Record (DIR) is the verified calling identity (display name, logo, call reasons) shown to recipients on outbound calls.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> DirResourceWithRawResponse:
+ """
+ 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 DirResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> DirResourceWithStreamingResponse:
+ """
+ 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 DirResourceWithStreamingResponse(self)
+
+ def create(
+ self,
+ enterprise_id: str,
+ *,
+ authorizer_email: str,
+ authorizer_name: str,
+ certify_brand_is_accurate: Literal[True],
+ certify_ip_ownership: Literal[True],
+ certify_no_shaft_content: Literal[True],
+ display_name: str,
+ call_reasons: SequenceNotStr[str] | Omit = omit,
+ documents: Iterable[dir_create_params.Document] | Omit = omit,
+ logo_url: str | Omit = omit,
+ reselling: bool | 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,
+ ) -> DirCreateResponse:
+ """Create a new DIR under the given enterprise.
+
+ The DIR starts in `draft` status;
+ it must be submitted (`POST .../submit`) and approved by Telnyx before any phone
+ number can be attached.
+
+ **Field rules**
+
+ - `display_name`: 1–35 characters, no emoji or whitespace-only strings; this is
+ the name shown to recipients.
+ - `call_reasons`: 1–10 strings, each ≤64 characters; describe why your business
+ calls customers (e.g. 'Appointment reminders', 'Billing inquiries'). Validate
+ the wording against `POST /call_reasons/validate`.
+ - `logo_url`: HTTPS URL (max 128 chars) to a 256×256 BMP (max 1 MB). The image
+ is downloaded and hashed at submission time.
+ - `documents`: up to 20 entries; each `document_id` must be obtained by
+ uploading the file via the Telnyx Documents API first. Within one DIR a
+ `document_id` may only appear once.
+ - `certify_brand_is_accurate`, `certify_no_shaft_content`,
+ `certify_ip_ownership` MUST all be `true`.
+
+ **Failure modes**
+
+ - `422` — validation error; `errors[].source.pointer` names the offending field.
+ - `403` — Branded Calling not activated on this enterprise (see
+ `POST /enterprises/{id}/branded_calling`).
+ - `404` — enterprise does not exist or does not belong to your account.
+
+ Args:
+ authorizer_email: Contact email of the authorizer. Telnyx may send verification or
+ infringement-notice email here; use a monitored mailbox.
+
+ authorizer_name: Name of the person at your enterprise who is authorizing this DIR registration.
+ Must be a real individual (used for audit and trademark-claim contests).
+
+ certify_brand_is_accurate: Must be `true`.
+
+ certify_ip_ownership: Must be `true`. Confirms ownership of any logos/trademarks shown.
+
+ certify_no_shaft_content: Must be `true`. Confirms this DIR is not used for SHAFT content (Sex, Hate,
+ Alcohol, Firearms, Tobacco) where prohibited.
+
+ display_name: Name shown to call recipients. No emoji; not whitespace-only.
+
+ call_reasons: 1–10 reasons your business calls customers. Validate phrasing against
+ `POST /call_reasons/validate`.
+
+ documents: Supporting documents. Each `document_id` may appear at most once on a DIR.
+
+ logo_url: Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB).
+
+ reselling: Set to true if your organization places calls on behalf of other enterprises
+ (BPO/reseller).
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return self._post(
+ path_template("/enterprises/{enterprise_id}/dir", enterprise_id=enterprise_id),
+ body=maybe_transform(
+ {
+ "authorizer_email": authorizer_email,
+ "authorizer_name": authorizer_name,
+ "certify_brand_is_accurate": certify_brand_is_accurate,
+ "certify_ip_ownership": certify_ip_ownership,
+ "certify_no_shaft_content": certify_no_shaft_content,
+ "display_name": display_name,
+ "call_reasons": call_reasons,
+ "documents": documents,
+ "logo_url": logo_url,
+ "reselling": reselling,
+ },
+ dir_create_params.DirCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirCreateResponse,
+ )
+
+ def list(
+ self,
+ enterprise_id: str,
+ *,
+ filter_expiring_at_gte: Union[str, datetime] | Omit = omit,
+ filter_expiring_at_lte: Union[str, datetime] | Omit = omit,
+ filter_expiring_within_days: int | Omit = omit,
+ page_number: int | Omit = omit,
+ page_size: int | Omit = omit,
+ search: str | Omit = omit,
+ sort: Literal[
+ "created_at",
+ "-created_at",
+ "updated_at",
+ "-updated_at",
+ "display_name",
+ "-display_name",
+ "status",
+ "-status",
+ "submitted_at",
+ "-submitted_at",
+ "verified_at",
+ "-verified_at",
+ "expiring_at",
+ "-expiring_at",
+ ]
+ | Omit = omit,
+ status: Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ | 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[DirListResponse]:
+ """
+ Return the DIRs (Display Identity Records) belonging to a single enterprise.
+ Pagination is JSON:API style (`page[number]`, `page[size]`, max 250). Filterable
+ by `status`. Searchable by case-insensitive partial match on `display_name`
+ (`search=`). Sortable by any of `created_at`, `updated_at`, `display_name`,
+ `status`, `submitted_at`, `verified_at`, `expiring_at` (prefix `-` for
+ descending; default `-created_at`). Supports the renewal-window filters
+ `filter[expiring_at][gte]` / `filter[expiring_at][lte]` and the convenience
+ `filter[expiring_within_days]` (mutually exclusive with the explicit gte/lte
+ form).
+
+ Args:
+ filter_expiring_at_gte: Return only DIRs whose `expiring_at` is at or after this ISO-8601 timestamp.
+
+ filter_expiring_at_lte: Return only DIRs whose `expiring_at` is at or before this ISO-8601 timestamp.
+
+ filter_expiring_within_days: Convenience: returns DIRs whose `expiring_at` falls within the next N days
+ (1–365). Equivalent to setting `filter[expiring_at][gte]=` +
+ `filter[expiring_at][lte]=`. Mutually exclusive with the explicit
+ `[gte]`/`[lte]` filters — combining returns 400.
+
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ search: Case-insensitive partial match on `display_name`.
+
+ sort: Sort field. Allowed: `created_at`, `updated_at`, `display_name`, `status`,
+ `submitted_at`, `verified_at`, `expiring_at`. Prefix with `-` for descending.
+ Default `-created_at`.
+
+ status: Filter by DIR status.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return self._get_api_list(
+ path_template("/enterprises/{enterprise_id}/dir", enterprise_id=enterprise_id),
+ page=SyncDefaultFlatPagination[DirListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "filter_expiring_at_gte": filter_expiring_at_gte,
+ "filter_expiring_at_lte": filter_expiring_at_lte,
+ "filter_expiring_within_days": filter_expiring_within_days,
+ "page_number": page_number,
+ "page_size": page_size,
+ "search": search,
+ "sort": sort,
+ "status": status,
+ },
+ dir_list_params.DirListParams,
+ ),
+ ),
+ model=DirListResponse,
+ )
+
+
+class AsyncDirResource(AsyncAPIResource):
+ """
+ A Display Identity Record (DIR) is the verified calling identity (display name, logo, call reasons) shown to recipients on outbound calls.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncDirResourceWithRawResponse:
+ """
+ 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 AsyncDirResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncDirResourceWithStreamingResponse:
+ """
+ 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 AsyncDirResourceWithStreamingResponse(self)
+
+ async def create(
+ self,
+ enterprise_id: str,
+ *,
+ authorizer_email: str,
+ authorizer_name: str,
+ certify_brand_is_accurate: Literal[True],
+ certify_ip_ownership: Literal[True],
+ certify_no_shaft_content: Literal[True],
+ display_name: str,
+ call_reasons: SequenceNotStr[str] | Omit = omit,
+ documents: Iterable[dir_create_params.Document] | Omit = omit,
+ logo_url: str | Omit = omit,
+ reselling: bool | 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,
+ ) -> DirCreateResponse:
+ """Create a new DIR under the given enterprise.
+
+ The DIR starts in `draft` status;
+ it must be submitted (`POST .../submit`) and approved by Telnyx before any phone
+ number can be attached.
+
+ **Field rules**
+
+ - `display_name`: 1–35 characters, no emoji or whitespace-only strings; this is
+ the name shown to recipients.
+ - `call_reasons`: 1–10 strings, each ≤64 characters; describe why your business
+ calls customers (e.g. 'Appointment reminders', 'Billing inquiries'). Validate
+ the wording against `POST /call_reasons/validate`.
+ - `logo_url`: HTTPS URL (max 128 chars) to a 256×256 BMP (max 1 MB). The image
+ is downloaded and hashed at submission time.
+ - `documents`: up to 20 entries; each `document_id` must be obtained by
+ uploading the file via the Telnyx Documents API first. Within one DIR a
+ `document_id` may only appear once.
+ - `certify_brand_is_accurate`, `certify_no_shaft_content`,
+ `certify_ip_ownership` MUST all be `true`.
+
+ **Failure modes**
+
+ - `422` — validation error; `errors[].source.pointer` names the offending field.
+ - `403` — Branded Calling not activated on this enterprise (see
+ `POST /enterprises/{id}/branded_calling`).
+ - `404` — enterprise does not exist or does not belong to your account.
+
+ Args:
+ authorizer_email: Contact email of the authorizer. Telnyx may send verification or
+ infringement-notice email here; use a monitored mailbox.
+
+ authorizer_name: Name of the person at your enterprise who is authorizing this DIR registration.
+ Must be a real individual (used for audit and trademark-claim contests).
+
+ certify_brand_is_accurate: Must be `true`.
+
+ certify_ip_ownership: Must be `true`. Confirms ownership of any logos/trademarks shown.
+
+ certify_no_shaft_content: Must be `true`. Confirms this DIR is not used for SHAFT content (Sex, Hate,
+ Alcohol, Firearms, Tobacco) where prohibited.
+
+ display_name: Name shown to call recipients. No emoji; not whitespace-only.
+
+ call_reasons: 1–10 reasons your business calls customers. Validate phrasing against
+ `POST /call_reasons/validate`.
+
+ documents: Supporting documents. Each `document_id` may appear at most once on a DIR.
+
+ logo_url: Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB).
+
+ reselling: Set to true if your organization places calls on behalf of other enterprises
+ (BPO/reseller).
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return await self._post(
+ path_template("/enterprises/{enterprise_id}/dir", enterprise_id=enterprise_id),
+ body=await async_maybe_transform(
+ {
+ "authorizer_email": authorizer_email,
+ "authorizer_name": authorizer_name,
+ "certify_brand_is_accurate": certify_brand_is_accurate,
+ "certify_ip_ownership": certify_ip_ownership,
+ "certify_no_shaft_content": certify_no_shaft_content,
+ "display_name": display_name,
+ "call_reasons": call_reasons,
+ "documents": documents,
+ "logo_url": logo_url,
+ "reselling": reselling,
+ },
+ dir_create_params.DirCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirCreateResponse,
+ )
+
+ def list(
+ self,
+ enterprise_id: str,
+ *,
+ filter_expiring_at_gte: Union[str, datetime] | Omit = omit,
+ filter_expiring_at_lte: Union[str, datetime] | Omit = omit,
+ filter_expiring_within_days: int | Omit = omit,
+ page_number: int | Omit = omit,
+ page_size: int | Omit = omit,
+ search: str | Omit = omit,
+ sort: Literal[
+ "created_at",
+ "-created_at",
+ "updated_at",
+ "-updated_at",
+ "display_name",
+ "-display_name",
+ "status",
+ "-status",
+ "submitted_at",
+ "-submitted_at",
+ "verified_at",
+ "-verified_at",
+ "expiring_at",
+ "-expiring_at",
+ ]
+ | Omit = omit,
+ status: Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ | 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[DirListResponse, AsyncDefaultFlatPagination[DirListResponse]]:
+ """
+ Return the DIRs (Display Identity Records) belonging to a single enterprise.
+ Pagination is JSON:API style (`page[number]`, `page[size]`, max 250). Filterable
+ by `status`. Searchable by case-insensitive partial match on `display_name`
+ (`search=`). Sortable by any of `created_at`, `updated_at`, `display_name`,
+ `status`, `submitted_at`, `verified_at`, `expiring_at` (prefix `-` for
+ descending; default `-created_at`). Supports the renewal-window filters
+ `filter[expiring_at][gte]` / `filter[expiring_at][lte]` and the convenience
+ `filter[expiring_within_days]` (mutually exclusive with the explicit gte/lte
+ form).
+
+ Args:
+ filter_expiring_at_gte: Return only DIRs whose `expiring_at` is at or after this ISO-8601 timestamp.
+
+ filter_expiring_at_lte: Return only DIRs whose `expiring_at` is at or before this ISO-8601 timestamp.
+
+ filter_expiring_within_days: Convenience: returns DIRs whose `expiring_at` falls within the next N days
+ (1–365). Equivalent to setting `filter[expiring_at][gte]=` +
+ `filter[expiring_at][lte]=`. Mutually exclusive with the explicit
+ `[gte]`/`[lte]` filters — combining returns 400.
+
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ search: Case-insensitive partial match on `display_name`.
+
+ sort: Sort field. Allowed: `created_at`, `updated_at`, `display_name`, `status`,
+ `submitted_at`, `verified_at`, `expiring_at`. Prefix with `-` for descending.
+ Default `-created_at`.
+
+ status: Filter by DIR status.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return self._get_api_list(
+ path_template("/enterprises/{enterprise_id}/dir", enterprise_id=enterprise_id),
+ page=AsyncDefaultFlatPagination[DirListResponse],
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "filter_expiring_at_gte": filter_expiring_at_gte,
+ "filter_expiring_at_lte": filter_expiring_at_lte,
+ "filter_expiring_within_days": filter_expiring_within_days,
+ "page_number": page_number,
+ "page_size": page_size,
+ "search": search,
+ "sort": sort,
+ "status": status,
+ },
+ dir_list_params.DirListParams,
+ ),
+ ),
+ model=DirListResponse,
+ )
+
+
+class DirResourceWithRawResponse:
+ def __init__(self, dir: DirResource) -> None:
+ self._dir = dir
+
+ self.create = to_raw_response_wrapper(
+ dir.create,
+ )
+ self.list = to_raw_response_wrapper(
+ dir.list,
+ )
+
+
+class AsyncDirResourceWithRawResponse:
+ def __init__(self, dir: AsyncDirResource) -> None:
+ self._dir = dir
+
+ self.create = async_to_raw_response_wrapper(
+ dir.create,
+ )
+ self.list = async_to_raw_response_wrapper(
+ dir.list,
+ )
+
+
+class DirResourceWithStreamingResponse:
+ def __init__(self, dir: DirResource) -> None:
+ self._dir = dir
+
+ self.create = to_streamed_response_wrapper(
+ dir.create,
+ )
+ self.list = to_streamed_response_wrapper(
+ dir.list,
+ )
+
+
+class AsyncDirResourceWithStreamingResponse:
+ def __init__(self, dir: AsyncDirResource) -> None:
+ self._dir = dir
+
+ self.create = async_to_streamed_response_wrapper(
+ dir.create,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ dir.list,
+ )
diff --git a/src/telnyx/resources/enterprises/enterprises.py b/src/telnyx/resources/enterprises/enterprises.py
index 8a9abcee..795ae227 100644
--- a/src/telnyx/resources/enterprises/enterprises.py
+++ b/src/telnyx/resources/enterprises/enterprises.py
@@ -2,10 +2,19 @@
from __future__ import annotations
+from typing import Optional
from typing_extensions import Literal
import httpx
+from .dir import (
+ DirResource,
+ AsyncDirResource,
+ DirResourceWithRawResponse,
+ AsyncDirResourceWithRawResponse,
+ DirResourceWithStreamingResponse,
+ AsyncDirResourceWithStreamingResponse,
+)
from ...types import (
enterprise_list_params,
enterprise_create_params,
@@ -39,19 +48,25 @@
from ...types.enterprise_update_response import EnterpriseUpdateResponse
from ...types.organization_contact_param import OrganizationContactParam
from ...types.enterprise_retrieve_response import EnterpriseRetrieveResponse
+from ...types.enterprise_activate_branded_calling_response import EnterpriseActivateBrandedCallingResponse
__all__ = ["EnterprisesResource", "AsyncEnterprisesResource"]
class EnterprisesResource(SyncAPIResource):
- """Enterprise management for Branded Calling and Number Reputation services"""
+ """Manage the legal-entity record that owns your DIRs and phone numbers."""
@cached_property
def reputation(self) -> ReputationResource:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return ReputationResource(self._client)
+
+ @cached_property
+ def dir(self) -> DirResource:
"""
- Manage Number Reputation enrollment and check frequency settings for an enterprise
+ A Display Identity Record (DIR) is the verified calling identity (display name, logo, call reasons) shown to recipients on outbound calls.
"""
- return ReputationResource(self._client)
+ return DirResource(self._client)
@cached_property
def with_raw_response(self) -> EnterprisesResourceWithRawResponse:
@@ -80,7 +95,52 @@ def create(
country_code: str,
doing_business_as: str,
fein: str,
- industry: str,
+ industry: Literal[
+ "accounting",
+ "finance",
+ "billing",
+ "collections",
+ "business",
+ "charity",
+ "nonprofit",
+ "communications",
+ "telecom",
+ "customer service",
+ "support",
+ "delivery",
+ "shipping",
+ "logistics",
+ "education",
+ "financial",
+ "banking",
+ "government",
+ "public",
+ "healthcare",
+ "health",
+ "pharmacy",
+ "medical",
+ "insurance",
+ "legal",
+ "law",
+ "notifications",
+ "scheduling",
+ "real estate",
+ "property",
+ "retail",
+ "ecommerce",
+ "sales",
+ "marketing",
+ "software",
+ "technology",
+ "tech",
+ "media",
+ "surveys",
+ "market research",
+ "travel",
+ "hospitality",
+ "hotel",
+ ],
+ jurisdiction_of_incorporation: str,
legal_name: str,
number_of_employees: Literal["1-10", "11-50", "51-200", "201-500", "501-2000", "2001-10000", "10001+"],
organization_contact: OrganizationContactParam,
@@ -88,11 +148,11 @@ def create(
organization_physical_address: PhysicalAddressParam,
organization_type: Literal["commercial", "government", "non_profit"],
website: str,
- corporate_registration_number: str | Omit = omit,
+ corporate_registration_number: Optional[str] | Omit = omit,
customer_reference: str | Omit = omit,
- dun_bradstreet_number: str | Omit = omit,
- primary_business_domain_sic_code: str | Omit = omit,
- professional_license_number: str | Omit = omit,
+ dun_bradstreet_number: Optional[str] | Omit = omit,
+ primary_business_domain_sic_code: Optional[str] | Omit = omit,
+ professional_license_number: Optional[str] | Omit = omit,
role_type: Literal["enterprise", "bpo"] | 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.
@@ -102,57 +162,61 @@ def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> EnterpriseCreateResponse:
"""
- Create a new enterprise for Branded Calling / Number Reputation services.
+ Create the legal entity that owns your Number Reputation registrations.
- Registers the enterprise in the Branded Calling / Number Reputation services,
- enabling it to create Display Identity Records (DIRs) or enroll in Number
- Reputation monitoring.
+ The response carries a server-assigned `id` you will use for every subsequent
+ call. After creating an enterprise and agreeing to the Number Reputation Terms
+ of Service (`POST /terms_of_service/number_reputation/agree`), enable reputation
+ monitoring via `POST /enterprises/{enterprise_id}/reputation`.
- **Required Fields:** `legal_name`, `doing_business_as`, `organization_type`,
- `country_code`, `website`, `fein`, `industry`, `number_of_employees`,
- `organization_legal_type`, `organization_contact`, `billing_contact`,
- `organization_physical_address`, `billing_address`
+ An enterprise is shared across Telnyx products; if you also use Branded Calling,
+ the same enterprise is reused.
Args:
- country_code: Country code. Currently only 'US' is accepted.
+ country_code: ISO 3166-1 alpha-2 country code. Currently `US` and `CA` are supported.
- doing_business_as: Primary business name / DBA name
+ fein: US Federal Employer Identification Number (`NN-NNNNNNN`) or Canadian equivalent.
- fein: Federal Employer Identification Number. Format: XX-XXXXXXX or 9-digit number
- (minimum 9 digits).
+ industry: Industry classification.
- industry: Industry classification. Case-insensitive. Accepted values: accounting, finance,
- billing, collections, business, charity, nonprofit, communications, telecom,
- customer service, support, delivery, shipping, logistics, education, financial,
- banking, government, public, healthcare, health, pharmacy, medical, insurance,
- legal, law, notifications, scheduling, real estate, property, retail, ecommerce,
- sales, marketing, software, technology, tech, media, surveys, market research,
- travel, hospitality, hotel
+ legal_name: Legal name of the enterprise.
- legal_name: Legal name of the enterprise
+ number_of_employees: Approximate headcount range. Used for vetting heuristics; pick the bucket that
+ contains your current employee count.
- number_of_employees: Employee count range
+ organization_legal_type:
+ Legal-entity form. Pick the form that matches your incorporation documents:
- organization_contact: Organization contact information. Note: the response returns this object with
- the phone field as 'phone' (not 'phone_number').
+ - `corporation` — C-corp or S-corp.
+ - `llc` — limited liability company.
+ - `partnership` — general/limited partnership.
+ - `nonprofit` — non-profit corporation, charitable trust, or
+ 501(c)(3)/equivalent.
+ - `other` — anything else (sole proprietorships, government bodies, DBAs, etc.).
+ You may be asked for additional documents during vetting.
- organization_legal_type: Legal structure type
+ organization_type:
+ Organization category for vetting purposes:
- organization_type: Type of organization
+ - `commercial` — for-profit business entities (LLC, corp, partnership, sole
+ proprietorship). Most callers fall here.
+ - `government` — federal/state/local government bodies.
+ - `non_profit` — registered 501(c)(3)/equivalent (incl. educational
+ institutions, charities, religious organisations).
- website: Enterprise website URL. Accepts any string — no URL format validation enforced.
+ corporate_registration_number: Optional corporate-registration / company-number identifier.
- corporate_registration_number: Corporate registration number (optional)
+ customer_reference: Optional free-form string the caller can attach for their own bookkeeping.
+ Telnyx does not interpret it.
- customer_reference: Optional customer reference identifier for your own tracking
+ dun_bradstreet_number: Optional D-U-N-S Number.
- dun_bradstreet_number: D-U-N-S Number (optional)
+ primary_business_domain_sic_code: Optional SIC code for the primary line of business.
- primary_business_domain_sic_code: SIC Code (optional)
+ professional_license_number: Optional professional-license number for regulated industries.
- professional_license_number: Professional license number (optional)
-
- role_type: Role type in Branded Calling / Number Reputation services
+ role_type: `enterprise` for an organization registering its own DIRs; `bpo` for a Business
+ Process Outsourcer placing calls on behalf of one or more enterprises.
extra_headers: Send extra headers
@@ -172,6 +236,7 @@ def create(
"doing_business_as": doing_business_as,
"fein": fein,
"industry": industry,
+ "jurisdiction_of_incorporation": jurisdiction_of_incorporation,
"legal_name": legal_name,
"number_of_employees": number_of_employees,
"organization_contact": organization_contact,
@@ -205,8 +270,10 @@ def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> EnterpriseRetrieveResponse:
- """
- Retrieve details of a specific enterprise by ID.
+ """Retrieve a single enterprise by id.
+
+ Returns `404` if the id does not exist or
+ does not belong to your account.
Args:
extra_headers: Send extra headers
@@ -233,20 +300,65 @@ def update(
*,
billing_address: BillingAddressParam | Omit = omit,
billing_contact: BillingContactParam | Omit = omit,
- corporate_registration_number: str | Omit = omit,
+ corporate_registration_number: Optional[str] | Omit = omit,
customer_reference: str | Omit = omit,
doing_business_as: str | Omit = omit,
- dun_bradstreet_number: str | Omit = omit,
+ dun_bradstreet_number: Optional[str] | Omit = omit,
fein: str | Omit = omit,
- industry: str | Omit = omit,
- legal_name: str | Omit = omit,
- number_of_employees: Literal["1-10", "11-50", "51-200", "201-500", "501-2000", "2001-10000", "10001+"]
+ industry: Literal[
+ "accounting",
+ "finance",
+ "billing",
+ "collections",
+ "business",
+ "charity",
+ "nonprofit",
+ "communications",
+ "telecom",
+ "customer service",
+ "support",
+ "delivery",
+ "shipping",
+ "logistics",
+ "education",
+ "financial",
+ "banking",
+ "government",
+ "public",
+ "healthcare",
+ "health",
+ "pharmacy",
+ "medical",
+ "insurance",
+ "legal",
+ "law",
+ "notifications",
+ "scheduling",
+ "real estate",
+ "property",
+ "retail",
+ "ecommerce",
+ "sales",
+ "marketing",
+ "software",
+ "technology",
+ "tech",
+ "media",
+ "surveys",
+ "market research",
+ "travel",
+ "hospitality",
+ "hotel",
+ ]
| Omit = omit,
+ jurisdiction_of_incorporation: str | Omit = omit,
+ legal_name: str | Omit = omit,
+ number_of_employees: str | Omit = omit,
organization_contact: OrganizationContactParam | Omit = omit,
- organization_legal_type: Literal["corporation", "llc", "partnership", "nonprofit", "other"] | Omit = omit,
+ organization_legal_type: str | Omit = omit,
organization_physical_address: PhysicalAddressParam | Omit = omit,
- primary_business_domain_sic_code: str | Omit = omit,
- professional_license_number: str | Omit = omit,
+ primary_business_domain_sic_code: Optional[str] | Omit = omit,
+ professional_license_number: Optional[str] | Omit = omit,
website: str | 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.
@@ -255,38 +367,18 @@ def update(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> EnterpriseUpdateResponse:
- """Update enterprise information.
+ """Replace the enterprise's mutable fields.
- All fields are optional — only the provided
- fields will be updated.
+ Only mutable fields may be sent.
+ Server-assigned and immutable fields (`id`, `record_type`, `created_at`,
+ `updated_at`, status fields, `organization_type`, `country_code`, `role_type`)
+ cannot be changed: including any of them in the body is rejected with
+ `400 Bad Request` (`Field 'X' is not allowed in this request`).
Args:
- corporate_registration_number: Corporate registration number
-
- customer_reference: Customer reference identifier
-
- doing_business_as: DBA name
-
- dun_bradstreet_number: D-U-N-S Number
-
- fein: Federal Employer Identification Number. Format: XX-XXXXXXX or XXXXXXXXX
-
- industry: Industry classification
-
- legal_name: Legal name of the enterprise
-
- number_of_employees: Employee count range
+ jurisdiction_of_incorporation: Updated state/province/country of incorporation. Optional on update.
- organization_contact: Organization contact information. Note: the response returns this object with
- the phone field as 'phone' (not 'phone_number').
-
- organization_legal_type: Legal structure type
-
- primary_business_domain_sic_code: SIC Code
-
- professional_license_number: Professional license number
-
- website: Company website URL
+ legal_name: Legal name of the enterprise.
extra_headers: Send extra headers
@@ -310,6 +402,7 @@ def update(
"dun_bradstreet_number": dun_bradstreet_number,
"fein": fein,
"industry": industry,
+ "jurisdiction_of_incorporation": jurisdiction_of_incorporation,
"legal_name": legal_name,
"number_of_employees": number_of_employees,
"organization_contact": organization_contact,
@@ -340,15 +433,17 @@ def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> SyncDefaultFlatPagination[EnterprisePublic]:
- """
- Retrieve a paginated list of enterprises associated with your account.
+ """Return the enterprises you own, paginated.
+
+ The default page size is 20; the
+ maximum is 250.
Args:
- legal_name: Filter by legal name (partial match)
+ legal_name: Filter by legal name (partial match).
- page_number: Page number (1-indexed)
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
- page_size: Number of items per page
+ page_size: Items per page. Default 10. Maximum 250; values above are clamped to 250.
extra_headers: Send extra headers
@@ -389,9 +484,12 @@ def delete(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """Delete an enterprise and all associated resources.
+ """Delete an enterprise.
- This action is irreversible.
+ Fails with `400` if the enterprise still has dependent
+ resources (e.g. active reputation settings or registered numbers); remove those
+ first. Returns `404` if the enterprise does not exist or does not belong to your
+ account.
Args:
extra_headers: Send extra headers
@@ -413,16 +511,73 @@ def delete(
cast_to=NoneType,
)
+ def activate_branded_calling(
+ self,
+ enterprise_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,
+ ) -> EnterpriseActivateBrandedCallingResponse:
+ """
+ Branded Calling is a paid product that must be activated on each enterprise.
+ Activation is idempotent:
+
+ - First call: marks the enterprise as activated and begins onboarding it with
+ the Branded Calling platform asynchronously. Returns `200` with
+ `branded_calling_enabled: true`.
+ - Re-call after success: no-op, returns the same enterprise body.
+ - Re-call after a prior failure: re-queues onboarding, returns `200`.
+
+ Prerequisite: the calling user must have agreed to the Branded Calling Terms of
+ Service (`POST /terms_of_service/branded_calling/agree`). Without that, this
+ endpoint returns `403 terms_of_service_not_accepted`.
+
+ Failure modes:
+
+ - `403` — Branded Calling Terms of Service not accepted.
+ - `404` — enterprise does not exist or does not belong to your account.
+
+ **Pricing:** This is a billable action. See https://telnyx.com/pricing/numbers
+ for current pricing.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return self._post(
+ path_template("/enterprises/{enterprise_id}/branded_calling", enterprise_id=enterprise_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=EnterpriseActivateBrandedCallingResponse,
+ )
+
class AsyncEnterprisesResource(AsyncAPIResource):
- """Enterprise management for Branded Calling and Number Reputation services"""
+ """Manage the legal-entity record that owns your DIRs and phone numbers."""
@cached_property
def reputation(self) -> AsyncReputationResource:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return AsyncReputationResource(self._client)
+
+ @cached_property
+ def dir(self) -> AsyncDirResource:
"""
- Manage Number Reputation enrollment and check frequency settings for an enterprise
+ A Display Identity Record (DIR) is the verified calling identity (display name, logo, call reasons) shown to recipients on outbound calls.
"""
- return AsyncReputationResource(self._client)
+ return AsyncDirResource(self._client)
@cached_property
def with_raw_response(self) -> AsyncEnterprisesResourceWithRawResponse:
@@ -451,7 +606,52 @@ async def create(
country_code: str,
doing_business_as: str,
fein: str,
- industry: str,
+ industry: Literal[
+ "accounting",
+ "finance",
+ "billing",
+ "collections",
+ "business",
+ "charity",
+ "nonprofit",
+ "communications",
+ "telecom",
+ "customer service",
+ "support",
+ "delivery",
+ "shipping",
+ "logistics",
+ "education",
+ "financial",
+ "banking",
+ "government",
+ "public",
+ "healthcare",
+ "health",
+ "pharmacy",
+ "medical",
+ "insurance",
+ "legal",
+ "law",
+ "notifications",
+ "scheduling",
+ "real estate",
+ "property",
+ "retail",
+ "ecommerce",
+ "sales",
+ "marketing",
+ "software",
+ "technology",
+ "tech",
+ "media",
+ "surveys",
+ "market research",
+ "travel",
+ "hospitality",
+ "hotel",
+ ],
+ jurisdiction_of_incorporation: str,
legal_name: str,
number_of_employees: Literal["1-10", "11-50", "51-200", "201-500", "501-2000", "2001-10000", "10001+"],
organization_contact: OrganizationContactParam,
@@ -459,11 +659,11 @@ async def create(
organization_physical_address: PhysicalAddressParam,
organization_type: Literal["commercial", "government", "non_profit"],
website: str,
- corporate_registration_number: str | Omit = omit,
+ corporate_registration_number: Optional[str] | Omit = omit,
customer_reference: str | Omit = omit,
- dun_bradstreet_number: str | Omit = omit,
- primary_business_domain_sic_code: str | Omit = omit,
- professional_license_number: str | Omit = omit,
+ dun_bradstreet_number: Optional[str] | Omit = omit,
+ primary_business_domain_sic_code: Optional[str] | Omit = omit,
+ professional_license_number: Optional[str] | Omit = omit,
role_type: Literal["enterprise", "bpo"] | 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.
@@ -473,57 +673,61 @@ async def create(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> EnterpriseCreateResponse:
"""
- Create a new enterprise for Branded Calling / Number Reputation services.
+ Create the legal entity that owns your Number Reputation registrations.
- Registers the enterprise in the Branded Calling / Number Reputation services,
- enabling it to create Display Identity Records (DIRs) or enroll in Number
- Reputation monitoring.
+ The response carries a server-assigned `id` you will use for every subsequent
+ call. After creating an enterprise and agreeing to the Number Reputation Terms
+ of Service (`POST /terms_of_service/number_reputation/agree`), enable reputation
+ monitoring via `POST /enterprises/{enterprise_id}/reputation`.
- **Required Fields:** `legal_name`, `doing_business_as`, `organization_type`,
- `country_code`, `website`, `fein`, `industry`, `number_of_employees`,
- `organization_legal_type`, `organization_contact`, `billing_contact`,
- `organization_physical_address`, `billing_address`
+ An enterprise is shared across Telnyx products; if you also use Branded Calling,
+ the same enterprise is reused.
Args:
- country_code: Country code. Currently only 'US' is accepted.
+ country_code: ISO 3166-1 alpha-2 country code. Currently `US` and `CA` are supported.
- doing_business_as: Primary business name / DBA name
+ fein: US Federal Employer Identification Number (`NN-NNNNNNN`) or Canadian equivalent.
- fein: Federal Employer Identification Number. Format: XX-XXXXXXX or 9-digit number
- (minimum 9 digits).
+ industry: Industry classification.
- industry: Industry classification. Case-insensitive. Accepted values: accounting, finance,
- billing, collections, business, charity, nonprofit, communications, telecom,
- customer service, support, delivery, shipping, logistics, education, financial,
- banking, government, public, healthcare, health, pharmacy, medical, insurance,
- legal, law, notifications, scheduling, real estate, property, retail, ecommerce,
- sales, marketing, software, technology, tech, media, surveys, market research,
- travel, hospitality, hotel
+ legal_name: Legal name of the enterprise.
- legal_name: Legal name of the enterprise
+ number_of_employees: Approximate headcount range. Used for vetting heuristics; pick the bucket that
+ contains your current employee count.
- number_of_employees: Employee count range
+ organization_legal_type:
+ Legal-entity form. Pick the form that matches your incorporation documents:
- organization_contact: Organization contact information. Note: the response returns this object with
- the phone field as 'phone' (not 'phone_number').
+ - `corporation` — C-corp or S-corp.
+ - `llc` — limited liability company.
+ - `partnership` — general/limited partnership.
+ - `nonprofit` — non-profit corporation, charitable trust, or
+ 501(c)(3)/equivalent.
+ - `other` — anything else (sole proprietorships, government bodies, DBAs, etc.).
+ You may be asked for additional documents during vetting.
- organization_legal_type: Legal structure type
+ organization_type:
+ Organization category for vetting purposes:
- organization_type: Type of organization
+ - `commercial` — for-profit business entities (LLC, corp, partnership, sole
+ proprietorship). Most callers fall here.
+ - `government` — federal/state/local government bodies.
+ - `non_profit` — registered 501(c)(3)/equivalent (incl. educational
+ institutions, charities, religious organisations).
- website: Enterprise website URL. Accepts any string — no URL format validation enforced.
+ corporate_registration_number: Optional corporate-registration / company-number identifier.
- corporate_registration_number: Corporate registration number (optional)
+ customer_reference: Optional free-form string the caller can attach for their own bookkeeping.
+ Telnyx does not interpret it.
- customer_reference: Optional customer reference identifier for your own tracking
+ dun_bradstreet_number: Optional D-U-N-S Number.
- dun_bradstreet_number: D-U-N-S Number (optional)
+ primary_business_domain_sic_code: Optional SIC code for the primary line of business.
- primary_business_domain_sic_code: SIC Code (optional)
+ professional_license_number: Optional professional-license number for regulated industries.
- professional_license_number: Professional license number (optional)
-
- role_type: Role type in Branded Calling / Number Reputation services
+ role_type: `enterprise` for an organization registering its own DIRs; `bpo` for a Business
+ Process Outsourcer placing calls on behalf of one or more enterprises.
extra_headers: Send extra headers
@@ -543,6 +747,7 @@ async def create(
"doing_business_as": doing_business_as,
"fein": fein,
"industry": industry,
+ "jurisdiction_of_incorporation": jurisdiction_of_incorporation,
"legal_name": legal_name,
"number_of_employees": number_of_employees,
"organization_contact": organization_contact,
@@ -576,8 +781,10 @@ async def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> EnterpriseRetrieveResponse:
- """
- Retrieve details of a specific enterprise by ID.
+ """Retrieve a single enterprise by id.
+
+ Returns `404` if the id does not exist or
+ does not belong to your account.
Args:
extra_headers: Send extra headers
@@ -604,20 +811,65 @@ async def update(
*,
billing_address: BillingAddressParam | Omit = omit,
billing_contact: BillingContactParam | Omit = omit,
- corporate_registration_number: str | Omit = omit,
+ corporate_registration_number: Optional[str] | Omit = omit,
customer_reference: str | Omit = omit,
doing_business_as: str | Omit = omit,
- dun_bradstreet_number: str | Omit = omit,
+ dun_bradstreet_number: Optional[str] | Omit = omit,
fein: str | Omit = omit,
- industry: str | Omit = omit,
- legal_name: str | Omit = omit,
- number_of_employees: Literal["1-10", "11-50", "51-200", "201-500", "501-2000", "2001-10000", "10001+"]
+ industry: Literal[
+ "accounting",
+ "finance",
+ "billing",
+ "collections",
+ "business",
+ "charity",
+ "nonprofit",
+ "communications",
+ "telecom",
+ "customer service",
+ "support",
+ "delivery",
+ "shipping",
+ "logistics",
+ "education",
+ "financial",
+ "banking",
+ "government",
+ "public",
+ "healthcare",
+ "health",
+ "pharmacy",
+ "medical",
+ "insurance",
+ "legal",
+ "law",
+ "notifications",
+ "scheduling",
+ "real estate",
+ "property",
+ "retail",
+ "ecommerce",
+ "sales",
+ "marketing",
+ "software",
+ "technology",
+ "tech",
+ "media",
+ "surveys",
+ "market research",
+ "travel",
+ "hospitality",
+ "hotel",
+ ]
| Omit = omit,
+ jurisdiction_of_incorporation: str | Omit = omit,
+ legal_name: str | Omit = omit,
+ number_of_employees: str | Omit = omit,
organization_contact: OrganizationContactParam | Omit = omit,
- organization_legal_type: Literal["corporation", "llc", "partnership", "nonprofit", "other"] | Omit = omit,
+ organization_legal_type: str | Omit = omit,
organization_physical_address: PhysicalAddressParam | Omit = omit,
- primary_business_domain_sic_code: str | Omit = omit,
- professional_license_number: str | Omit = omit,
+ primary_business_domain_sic_code: Optional[str] | Omit = omit,
+ professional_license_number: Optional[str] | Omit = omit,
website: str | 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.
@@ -626,38 +878,18 @@ async def update(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> EnterpriseUpdateResponse:
- """Update enterprise information.
+ """Replace the enterprise's mutable fields.
- All fields are optional — only the provided
- fields will be updated.
+ Only mutable fields may be sent.
+ Server-assigned and immutable fields (`id`, `record_type`, `created_at`,
+ `updated_at`, status fields, `organization_type`, `country_code`, `role_type`)
+ cannot be changed: including any of them in the body is rejected with
+ `400 Bad Request` (`Field 'X' is not allowed in this request`).
Args:
- corporate_registration_number: Corporate registration number
-
- customer_reference: Customer reference identifier
+ jurisdiction_of_incorporation: Updated state/province/country of incorporation. Optional on update.
- doing_business_as: DBA name
-
- dun_bradstreet_number: D-U-N-S Number
-
- fein: Federal Employer Identification Number. Format: XX-XXXXXXX or XXXXXXXXX
-
- industry: Industry classification
-
- legal_name: Legal name of the enterprise
-
- number_of_employees: Employee count range
-
- organization_contact: Organization contact information. Note: the response returns this object with
- the phone field as 'phone' (not 'phone_number').
-
- organization_legal_type: Legal structure type
-
- primary_business_domain_sic_code: SIC Code
-
- professional_license_number: Professional license number
-
- website: Company website URL
+ legal_name: Legal name of the enterprise.
extra_headers: Send extra headers
@@ -681,6 +913,7 @@ async def update(
"dun_bradstreet_number": dun_bradstreet_number,
"fein": fein,
"industry": industry,
+ "jurisdiction_of_incorporation": jurisdiction_of_incorporation,
"legal_name": legal_name,
"number_of_employees": number_of_employees,
"organization_contact": organization_contact,
@@ -711,15 +944,17 @@ def list(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> AsyncPaginator[EnterprisePublic, AsyncDefaultFlatPagination[EnterprisePublic]]:
- """
- Retrieve a paginated list of enterprises associated with your account.
+ """Return the enterprises you own, paginated.
+
+ The default page size is 20; the
+ maximum is 250.
Args:
- legal_name: Filter by legal name (partial match)
+ legal_name: Filter by legal name (partial match).
- page_number: Page number (1-indexed)
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
- page_size: Number of items per page
+ page_size: Items per page. Default 10. Maximum 250; values above are clamped to 250.
extra_headers: Send extra headers
@@ -760,9 +995,12 @@ async def delete(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """Delete an enterprise and all associated resources.
+ """Delete an enterprise.
- This action is irreversible.
+ Fails with `400` if the enterprise still has dependent
+ resources (e.g. active reputation settings or registered numbers); remove those
+ first. Returns `404` if the enterprise does not exist or does not belong to your
+ account.
Args:
extra_headers: Send extra headers
@@ -784,6 +1022,58 @@ async def delete(
cast_to=NoneType,
)
+ async def activate_branded_calling(
+ self,
+ enterprise_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,
+ ) -> EnterpriseActivateBrandedCallingResponse:
+ """
+ Branded Calling is a paid product that must be activated on each enterprise.
+ Activation is idempotent:
+
+ - First call: marks the enterprise as activated and begins onboarding it with
+ the Branded Calling platform asynchronously. Returns `200` with
+ `branded_calling_enabled: true`.
+ - Re-call after success: no-op, returns the same enterprise body.
+ - Re-call after a prior failure: re-queues onboarding, returns `200`.
+
+ Prerequisite: the calling user must have agreed to the Branded Calling Terms of
+ Service (`POST /terms_of_service/branded_calling/agree`). Without that, this
+ endpoint returns `403 terms_of_service_not_accepted`.
+
+ Failure modes:
+
+ - `403` — Branded Calling Terms of Service not accepted.
+ - `404` — enterprise does not exist or does not belong to your account.
+
+ **Pricing:** This is a billable action. See https://telnyx.com/pricing/numbers
+ for current pricing.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return await self._post(
+ path_template("/enterprises/{enterprise_id}/branded_calling", enterprise_id=enterprise_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=EnterpriseActivateBrandedCallingResponse,
+ )
+
class EnterprisesResourceWithRawResponse:
def __init__(self, enterprises: EnterprisesResource) -> None:
@@ -804,13 +1094,21 @@ def __init__(self, enterprises: EnterprisesResource) -> None:
self.delete = to_raw_response_wrapper(
enterprises.delete,
)
+ self.activate_branded_calling = to_raw_response_wrapper(
+ enterprises.activate_branded_calling,
+ )
@cached_property
def reputation(self) -> ReputationResourceWithRawResponse:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return ReputationResourceWithRawResponse(self._enterprises.reputation)
+
+ @cached_property
+ def dir(self) -> DirResourceWithRawResponse:
"""
- Manage Number Reputation enrollment and check frequency settings for an enterprise
+ A Display Identity Record (DIR) is the verified calling identity (display name, logo, call reasons) shown to recipients on outbound calls.
"""
- return ReputationResourceWithRawResponse(self._enterprises.reputation)
+ return DirResourceWithRawResponse(self._enterprises.dir)
class AsyncEnterprisesResourceWithRawResponse:
@@ -832,13 +1130,21 @@ def __init__(self, enterprises: AsyncEnterprisesResource) -> None:
self.delete = async_to_raw_response_wrapper(
enterprises.delete,
)
+ self.activate_branded_calling = async_to_raw_response_wrapper(
+ enterprises.activate_branded_calling,
+ )
@cached_property
def reputation(self) -> AsyncReputationResourceWithRawResponse:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return AsyncReputationResourceWithRawResponse(self._enterprises.reputation)
+
+ @cached_property
+ def dir(self) -> AsyncDirResourceWithRawResponse:
"""
- Manage Number Reputation enrollment and check frequency settings for an enterprise
+ A Display Identity Record (DIR) is the verified calling identity (display name, logo, call reasons) shown to recipients on outbound calls.
"""
- return AsyncReputationResourceWithRawResponse(self._enterprises.reputation)
+ return AsyncDirResourceWithRawResponse(self._enterprises.dir)
class EnterprisesResourceWithStreamingResponse:
@@ -860,13 +1166,21 @@ def __init__(self, enterprises: EnterprisesResource) -> None:
self.delete = to_streamed_response_wrapper(
enterprises.delete,
)
+ self.activate_branded_calling = to_streamed_response_wrapper(
+ enterprises.activate_branded_calling,
+ )
@cached_property
def reputation(self) -> ReputationResourceWithStreamingResponse:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return ReputationResourceWithStreamingResponse(self._enterprises.reputation)
+
+ @cached_property
+ def dir(self) -> DirResourceWithStreamingResponse:
"""
- Manage Number Reputation enrollment and check frequency settings for an enterprise
+ A Display Identity Record (DIR) is the verified calling identity (display name, logo, call reasons) shown to recipients on outbound calls.
"""
- return ReputationResourceWithStreamingResponse(self._enterprises.reputation)
+ return DirResourceWithStreamingResponse(self._enterprises.dir)
class AsyncEnterprisesResourceWithStreamingResponse:
@@ -888,10 +1202,18 @@ def __init__(self, enterprises: AsyncEnterprisesResource) -> None:
self.delete = async_to_streamed_response_wrapper(
enterprises.delete,
)
+ self.activate_branded_calling = async_to_streamed_response_wrapper(
+ enterprises.activate_branded_calling,
+ )
@cached_property
def reputation(self) -> AsyncReputationResourceWithStreamingResponse:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return AsyncReputationResourceWithStreamingResponse(self._enterprises.reputation)
+
+ @cached_property
+ def dir(self) -> AsyncDirResourceWithStreamingResponse:
"""
- Manage Number Reputation enrollment and check frequency settings for an enterprise
+ A Display Identity Record (DIR) is the verified calling identity (display name, logo, call reasons) shown to recipients on outbound calls.
"""
- return AsyncReputationResourceWithStreamingResponse(self._enterprises.reputation)
+ return AsyncDirResourceWithStreamingResponse(self._enterprises.dir)
diff --git a/src/telnyx/resources/enterprises/reputation/__init__.py b/src/telnyx/resources/enterprises/reputation/__init__.py
index 147c4c1b..18229566 100644
--- a/src/telnyx/resources/enterprises/reputation/__init__.py
+++ b/src/telnyx/resources/enterprises/reputation/__init__.py
@@ -1,5 +1,13 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from .loa import (
+ LoaResource,
+ AsyncLoaResource,
+ LoaResourceWithRawResponse,
+ AsyncLoaResourceWithRawResponse,
+ LoaResourceWithStreamingResponse,
+ AsyncLoaResourceWithStreamingResponse,
+)
from .numbers import (
NumbersResource,
AsyncNumbersResource,
@@ -24,6 +32,12 @@
"AsyncNumbersResourceWithRawResponse",
"NumbersResourceWithStreamingResponse",
"AsyncNumbersResourceWithStreamingResponse",
+ "LoaResource",
+ "AsyncLoaResource",
+ "LoaResourceWithRawResponse",
+ "AsyncLoaResourceWithRawResponse",
+ "LoaResourceWithStreamingResponse",
+ "AsyncLoaResourceWithStreamingResponse",
"ReputationResource",
"AsyncReputationResource",
"ReputationResourceWithRawResponse",
diff --git a/src/telnyx/resources/enterprises/reputation/loa.py b/src/telnyx/resources/enterprises/reputation/loa.py
new file mode 100644
index 00000000..f394d214
--- /dev/null
+++ b/src/telnyx/resources/enterprises/reputation/loa.py
@@ -0,0 +1,323 @@
+# 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, async_maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ to_custom_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+ to_custom_streamed_response_wrapper,
+ async_to_custom_raw_response_wrapper,
+ async_to_custom_streamed_response_wrapper,
+)
+from ...._base_client import make_request_options
+from ....types.enterprises.reputation import loa_render_params, loa_update_params
+from ....types.enterprises.reputation.loa_update_response import LoaUpdateResponse
+
+__all__ = ["LoaResource", "AsyncLoaResource"]
+
+
+class LoaResource(SyncAPIResource):
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+
+ @cached_property
+ def with_raw_response(self) -> LoaResourceWithRawResponse:
+ """
+ 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 LoaResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> LoaResourceWithStreamingResponse:
+ """
+ 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 LoaResourceWithStreamingResponse(self)
+
+ def update(
+ self,
+ enterprise_id: str,
+ *,
+ loa_document_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,
+ ) -> LoaUpdateResponse:
+ """Point the enterprise's reputation settings at a new signed LOA document.
+
+ This
+ resets LOA approval to `pending`; the new document must be approved before
+ additional phone numbers can be added.
+
+ Args:
+ loa_document_id: Id of the new signed LOA document (from the Telnyx Documents API). Changing it
+ resets LOA approval; the new document must be approved before more numbers can
+ be added.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return self._patch(
+ path_template("/enterprises/{enterprise_id}/reputation/loa", enterprise_id=enterprise_id),
+ body=maybe_transform({"loa_document_id": loa_document_id}, loa_update_params.LoaUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=LoaUpdateResponse,
+ )
+
+ def render(
+ self,
+ enterprise_id: str,
+ *,
+ agent: loa_render_params.Agent | Omit = omit,
+ signature: loa_render_params.Signature | 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,
+ ) -> BinaryAPIResponse:
+ """Render the LOA for this enterprise as a PDF.
+
+ The enterprise identity, address,
+ and authorized-representative contact are taken from the enterprise record; the
+ optional `agent` block is supplied only when a third-party partner manages the
+ numbers. The response is the PDF itself (unsigned unless a `signature` is
+ provided). Sign it and upload it to the Telnyx Documents API
+ (`POST /v2/documents`, see https://developers.telnyx.com/api/documents) to
+ obtain the `loa_document_id` required by `POST .../reputation`.
+
+ Args:
+ agent: Third-party reseller / partner managing the enterprise's phone numbers. Omit
+ when the enterprise works directly with Telnyx.
+
+ signature: Optional signature embedded in the rendered PDF. When omitted the PDF is
+ returned unsigned for the customer to sign and upload.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ extra_headers = {"Accept": "application/pdf", **(extra_headers or {})}
+ return self._post(
+ path_template("/enterprises/{enterprise_id}/reputation/loa", enterprise_id=enterprise_id),
+ body=maybe_transform(
+ {
+ "agent": agent,
+ "signature": signature,
+ },
+ loa_render_params.LoaRenderParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=BinaryAPIResponse,
+ )
+
+
+class AsyncLoaResource(AsyncAPIResource):
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+
+ @cached_property
+ def with_raw_response(self) -> AsyncLoaResourceWithRawResponse:
+ """
+ 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 AsyncLoaResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncLoaResourceWithStreamingResponse:
+ """
+ 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 AsyncLoaResourceWithStreamingResponse(self)
+
+ async def update(
+ self,
+ enterprise_id: str,
+ *,
+ loa_document_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,
+ ) -> LoaUpdateResponse:
+ """Point the enterprise's reputation settings at a new signed LOA document.
+
+ This
+ resets LOA approval to `pending`; the new document must be approved before
+ additional phone numbers can be added.
+
+ Args:
+ loa_document_id: Id of the new signed LOA document (from the Telnyx Documents API). Changing it
+ resets LOA approval; the new document must be approved before more numbers can
+ be added.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return await self._patch(
+ path_template("/enterprises/{enterprise_id}/reputation/loa", enterprise_id=enterprise_id),
+ body=await async_maybe_transform({"loa_document_id": loa_document_id}, loa_update_params.LoaUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=LoaUpdateResponse,
+ )
+
+ async def render(
+ self,
+ enterprise_id: str,
+ *,
+ agent: loa_render_params.Agent | Omit = omit,
+ signature: loa_render_params.Signature | 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,
+ ) -> AsyncBinaryAPIResponse:
+ """Render the LOA for this enterprise as a PDF.
+
+ The enterprise identity, address,
+ and authorized-representative contact are taken from the enterprise record; the
+ optional `agent` block is supplied only when a third-party partner manages the
+ numbers. The response is the PDF itself (unsigned unless a `signature` is
+ provided). Sign it and upload it to the Telnyx Documents API
+ (`POST /v2/documents`, see https://developers.telnyx.com/api/documents) to
+ obtain the `loa_document_id` required by `POST .../reputation`.
+
+ Args:
+ agent: Third-party reseller / partner managing the enterprise's phone numbers. Omit
+ when the enterprise works directly with Telnyx.
+
+ signature: Optional signature embedded in the rendered PDF. When omitted the PDF is
+ returned unsigned for the customer to sign and upload.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ extra_headers = {"Accept": "application/pdf", **(extra_headers or {})}
+ return await self._post(
+ path_template("/enterprises/{enterprise_id}/reputation/loa", enterprise_id=enterprise_id),
+ body=await async_maybe_transform(
+ {
+ "agent": agent,
+ "signature": signature,
+ },
+ loa_render_params.LoaRenderParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AsyncBinaryAPIResponse,
+ )
+
+
+class LoaResourceWithRawResponse:
+ def __init__(self, loa: LoaResource) -> None:
+ self._loa = loa
+
+ self.update = to_raw_response_wrapper(
+ loa.update,
+ )
+ self.render = to_custom_raw_response_wrapper(
+ loa.render,
+ BinaryAPIResponse,
+ )
+
+
+class AsyncLoaResourceWithRawResponse:
+ def __init__(self, loa: AsyncLoaResource) -> None:
+ self._loa = loa
+
+ self.update = async_to_raw_response_wrapper(
+ loa.update,
+ )
+ self.render = async_to_custom_raw_response_wrapper(
+ loa.render,
+ AsyncBinaryAPIResponse,
+ )
+
+
+class LoaResourceWithStreamingResponse:
+ def __init__(self, loa: LoaResource) -> None:
+ self._loa = loa
+
+ self.update = to_streamed_response_wrapper(
+ loa.update,
+ )
+ self.render = to_custom_streamed_response_wrapper(
+ loa.render,
+ StreamedBinaryAPIResponse,
+ )
+
+
+class AsyncLoaResourceWithStreamingResponse:
+ def __init__(self, loa: AsyncLoaResource) -> None:
+ self._loa = loa
+
+ self.update = async_to_streamed_response_wrapper(
+ loa.update,
+ )
+ self.render = async_to_custom_streamed_response_wrapper(
+ loa.render,
+ AsyncStreamedBinaryAPIResponse,
+ )
diff --git a/src/telnyx/resources/enterprises/reputation/numbers.py b/src/telnyx/resources/enterprises/reputation/numbers.py
index 242cc668..472e0206 100644
--- a/src/telnyx/resources/enterprises/reputation/numbers.py
+++ b/src/telnyx/resources/enterprises/reputation/numbers.py
@@ -16,18 +16,22 @@
)
from ....pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
from ...._base_client import AsyncPaginator, make_request_options
-from ....types.enterprises.reputation import number_list_params, number_retrieve_params, number_associate_params
+from ....types.enterprises.reputation import (
+ number_list_params,
+ number_refresh_params,
+ number_retrieve_params,
+ number_associate_params,
+)
+from ....types.enterprises.reputation.number_list_response import NumberListResponse
+from ....types.enterprises.reputation.number_refresh_response import NumberRefreshResponse
from ....types.enterprises.reputation.number_retrieve_response import NumberRetrieveResponse
from ....types.enterprises.reputation.number_associate_response import NumberAssociateResponse
-from ....types.shared.reputation_phone_number_with_reputation_data import ReputationPhoneNumberWithReputationData
__all__ = ["NumbersResource", "AsyncNumbersResource"]
class NumbersResource(SyncAPIResource):
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
@cached_property
def with_raw_response(self) -> NumbersResourceWithRawResponse:
@@ -61,29 +65,15 @@ def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> NumberRetrieveResponse:
- """
- Get detailed reputation data for a specific phone number associated with an
- enterprise.
-
- **Query Parameters:**
+ """Retrieve one registered number with its latest reputation snapshot.
- - `fresh` (default: `false`): When `true`, fetches fresh reputation data (incurs
- API cost). When `false`, returns cached data. If no cached data exists, fresh
- data is automatically fetched.
-
- **Returns:**
-
- - `spam_risk`: Overall spam risk level (`low`, `medium`, `high`)
- - `spam_category`: Spam category classification
- - `maturity_score`: Maturity metric (0–100)
- - `connection_score`: Connection quality metric (0–100)
- - `engagement_score`: Engagement metric (0–100)
- - `sentiment_score`: Sentiment metric (0–100)
- - `last_refreshed_at`: Timestamp of last data refresh
+ The
+ `phone_number` path parameter is in E.164 format and must be URL-encoded (e.g.
+ `%2B19493253498`).
Args:
- fresh: When true, fetches fresh reputation data (incurs API cost). When false, returns
- cached data.
+ fresh: When true, fetches fresh reputation data (incurs API cost). When false
+ (default), returns cached data.
extra_headers: Send extra headers
@@ -126,20 +116,18 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData]:
+ ) -> SyncDefaultFlatPagination[NumberListResponse]:
"""
- List all phone numbers associated with an enterprise for Number Reputation
- monitoring.
-
- Returns phone numbers with their cached reputation data (if available). Supports
- pagination and filtering by phone number.
+ Paginated list of phone numbers registered for reputation monitoring under this
+ enterprise. The response includes the latest reputation snapshot per number
+ where one has been collected.
Args:
- page_number: Page number (1-indexed)
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
- page_size: Number of items per page
+ page_size: Items per page. Default 10. Maximum 250; values above are clamped to 250.
- phone_number: Filter by specific phone number (E.164 format)
+ phone_number: Filter by specific phone number (E.164 format).
extra_headers: Send extra headers
@@ -153,7 +141,7 @@ def list(
raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
return self._get_api_list(
path_template("/enterprises/{enterprise_id}/reputation/numbers", enterprise_id=enterprise_id),
- page=SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData],
+ page=SyncDefaultFlatPagination[NumberListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -168,7 +156,7 @@ def list(
number_list_params.NumberListParams,
),
),
- model=ReputationPhoneNumberWithReputationData,
+ model=NumberListResponse,
)
def associate(
@@ -183,25 +171,20 @@ def associate(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> NumberAssociateResponse:
- """
- Associate one or more phone numbers with an enterprise for Number Reputation
- monitoring.
-
- **Validations:**
+ """Add up to 100 phone numbers to reputation monitoring on this enterprise.
- - Phone numbers must be in E.164 format (e.g., `+16035551234`)
- - Phone numbers must be in-service and belong to your account (verified via
- Warehouse)
- - Phone numbers must be US local numbers
- - Phone numbers cannot already be associated with any enterprise
+ Each
+ must be in E.164 format (`+1NPANXXXXXX` for US/CA) and belong to your Telnyx
+ phone-number inventory.
- **Note:** This operation is atomic — if any number fails validation, the entire
- request fails.
+ **Prerequisite**: reputation must already be enabled on this enterprise (see
+ `POST .../reputation`).
- **Maximum:** 100 phone numbers per request.
+ **Pricing:** This is a billable action. See https://telnyx.com/pricing/numbers
+ for current pricing.
Args:
- phone_numbers: List of phone numbers to associate for reputation monitoring (max 100)
+ phone_numbers: 1–100 phone numbers in E.164 format with a leading `+`.
extra_headers: Send extra headers
@@ -234,11 +217,10 @@ def disassociate(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """
- Remove a phone number from Number Reputation monitoring for an enterprise.
+ """Stop tracking the reputation of this phone number.
- The number will no longer be tracked and reputation data will no longer be
- refreshed.
+ The number itself remains in
+ your inventory; only the reputation registration is removed.
Args:
extra_headers: Send extra headers
@@ -266,11 +248,54 @@ def disassociate(
cast_to=NoneType,
)
+ def refresh(
+ self,
+ enterprise_id: str,
+ *,
+ phone_numbers: SequenceNotStr[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,
+ ) -> NumberRefreshResponse:
+ """Immediately refresh the stored reputation data for the listed numbers.
+
+ This is
+ in addition to the periodic refresh determined by `check_frequency`. Up to 100
+ numbers per call. The response carries the kicked-off jobs; the actual refresh
+ runs asynchronously.
+
+ **Pricing:** Forcing a refresh performs live reputation lookups, which are
+ billable. See https://telnyx.com/pricing/numbers for current pricing.
+
+ Args:
+ phone_numbers: Phone numbers to refresh reputation data for. 1–100 numbers per request, each in
+ E.164 format. Reputation refreshes are subject to per-enterprise rate limits.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return self._post(
+ path_template("/enterprises/{enterprise_id}/reputation/numbers/refresh", enterprise_id=enterprise_id),
+ body=maybe_transform({"phone_numbers": phone_numbers}, number_refresh_params.NumberRefreshParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NumberRefreshResponse,
+ )
+
class AsyncNumbersResource(AsyncAPIResource):
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
@cached_property
def with_raw_response(self) -> AsyncNumbersResourceWithRawResponse:
@@ -304,29 +329,15 @@ async def retrieve(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> NumberRetrieveResponse:
- """
- Get detailed reputation data for a specific phone number associated with an
- enterprise.
-
- **Query Parameters:**
-
- - `fresh` (default: `false`): When `true`, fetches fresh reputation data (incurs
- API cost). When `false`, returns cached data. If no cached data exists, fresh
- data is automatically fetched.
+ """Retrieve one registered number with its latest reputation snapshot.
- **Returns:**
-
- - `spam_risk`: Overall spam risk level (`low`, `medium`, `high`)
- - `spam_category`: Spam category classification
- - `maturity_score`: Maturity metric (0–100)
- - `connection_score`: Connection quality metric (0–100)
- - `engagement_score`: Engagement metric (0–100)
- - `sentiment_score`: Sentiment metric (0–100)
- - `last_refreshed_at`: Timestamp of last data refresh
+ The
+ `phone_number` path parameter is in E.164 format and must be URL-encoded (e.g.
+ `%2B19493253498`).
Args:
- fresh: When true, fetches fresh reputation data (incurs API cost). When false, returns
- cached data.
+ fresh: When true, fetches fresh reputation data (incurs API cost). When false
+ (default), returns cached data.
extra_headers: Send extra headers
@@ -369,22 +380,18 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[
- ReputationPhoneNumberWithReputationData, AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData]
- ]:
+ ) -> AsyncPaginator[NumberListResponse, AsyncDefaultFlatPagination[NumberListResponse]]:
"""
- List all phone numbers associated with an enterprise for Number Reputation
- monitoring.
-
- Returns phone numbers with their cached reputation data (if available). Supports
- pagination and filtering by phone number.
+ Paginated list of phone numbers registered for reputation monitoring under this
+ enterprise. The response includes the latest reputation snapshot per number
+ where one has been collected.
Args:
- page_number: Page number (1-indexed)
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
- page_size: Number of items per page
+ page_size: Items per page. Default 10. Maximum 250; values above are clamped to 250.
- phone_number: Filter by specific phone number (E.164 format)
+ phone_number: Filter by specific phone number (E.164 format).
extra_headers: Send extra headers
@@ -398,7 +405,7 @@ def list(
raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
return self._get_api_list(
path_template("/enterprises/{enterprise_id}/reputation/numbers", enterprise_id=enterprise_id),
- page=AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData],
+ page=AsyncDefaultFlatPagination[NumberListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -413,7 +420,7 @@ def list(
number_list_params.NumberListParams,
),
),
- model=ReputationPhoneNumberWithReputationData,
+ model=NumberListResponse,
)
async def associate(
@@ -428,25 +435,20 @@ async def associate(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> NumberAssociateResponse:
- """
- Associate one or more phone numbers with an enterprise for Number Reputation
- monitoring.
+ """Add up to 100 phone numbers to reputation monitoring on this enterprise.
- **Validations:**
+ Each
+ must be in E.164 format (`+1NPANXXXXXX` for US/CA) and belong to your Telnyx
+ phone-number inventory.
- - Phone numbers must be in E.164 format (e.g., `+16035551234`)
- - Phone numbers must be in-service and belong to your account (verified via
- Warehouse)
- - Phone numbers must be US local numbers
- - Phone numbers cannot already be associated with any enterprise
+ **Prerequisite**: reputation must already be enabled on this enterprise (see
+ `POST .../reputation`).
- **Note:** This operation is atomic — if any number fails validation, the entire
- request fails.
-
- **Maximum:** 100 phone numbers per request.
+ **Pricing:** This is a billable action. See https://telnyx.com/pricing/numbers
+ for current pricing.
Args:
- phone_numbers: List of phone numbers to associate for reputation monitoring (max 100)
+ phone_numbers: 1–100 phone numbers in E.164 format with a leading `+`.
extra_headers: Send extra headers
@@ -481,11 +483,10 @@ async def disassociate(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """
- Remove a phone number from Number Reputation monitoring for an enterprise.
+ """Stop tracking the reputation of this phone number.
- The number will no longer be tracked and reputation data will no longer be
- refreshed.
+ The number itself remains in
+ your inventory; only the reputation registration is removed.
Args:
extra_headers: Send extra headers
@@ -513,6 +514,53 @@ async def disassociate(
cast_to=NoneType,
)
+ async def refresh(
+ self,
+ enterprise_id: str,
+ *,
+ phone_numbers: SequenceNotStr[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,
+ ) -> NumberRefreshResponse:
+ """Immediately refresh the stored reputation data for the listed numbers.
+
+ This is
+ in addition to the periodic refresh determined by `check_frequency`. Up to 100
+ numbers per call. The response carries the kicked-off jobs; the actual refresh
+ runs asynchronously.
+
+ **Pricing:** Forcing a refresh performs live reputation lookups, which are
+ billable. See https://telnyx.com/pricing/numbers for current pricing.
+
+ Args:
+ phone_numbers: Phone numbers to refresh reputation data for. 1–100 numbers per request, each in
+ E.164 format. Reputation refreshes are subject to per-enterprise rate limits.
+
+ 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 enterprise_id:
+ raise ValueError(f"Expected a non-empty value for `enterprise_id` but received {enterprise_id!r}")
+ return await self._post(
+ path_template("/enterprises/{enterprise_id}/reputation/numbers/refresh", enterprise_id=enterprise_id),
+ body=await async_maybe_transform(
+ {"phone_numbers": phone_numbers}, number_refresh_params.NumberRefreshParams
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=NumberRefreshResponse,
+ )
+
class NumbersResourceWithRawResponse:
def __init__(self, numbers: NumbersResource) -> None:
@@ -530,6 +578,9 @@ def __init__(self, numbers: NumbersResource) -> None:
self.disassociate = to_raw_response_wrapper(
numbers.disassociate,
)
+ self.refresh = to_raw_response_wrapper(
+ numbers.refresh,
+ )
class AsyncNumbersResourceWithRawResponse:
@@ -548,6 +599,9 @@ def __init__(self, numbers: AsyncNumbersResource) -> None:
self.disassociate = async_to_raw_response_wrapper(
numbers.disassociate,
)
+ self.refresh = async_to_raw_response_wrapper(
+ numbers.refresh,
+ )
class NumbersResourceWithStreamingResponse:
@@ -566,6 +620,9 @@ def __init__(self, numbers: NumbersResource) -> None:
self.disassociate = to_streamed_response_wrapper(
numbers.disassociate,
)
+ self.refresh = to_streamed_response_wrapper(
+ numbers.refresh,
+ )
class AsyncNumbersResourceWithStreamingResponse:
@@ -584,3 +641,6 @@ def __init__(self, numbers: AsyncNumbersResource) -> None:
self.disassociate = async_to_streamed_response_wrapper(
numbers.disassociate,
)
+ self.refresh = async_to_streamed_response_wrapper(
+ numbers.refresh,
+ )
diff --git a/src/telnyx/resources/enterprises/reputation/reputation.py b/src/telnyx/resources/enterprises/reputation/reputation.py
index 615635e4..de601c43 100644
--- a/src/telnyx/resources/enterprises/reputation/reputation.py
+++ b/src/telnyx/resources/enterprises/reputation/reputation.py
@@ -6,6 +6,14 @@
import httpx
+from .loa import (
+ LoaResource,
+ AsyncLoaResource,
+ LoaResourceWithRawResponse,
+ AsyncLoaResourceWithRawResponse,
+ LoaResourceWithStreamingResponse,
+ AsyncLoaResourceWithStreamingResponse,
+)
from .numbers import (
NumbersResource,
AsyncNumbersResource,
@@ -34,17 +42,18 @@
class ReputationResource(SyncAPIResource):
- """
- Manage Number Reputation enrollment and check frequency settings for an enterprise
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
@cached_property
def numbers(self) -> NumbersResource:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return NumbersResource(self._client)
+ @cached_property
+ def loa(self) -> LoaResource:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return LoaResource(self._client)
+
@cached_property
def with_raw_response(self) -> ReputationResourceWithRawResponse:
"""
@@ -76,12 +85,12 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ReputationRetrieveResponse:
"""
- Retrieve the current Number Reputation settings for an enterprise.
-
- Returns the enrollment status (`pending`, `approved`, `rejected`, `deleted`),
- check frequency, and any rejection reasons.
+ Phone Number Reputation tracks how your outbound caller-IDs are perceived (spam
+ risk, engagement, etc.) across the call-screening ecosystem. This endpoint reads
+ the enterprise-level settings: whether the product is enabled, the refresh
+ cadence, and the stored Letter of Authorization document id.
- Returns `404` if reputation has not been enabled for this enterprise.
+ Returns `404` if reputation has never been enabled for this enterprise.
Args:
extra_headers: Send extra headers
@@ -113,16 +122,11 @@ def disable(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """
- Disable Number Reputation for an enterprise.
-
- This will:
-
- - Delete the reputation settings record
- - Log the deletion for audit purposes
- - Stop all future automated reputation checks
+ """Disable Phone Number Reputation.
- **Note:** Can only be performed on `approved` reputation settings.
+ All registered numbers are de-registered as a
+ cascade. The enterprise itself is unaffected. Returns `204` on success, `404` if
+ reputation is not enabled for this enterprise.
Args:
extra_headers: Send extra headers
@@ -157,38 +161,33 @@ def enable(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ReputationEnableResponse:
- """
- Enable Number Reputation service for an enterprise.
-
- **Requirements:**
+ """Activate Phone Number Reputation for the given enterprise.
- - Signed LOA (Letter of Authorization) document ID
- - Reputation check frequency (defaults to `business_daily`)
- - Number Reputation Terms of Service must be accepted
+ Requires an uploaded
+ Letter of Authorization document (the `loa_document_id` references the Telnyx
+ Documents API) and a refresh-frequency selection. After activation, individual
+ phone numbers can be registered via `POST .../reputation/numbers`.
- **Flow:**
+ **Prerequisite**: the calling user must have agreed to the Phone Number
+ Reputation Terms of Service (`POST /terms_of_service/number_reputation/agree`).
- 1. Registers the enterprise for reputation monitoring
- 2. Creates reputation settings with `pending` status
- 3. Awaits admin approval before monitoring begins
+ Failure modes:
- **Resubmission After Rejection:** If a previously rejected record exists, this
- endpoint will delete it and create a new `pending` record.
+ - `403` — Phone Number Reputation Terms of Service not accepted.
+ - `404` — enterprise does not exist or does not belong to your account.
+ - `400` — reputation already enabled for this enterprise.
+ - `422` — `loa_document_id` missing or `check_frequency` invalid.
- **Available Frequencies:**
-
- - `business_daily` — Monday–Friday
- - `daily` — Every day
- - `weekly` — Once per week
- - `biweekly` — Once every two weeks
- - `monthly` — Once per month
- - `never` — Manual refresh only
+ **Pricing:** This is a billable action. See https://telnyx.com/pricing/numbers
+ for current pricing.
Args:
- loa_document_id: ID of the signed Letter of Authorization (LOA) document uploaded to the document
- service
+ loa_document_id: Id of the signed Letter of Authorization document, returned by the Telnyx
+ Documents API after upload (upload via `POST /v2/documents`; see
+ https://developers.telnyx.com/api/documents).
- check_frequency: Frequency for automatically refreshing reputation data
+ check_frequency: How often Telnyx refreshes the stored reputation data for this enterprise's
+ registered numbers.
extra_headers: Send extra headers
@@ -228,22 +227,16 @@ def update_frequency(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ReputationUpdateFrequencyResponse:
"""
- Update how often reputation data is automatically refreshed.
-
- **Note:** The enterprise must have `approved` reputation settings. Updating
- frequency on `pending` or `rejected` settings will return an error.
-
- **Available Frequencies:**
+ Update how often Telnyx refreshes the reputation data for this enterprise's
+ registered numbers. The new frequency takes effect on the next scheduled
+ refresh.
- - `business_daily` — Monday–Friday
- - `daily` — Every day including weekends
- - `weekly` — Once per week
- - `biweekly` — Once every two weeks
- - `monthly` — Once per month
- - `never` — Manual refresh only (no automatic checks)
+ The enterprise's reputation must be in `approved` status. A request made while
+ the status is `pending` is rejected with `400 Bad Request`.
Args:
- check_frequency: New frequency for refreshing reputation data
+ check_frequency: How often Telnyx refreshes the stored reputation data for this enterprise's
+ registered numbers.
extra_headers: Send extra headers
@@ -268,17 +261,18 @@ def update_frequency(
class AsyncReputationResource(AsyncAPIResource):
- """
- Manage Number Reputation enrollment and check frequency settings for an enterprise
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
@cached_property
def numbers(self) -> AsyncNumbersResource:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return AsyncNumbersResource(self._client)
+ @cached_property
+ def loa(self) -> AsyncLoaResource:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return AsyncLoaResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncReputationResourceWithRawResponse:
"""
@@ -310,12 +304,12 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ReputationRetrieveResponse:
"""
- Retrieve the current Number Reputation settings for an enterprise.
-
- Returns the enrollment status (`pending`, `approved`, `rejected`, `deleted`),
- check frequency, and any rejection reasons.
+ Phone Number Reputation tracks how your outbound caller-IDs are perceived (spam
+ risk, engagement, etc.) across the call-screening ecosystem. This endpoint reads
+ the enterprise-level settings: whether the product is enabled, the refresh
+ cadence, and the stored Letter of Authorization document id.
- Returns `404` if reputation has not been enabled for this enterprise.
+ Returns `404` if reputation has never been enabled for this enterprise.
Args:
extra_headers: Send extra headers
@@ -347,16 +341,11 @@ async def disable(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
- """
- Disable Number Reputation for an enterprise.
-
- This will:
-
- - Delete the reputation settings record
- - Log the deletion for audit purposes
- - Stop all future automated reputation checks
+ """Disable Phone Number Reputation.
- **Note:** Can only be performed on `approved` reputation settings.
+ All registered numbers are de-registered as a
+ cascade. The enterprise itself is unaffected. Returns `204` on success, `404` if
+ reputation is not enabled for this enterprise.
Args:
extra_headers: Send extra headers
@@ -391,38 +380,33 @@ async def enable(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ReputationEnableResponse:
- """
- Enable Number Reputation service for an enterprise.
-
- **Requirements:**
-
- - Signed LOA (Letter of Authorization) document ID
- - Reputation check frequency (defaults to `business_daily`)
- - Number Reputation Terms of Service must be accepted
+ """Activate Phone Number Reputation for the given enterprise.
- **Flow:**
+ Requires an uploaded
+ Letter of Authorization document (the `loa_document_id` references the Telnyx
+ Documents API) and a refresh-frequency selection. After activation, individual
+ phone numbers can be registered via `POST .../reputation/numbers`.
- 1. Registers the enterprise for reputation monitoring
- 2. Creates reputation settings with `pending` status
- 3. Awaits admin approval before monitoring begins
+ **Prerequisite**: the calling user must have agreed to the Phone Number
+ Reputation Terms of Service (`POST /terms_of_service/number_reputation/agree`).
- **Resubmission After Rejection:** If a previously rejected record exists, this
- endpoint will delete it and create a new `pending` record.
+ Failure modes:
- **Available Frequencies:**
+ - `403` — Phone Number Reputation Terms of Service not accepted.
+ - `404` — enterprise does not exist or does not belong to your account.
+ - `400` — reputation already enabled for this enterprise.
+ - `422` — `loa_document_id` missing or `check_frequency` invalid.
- - `business_daily` — Monday–Friday
- - `daily` — Every day
- - `weekly` — Once per week
- - `biweekly` — Once every two weeks
- - `monthly` — Once per month
- - `never` — Manual refresh only
+ **Pricing:** This is a billable action. See https://telnyx.com/pricing/numbers
+ for current pricing.
Args:
- loa_document_id: ID of the signed Letter of Authorization (LOA) document uploaded to the document
- service
+ loa_document_id: Id of the signed Letter of Authorization document, returned by the Telnyx
+ Documents API after upload (upload via `POST /v2/documents`; see
+ https://developers.telnyx.com/api/documents).
- check_frequency: Frequency for automatically refreshing reputation data
+ check_frequency: How often Telnyx refreshes the stored reputation data for this enterprise's
+ registered numbers.
extra_headers: Send extra headers
@@ -462,22 +446,16 @@ async def update_frequency(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> ReputationUpdateFrequencyResponse:
"""
- Update how often reputation data is automatically refreshed.
+ Update how often Telnyx refreshes the reputation data for this enterprise's
+ registered numbers. The new frequency takes effect on the next scheduled
+ refresh.
- **Note:** The enterprise must have `approved` reputation settings. Updating
- frequency on `pending` or `rejected` settings will return an error.
-
- **Available Frequencies:**
-
- - `business_daily` — Monday–Friday
- - `daily` — Every day including weekends
- - `weekly` — Once per week
- - `biweekly` — Once every two weeks
- - `monthly` — Once per month
- - `never` — Manual refresh only (no automatic checks)
+ The enterprise's reputation must be in `approved` status. A request made while
+ the status is `pending` is rejected with `400 Bad Request`.
Args:
- check_frequency: New frequency for refreshing reputation data
+ check_frequency: How often Telnyx refreshes the stored reputation data for this enterprise's
+ registered numbers.
extra_headers: Send extra headers
@@ -520,11 +498,14 @@ def __init__(self, reputation: ReputationResource) -> None:
@cached_property
def numbers(self) -> NumbersResourceWithRawResponse:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return NumbersResourceWithRawResponse(self._reputation.numbers)
+ @cached_property
+ def loa(self) -> LoaResourceWithRawResponse:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return LoaResourceWithRawResponse(self._reputation.loa)
+
class AsyncReputationResourceWithRawResponse:
def __init__(self, reputation: AsyncReputationResource) -> None:
@@ -545,11 +526,14 @@ def __init__(self, reputation: AsyncReputationResource) -> None:
@cached_property
def numbers(self) -> AsyncNumbersResourceWithRawResponse:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return AsyncNumbersResourceWithRawResponse(self._reputation.numbers)
+ @cached_property
+ def loa(self) -> AsyncLoaResourceWithRawResponse:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return AsyncLoaResourceWithRawResponse(self._reputation.loa)
+
class ReputationResourceWithStreamingResponse:
def __init__(self, reputation: ReputationResource) -> None:
@@ -570,11 +554,14 @@ def __init__(self, reputation: ReputationResource) -> None:
@cached_property
def numbers(self) -> NumbersResourceWithStreamingResponse:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return NumbersResourceWithStreamingResponse(self._reputation.numbers)
+ @cached_property
+ def loa(self) -> LoaResourceWithStreamingResponse:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return LoaResourceWithStreamingResponse(self._reputation.loa)
+
class AsyncReputationResourceWithStreamingResponse:
def __init__(self, reputation: AsyncReputationResource) -> None:
@@ -595,7 +582,10 @@ def __init__(self, reputation: AsyncReputationResource) -> None:
@cached_property
def numbers(self) -> AsyncNumbersResourceWithStreamingResponse:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return AsyncNumbersResourceWithStreamingResponse(self._reputation.numbers)
+
+ @cached_property
+ def loa(self) -> AsyncLoaResourceWithStreamingResponse:
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
+ return AsyncLoaResourceWithStreamingResponse(self._reputation.loa)
diff --git a/src/telnyx/resources/infringement_claims.py b/src/telnyx/resources/infringement_claims.py
new file mode 100644
index 00000000..3d4a93cd
--- /dev/null
+++ b/src/telnyx/resources/infringement_claims.py
@@ -0,0 +1,320 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+
+import httpx
+
+from ..types import infringement_claim_contest_params
+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.infringement_claim_contest_response import InfringementClaimContestResponse
+from ..types.infringement_claim_retrieve_response import InfringementClaimRetrieveResponse
+
+__all__ = ["InfringementClaimsResource", "AsyncInfringementClaimsResource"]
+
+
+class InfringementClaimsResource(SyncAPIResource):
+ """Trademark or impersonation claims filed against your DIR.
+
+ Customers may contest a claim with supporting evidence.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> InfringementClaimsResourceWithRawResponse:
+ """
+ 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 InfringementClaimsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> InfringementClaimsResourceWithStreamingResponse:
+ """
+ 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 InfringementClaimsResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ claim_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,
+ ) -> InfringementClaimRetrieveResponse:
+ """Retrieve a single claim by id.
+
+ Returns `404` if the claim does not exist or is
+ not against a DIR you own.
+
+ 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 claim_id:
+ raise ValueError(f"Expected a non-empty value for `claim_id` but received {claim_id!r}")
+ return self._get(
+ path_template("/infringement_claims/{claim_id}", claim_id=claim_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InfringementClaimRetrieveResponse,
+ )
+
+ def contest(
+ self,
+ claim_id: str,
+ *,
+ contest_notes: str,
+ documents: Iterable[infringement_claim_contest_params.Document] | 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,
+ ) -> InfringementClaimContestResponse:
+ """Submit a written response and supporting documents disputing the claim.
+
+ The
+ first call moves the claim from `pending` to `contested`; subsequent calls
+ append supplementary evidence without changing status. The `documents[]` you
+ attach are aggregated across rounds in the claim's `contest_documents` field.
+
+ Only `pending` and `contested` claims accept new evidence. A `resolved` claim
+ returns `400`.
+
+ Failure modes:
+
+ - `400` — the claim is `resolved` (terminal); cannot be contested further.
+ - `404` — the claim does not exist or is not against a DIR you own.
+ - `422` — `contest_notes` is too short (< 10 chars), too long (> 2000 chars),
+ `documents` is > 20 entries, or a `document_id` is duplicated within the same
+ submission.
+
+ Args:
+ contest_notes: Customer's response to the claim. 10–2000 characters.
+
+ documents: Up to 20 supporting documents per submission. `document_id` must be unique
+ within this submission. Documents are aggregated into the claim's
+ `contest_documents` across all submissions.
+
+ 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 claim_id:
+ raise ValueError(f"Expected a non-empty value for `claim_id` but received {claim_id!r}")
+ return self._post(
+ path_template("/infringement_claims/{claim_id}/contest", claim_id=claim_id),
+ body=maybe_transform(
+ {
+ "contest_notes": contest_notes,
+ "documents": documents,
+ },
+ infringement_claim_contest_params.InfringementClaimContestParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InfringementClaimContestResponse,
+ )
+
+
+class AsyncInfringementClaimsResource(AsyncAPIResource):
+ """Trademark or impersonation claims filed against your DIR.
+
+ Customers may contest a claim with supporting evidence.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncInfringementClaimsResourceWithRawResponse:
+ """
+ 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 AsyncInfringementClaimsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncInfringementClaimsResourceWithStreamingResponse:
+ """
+ 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 AsyncInfringementClaimsResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ claim_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,
+ ) -> InfringementClaimRetrieveResponse:
+ """Retrieve a single claim by id.
+
+ Returns `404` if the claim does not exist or is
+ not against a DIR you own.
+
+ 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 claim_id:
+ raise ValueError(f"Expected a non-empty value for `claim_id` but received {claim_id!r}")
+ return await self._get(
+ path_template("/infringement_claims/{claim_id}", claim_id=claim_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InfringementClaimRetrieveResponse,
+ )
+
+ async def contest(
+ self,
+ claim_id: str,
+ *,
+ contest_notes: str,
+ documents: Iterable[infringement_claim_contest_params.Document] | 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,
+ ) -> InfringementClaimContestResponse:
+ """Submit a written response and supporting documents disputing the claim.
+
+ The
+ first call moves the claim from `pending` to `contested`; subsequent calls
+ append supplementary evidence without changing status. The `documents[]` you
+ attach are aggregated across rounds in the claim's `contest_documents` field.
+
+ Only `pending` and `contested` claims accept new evidence. A `resolved` claim
+ returns `400`.
+
+ Failure modes:
+
+ - `400` — the claim is `resolved` (terminal); cannot be contested further.
+ - `404` — the claim does not exist or is not against a DIR you own.
+ - `422` — `contest_notes` is too short (< 10 chars), too long (> 2000 chars),
+ `documents` is > 20 entries, or a `document_id` is duplicated within the same
+ submission.
+
+ Args:
+ contest_notes: Customer's response to the claim. 10–2000 characters.
+
+ documents: Up to 20 supporting documents per submission. `document_id` must be unique
+ within this submission. Documents are aggregated into the claim's
+ `contest_documents` across all submissions.
+
+ 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 claim_id:
+ raise ValueError(f"Expected a non-empty value for `claim_id` but received {claim_id!r}")
+ return await self._post(
+ path_template("/infringement_claims/{claim_id}/contest", claim_id=claim_id),
+ body=await async_maybe_transform(
+ {
+ "contest_notes": contest_notes,
+ "documents": documents,
+ },
+ infringement_claim_contest_params.InfringementClaimContestParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=InfringementClaimContestResponse,
+ )
+
+
+class InfringementClaimsResourceWithRawResponse:
+ def __init__(self, infringement_claims: InfringementClaimsResource) -> None:
+ self._infringement_claims = infringement_claims
+
+ self.retrieve = to_raw_response_wrapper(
+ infringement_claims.retrieve,
+ )
+ self.contest = to_raw_response_wrapper(
+ infringement_claims.contest,
+ )
+
+
+class AsyncInfringementClaimsResourceWithRawResponse:
+ def __init__(self, infringement_claims: AsyncInfringementClaimsResource) -> None:
+ self._infringement_claims = infringement_claims
+
+ self.retrieve = async_to_raw_response_wrapper(
+ infringement_claims.retrieve,
+ )
+ self.contest = async_to_raw_response_wrapper(
+ infringement_claims.contest,
+ )
+
+
+class InfringementClaimsResourceWithStreamingResponse:
+ def __init__(self, infringement_claims: InfringementClaimsResource) -> None:
+ self._infringement_claims = infringement_claims
+
+ self.retrieve = to_streamed_response_wrapper(
+ infringement_claims.retrieve,
+ )
+ self.contest = to_streamed_response_wrapper(
+ infringement_claims.contest,
+ )
+
+
+class AsyncInfringementClaimsResourceWithStreamingResponse:
+ def __init__(self, infringement_claims: AsyncInfringementClaimsResource) -> None:
+ self._infringement_claims = infringement_claims
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ infringement_claims.retrieve,
+ )
+ self.contest = async_to_streamed_response_wrapper(
+ infringement_claims.contest,
+ )
diff --git a/src/telnyx/resources/public_internet_gateways.py b/src/telnyx/resources/public_internet_gateways.py
index 7e7919b1..8e8f9c52 100644
--- a/src/telnyx/resources/public_internet_gateways.py
+++ b/src/telnyx/resources/public_internet_gateways.py
@@ -17,7 +17,7 @@
)
from ..pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
from .._base_client import AsyncPaginator, make_request_options
-from ..types.public_internet_gateway_read import PublicInternetGatewayRead
+from ..types.public_internet_gateway_list_response import PublicInternetGatewayListResponse
from ..types.public_internet_gateway_create_response import PublicInternetGatewayCreateResponse
from ..types.public_internet_gateway_delete_response import PublicInternetGatewayDeleteResponse
from ..types.public_internet_gateway_retrieve_response import PublicInternetGatewayRetrieveResponse
@@ -139,7 +139,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncDefaultFlatPagination[PublicInternetGatewayRead]:
+ ) -> SyncDefaultFlatPagination[PublicInternetGatewayListResponse]:
"""
List all Public Internet Gateways.
@@ -156,7 +156,7 @@ def list(
"""
return self._get_api_list(
"/public_internet_gateways",
- page=SyncDefaultFlatPagination[PublicInternetGatewayRead],
+ page=SyncDefaultFlatPagination[PublicInternetGatewayListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -171,7 +171,7 @@ def list(
public_internet_gateway_list_params.PublicInternetGatewayListParams,
),
),
- model=PublicInternetGatewayRead,
+ model=PublicInternetGatewayListResponse,
)
def delete(
@@ -322,7 +322,9 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[PublicInternetGatewayRead, AsyncDefaultFlatPagination[PublicInternetGatewayRead]]:
+ ) -> AsyncPaginator[
+ PublicInternetGatewayListResponse, AsyncDefaultFlatPagination[PublicInternetGatewayListResponse]
+ ]:
"""
List all Public Internet Gateways.
@@ -339,7 +341,7 @@ def list(
"""
return self._get_api_list(
"/public_internet_gateways",
- page=AsyncDefaultFlatPagination[PublicInternetGatewayRead],
+ page=AsyncDefaultFlatPagination[PublicInternetGatewayListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -354,7 +356,7 @@ def list(
public_internet_gateway_list_params.PublicInternetGatewayListParams,
),
),
- model=PublicInternetGatewayRead,
+ model=PublicInternetGatewayListResponse,
)
async def delete(
diff --git a/src/telnyx/resources/reputation/numbers.py b/src/telnyx/resources/reputation/numbers.py
index 6920ac29..e58ec23d 100644
--- a/src/telnyx/resources/reputation/numbers.py
+++ b/src/telnyx/resources/reputation/numbers.py
@@ -17,16 +17,14 @@
from ...pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
from ..._base_client import AsyncPaginator, make_request_options
from ...types.reputation import number_list_params, number_retrieve_params
+from ...types.reputation.number_list_response import NumberListResponse
from ...types.reputation.number_retrieve_response import NumberRetrieveResponse
-from ...types.shared.reputation_phone_number_with_reputation_data import ReputationPhoneNumberWithReputationData
__all__ = ["NumbersResource", "AsyncNumbersResource"]
class NumbersResource(SyncAPIResource):
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
@cached_property
def with_raw_response(self) -> NumbersResourceWithRawResponse:
@@ -60,14 +58,12 @@ def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> NumberRetrieveResponse:
"""
- Get reputation data for a specific phone number without requiring an
- `enterprise_id`.
-
- Same response as the enterprise-scoped endpoint. Uses cached data by default.
+ Convenience alias for
+ `GET /v2/enterprises/{enterprise_id}/reputation/numbers/{phone_number}`.
Args:
- fresh: When true, fetches fresh reputation data (incurs API cost). When false, returns
- cached data.
+ fresh: When true, fetches fresh reputation data (incurs API cost). When false
+ (default), returns cached data.
extra_headers: Send extra headers
@@ -103,21 +99,18 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData]:
- """List all phone numbers enrolled in Number Reputation monitoring for your
- account.
-
- This is a simplified endpoint that does not require an `enterprise_id`
- — it returns numbers across all your enterprises.
-
- Supports pagination and filtering by phone number.
+ ) -> SyncDefaultFlatPagination[NumberListResponse]:
+ """
+ Convenience alias for `GET /v2/enterprises/{enterprise_id}/reputation/numbers`
+ that returns numbers across every enterprise you own. Useful when you don't want
+ to look up the enterprise id first.
Args:
- page_number: Page number (1-indexed)
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
- page_size: Number of items per page
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
- phone_number: Filter by specific phone number (E.164 format)
+ phone_number: Filter by specific phone number (E.164 format).
extra_headers: Send extra headers
@@ -129,7 +122,7 @@ def list(
"""
return self._get_api_list(
"/reputation/numbers",
- page=SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData],
+ page=SyncDefaultFlatPagination[NumberListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -144,7 +137,7 @@ def list(
number_list_params.NumberListParams,
),
),
- model=ReputationPhoneNumberWithReputationData,
+ model=NumberListResponse,
)
def delete(
@@ -159,8 +152,8 @@ def delete(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
- Remove a phone number from Number Reputation monitoring without requiring an
- `enterprise_id`.
+ Convenience alias for
+ `DELETE /v2/enterprises/{enterprise_id}/reputation/numbers/{phone_number}`.
Args:
extra_headers: Send extra headers
@@ -184,9 +177,7 @@ def delete(
class AsyncNumbersResource(AsyncAPIResource):
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
@cached_property
def with_raw_response(self) -> AsyncNumbersResourceWithRawResponse:
@@ -220,14 +211,12 @@ async def retrieve(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> NumberRetrieveResponse:
"""
- Get reputation data for a specific phone number without requiring an
- `enterprise_id`.
-
- Same response as the enterprise-scoped endpoint. Uses cached data by default.
+ Convenience alias for
+ `GET /v2/enterprises/{enterprise_id}/reputation/numbers/{phone_number}`.
Args:
- fresh: When true, fetches fresh reputation data (incurs API cost). When false, returns
- cached data.
+ fresh: When true, fetches fresh reputation data (incurs API cost). When false
+ (default), returns cached data.
extra_headers: Send extra headers
@@ -263,23 +252,18 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[
- ReputationPhoneNumberWithReputationData, AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData]
- ]:
- """List all phone numbers enrolled in Number Reputation monitoring for your
- account.
-
- This is a simplified endpoint that does not require an `enterprise_id`
- — it returns numbers across all your enterprises.
-
- Supports pagination and filtering by phone number.
+ ) -> AsyncPaginator[NumberListResponse, AsyncDefaultFlatPagination[NumberListResponse]]:
+ """
+ Convenience alias for `GET /v2/enterprises/{enterprise_id}/reputation/numbers`
+ that returns numbers across every enterprise you own. Useful when you don't want
+ to look up the enterprise id first.
Args:
- page_number: Page number (1-indexed)
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
- page_size: Number of items per page
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
- phone_number: Filter by specific phone number (E.164 format)
+ phone_number: Filter by specific phone number (E.164 format).
extra_headers: Send extra headers
@@ -291,7 +275,7 @@ def list(
"""
return self._get_api_list(
"/reputation/numbers",
- page=AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData],
+ page=AsyncDefaultFlatPagination[NumberListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -306,7 +290,7 @@ def list(
number_list_params.NumberListParams,
),
),
- model=ReputationPhoneNumberWithReputationData,
+ model=NumberListResponse,
)
async def delete(
@@ -321,8 +305,8 @@ async def delete(
timeout: float | httpx.Timeout | None | NotGiven = not_given,
) -> None:
"""
- Remove a phone number from Number Reputation monitoring without requiring an
- `enterprise_id`.
+ Convenience alias for
+ `DELETE /v2/enterprises/{enterprise_id}/reputation/numbers/{phone_number}`.
Args:
extra_headers: Send extra headers
diff --git a/src/telnyx/resources/reputation/reputation.py b/src/telnyx/resources/reputation/reputation.py
index 5cf57070..5c7bfd84 100644
--- a/src/telnyx/resources/reputation/reputation.py
+++ b/src/telnyx/resources/reputation/reputation.py
@@ -19,9 +19,7 @@
class ReputationResource(SyncAPIResource):
@cached_property
def numbers(self) -> NumbersResource:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return NumbersResource(self._client)
@cached_property
@@ -47,9 +45,7 @@ def with_streaming_response(self) -> ReputationResourceWithStreamingResponse:
class AsyncReputationResource(AsyncAPIResource):
@cached_property
def numbers(self) -> AsyncNumbersResource:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return AsyncNumbersResource(self._client)
@cached_property
@@ -78,9 +74,7 @@ def __init__(self, reputation: ReputationResource) -> None:
@cached_property
def numbers(self) -> NumbersResourceWithRawResponse:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return NumbersResourceWithRawResponse(self._reputation.numbers)
@@ -90,9 +84,7 @@ def __init__(self, reputation: AsyncReputationResource) -> None:
@cached_property
def numbers(self) -> AsyncNumbersResourceWithRawResponse:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return AsyncNumbersResourceWithRawResponse(self._reputation.numbers)
@@ -102,9 +94,7 @@ def __init__(self, reputation: ReputationResource) -> None:
@cached_property
def numbers(self) -> NumbersResourceWithStreamingResponse:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return NumbersResourceWithStreamingResponse(self._reputation.numbers)
@@ -114,7 +104,5 @@ def __init__(self, reputation: AsyncReputationResource) -> None:
@cached_property
def numbers(self) -> AsyncNumbersResourceWithStreamingResponse:
- """
- Associate phone numbers with an enterprise for reputation monitoring and retrieve reputation scores
- """
+ """Phone-number reputation monitoring (spam-score lookup and tracking)."""
return AsyncNumbersResourceWithStreamingResponse(self._reputation.numbers)
diff --git a/src/telnyx/resources/terms_of_service/__init__.py b/src/telnyx/resources/terms_of_service/__init__.py
index 3782003e..d1e8cd99 100644
--- a/src/telnyx/resources/terms_of_service/__init__.py
+++ b/src/telnyx/resources/terms_of_service/__init__.py
@@ -1,5 +1,21 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+from .agreements import (
+ AgreementsResource,
+ AsyncAgreementsResource,
+ AgreementsResourceWithRawResponse,
+ AsyncAgreementsResourceWithRawResponse,
+ AgreementsResourceWithStreamingResponse,
+ AsyncAgreementsResourceWithStreamingResponse,
+)
+from .branded_calling import (
+ BrandedCallingResource,
+ AsyncBrandedCallingResource,
+ BrandedCallingResourceWithRawResponse,
+ AsyncBrandedCallingResourceWithRawResponse,
+ BrandedCallingResourceWithStreamingResponse,
+ AsyncBrandedCallingResourceWithStreamingResponse,
+)
from .terms_of_service import (
TermsOfServiceResource,
AsyncTermsOfServiceResource,
@@ -24,6 +40,18 @@
"AsyncNumberReputationResourceWithRawResponse",
"NumberReputationResourceWithStreamingResponse",
"AsyncNumberReputationResourceWithStreamingResponse",
+ "AgreementsResource",
+ "AsyncAgreementsResource",
+ "AgreementsResourceWithRawResponse",
+ "AsyncAgreementsResourceWithRawResponse",
+ "AgreementsResourceWithStreamingResponse",
+ "AsyncAgreementsResourceWithStreamingResponse",
+ "BrandedCallingResource",
+ "AsyncBrandedCallingResource",
+ "BrandedCallingResourceWithRawResponse",
+ "AsyncBrandedCallingResourceWithRawResponse",
+ "BrandedCallingResourceWithStreamingResponse",
+ "AsyncBrandedCallingResourceWithStreamingResponse",
"TermsOfServiceResource",
"AsyncTermsOfServiceResource",
"TermsOfServiceResourceWithRawResponse",
diff --git a/src/telnyx/resources/terms_of_service/agreements.py b/src/telnyx/resources/terms_of_service/agreements.py
new file mode 100644
index 00000000..160f7065
--- /dev/null
+++ b/src/telnyx/resources/terms_of_service/agreements.py
@@ -0,0 +1,321 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+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
+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.terms_of_service import agreement_list_params
+from ...types.terms_of_service.agreement_list_response import AgreementListResponse
+from ...types.terms_of_service.agreement_retrieve_response import AgreementRetrieveResponse
+
+__all__ = ["AgreementsResource", "AsyncAgreementsResource"]
+
+
+class AgreementsResource(SyncAPIResource):
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AgreementsResourceWithRawResponse:
+ """
+ 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 AgreementsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AgreementsResourceWithStreamingResponse:
+ """
+ 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 AgreementsResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ agreement_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,
+ ) -> AgreementRetrieveResponse:
+ """Retrieve a single ToS agreement record.
+
+ Returns `404` if the agreement does not
+ exist or does not belong to the authenticated 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 agreement_id:
+ raise ValueError(f"Expected a non-empty value for `agreement_id` but received {agreement_id!r}")
+ return self._get(
+ path_template("/terms_of_service/agreements/{agreement_id}", agreement_id=agreement_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AgreementRetrieveResponse,
+ )
+
+ def list(
+ self,
+ *,
+ page_number: int | Omit = omit,
+ page_size: int | Omit = omit,
+ product_type: Literal["branded_calling", "number_reputation"] | 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[AgreementListResponse]:
+ """Returns the Terms of Service agreements the authenticated user has on file.
+
+ Each
+ entry records the version agreed to and when. Most users only have one agreement
+ per product, but if the ToS is updated and the user re-agrees a new entry is
+ added.
+
+ Results are paginated with the standard `page[number]` / `page[size]`
+ parameters; the response uses the standard `{data, meta}` JSON:API envelope.
+
+ By default this returns agreements for **all** products the user has agreed to
+ (including Branded Calling). Pass the `product_type` query parameter to scope
+ the result to a single product.
+
+ Args:
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ product_type: Optional filter. Omit to list the user's agreements for **every** product
+ (branded_calling and number_reputation); pass a value to return only that
+ product's agreements.
+
+ 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(
+ "/terms_of_service/agreements",
+ page=SyncDefaultFlatPagination[AgreementListResponse],
+ 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,
+ "product_type": product_type,
+ },
+ agreement_list_params.AgreementListParams,
+ ),
+ ),
+ model=AgreementListResponse,
+ )
+
+
+class AsyncAgreementsResource(AsyncAPIResource):
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncAgreementsResourceWithRawResponse:
+ """
+ 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 AsyncAgreementsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncAgreementsResourceWithStreamingResponse:
+ """
+ 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 AsyncAgreementsResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ agreement_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,
+ ) -> AgreementRetrieveResponse:
+ """Retrieve a single ToS agreement record.
+
+ Returns `404` if the agreement does not
+ exist or does not belong to the authenticated 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 agreement_id:
+ raise ValueError(f"Expected a non-empty value for `agreement_id` but received {agreement_id!r}")
+ return await self._get(
+ path_template("/terms_of_service/agreements/{agreement_id}", agreement_id=agreement_id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AgreementRetrieveResponse,
+ )
+
+ def list(
+ self,
+ *,
+ page_number: int | Omit = omit,
+ page_size: int | Omit = omit,
+ product_type: Literal["branded_calling", "number_reputation"] | 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[AgreementListResponse, AsyncDefaultFlatPagination[AgreementListResponse]]:
+ """Returns the Terms of Service agreements the authenticated user has on file.
+
+ Each
+ entry records the version agreed to and when. Most users only have one agreement
+ per product, but if the ToS is updated and the user re-agrees a new entry is
+ added.
+
+ Results are paginated with the standard `page[number]` / `page[size]`
+ parameters; the response uses the standard `{data, meta}` JSON:API envelope.
+
+ By default this returns agreements for **all** products the user has agreed to
+ (including Branded Calling). Pass the `product_type` query parameter to scope
+ the result to a single product.
+
+ Args:
+ page_number: 1-based page number. Out-of-range values return an empty page with correct meta.
+
+ page_size: Items per page. Maximum 250; values above are clamped to 250.
+
+ product_type: Optional filter. Omit to list the user's agreements for **every** product
+ (branded_calling and number_reputation); pass a value to return only that
+ product's agreements.
+
+ 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(
+ "/terms_of_service/agreements",
+ page=AsyncDefaultFlatPagination[AgreementListResponse],
+ 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,
+ "product_type": product_type,
+ },
+ agreement_list_params.AgreementListParams,
+ ),
+ ),
+ model=AgreementListResponse,
+ )
+
+
+class AgreementsResourceWithRawResponse:
+ def __init__(self, agreements: AgreementsResource) -> None:
+ self._agreements = agreements
+
+ self.retrieve = to_raw_response_wrapper(
+ agreements.retrieve,
+ )
+ self.list = to_raw_response_wrapper(
+ agreements.list,
+ )
+
+
+class AsyncAgreementsResourceWithRawResponse:
+ def __init__(self, agreements: AsyncAgreementsResource) -> None:
+ self._agreements = agreements
+
+ self.retrieve = async_to_raw_response_wrapper(
+ agreements.retrieve,
+ )
+ self.list = async_to_raw_response_wrapper(
+ agreements.list,
+ )
+
+
+class AgreementsResourceWithStreamingResponse:
+ def __init__(self, agreements: AgreementsResource) -> None:
+ self._agreements = agreements
+
+ self.retrieve = to_streamed_response_wrapper(
+ agreements.retrieve,
+ )
+ self.list = to_streamed_response_wrapper(
+ agreements.list,
+ )
+
+
+class AsyncAgreementsResourceWithStreamingResponse:
+ def __init__(self, agreements: AsyncAgreementsResource) -> None:
+ self._agreements = agreements
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ agreements.retrieve,
+ )
+ self.list = async_to_streamed_response_wrapper(
+ agreements.list,
+ )
diff --git a/src/telnyx/resources/terms_of_service/branded_calling.py b/src/telnyx/resources/terms_of_service/branded_calling.py
new file mode 100644
index 00000000..a4693e3f
--- /dev/null
+++ b/src/telnyx/resources/terms_of_service/branded_calling.py
@@ -0,0 +1,159 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import httpx
+
+from ..._types import Body, Query, Headers, NotGiven, not_given
+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.terms_of_service.branded_calling_agree_response import BrandedCallingAgreeResponse
+
+__all__ = ["BrandedCallingResource", "AsyncBrandedCallingResource"]
+
+
+class BrandedCallingResource(SyncAPIResource):
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> BrandedCallingResourceWithRawResponse:
+ """
+ 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 BrandedCallingResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> BrandedCallingResourceWithStreamingResponse:
+ """
+ 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 BrandedCallingResourceWithStreamingResponse(self)
+
+ def agree(
+ self,
+ *,
+ # 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,
+ ) -> BrandedCallingAgreeResponse:
+ """
+ Records the authenticated user's agreement to the current Branded Calling ToS.
+ No body required. Idempotent — re-calling after agreement is a no-op and returns
+ the existing agreement.
+
+ This is a prerequisite for activating Branded Calling on any enterprise
+ (`POST /enterprises/{id}/branded_calling`); without an agreement, activation
+ returns `403`.
+ """
+ return self._post(
+ "/terms_of_service/branded_calling/agree",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=BrandedCallingAgreeResponse,
+ )
+
+
+class AsyncBrandedCallingResource(AsyncAPIResource):
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+
+ @cached_property
+ def with_raw_response(self) -> AsyncBrandedCallingResourceWithRawResponse:
+ """
+ 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 AsyncBrandedCallingResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncBrandedCallingResourceWithStreamingResponse:
+ """
+ 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 AsyncBrandedCallingResourceWithStreamingResponse(self)
+
+ async def agree(
+ self,
+ *,
+ # 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,
+ ) -> BrandedCallingAgreeResponse:
+ """
+ Records the authenticated user's agreement to the current Branded Calling ToS.
+ No body required. Idempotent — re-calling after agreement is a no-op and returns
+ the existing agreement.
+
+ This is a prerequisite for activating Branded Calling on any enterprise
+ (`POST /enterprises/{id}/branded_calling`); without an agreement, activation
+ returns `403`.
+ """
+ return await self._post(
+ "/terms_of_service/branded_calling/agree",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=BrandedCallingAgreeResponse,
+ )
+
+
+class BrandedCallingResourceWithRawResponse:
+ def __init__(self, branded_calling: BrandedCallingResource) -> None:
+ self._branded_calling = branded_calling
+
+ self.agree = to_raw_response_wrapper(
+ branded_calling.agree,
+ )
+
+
+class AsyncBrandedCallingResourceWithRawResponse:
+ def __init__(self, branded_calling: AsyncBrandedCallingResource) -> None:
+ self._branded_calling = branded_calling
+
+ self.agree = async_to_raw_response_wrapper(
+ branded_calling.agree,
+ )
+
+
+class BrandedCallingResourceWithStreamingResponse:
+ def __init__(self, branded_calling: BrandedCallingResource) -> None:
+ self._branded_calling = branded_calling
+
+ self.agree = to_streamed_response_wrapper(
+ branded_calling.agree,
+ )
+
+
+class AsyncBrandedCallingResourceWithStreamingResponse:
+ def __init__(self, branded_calling: AsyncBrandedCallingResource) -> None:
+ self._branded_calling = branded_calling
+
+ self.agree = async_to_streamed_response_wrapper(
+ branded_calling.agree,
+ )
diff --git a/src/telnyx/resources/terms_of_service/number_reputation.py b/src/telnyx/resources/terms_of_service/number_reputation.py
index d047e0b0..50c63a56 100644
--- a/src/telnyx/resources/terms_of_service/number_reputation.py
+++ b/src/telnyx/resources/terms_of_service/number_reputation.py
@@ -4,7 +4,7 @@
import httpx
-from ..._types import Body, Query, Headers, NoneType, NotGiven, not_given
+from ..._types import Body, Query, Headers, NotGiven, not_given
from ..._compat import cached_property
from ..._resource import SyncAPIResource, AsyncAPIResource
from ..._response import (
@@ -14,12 +14,15 @@
async_to_streamed_response_wrapper,
)
from ..._base_client import make_request_options
+from ...types.terms_of_service.number_reputation_agree_response import NumberReputationAgreeResponse
__all__ = ["NumberReputationResource", "AsyncNumberReputationResource"]
class NumberReputationResource(SyncAPIResource):
- """Terms of Service agreement endpoints"""
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
@cached_property
def with_raw_response(self) -> NumberReputationResourceWithRawResponse:
@@ -49,27 +52,26 @@ def agree(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """Accept the Terms of Service for the Number Reputation product.
-
- Must be called
- before using Number Reputation endpoints.
+ ) -> NumberReputationAgreeResponse:
+ """
+ Records the authenticated user's agreement to the current Phone Number
+ Reputation ToS. No body required. Idempotent.
- Returns `400` with error code `10015` if the user has already agreed to the
- current ToS version.
+ Prerequisite for using any of the `/v2/.../reputation/*` endpoints.
"""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return self._post(
"/terms_of_service/number_reputation/agree",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=NoneType,
+ cast_to=NumberReputationAgreeResponse,
)
class AsyncNumberReputationResource(AsyncAPIResource):
- """Terms of Service agreement endpoints"""
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
@cached_property
def with_raw_response(self) -> AsyncNumberReputationResourceWithRawResponse:
@@ -99,22 +101,19 @@ async def agree(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> None:
- """Accept the Terms of Service for the Number Reputation product.
-
- Must be called
- before using Number Reputation endpoints.
+ ) -> NumberReputationAgreeResponse:
+ """
+ Records the authenticated user's agreement to the current Phone Number
+ Reputation ToS. No body required. Idempotent.
- Returns `400` with error code `10015` if the user has already agreed to the
- current ToS version.
+ Prerequisite for using any of the `/v2/.../reputation/*` endpoints.
"""
- extra_headers = {"Accept": "*/*", **(extra_headers or {})}
return await self._post(
"/terms_of_service/number_reputation/agree",
options=make_request_options(
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
),
- cast_to=NoneType,
+ cast_to=NumberReputationAgreeResponse,
)
diff --git a/src/telnyx/resources/terms_of_service/terms_of_service.py b/src/telnyx/resources/terms_of_service/terms_of_service.py
index b94ff0c8..fdc3d060 100644
--- a/src/telnyx/resources/terms_of_service/terms_of_service.py
+++ b/src/telnyx/resources/terms_of_service/terms_of_service.py
@@ -2,8 +2,38 @@
from __future__ import annotations
+from typing_extensions import Literal
+
+import httpx
+
+from ...types import terms_of_service_status_params
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import maybe_transform, async_maybe_transform
from ..._compat import cached_property
+from .agreements import (
+ AgreementsResource,
+ AsyncAgreementsResource,
+ AgreementsResourceWithRawResponse,
+ AsyncAgreementsResourceWithRawResponse,
+ AgreementsResourceWithStreamingResponse,
+ AsyncAgreementsResourceWithStreamingResponse,
+)
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 .branded_calling import (
+ BrandedCallingResource,
+ AsyncBrandedCallingResource,
+ BrandedCallingResourceWithRawResponse,
+ AsyncBrandedCallingResourceWithRawResponse,
+ BrandedCallingResourceWithStreamingResponse,
+ AsyncBrandedCallingResourceWithStreamingResponse,
+)
from .number_reputation import (
NumberReputationResource,
AsyncNumberReputationResource,
@@ -12,16 +42,37 @@
NumberReputationResourceWithStreamingResponse,
AsyncNumberReputationResourceWithStreamingResponse,
)
+from ...types.terms_of_service_status_response import TermsOfServiceStatusResponse
__all__ = ["TermsOfServiceResource", "AsyncTermsOfServiceResource"]
class TermsOfServiceResource(SyncAPIResource):
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+
@cached_property
def number_reputation(self) -> NumberReputationResource:
- """Terms of Service agreement endpoints"""
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
return NumberReputationResource(self._client)
+ @cached_property
+ def agreements(self) -> AgreementsResource:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AgreementsResource(self._client)
+
+ @cached_property
+ def branded_calling(self) -> BrandedCallingResource:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return BrandedCallingResource(self._client)
+
@cached_property
def with_raw_response(self) -> TermsOfServiceResourceWithRawResponse:
"""
@@ -41,13 +92,80 @@ def with_streaming_response(self) -> TermsOfServiceResourceWithStreamingResponse
"""
return TermsOfServiceResourceWithStreamingResponse(self)
+ def status(
+ self,
+ *,
+ product_type: Literal["branded_calling", "number_reputation"] | 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,
+ ) -> TermsOfServiceStatusResponse:
+ """
+ Returns whether the authenticated user has agreed to the current Number
+ Reputation Terms of Service. Used during onboarding to decide whether to prompt
+ the user with the ToS dialog before continuing.
+
+ The `agreement_required: true` value means the user has not yet agreed (or has
+ agreed to an outdated version) and must call
+ `POST /terms_of_service/number_reputation/agree` before they can use the Number
+ Reputation endpoints on an enterprise.
+
+ Args:
+ product_type: Which product's ToS to check. Defaults to `branded_calling`; pass
+ `number_reputation` to check the Number Reputation Terms of Service.
+
+ 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(
+ "/terms_of_service/status",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"product_type": product_type}, terms_of_service_status_params.TermsOfServiceStatusParams
+ ),
+ ),
+ cast_to=TermsOfServiceStatusResponse,
+ )
+
class AsyncTermsOfServiceResource(AsyncAPIResource):
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+
@cached_property
def number_reputation(self) -> AsyncNumberReputationResource:
- """Terms of Service agreement endpoints"""
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
return AsyncNumberReputationResource(self._client)
+ @cached_property
+ def agreements(self) -> AsyncAgreementsResource:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AsyncAgreementsResource(self._client)
+
+ @cached_property
+ def branded_calling(self) -> AsyncBrandedCallingResource:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AsyncBrandedCallingResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncTermsOfServiceResourceWithRawResponse:
"""
@@ -67,42 +185,169 @@ def with_streaming_response(self) -> AsyncTermsOfServiceResourceWithStreamingRes
"""
return AsyncTermsOfServiceResourceWithStreamingResponse(self)
+ async def status(
+ self,
+ *,
+ product_type: Literal["branded_calling", "number_reputation"] | 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,
+ ) -> TermsOfServiceStatusResponse:
+ """
+ Returns whether the authenticated user has agreed to the current Number
+ Reputation Terms of Service. Used during onboarding to decide whether to prompt
+ the user with the ToS dialog before continuing.
+
+ The `agreement_required: true` value means the user has not yet agreed (or has
+ agreed to an outdated version) and must call
+ `POST /terms_of_service/number_reputation/agree` before they can use the Number
+ Reputation endpoints on an enterprise.
+
+ Args:
+ product_type: Which product's ToS to check. Defaults to `branded_calling`; pass
+ `number_reputation` to check the Number Reputation Terms of Service.
+
+ 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 await self._get(
+ "/terms_of_service/status",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"product_type": product_type}, terms_of_service_status_params.TermsOfServiceStatusParams
+ ),
+ ),
+ cast_to=TermsOfServiceStatusResponse,
+ )
+
class TermsOfServiceResourceWithRawResponse:
def __init__(self, terms_of_service: TermsOfServiceResource) -> None:
self._terms_of_service = terms_of_service
+ self.status = to_raw_response_wrapper(
+ terms_of_service.status,
+ )
+
@cached_property
def number_reputation(self) -> NumberReputationResourceWithRawResponse:
- """Terms of Service agreement endpoints"""
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
return NumberReputationResourceWithRawResponse(self._terms_of_service.number_reputation)
+ @cached_property
+ def agreements(self) -> AgreementsResourceWithRawResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AgreementsResourceWithRawResponse(self._terms_of_service.agreements)
+
+ @cached_property
+ def branded_calling(self) -> BrandedCallingResourceWithRawResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return BrandedCallingResourceWithRawResponse(self._terms_of_service.branded_calling)
+
class AsyncTermsOfServiceResourceWithRawResponse:
def __init__(self, terms_of_service: AsyncTermsOfServiceResource) -> None:
self._terms_of_service = terms_of_service
+ self.status = async_to_raw_response_wrapper(
+ terms_of_service.status,
+ )
+
@cached_property
def number_reputation(self) -> AsyncNumberReputationResourceWithRawResponse:
- """Terms of Service agreement endpoints"""
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
return AsyncNumberReputationResourceWithRawResponse(self._terms_of_service.number_reputation)
+ @cached_property
+ def agreements(self) -> AsyncAgreementsResourceWithRawResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AsyncAgreementsResourceWithRawResponse(self._terms_of_service.agreements)
+
+ @cached_property
+ def branded_calling(self) -> AsyncBrandedCallingResourceWithRawResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AsyncBrandedCallingResourceWithRawResponse(self._terms_of_service.branded_calling)
+
class TermsOfServiceResourceWithStreamingResponse:
def __init__(self, terms_of_service: TermsOfServiceResource) -> None:
self._terms_of_service = terms_of_service
+ self.status = to_streamed_response_wrapper(
+ terms_of_service.status,
+ )
+
@cached_property
def number_reputation(self) -> NumberReputationResourceWithStreamingResponse:
- """Terms of Service agreement endpoints"""
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
return NumberReputationResourceWithStreamingResponse(self._terms_of_service.number_reputation)
+ @cached_property
+ def agreements(self) -> AgreementsResourceWithStreamingResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AgreementsResourceWithStreamingResponse(self._terms_of_service.agreements)
+
+ @cached_property
+ def branded_calling(self) -> BrandedCallingResourceWithStreamingResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return BrandedCallingResourceWithStreamingResponse(self._terms_of_service.branded_calling)
+
class AsyncTermsOfServiceResourceWithStreamingResponse:
def __init__(self, terms_of_service: AsyncTermsOfServiceResource) -> None:
self._terms_of_service = terms_of_service
+ self.status = async_to_streamed_response_wrapper(
+ terms_of_service.status,
+ )
+
@cached_property
def number_reputation(self) -> AsyncNumberReputationResourceWithStreamingResponse:
- """Terms of Service agreement endpoints"""
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
return AsyncNumberReputationResourceWithStreamingResponse(self._terms_of_service.number_reputation)
+
+ @cached_property
+ def agreements(self) -> AsyncAgreementsResourceWithStreamingResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AsyncAgreementsResourceWithStreamingResponse(self._terms_of_service.agreements)
+
+ @cached_property
+ def branded_calling(self) -> AsyncBrandedCallingResourceWithStreamingResponse:
+ """
+ Accept and review the Branded Calling and Phone Number Reputation terms of service.
+ """
+ return AsyncBrandedCallingResourceWithStreamingResponse(self._terms_of_service.branded_calling)
diff --git a/src/telnyx/resources/uac_connections/uac_connections.py b/src/telnyx/resources/uac_connections/uac_connections.py
index 87dcdaab..53a7d738 100644
--- a/src/telnyx/resources/uac_connections/uac_connections.py
+++ b/src/telnyx/resources/uac_connections/uac_connections.py
@@ -36,12 +36,9 @@
from ...pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
from ..._base_client import AsyncPaginator, make_request_options
from ...types.dtmf_type import DtmfType
-from ...types.uac_connection import UacConnection
from ...types.encrypted_media import EncryptedMedia
-from ...types.uac_outbound_param import UacOutboundParam
from ...types.anchorsite_override import AnchorsiteOverride
-from ...types.uac_external_settings_param import UacExternalSettingsParam
-from ...types.uac_internal_settings_param import UacInternalSettingsParam
+from ...types.uac_connection_list_response import UacConnectionListResponse
from ...types.connection_rtcp_settings_param import ConnectionRtcpSettingsParam
from ...types.uac_connection_create_response import UacConnectionCreateResponse
from ...types.uac_connection_delete_response import UacConnectionDeleteResponse
@@ -92,15 +89,15 @@ def create(
dtmf_type: DtmfType | Omit = omit,
encode_contact_header_enabled: bool | Omit = omit,
encrypted_media: Optional[EncryptedMedia] | Omit = omit,
- external_uac_settings: UacExternalSettingsParam | Omit = omit,
+ external_uac_settings: uac_connection_create_params.ExternalUacSettings | Omit = omit,
inbound: uac_connection_create_params.Inbound | Omit = omit,
- internal_uac_settings: UacInternalSettingsParam | Omit = omit,
+ internal_uac_settings: uac_connection_create_params.InternalUacSettings | Omit = omit,
ios_push_credential_id: Optional[str] | Omit = omit,
jitter_buffer: ConnectionJitterBuffer | Omit = omit,
noise_suppression: Literal["inbound", "outbound", "both", "disabled"] | Omit = omit,
noise_suppression_details: ConnectionNoiseSuppressionDetails | Omit = omit,
onnet_t38_passthrough_enabled: bool | Omit = omit,
- outbound: UacOutboundParam | Omit = omit,
+ outbound: uac_connection_create_params.Outbound | Omit = omit,
password: str | Omit = omit,
rtcp_settings: ConnectionRtcpSettingsParam | Omit = omit,
sip_uri_calling_preference: Literal["disabled", "unrestricted", "internal"] | Omit = omit,
@@ -301,15 +298,15 @@ def update(
dtmf_type: DtmfType | Omit = omit,
encode_contact_header_enabled: bool | Omit = omit,
encrypted_media: Optional[EncryptedMedia] | Omit = omit,
- external_uac_settings: UacExternalSettingsParam | Omit = omit,
+ external_uac_settings: uac_connection_update_params.ExternalUacSettings | Omit = omit,
inbound: uac_connection_update_params.Inbound | Omit = omit,
- internal_uac_settings: UacInternalSettingsParam | Omit = omit,
+ internal_uac_settings: uac_connection_update_params.InternalUacSettings | Omit = omit,
ios_push_credential_id: Optional[str] | Omit = omit,
jitter_buffer: ConnectionJitterBuffer | Omit = omit,
noise_suppression: Literal["inbound", "outbound", "both", "disabled"] | Omit = omit,
noise_suppression_details: ConnectionNoiseSuppressionDetails | Omit = omit,
onnet_t38_passthrough_enabled: bool | Omit = omit,
- outbound: UacOutboundParam | Omit = omit,
+ outbound: uac_connection_update_params.Outbound | Omit = omit,
password: str | Omit = omit,
rtcp_settings: ConnectionRtcpSettingsParam | Omit = omit,
sip_uri_calling_preference: Literal["disabled", "unrestricted", "internal"] | Omit = omit,
@@ -473,7 +470,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncDefaultFlatPagination[UacConnection]:
+ ) -> SyncDefaultFlatPagination[UacConnectionListResponse]:
"""Returns a list of your UAC connections.
A UAC (User Agent Client) Connection
@@ -512,7 +509,7 @@ def list(
"""
return self._get_api_list(
"/uac_connections",
- page=SyncDefaultFlatPagination[UacConnection],
+ page=SyncDefaultFlatPagination[UacConnectionListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -528,7 +525,7 @@ def list(
uac_connection_list_params.UacConnectionListParams,
),
),
- model=UacConnection,
+ model=UacConnectionListResponse,
)
def delete(
@@ -604,15 +601,15 @@ async def create(
dtmf_type: DtmfType | Omit = omit,
encode_contact_header_enabled: bool | Omit = omit,
encrypted_media: Optional[EncryptedMedia] | Omit = omit,
- external_uac_settings: UacExternalSettingsParam | Omit = omit,
+ external_uac_settings: uac_connection_create_params.ExternalUacSettings | Omit = omit,
inbound: uac_connection_create_params.Inbound | Omit = omit,
- internal_uac_settings: UacInternalSettingsParam | Omit = omit,
+ internal_uac_settings: uac_connection_create_params.InternalUacSettings | Omit = omit,
ios_push_credential_id: Optional[str] | Omit = omit,
jitter_buffer: ConnectionJitterBuffer | Omit = omit,
noise_suppression: Literal["inbound", "outbound", "both", "disabled"] | Omit = omit,
noise_suppression_details: ConnectionNoiseSuppressionDetails | Omit = omit,
onnet_t38_passthrough_enabled: bool | Omit = omit,
- outbound: UacOutboundParam | Omit = omit,
+ outbound: uac_connection_create_params.Outbound | Omit = omit,
password: str | Omit = omit,
rtcp_settings: ConnectionRtcpSettingsParam | Omit = omit,
sip_uri_calling_preference: Literal["disabled", "unrestricted", "internal"] | Omit = omit,
@@ -813,15 +810,15 @@ async def update(
dtmf_type: DtmfType | Omit = omit,
encode_contact_header_enabled: bool | Omit = omit,
encrypted_media: Optional[EncryptedMedia] | Omit = omit,
- external_uac_settings: UacExternalSettingsParam | Omit = omit,
+ external_uac_settings: uac_connection_update_params.ExternalUacSettings | Omit = omit,
inbound: uac_connection_update_params.Inbound | Omit = omit,
- internal_uac_settings: UacInternalSettingsParam | Omit = omit,
+ internal_uac_settings: uac_connection_update_params.InternalUacSettings | Omit = omit,
ios_push_credential_id: Optional[str] | Omit = omit,
jitter_buffer: ConnectionJitterBuffer | Omit = omit,
noise_suppression: Literal["inbound", "outbound", "both", "disabled"] | Omit = omit,
noise_suppression_details: ConnectionNoiseSuppressionDetails | Omit = omit,
onnet_t38_passthrough_enabled: bool | Omit = omit,
- outbound: UacOutboundParam | Omit = omit,
+ outbound: uac_connection_update_params.Outbound | Omit = omit,
password: str | Omit = omit,
rtcp_settings: ConnectionRtcpSettingsParam | Omit = omit,
sip_uri_calling_preference: Literal["disabled", "unrestricted", "internal"] | Omit = omit,
@@ -985,7 +982,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[UacConnection, AsyncDefaultFlatPagination[UacConnection]]:
+ ) -> AsyncPaginator[UacConnectionListResponse, AsyncDefaultFlatPagination[UacConnectionListResponse]]:
"""Returns a list of your UAC connections.
A UAC (User Agent Client) Connection
@@ -1024,7 +1021,7 @@ def list(
"""
return self._get_api_list(
"/uac_connections",
- page=AsyncDefaultFlatPagination[UacConnection],
+ page=AsyncDefaultFlatPagination[UacConnectionListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -1040,7 +1037,7 @@ def list(
uac_connection_list_params.UacConnectionListParams,
),
),
- model=UacConnection,
+ model=UacConnectionListResponse,
)
async def delete(
diff --git a/src/telnyx/resources/virtual_cross_connects.py b/src/telnyx/resources/virtual_cross_connects.py
index a7b37fbc..042383c0 100644
--- a/src/telnyx/resources/virtual_cross_connects.py
+++ b/src/telnyx/resources/virtual_cross_connects.py
@@ -23,7 +23,7 @@
)
from ..pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
from .._base_client import AsyncPaginator, make_request_options
-from ..types.virtual_cross_connect_combined import VirtualCrossConnectCombined
+from ..types.virtual_cross_connect_list_response import VirtualCrossConnectListResponse
from ..types.virtual_cross_connect_create_response import VirtualCrossConnectCreateResponse
from ..types.virtual_cross_connect_delete_response import VirtualCrossConnectDeleteResponse
from ..types.virtual_cross_connect_update_response import VirtualCrossConnectUpdateResponse
@@ -294,7 +294,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncDefaultFlatPagination[VirtualCrossConnectCombined]:
+ ) -> SyncDefaultFlatPagination[VirtualCrossConnectListResponse]:
"""
List all Virtual Cross Connects.
@@ -311,7 +311,7 @@ def list(
"""
return self._get_api_list(
"/virtual_cross_connects",
- page=SyncDefaultFlatPagination[VirtualCrossConnectCombined],
+ page=SyncDefaultFlatPagination[VirtualCrossConnectListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -326,7 +326,7 @@ def list(
virtual_cross_connect_list_params.VirtualCrossConnectListParams,
),
),
- model=VirtualCrossConnectCombined,
+ model=VirtualCrossConnectListResponse,
)
def delete(
@@ -625,7 +625,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[VirtualCrossConnectCombined, AsyncDefaultFlatPagination[VirtualCrossConnectCombined]]:
+ ) -> AsyncPaginator[VirtualCrossConnectListResponse, AsyncDefaultFlatPagination[VirtualCrossConnectListResponse]]:
"""
List all Virtual Cross Connects.
@@ -642,7 +642,7 @@ def list(
"""
return self._get_api_list(
"/virtual_cross_connects",
- page=AsyncDefaultFlatPagination[VirtualCrossConnectCombined],
+ page=AsyncDefaultFlatPagination[VirtualCrossConnectListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -657,7 +657,7 @@ def list(
virtual_cross_connect_list_params.VirtualCrossConnectListParams,
),
),
- model=VirtualCrossConnectCombined,
+ model=VirtualCrossConnectListResponse,
)
async def delete(
diff --git a/src/telnyx/resources/wireguard_interfaces.py b/src/telnyx/resources/wireguard_interfaces.py
index d2f6bad1..3266d472 100644
--- a/src/telnyx/resources/wireguard_interfaces.py
+++ b/src/telnyx/resources/wireguard_interfaces.py
@@ -17,7 +17,7 @@
)
from ..pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
from .._base_client import AsyncPaginator, make_request_options
-from ..types.wireguard_interface_read import WireguardInterfaceRead
+from ..types.wireguard_interface_list_response import WireguardInterfaceListResponse
from ..types.wireguard_interface_create_response import WireguardInterfaceCreateResponse
from ..types.wireguard_interface_delete_response import WireguardInterfaceDeleteResponse
from ..types.wireguard_interface_retrieve_response import WireguardInterfaceRetrieveResponse
@@ -145,7 +145,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> SyncDefaultFlatPagination[WireguardInterfaceRead]:
+ ) -> SyncDefaultFlatPagination[WireguardInterfaceListResponse]:
"""
List all WireGuard Interfaces.
@@ -162,7 +162,7 @@ def list(
"""
return self._get_api_list(
"/wireguard_interfaces",
- page=SyncDefaultFlatPagination[WireguardInterfaceRead],
+ page=SyncDefaultFlatPagination[WireguardInterfaceListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -177,7 +177,7 @@ def list(
wireguard_interface_list_params.WireguardInterfaceListParams,
),
),
- model=WireguardInterfaceRead,
+ model=WireguardInterfaceListResponse,
)
def delete(
@@ -334,7 +334,7 @@ def list(
extra_query: Query | None = None,
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = not_given,
- ) -> AsyncPaginator[WireguardInterfaceRead, AsyncDefaultFlatPagination[WireguardInterfaceRead]]:
+ ) -> AsyncPaginator[WireguardInterfaceListResponse, AsyncDefaultFlatPagination[WireguardInterfaceListResponse]]:
"""
List all WireGuard Interfaces.
@@ -351,7 +351,7 @@ def list(
"""
return self._get_api_list(
"/wireguard_interfaces",
- page=AsyncDefaultFlatPagination[WireguardInterfaceRead],
+ page=AsyncDefaultFlatPagination[WireguardInterfaceListResponse],
options=make_request_options(
extra_headers=extra_headers,
extra_query=extra_query,
@@ -366,7 +366,7 @@ def list(
wireguard_interface_list_params.WireguardInterfaceListParams,
),
),
- model=WireguardInterfaceRead,
+ model=WireguardInterfaceListResponse,
)
async def delete(
diff --git a/src/telnyx/types/__init__.py b/src/telnyx/types/__init__.py
index b5541f55..f42c8a25 100644
--- a/src/telnyx/types/__init__.py
+++ b/src/telnyx/types/__init__.py
@@ -16,7 +16,6 @@
Feature as Feature,
APIError as APIError,
Metadata as Metadata,
- MetaInfo as MetaInfo,
ShortCode as ShortCode,
HostedNumber as HostedNumber,
SimCardStatus as SimCardStatus,
@@ -25,7 +24,6 @@
CostInformation as CostInformation,
NetappsLocation as NetappsLocation,
RoomParticipant as RoomParticipant,
- XaiVoiceSettings as XaiVoiceSettings,
RegionInformation as RegionInformation,
RimeVoiceSettings as RimeVoiceSettings,
AzureVoiceSettings as AzureVoiceSettings,
@@ -52,7 +50,6 @@
AvailablePhoneNumbersMetadata as AvailablePhoneNumbersMetadata,
PhoneNumberWithMessagingSettings as PhoneNumberWithMessagingSettings,
ConnectionNoiseSuppressionDetails as ConnectionNoiseSuppressionDetails,
- ReputationPhoneNumberWithReputationData as ReputationPhoneNumberWithReputationData,
SubNumberOrderRegulatoryRequirementWithValue as SubNumberOrderRegulatoryRequirementWithValue,
)
from .address import Address as Address
@@ -71,7 +68,6 @@
from .oauth_grant import OAuthGrant as OAuthGrant
from .outbound_ip import OutboundIP as OutboundIP
from .rcs_to_item import RcsToItem as RcsToItem
-from .uac_inbound import UacInbound as UacInbound
from .call_bridged import CallBridged as CallBridged
from .inbound_fqdn import InboundFqdn as InboundFqdn
from .month_detail import MonthDetail as MonthDetail
@@ -81,7 +77,6 @@
from .service_plan import ServicePlan as ServicePlan
from .stream_codec import StreamCodec as StreamCodec
from .traffic_type import TrafficType as TrafficType
-from .uac_outbound import UacOutbound as UacOutbound
from .user_address import UserAddress as UserAddress
from .verification import Verification as Verification
from .video_region import VideoRegion as VideoRegion
@@ -97,12 +92,10 @@
from .call_initiated import CallInitiated as CallInitiated
from .ip_list_params import IPListParams as IPListParams
from .media_resource import MediaResource as MediaResource
-from .model_metadata import ModelMetadata as ModelMetadata
from .rcs_suggestion import RcsSuggestion as RcsSuggestion
from .settings_param import SettingsParam as SettingsParam
from .sim_card_group import SimCardGroup as SimCardGroup
from .sim_card_order import SimCardOrder as SimCardOrder
-from .uac_connection import UacConnection as UacConnection
from .verify_profile import VerifyProfile as VerifyProfile
from .whatsapp_media import WhatsappMedia as WhatsappMedia
from .wireless_error import WirelessError as WirelessError
@@ -110,6 +103,7 @@
from .billing_address import BillingAddress as BillingAddress
from .billing_contact import BillingContact as BillingContact
from .call_left_queue import CallLeftQueue as CallLeftQueue
+from .dir_list_params import DirListParams as DirListParams
from .encrypted_media import EncryptedMedia as EncryptedMedia
from .fax_application import FaxApplication as FaxApplication
from .fax_list_params import FaxListParams as FaxListParams
@@ -148,10 +142,13 @@
from .call_gather_ended import CallGatherEnded as CallGatherEnded
from .call_refer_failed import CallReferFailed as CallReferFailed
from .custom_sip_header import CustomSipHeader as CustomSipHeader
+from .dir_list_response import DirListResponse as DirListResponse
+from .dir_update_params import DirUpdateParams as DirUpdateParams
from .enterprise_public import EnterprisePublic as EnterprisePublic
from .fax_create_params import FaxCreateParams as FaxCreateParams
from .media_list_params import MediaListParams as MediaListParams
from .messaging_profile import MessagingProfile as MessagingProfile
+from .network_interface import NetworkInterface as NetworkInterface
from .outbound_ip_param import OutboundIPParam as OutboundIPParam
from .queue_list_params import QueueListParams as QueueListParams
from .rcs_agent_message import RcsAgentMessage as RcsAgentMessage
@@ -183,7 +180,6 @@
from .room_create_params import RoomCreateParams as RoomCreateParams
from .room_update_params import RoomUpdateParams as RoomUpdateParams
from .transport_protocol import TransportProtocol as TransportProtocol
-from .uac_outbound_param import UacOutboundParam as UacOutboundParam
from .video_region_param import VideoRegionParam as VideoRegionParam
from .wireless_blocklist import WirelessBlocklist as WirelessBlocklist
from .address_list_params import AddressListParams as AddressListParams
@@ -194,6 +190,8 @@
from .call_siprec_stopped import CallSiprecStopped as CallSiprecStopped
from .comment_list_params import CommentListParams as CommentListParams
from .credential_outbound import CredentialOutbound as CredentialOutbound
+from .dir_submit_response import DirSubmitResponse as DirSubmitResponse
+from .dir_update_response import DirUpdateResponse as DirUpdateResponse
from .external_connection import ExternalConnection as ExternalConnection
from .fax_create_response import FaxCreateResponse as FaxCreateResponse
from .fax_media_processed import FaxMediaProcessed as FaxMediaProcessed
@@ -254,6 +252,7 @@
from .comment_create_params import CommentCreateParams as CommentCreateParams
from .comment_list_response import CommentListResponse as CommentListResponse
from .credential_connection import CredentialConnection as CredentialConnection
+from .dir_retrieve_response import DirRetrieveResponse as DirRetrieveResponse
from .fax_retrieve_response import FaxRetrieveResponse as FaxRetrieveResponse
from .global_ip_list_params import GlobalIPListParams as GlobalIPListParams
from .invoice_list_response import InvoiceListResponse as InvoiceListResponse
@@ -272,8 +271,6 @@
from .recording_list_params import RecordingListParams as RecordingListParams
from .reserved_phone_number import ReservedPhoneNumber as ReservedPhoneNumber
from .s3_configuration_data import S3ConfigurationData as S3ConfigurationData
-from .uac_external_settings import UacExternalSettings as UacExternalSettings
-from .uac_internal_settings import UacInternalSettings as UacInternalSettings
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
@@ -315,6 +312,7 @@
from .call_conversation_ended import CallConversationEnded as CallConversationEnded
from .call_cost_webhook_event import CallCostWebhookEvent as CallCostWebhookEvent
from .call_hold_webhook_event import CallHoldWebhookEvent as CallHoldWebhookEvent
+from .call_reason_list_params import CallReasonListParams as CallReasonListParams
from .comment_create_response import CommentCreateResponse as CommentCreateResponse
from .custom_sip_header_param import CustomSipHeaderParam as CustomSipHeaderParam
from .customer_service_record import CustomerServiceRecord as CustomerServiceRecord
@@ -380,12 +378,12 @@
from .user_address_list_params import UserAddressListParams as UserAddressListParams
from .voice_design_list_params import VoiceDesignListParams as VoiceDesignListParams
from .whatsapp_message_content import WhatsappMessageContent as WhatsappMessageContent
-from .wireguard_interface_read import WireguardInterfaceRead as WireguardInterfaceRead
from .address_retrieve_response import AddressRetrieveResponse as AddressRetrieveResponse
from .audit_event_list_response import AuditEventListResponse as AuditEventListResponse
from .balance_retrieve_response import BalanceRetrieveResponse as BalanceRetrieveResponse
from .billing_group_list_params import BillingGroupListParams as BillingGroupListParams
from .call_hangup_webhook_event import CallHangupWebhookEvent as CallHangupWebhookEvent
+from .call_reason_list_response import CallReasonListResponse as CallReasonListResponse
from .call_unhold_webhook_event import CallUnholdWebhookEvent as CallUnholdWebhookEvent
from .comment_retrieve_response import CommentRetrieveResponse as CommentRetrieveResponse
from .conference_playback_ended import ConferencePlaybackEnded as ConferencePlaybackEnded
@@ -458,6 +456,7 @@
from .call_answered_webhook_event import CallAnsweredWebhookEvent as CallAnsweredWebhookEvent
from .call_enqueued_webhook_event import CallEnqueuedWebhookEvent as CallEnqueuedWebhookEvent
from .call_machine_greeting_ended import CallMachineGreetingEnded as CallMachineGreetingEnded
+from .call_reason_validate_params import CallReasonValidateParams as CallReasonValidateParams
from .conference_participant_left import ConferenceParticipantLeft as ConferenceParticipantLeft
from .conference_playback_started import ConferencePlaybackStarted as ConferencePlaybackStarted
from .detail_record_list_response import DetailRecordListResponse as DetailRecordListResponse
@@ -478,8 +477,6 @@
from .reserved_phone_number_param import ReservedPhoneNumberParam as ReservedPhoneNumberParam
from .s3_configuration_data_param import S3ConfigurationDataParam as S3ConfigurationDataParam
from .transcription_webhook_event import TranscriptionWebhookEvent as TranscriptionWebhookEvent
-from .uac_external_settings_param import UacExternalSettingsParam as UacExternalSettingsParam
-from .uac_internal_settings_param import UacInternalSettingsParam as UacInternalSettingsParam
from .unsafe_unwrap_webhook_event import UnsafeUnwrapWebhookEvent as UnsafeUnwrapWebhookEvent
from .verified_number_list_params import VerifiedNumberListParams as VerifiedNumberListParams
from .voice_clone_create_response import VoiceCloneCreateResponse as VoiceCloneCreateResponse
@@ -511,7 +508,6 @@
from .porting_order_end_user_admin import PortingOrderEndUserAdmin as PortingOrderEndUserAdmin
from .porting_order_end_user_param import PortingOrderEndUserParam as PortingOrderEndUserParam
from .portout_update_status_params import PortoutUpdateStatusParams as PortoutUpdateStatusParams
-from .public_internet_gateway_read import PublicInternetGatewayRead as PublicInternetGatewayRead
from .requirement_type_list_params import RequirementTypeListParams as RequirementTypeListParams
from .room_composition_list_params import RoomCompositionListParams as RoomCompositionListParams
from .room_participant_list_params import RoomParticipantListParams as RoomParticipantListParams
@@ -523,6 +519,7 @@
from .sim_card_order_create_params import SimCardOrderCreateParams as SimCardOrderCreateParams
from .sub_number_order_list_params import SubNumberOrderListParams as SubNumberOrderListParams
from .uac_connection_create_params import UacConnectionCreateParams as UacConnectionCreateParams
+from .uac_connection_list_response import UacConnectionListResponse as UacConnectionListResponse
from .uac_connection_update_params import UacConnectionUpdateParams as UacConnectionUpdateParams
from .url_shortener_settings_param import URLShortenerSettingsParam as URLShortenerSettingsParam
from .user_address_create_response import UserAddressCreateResponse as UserAddressCreateResponse
@@ -543,6 +540,7 @@
from .billing_group_delete_response import BillingGroupDeleteResponse as BillingGroupDeleteResponse
from .billing_group_update_response import BillingGroupUpdateResponse as BillingGroupUpdateResponse
from .call_left_queue_webhook_event import CallLeftQueueWebhookEvent as CallLeftQueueWebhookEvent
+from .call_reason_validate_response import CallReasonValidateResponse as CallReasonValidateResponse
from .call_retrieve_status_response import CallRetrieveStatusResponse as CallRetrieveStatusResponse
from .comment_mark_as_read_response import CommentMarkAsReadResponse as CommentMarkAsReadResponse
from .conference_participant_joined import ConferenceParticipantJoined as ConferenceParticipantJoined
@@ -586,6 +584,7 @@
from .call_speak_ended_webhook_event import CallSpeakEndedWebhookEvent as CallSpeakEndedWebhookEvent
from .conference_ended_webhook_event import ConferenceEndedWebhookEvent as ConferenceEndedWebhookEvent
from .connection_rtcp_settings_param import ConnectionRtcpSettingsParam as ConnectionRtcpSettingsParam
+from .dir_update_infringement_params import DirUpdateInfringementParams as DirUpdateInfringementParams
from .integration_secret_list_params import IntegrationSecretListParams as IntegrationSecretListParams
from .inventory_coverage_list_params import InventoryCoverageListParams as InventoryCoverageListParams
from .list_retrieve_by_zone_response import ListRetrieveByZoneResponse as ListRetrieveByZoneResponse
@@ -615,13 +614,13 @@
from .siprec_connector_update_params import SiprecConnectorUpdateParams as SiprecConnectorUpdateParams
from .sub_number_order_list_response import SubNumberOrderListResponse as SubNumberOrderListResponse
from .sub_number_order_update_params import SubNumberOrderUpdateParams as SubNumberOrderUpdateParams
+from .terms_of_service_status_params import TermsOfServiceStatusParams as TermsOfServiceStatusParams
from .text_to_speech_generate_params import TextToSpeechGenerateParams as TextToSpeechGenerateParams
from .uac_connection_create_response import UacConnectionCreateResponse as UacConnectionCreateResponse
from .uac_connection_delete_response import UacConnectionDeleteResponse as UacConnectionDeleteResponse
from .uac_connection_update_response import UacConnectionUpdateResponse as UacConnectionUpdateResponse
from .user_address_retrieve_response import UserAddressRetrieveResponse as UserAddressRetrieveResponse
from .verification_retrieve_response import VerificationRetrieveResponse as VerificationRetrieveResponse
-from .virtual_cross_connect_combined import VirtualCrossConnectCombined as VirtualCrossConnectCombined
from .voice_design_retrieve_response import VoiceDesignRetrieveResponse as VoiceDesignRetrieveResponse
from .webhook_delivery_list_response import WebhookDeliveryListResponse as WebhookDeliveryListResponse
from .whatsapp_message_content_param import WhatsappMessageContentParam as WhatsappMessageContentParam
@@ -682,6 +681,8 @@
from .call_siprec_failed_webhook_event import CallSiprecFailedWebhookEvent as CallSiprecFailedWebhookEvent
from .call_speak_started_webhook_event import CallSpeakStartedWebhookEvent as CallSpeakStartedWebhookEvent
from .conference_created_webhook_event import ConferenceCreatedWebhookEvent as ConferenceCreatedWebhookEvent
+from .dir_list_document_types_response import DirListDocumentTypesResponse as DirListDocumentTypesResponse
+from .dir_update_infringement_response import DirUpdateInfringementResponse as DirUpdateInfringementResponse
from .global_ip_assignment_list_params import GlobalIPAssignmentListParams as GlobalIPAssignmentListParams
from .global_ip_protocol_list_response import GlobalIPProtocolListResponse as GlobalIPProtocolListResponse
from .inexplicit_number_order_response import InexplicitNumberOrderResponse as InexplicitNumberOrderResponse
@@ -712,6 +713,7 @@
from .sub_number_order_retrieve_params import SubNumberOrderRetrieveParams as SubNumberOrderRetrieveParams
from .sub_number_order_update_response import SubNumberOrderUpdateResponse as SubNumberOrderUpdateResponse
from .telephony_credential_list_params import TelephonyCredentialListParams as TelephonyCredentialListParams
+from .terms_of_service_status_response import TermsOfServiceStatusResponse as TermsOfServiceStatusResponse
from .text_to_speech_generate_response import TextToSpeechGenerateResponse as TextToSpeechGenerateResponse
from .uac_connection_retrieve_response import UacConnectionRetrieveResponse as UacConnectionRetrieveResponse
from .verification_trigger_call_params import VerificationTriggerCallParams as VerificationTriggerCallParams
@@ -732,6 +734,7 @@
from .fqdn_connection_retrieve_response import FqdnConnectionRetrieveResponse as FqdnConnectionRetrieveResponse
from .global_ip_latency_retrieve_params import GlobalIPLatencyRetrieveParams as GlobalIPLatencyRetrieveParams
from .global_ip_usage_retrieve_response import GlobalIPUsageRetrieveResponse as GlobalIPUsageRetrieveResponse
+from .infringement_claim_contest_params import InfringementClaimContestParams as InfringementClaimContestParams
from .managed_account_retrieve_response import ManagedAccountRetrieveResponse as ManagedAccountRetrieveResponse
from .message_cancel_scheduled_response import MessageCancelScheduledResponse as MessageCancelScheduledResponse
from .message_send_number_pool_response import MessageSendNumberPoolResponse as MessageSendNumberPoolResponse
@@ -753,6 +756,7 @@
from .virtual_cross_connect_list_params import VirtualCrossConnectListParams as VirtualCrossConnectListParams
from .voice_sdk_call_report_list_params import VoiceSDKCallReportListParams as VoiceSDKCallReportListParams
from .wireguard_interface_create_params import WireguardInterfaceCreateParams as WireguardInterfaceCreateParams
+from .wireguard_interface_list_response import WireguardInterfaceListResponse as WireguardInterfaceListResponse
from .alphanumeric_sender_id_list_params import AlphanumericSenderIDListParams as AlphanumericSenderIDListParams
from .available_phone_number_list_params import AvailablePhoneNumberListParams as AvailablePhoneNumberListParams
from .bulk_sim_card_action_list_response import BulkSimCardActionListResponse as BulkSimCardActionListResponse
@@ -807,11 +811,13 @@
from .customer_service_record_list_params import CustomerServiceRecordListParams as CustomerServiceRecordListParams
from .dialogflow_connection_create_params import DialogflowConnectionCreateParams as DialogflowConnectionCreateParams
from .dialogflow_connection_update_params import DialogflowConnectionUpdateParams as DialogflowConnectionUpdateParams
+from .dir_list_infringement_claims_params import DirListInfringementClaimsParams as DirListInfringementClaimsParams
from .external_connection_create_response import ExternalConnectionCreateResponse as ExternalConnectionCreateResponse
from .external_connection_delete_response import ExternalConnectionDeleteResponse as ExternalConnectionDeleteResponse
from .external_connection_update_response import ExternalConnectionUpdateResponse as ExternalConnectionUpdateResponse
from .global_ip_latency_retrieve_response import GlobalIPLatencyRetrieveResponse as GlobalIPLatencyRetrieveResponse
from .inexplicit_number_order_list_params import InexplicitNumberOrderListParams as InexplicitNumberOrderListParams
+from .infringement_claim_contest_response import InfringementClaimContestResponse as InfringementClaimContestResponse
from .messaging_hosted_number_list_params import MessagingHostedNumberListParams as MessagingHostedNumberListParams
from .messaging_profile_retrieve_response import MessagingProfileRetrieveResponse as MessagingProfileRetrieveResponse
from .mobile_network_operator_list_params import MobileNetworkOperatorListParams as MobileNetworkOperatorListParams
@@ -826,6 +832,7 @@
from .text_to_speech_list_voices_response import TextToSpeechListVoicesResponse as TextToSpeechListVoicesResponse
from .update_regulatory_requirement_param import UpdateRegulatoryRequirementParam as UpdateRegulatoryRequirementParam
from .virtual_cross_connect_create_params import VirtualCrossConnectCreateParams as VirtualCrossConnectCreateParams
+from .virtual_cross_connect_list_response import VirtualCrossConnectListResponse as VirtualCrossConnectListResponse
from .virtual_cross_connect_update_params import VirtualCrossConnectUpdateParams as VirtualCrossConnectUpdateParams
from .voice_design_download_sample_params import VoiceDesignDownloadSampleParams as VoiceDesignDownloadSampleParams
from .voice_sdk_call_report_list_response import VoiceSDKCallReportListResponse as VoiceSDKCallReportListResponse
@@ -848,6 +855,7 @@
from .global_ip_assignment_update_response import GlobalIPAssignmentUpdateResponse as GlobalIPAssignmentUpdateResponse
from .global_ip_health_check_create_params import GlobalIPHealthCheckCreateParams as GlobalIPHealthCheckCreateParams
from .global_ip_health_check_list_response import GlobalIPHealthCheckListResponse as GlobalIPHealthCheckListResponse
+from .infringement_claim_retrieve_response import InfringementClaimRetrieveResponse as InfringementClaimRetrieveResponse
from .messaging_profile_metric_list_params import MessagingProfileMetricListParams as MessagingProfileMetricListParams
from .mobile_push_credential_create_params import MobilePushCredentialCreateParams as MobilePushCredentialCreateParams
from .notification_channel_create_response import NotificationChannelCreateResponse as NotificationChannelCreateResponse
@@ -909,6 +917,9 @@
from .dialogflow_connection_update_response import (
DialogflowConnectionUpdateResponse as DialogflowConnectionUpdateResponse,
)
+from .dir_list_infringement_claims_response import (
+ DirListInfringementClaimsResponse as DirListInfringementClaimsResponse,
+)
from .dynamic_emergency_address_list_params import (
DynamicEmergencyAddressListParams as DynamicEmergencyAddressListParams,
)
@@ -944,6 +955,9 @@
from .public_internet_gateway_create_params import (
PublicInternetGatewayCreateParams as PublicInternetGatewayCreateParams,
)
+from .public_internet_gateway_list_response import (
+ PublicInternetGatewayListResponse as PublicInternetGatewayListResponse,
+)
from .sim_card_get_activation_code_response import SimCardGetActivationCodeResponse as SimCardGetActivationCodeResponse
from .sim_card_order_preview_preview_params import SimCardOrderPreviewPreviewParams as SimCardOrderPreviewPreviewParams
from .verification_trigger_flashcall_params import (
@@ -1388,6 +1402,9 @@
from .dynamic_emergency_endpoint_retrieve_response import (
DynamicEmergencyEndpointRetrieveResponse as DynamicEmergencyEndpointRetrieveResponse,
)
+from .enterprise_activate_branded_calling_response import (
+ EnterpriseActivateBrandedCallingResponse as EnterpriseActivateBrandedCallingResponse,
+)
from .external_connection_update_location_response import (
ExternalConnectionUpdateLocationResponse as ExternalConnectionUpdateLocationResponse,
)
diff --git a/src/telnyx/types/ai/__init__.py b/src/telnyx/types/ai/__init__.py
index 6f72480c..9b9fb7e8 100644
--- a/src/telnyx/types/ai/__init__.py
+++ b/src/telnyx/types/ai/__init__.py
@@ -5,7 +5,6 @@
from .bucket_ids import BucketIDs as BucketIDs
from .hangup_tool import HangupTool as HangupTool
from .conversation import Conversation as Conversation
-from .external_llm import ExternalLlm as ExternalLlm
from .mission_data import MissionData as MissionData
from .observability import Observability as Observability
from .assistant_tool import AssistantTool as AssistantTool
@@ -13,7 +12,6 @@
from .voice_settings import VoiceSettings as VoiceSettings
from .assistant_param import AssistantParam as AssistantParam
from .assistants_list import AssistantsList as AssistantsList
-from .fallback_config import FallbackConfig as FallbackConfig
from .import_metadata import ImportMetadata as ImportMetadata
from .widget_settings import WidgetSettings as WidgetSettings
from .bucket_ids_param import BucketIDsParam as BucketIDsParam
@@ -34,9 +32,7 @@
from .cluster_list_params import ClusterListParams as ClusterListParams
from .inference_embedding import InferenceEmbedding as InferenceEmbedding
from .mission_list_params import MissionListParams as MissionListParams
-from .start_speaking_plan import StartSpeakingPlan as StartSpeakingPlan
from .transfer_tool_param import TransferToolParam as TransferToolParam
-from .assistant_mcp_server import AssistantMcpServer as AssistantMcpServer
from .assistant_tool_param import AssistantToolParam as AssistantToolParam
from .embedding_url_params import EmbeddingURLParams as EmbeddingURLParams
from .retrieval_tool_param import RetrievalToolParam as RetrievalToolParam
@@ -44,14 +40,12 @@
from .tool_update_response import ToolUpdateResponse as ToolUpdateResponse
from .voice_settings_param import VoiceSettingsParam as VoiceSettingsParam
from .assistant_chat_params import AssistantChatParams as AssistantChatParams
-from .assistant_integration import AssistantIntegration as AssistantIntegration
from .cluster_list_response import ClusterListResponse as ClusterListResponse
from .embedding_list_params import EmbeddingListParams as EmbeddingListParams
from .mission_create_params import MissionCreateParams as MissionCreateParams
from .widget_settings_param import WidgetSettingsParam as WidgetSettingsParam
from .background_task_status import BackgroundTaskStatus as BackgroundTaskStatus
from .cluster_compute_params import ClusterComputeParams as ClusterComputeParams
-from .external_llm_req_param import ExternalLlmReqParam as ExternalLlmReqParam
from .insight_settings_param import InsightSettingsParam as InsightSettingsParam
from .mcp_server_list_params import McpServerListParams as McpServerListParams
from .privacy_settings_param import PrivacySettingsParam as PrivacySettingsParam
@@ -81,11 +75,8 @@
from .assistant_send_sms_params import AssistantSendSMSParams as AssistantSendSMSParams
from .audio_transcribe_response import AudioTranscribeResponse as AudioTranscribeResponse
from .cluster_retrieve_response import ClusterRetrieveResponse as ClusterRetrieveResponse
-from .fallback_config_req_param import FallbackConfigReqParam as FallbackConfigReqParam
from .integration_list_response import IntegrationListResponse as IntegrationListResponse
from .mission_retrieve_response import MissionRetrieveResponse as MissionRetrieveResponse
-from .start_speaking_plan_param import StartSpeakingPlanParam as StartSpeakingPlanParam
-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
from .conversation_list_response import ConversationListResponse as ConversationListResponse
@@ -93,8 +84,6 @@
from .mcp_server_create_response import McpServerCreateResponse as McpServerCreateResponse
from .mcp_server_update_response import McpServerUpdateResponse as McpServerUpdateResponse
from .mission_list_events_params import MissionListEventsParams as MissionListEventsParams
-from .post_conversation_settings import PostConversationSettings as PostConversationSettings
-from .assistant_integration_param import AssistantIntegrationParam as AssistantIntegrationParam
from .assistant_send_sms_response import AssistantSendSMSResponse as AssistantSendSMSResponse
from .embedding_retrieve_response import EmbeddingRetrieveResponse as EmbeddingRetrieveResponse
from .openai_list_models_response import OpenAIListModelsResponse as OpenAIListModelsResponse
@@ -109,7 +98,6 @@
from .openai_create_response_params import OpenAICreateResponseParams as OpenAICreateResponseParams
from .transcription_settings_config import TranscriptionSettingsConfig as TranscriptionSettingsConfig
from .conversation_retrieve_response import ConversationRetrieveResponse as ConversationRetrieveResponse
-from .transcription_endpointing_plan import TranscriptionEndpointingPlan as TranscriptionEndpointingPlan
from .chat_create_completion_response import ChatCreateCompletionResponse as ChatCreateCompletionResponse
from .conversation_add_message_params import ConversationAddMessageParams as ConversationAddMessageParams
from .mission_update_mission_response import MissionUpdateMissionResponse as MissionUpdateMissionResponse
@@ -117,20 +105,12 @@
from .embedding_similarity_search_params import EmbeddingSimilaritySearchParams as EmbeddingSimilaritySearchParams
from .transcription_settings_config_param import TranscriptionSettingsConfigParam as TranscriptionSettingsConfigParam
from .embedding_similarity_search_response import EmbeddingSimilaritySearchResponse as EmbeddingSimilaritySearchResponse
-from .post_conversation_settings_req_param import PostConversationSettingsReqParam as PostConversationSettingsReqParam
-from .transcription_endpointing_plan_param import TranscriptionEndpointingPlanParam as TranscriptionEndpointingPlanParam
from .inference_embedding_webhook_tool_params import (
InferenceEmbeddingWebhookToolParams as InferenceEmbeddingWebhookToolParams,
)
-from .inference_embedding_interruption_settings import (
- InferenceEmbeddingInterruptionSettings as InferenceEmbeddingInterruptionSettings,
-)
from .inference_embedding_webhook_tool_params_param import (
InferenceEmbeddingWebhookToolParamsParam as InferenceEmbeddingWebhookToolParamsParam,
)
-from .inference_embedding_interruption_settings_param import (
- InferenceEmbeddingInterruptionSettingsParam as InferenceEmbeddingInterruptionSettingsParam,
-)
from .conversation_retrieve_conversations_insights_response import (
ConversationRetrieveConversationsInsightsResponse as ConversationRetrieveConversationsInsightsResponse,
)
diff --git a/src/telnyx/types/ai/assistant_create_params.py b/src/telnyx/types/ai/assistant_create_params.py
index 656a379e..bebde025 100644
--- a/src/telnyx/types/ai/assistant_create_params.py
+++ b/src/telnyx/types/ai/assistant_create_params.py
@@ -10,24 +10,19 @@
from .assistant_tool_param import AssistantToolParam
from .voice_settings_param import VoiceSettingsParam
from .widget_settings_param import WidgetSettingsParam
-from .external_llm_req_param import ExternalLlmReqParam
from .insight_settings_param import InsightSettingsParam
from .privacy_settings_param import PrivacySettingsParam
from .observability_req_param import ObservabilityReqParam
from .messaging_settings_param import MessagingSettingsParam
from .telephony_settings_param import TelephonySettingsParam
-from .fallback_config_req_param import FallbackConfigReqParam
-from .assistant_mcp_server_param import AssistantMcpServerParam
-from .assistant_integration_param import AssistantIntegrationParam
from .transcription_settings_param import TranscriptionSettingsParam
-from .post_conversation_settings_req_param import PostConversationSettingsReqParam
-from .inference_embedding_interruption_settings_param import InferenceEmbeddingInterruptionSettingsParam
__all__ = [
"AssistantCreateParams",
"ConversationFlow",
"ConversationFlowNode",
"ConversationFlowNodeFlowNodeReq",
+ "ConversationFlowNodeFlowNodeReqExternalLlm",
"ConversationFlowNodeFlowNodeReqPosition",
"ConversationFlowNodeToolNodeReq",
"ConversationFlowNodeToolNodeReqPosition",
@@ -47,6 +42,15 @@
"ConversationFlowEdgeTargetNodeTarget",
"ConversationFlowEdgeTargetAssistantTarget",
"ConversationFlowEdgeTargetAssistantTargetPosition",
+ "ExternalLlm",
+ "FallbackConfig",
+ "FallbackConfigExternalLlm",
+ "Integration",
+ "InterruptionSettings",
+ "InterruptionSettingsStartSpeakingPlan",
+ "InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan",
+ "McpServer",
+ "PostConversationSettings",
]
@@ -95,9 +99,9 @@ class AssistantCreateParams(TypedDict, total=False):
enabled_features: List[EnabledFeatures]
- external_llm: ExternalLlmReqParam
+ external_llm: ExternalLlm
- fallback_config: FallbackConfigReqParam
+ fallback_config: FallbackConfig
greeting: str
"""Text that the assistant will use to start the conversation.
@@ -111,7 +115,7 @@ class AssistantCreateParams(TypedDict, total=False):
insight_settings: InsightSettingsParam
- integrations: Iterable[AssistantIntegrationParam]
+ integrations: Iterable[Integration]
"""Connected integrations attached to the assistant.
The catalog of available integrations is at `/ai/integrations`; the user's
@@ -119,7 +123,7 @@ class AssistantCreateParams(TypedDict, total=False):
references a catalog integration by `integration_id`.
"""
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam
+ interruption_settings: InterruptionSettings
"""
Settings for interruptions and how the assistant decides the user has finished
speaking. These timings are most relevant when using non turn-taking
@@ -139,7 +143,7 @@ class AssistantCreateParams(TypedDict, total=False):
are unlikely to work with this integration.
"""
- mcp_servers: Iterable[AssistantMcpServerParam]
+ mcp_servers: Iterable[McpServer]
"""MCP servers attached to the assistant.
Create MCP servers with `/ai/mcp_servers`, then reference them by `id` here.
@@ -159,7 +163,7 @@ class AssistantCreateParams(TypedDict, total=False):
observability_settings: ObservabilityReqParam
- post_conversation_settings: PostConversationSettingsReqParam
+ post_conversation_settings: PostConversationSettings
"""Configuration for post-conversation processing.
When enabled, the assistant receives one additional LLM turn after the
@@ -200,6 +204,47 @@ class AssistantCreateParams(TypedDict, total=False):
"""Configuration settings for the assistant's web widget."""
+class ConversationFlowNodeFlowNodeReqExternalLlm(TypedDict, total=False):
+ """Override for `Assistant.external_llm` while this node is active.
+
+ Use this to route a node's turns to a different external LLM (different `model`, `base_url`, credentials). Part of the LLM bundle — see `model` for cascade semantics. Mutually exclusive with `model` on the node (a single LLM identity per node).
+ """
+
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
class ConversationFlowNodeFlowNodeReqPosition(TypedDict, total=False):
"""Optional canvas coordinates used by authoring UIs to lay out the graph.
@@ -226,7 +271,7 @@ class ConversationFlowNodeFlowNodeReq(TypedDict, total=False):
instructions: Required[str]
"""Prompt that drives the LLM while this node is active. Required."""
- external_llm: ExternalLlmReqParam
+ external_llm: ConversationFlowNodeFlowNodeReqExternalLlm
"""Override for `Assistant.external_llm` while this node is active.
Use this to route a node's turns to a different external LLM (different `model`,
@@ -627,3 +672,199 @@ class ConversationFlow(TypedDict, total=False):
edges: Iterable[ConversationFlowEdge]
"""Directed transitions between nodes. May be empty for a single-node flow."""
+
+
+class ExternalLlm(TypedDict, total=False):
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
+class FallbackConfigExternalLlm(TypedDict, total=False):
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
+class FallbackConfig(TypedDict, total=False):
+ external_llm: FallbackConfigExternalLlm
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the fallback model API key."""
+
+ model: str
+ """
+ Fallback Telnyx-hosted model to use when the primary LLM provider is
+ unavailable.
+ """
+
+
+class Integration(TypedDict, total=False):
+ """Reference to a connected integration attached to an assistant.
+
+ Discover available integrations with `/ai/integrations` and connected integrations with `/ai/integrations/connections`.
+ """
+
+ integration_id: Required[str]
+ """Catalog integration ID to attach.
+
+ This is the `id` from the integrations catalog at `/ai/integrations` (the same
+ value also appears as `integration_id` on entries returned by
+ `/ai/integrations/connections`). It is **not** the connection-level `id` from
+ `/ai/integrations/connections`.
+ """
+
+ allowed_list: SequenceNotStr[str]
+ """Optional per-assistant allowlist of integration tool names.
+
+ When omitted or empty, all tools allowed by the connected integration are
+ available to the assistant.
+ """
+
+
+class InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan(TypedDict, total=False):
+ """Endpointing thresholds used to decide when the user has finished speaking.
+
+ Applies to non turn-taking transcription models. For `deepgram/flux`, use `transcription.settings.eot_threshold` / `eot_timeout_ms` / `eager_eot_threshold`.
+ """
+
+ on_no_punctuation_seconds: float
+ """Seconds to wait after the transcript ends without punctuation."""
+
+ on_number_seconds: float
+ """Seconds to wait after the transcript ends with a number."""
+
+ on_punctuation_seconds: float
+ """Seconds to wait after the transcript ends with punctuation."""
+
+
+class InterruptionSettingsStartSpeakingPlan(TypedDict, total=False):
+ """Controls when the assistant starts speaking after the user stops.
+
+ These thresholds primarily apply to non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the transcription end-of-turn settings under `transcription.settings` instead.
+ """
+
+ transcription_endpointing_plan: InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan
+ """Endpointing thresholds used to decide when the user has finished speaking.
+
+ Applies to non turn-taking transcription models. For `deepgram/flux`, use
+ `transcription.settings.eot_threshold` / `eot_timeout_ms` /
+ `eager_eot_threshold`.
+ """
+
+ wait_seconds: float
+ """Minimum seconds to wait before the assistant starts speaking."""
+
+
+class InterruptionSettings(TypedDict, total=False):
+ """
+ Settings for interruptions and how the assistant decides the user has finished speaking. These timings are most relevant when using non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn behavior is controlled by the transcription end-of-turn settings under `transcription.settings` (`eot_threshold`, `eot_timeout_ms`, `eager_eot_threshold`).
+ """
+
+ disable_greeting_interruption: bool
+ """When true, disables user interruptions while the assistant greeting is playing."""
+
+ enable: bool
+ """Whether users can interrupt the assistant while it is speaking."""
+
+ start_speaking_plan: InterruptionSettingsStartSpeakingPlan
+ """Controls when the assistant starts speaking after the user stops.
+
+ These thresholds primarily apply to non turn-taking transcription models. For
+ turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the
+ transcription end-of-turn settings under `transcription.settings` instead.
+ """
+
+
+class McpServer(TypedDict, total=False):
+ """Reference to an MCP server attached to an assistant.
+
+ Create and manage MCP servers with the `/ai/mcp_servers` endpoints, then attach them to assistants by ID.
+ """
+
+ id: Required[str]
+ """ID of the MCP server to attach.
+
+ This must be the `id` of an MCP server returned by the `/ai/mcp_servers`
+ endpoints.
+ """
+
+ allowed_tools: SequenceNotStr[str]
+ """Optional per-assistant allowlist of MCP tool names.
+
+ When omitted, the assistant uses the MCP server's configured `allowed_tools`.
+ """
+
+
+class PostConversationSettings(TypedDict, total=False):
+ """Configuration for post-conversation processing.
+
+ When enabled, the assistant receives one additional LLM turn after the conversation ends, allowing it to execute tool calls such as logging to a CRM or sending a summary. The assistant can execute multiple parallel or sequential tools during this phase. Telephony-control tools (e.g. hangup, transfer) are unavailable post-conversation. Beta feature.
+ """
+
+ enabled: bool
+ """Whether post-conversation processing is enabled.
+
+ When true, the assistant will be invoked after the conversation ends to perform
+ any final tool calls. Defaults to false.
+ """
diff --git a/src/telnyx/types/ai/assistant_integration.py b/src/telnyx/types/ai/assistant_integration.py
deleted file mode 100644
index f686769d..00000000
--- a/src/telnyx/types/ai/assistant_integration.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-
-from ..._models import BaseModel
-
-__all__ = ["AssistantIntegration"]
-
-
-class AssistantIntegration(BaseModel):
- """Reference to a connected integration attached to an assistant.
-
- Discover available integrations with `/ai/integrations` and connected integrations with `/ai/integrations/connections`.
- """
-
- integration_id: str
- """Catalog integration ID to attach.
-
- This is the `id` from the integrations catalog at `/ai/integrations` (the same
- value also appears as `integration_id` on entries returned by
- `/ai/integrations/connections`). It is **not** the connection-level `id` from
- `/ai/integrations/connections`.
- """
-
- allowed_list: Optional[List[str]] = None
- """Optional per-assistant allowlist of integration tool names.
-
- When omitted or empty, all tools allowed by the connected integration are
- available to the assistant.
- """
diff --git a/src/telnyx/types/ai/assistant_integration_param.py b/src/telnyx/types/ai/assistant_integration_param.py
deleted file mode 100644
index 9f8e9a70..00000000
--- a/src/telnyx/types/ai/assistant_integration_param.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-from ..._types import SequenceNotStr
-
-__all__ = ["AssistantIntegrationParam"]
-
-
-class AssistantIntegrationParam(TypedDict, total=False):
- """Reference to a connected integration attached to an assistant.
-
- Discover available integrations with `/ai/integrations` and connected integrations with `/ai/integrations/connections`.
- """
-
- integration_id: Required[str]
- """Catalog integration ID to attach.
-
- This is the `id` from the integrations catalog at `/ai/integrations` (the same
- value also appears as `integration_id` on entries returned by
- `/ai/integrations/connections`). It is **not** the connection-level `id` from
- `/ai/integrations/connections`.
- """
-
- allowed_list: SequenceNotStr[str]
- """Optional per-assistant allowlist of integration tool names.
-
- When omitted or empty, all tools allowed by the connected integration are
- available to the assistant.
- """
diff --git a/src/telnyx/types/ai/assistant_mcp_server.py b/src/telnyx/types/ai/assistant_mcp_server.py
deleted file mode 100644
index c12e8217..00000000
--- a/src/telnyx/types/ai/assistant_mcp_server.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-
-from ..._models import BaseModel
-
-__all__ = ["AssistantMcpServer"]
-
-
-class AssistantMcpServer(BaseModel):
- """Reference to an MCP server attached to an assistant.
-
- Create and manage MCP servers with the `/ai/mcp_servers` endpoints, then attach them to assistants by ID.
- """
-
- id: str
- """ID of the MCP server to attach.
-
- This must be the `id` of an MCP server returned by the `/ai/mcp_servers`
- endpoints.
- """
-
- allowed_tools: Optional[List[str]] = None
- """Optional per-assistant allowlist of MCP tool names.
-
- When omitted, the assistant uses the MCP server's configured `allowed_tools`.
- """
diff --git a/src/telnyx/types/ai/assistant_mcp_server_param.py b/src/telnyx/types/ai/assistant_mcp_server_param.py
deleted file mode 100644
index 520d4696..00000000
--- a/src/telnyx/types/ai/assistant_mcp_server_param.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-from ..._types import SequenceNotStr
-
-__all__ = ["AssistantMcpServerParam"]
-
-
-class AssistantMcpServerParam(TypedDict, total=False):
- """Reference to an MCP server attached to an assistant.
-
- Create and manage MCP servers with the `/ai/mcp_servers` endpoints, then attach them to assistants by ID.
- """
-
- id: Required[str]
- """ID of the MCP server to attach.
-
- This must be the `id` of an MCP server returned by the `/ai/mcp_servers`
- endpoints.
- """
-
- allowed_tools: SequenceNotStr[str]
- """Optional per-assistant allowlist of MCP tool names.
-
- When omitted, the assistant uses the MCP server's configured `allowed_tools`.
- """
diff --git a/src/telnyx/types/ai/assistant_tool.py b/src/telnyx/types/ai/assistant_tool.py
index ca0927c8..b9092f3f 100644
--- a/src/telnyx/types/ai/assistant_tool.py
+++ b/src/telnyx/types/ai/assistant_tool.py
@@ -18,7 +18,7 @@
"HandoffHandoffAIAssistant",
"Transfer",
"TransferTransfer",
- "TransferTransferTargetsTargetsList",
+ "TransferTransferTargetsUnionMember0",
"TransferTransferCustomHeader",
"TransferTransferVoicemailDetection",
"TransferTransferVoicemailDetectionDetectionConfig",
@@ -27,7 +27,7 @@
"Invite",
"InviteInvite",
"InviteInviteCustomHeader",
- "InviteInviteTargetsTargetsList",
+ "InviteInviteTargetsUnionMember0",
"InviteInviteVoicemailDetection",
"InviteInviteVoicemailDetectionOnVoicemailDetected",
"Refer",
@@ -74,7 +74,7 @@ class Handoff(BaseModel):
type: Literal["handoff"]
-class TransferTransferTargetsTargetsList(BaseModel):
+class TransferTransferTargetsUnionMember0(BaseModel):
to: str
"""The destination number or SIP URI of the call."""
@@ -200,7 +200,7 @@ class TransferTransfer(BaseModel):
from_: str = FieldInfo(alias="from")
"""Number or SIP URI placing the call."""
- targets: Union[List[TransferTransferTargetsTargetsList], str]
+ targets: Union[List[TransferTransferTargetsUnionMember0], str]
"""The different possible targets of the transfer.
The assistant will be able to choose one of the targets to transfer the call to.
@@ -261,7 +261,7 @@ class InviteInviteCustomHeader(BaseModel):
"""
-class InviteInviteTargetsTargetsList(BaseModel):
+class InviteInviteTargetsUnionMember0(BaseModel):
to: str
"""The destination number or SIP URI of the call."""
@@ -299,7 +299,7 @@ class InviteInvite(BaseModel):
custom_headers: Optional[List[InviteInviteCustomHeader]] = None
"""Custom headers to be added to the SIP INVITE for the invite command."""
- targets: Union[List[InviteInviteTargetsTargetsList], str, None] = None
+ targets: Union[List[InviteInviteTargetsUnionMember0], str, None] = None
"""The different possible targets of the invite.
The assistant will be able to choose one of the targets to invite to the call.
diff --git a/src/telnyx/types/ai/assistant_tool_param.py b/src/telnyx/types/ai/assistant_tool_param.py
index f2ad8bc6..0cbd6605 100644
--- a/src/telnyx/types/ai/assistant_tool_param.py
+++ b/src/telnyx/types/ai/assistant_tool_param.py
@@ -16,7 +16,7 @@
"HandoffHandoffAIAssistant",
"Transfer",
"TransferTransfer",
- "TransferTransferTargetsTargetsList",
+ "TransferTransferTargetsUnionMember0",
"TransferTransferCustomHeader",
"TransferTransferVoicemailDetection",
"TransferTransferVoicemailDetectionDetectionConfig",
@@ -25,7 +25,7 @@
"Invite",
"InviteInvite",
"InviteInviteCustomHeader",
- "InviteInviteTargetsTargetsList",
+ "InviteInviteTargetsUnionMember0",
"InviteInviteVoicemailDetection",
"InviteInviteVoicemailDetectionOnVoicemailDetected",
"Refer",
@@ -72,7 +72,7 @@ class Handoff(TypedDict, total=False):
type: Required[Literal["handoff"]]
-class TransferTransferTargetsTargetsList(TypedDict, total=False):
+class TransferTransferTargetsUnionMember0(TypedDict, total=False):
to: Required[str]
"""The destination number or SIP URI of the call."""
@@ -204,7 +204,7 @@ class TransferTransferVoicemailDetection(TypedDict, total=False):
class TransferTransfer(_TransferTransferReservedKeywords, total=False):
- targets: Required[Union[Iterable[TransferTransferTargetsTargetsList], str]]
+ targets: Required[Union[Iterable[TransferTransferTargetsUnionMember0], str]]
"""The different possible targets of the transfer.
The assistant will be able to choose one of the targets to transfer the call to.
@@ -265,7 +265,7 @@ class InviteInviteCustomHeader(TypedDict, total=False):
"""
-class InviteInviteTargetsTargetsList(TypedDict, total=False):
+class InviteInviteTargetsUnionMember0(TypedDict, total=False):
to: Required[str]
"""The destination number or SIP URI of the call."""
@@ -309,7 +309,7 @@ class InviteInvite(_InviteInviteReservedKeywords, total=False):
custom_headers: Iterable[InviteInviteCustomHeader]
"""Custom headers to be added to the SIP INVITE for the invite command."""
- targets: Union[Iterable[InviteInviteTargetsTargetsList], str, None]
+ targets: Union[Iterable[InviteInviteTargetsUnionMember0], str, None]
"""The different possible targets of the invite.
The assistant will be able to choose one of the targets to invite to the call.
diff --git a/src/telnyx/types/ai/assistant_update_params.py b/src/telnyx/types/ai/assistant_update_params.py
index 221e0e62..a8ffd1de 100644
--- a/src/telnyx/types/ai/assistant_update_params.py
+++ b/src/telnyx/types/ai/assistant_update_params.py
@@ -10,24 +10,19 @@
from .assistant_tool_param import AssistantToolParam
from .voice_settings_param import VoiceSettingsParam
from .widget_settings_param import WidgetSettingsParam
-from .external_llm_req_param import ExternalLlmReqParam
from .insight_settings_param import InsightSettingsParam
from .privacy_settings_param import PrivacySettingsParam
from .observability_req_param import ObservabilityReqParam
from .messaging_settings_param import MessagingSettingsParam
from .telephony_settings_param import TelephonySettingsParam
-from .fallback_config_req_param import FallbackConfigReqParam
-from .assistant_mcp_server_param import AssistantMcpServerParam
-from .assistant_integration_param import AssistantIntegrationParam
from .transcription_settings_param import TranscriptionSettingsParam
-from .post_conversation_settings_req_param import PostConversationSettingsReqParam
-from .inference_embedding_interruption_settings_param import InferenceEmbeddingInterruptionSettingsParam
__all__ = [
"AssistantUpdateParams",
"ConversationFlow",
"ConversationFlowNode",
"ConversationFlowNodeFlowNodeReq",
+ "ConversationFlowNodeFlowNodeReqExternalLlm",
"ConversationFlowNodeFlowNodeReqPosition",
"ConversationFlowNodeToolNodeReq",
"ConversationFlowNodeToolNodeReqPosition",
@@ -47,6 +42,15 @@
"ConversationFlowEdgeTargetNodeTarget",
"ConversationFlowEdgeTargetAssistantTarget",
"ConversationFlowEdgeTargetAssistantTargetPosition",
+ "ExternalLlm",
+ "FallbackConfig",
+ "FallbackConfigExternalLlm",
+ "Integration",
+ "InterruptionSettings",
+ "InterruptionSettingsStartSpeakingPlan",
+ "InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan",
+ "McpServer",
+ "PostConversationSettings",
]
@@ -86,9 +90,9 @@ class AssistantUpdateParams(TypedDict, total=False):
enabled_features: List[EnabledFeatures]
- external_llm: ExternalLlmReqParam
+ external_llm: ExternalLlm
- fallback_config: FallbackConfigReqParam
+ fallback_config: FallbackConfig
greeting: str
"""Text that the assistant will use to start the conversation.
@@ -109,7 +113,7 @@ class AssistantUpdateParams(TypedDict, total=False):
[dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables)
"""
- integrations: Iterable[AssistantIntegrationParam]
+ integrations: Iterable[Integration]
"""Connected integrations attached to the assistant.
The catalog of available integrations is at `/ai/integrations`; the user's
@@ -117,7 +121,7 @@ class AssistantUpdateParams(TypedDict, total=False):
references a catalog integration by `integration_id`.
"""
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam
+ interruption_settings: InterruptionSettings
"""
Settings for interruptions and how the assistant decides the user has finished
speaking. These timings are most relevant when using non turn-taking
@@ -137,7 +141,7 @@ class AssistantUpdateParams(TypedDict, total=False):
are unlikely to work with this integration.
"""
- mcp_servers: Iterable[AssistantMcpServerParam]
+ mcp_servers: Iterable[McpServer]
"""MCP servers attached to the assistant.
Create MCP servers with `/ai/mcp_servers`, then reference them by `id` here.
@@ -159,7 +163,7 @@ class AssistantUpdateParams(TypedDict, total=False):
observability_settings: ObservabilityReqParam
- post_conversation_settings: PostConversationSettingsReqParam
+ post_conversation_settings: PostConversationSettings
"""Configuration for post-conversation processing.
When enabled, the assistant receives one additional LLM turn after the
@@ -209,6 +213,47 @@ class AssistantUpdateParams(TypedDict, total=False):
"""Configuration settings for the assistant's web widget."""
+class ConversationFlowNodeFlowNodeReqExternalLlm(TypedDict, total=False):
+ """Override for `Assistant.external_llm` while this node is active.
+
+ Use this to route a node's turns to a different external LLM (different `model`, `base_url`, credentials). Part of the LLM bundle — see `model` for cascade semantics. Mutually exclusive with `model` on the node (a single LLM identity per node).
+ """
+
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
class ConversationFlowNodeFlowNodeReqPosition(TypedDict, total=False):
"""Optional canvas coordinates used by authoring UIs to lay out the graph.
@@ -235,7 +280,7 @@ class ConversationFlowNodeFlowNodeReq(TypedDict, total=False):
instructions: Required[str]
"""Prompt that drives the LLM while this node is active. Required."""
- external_llm: ExternalLlmReqParam
+ external_llm: ConversationFlowNodeFlowNodeReqExternalLlm
"""Override for `Assistant.external_llm` while this node is active.
Use this to route a node's turns to a different external LLM (different `model`,
@@ -636,3 +681,199 @@ class ConversationFlow(TypedDict, total=False):
edges: Iterable[ConversationFlowEdge]
"""Directed transitions between nodes. May be empty for a single-node flow."""
+
+
+class ExternalLlm(TypedDict, total=False):
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
+class FallbackConfigExternalLlm(TypedDict, total=False):
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
+class FallbackConfig(TypedDict, total=False):
+ external_llm: FallbackConfigExternalLlm
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the fallback model API key."""
+
+ model: str
+ """
+ Fallback Telnyx-hosted model to use when the primary LLM provider is
+ unavailable.
+ """
+
+
+class Integration(TypedDict, total=False):
+ """Reference to a connected integration attached to an assistant.
+
+ Discover available integrations with `/ai/integrations` and connected integrations with `/ai/integrations/connections`.
+ """
+
+ integration_id: Required[str]
+ """Catalog integration ID to attach.
+
+ This is the `id` from the integrations catalog at `/ai/integrations` (the same
+ value also appears as `integration_id` on entries returned by
+ `/ai/integrations/connections`). It is **not** the connection-level `id` from
+ `/ai/integrations/connections`.
+ """
+
+ allowed_list: SequenceNotStr[str]
+ """Optional per-assistant allowlist of integration tool names.
+
+ When omitted or empty, all tools allowed by the connected integration are
+ available to the assistant.
+ """
+
+
+class InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan(TypedDict, total=False):
+ """Endpointing thresholds used to decide when the user has finished speaking.
+
+ Applies to non turn-taking transcription models. For `deepgram/flux`, use `transcription.settings.eot_threshold` / `eot_timeout_ms` / `eager_eot_threshold`.
+ """
+
+ on_no_punctuation_seconds: float
+ """Seconds to wait after the transcript ends without punctuation."""
+
+ on_number_seconds: float
+ """Seconds to wait after the transcript ends with a number."""
+
+ on_punctuation_seconds: float
+ """Seconds to wait after the transcript ends with punctuation."""
+
+
+class InterruptionSettingsStartSpeakingPlan(TypedDict, total=False):
+ """Controls when the assistant starts speaking after the user stops.
+
+ These thresholds primarily apply to non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the transcription end-of-turn settings under `transcription.settings` instead.
+ """
+
+ transcription_endpointing_plan: InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan
+ """Endpointing thresholds used to decide when the user has finished speaking.
+
+ Applies to non turn-taking transcription models. For `deepgram/flux`, use
+ `transcription.settings.eot_threshold` / `eot_timeout_ms` /
+ `eager_eot_threshold`.
+ """
+
+ wait_seconds: float
+ """Minimum seconds to wait before the assistant starts speaking."""
+
+
+class InterruptionSettings(TypedDict, total=False):
+ """
+ Settings for interruptions and how the assistant decides the user has finished speaking. These timings are most relevant when using non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn behavior is controlled by the transcription end-of-turn settings under `transcription.settings` (`eot_threshold`, `eot_timeout_ms`, `eager_eot_threshold`).
+ """
+
+ disable_greeting_interruption: bool
+ """When true, disables user interruptions while the assistant greeting is playing."""
+
+ enable: bool
+ """Whether users can interrupt the assistant while it is speaking."""
+
+ start_speaking_plan: InterruptionSettingsStartSpeakingPlan
+ """Controls when the assistant starts speaking after the user stops.
+
+ These thresholds primarily apply to non turn-taking transcription models. For
+ turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the
+ transcription end-of-turn settings under `transcription.settings` instead.
+ """
+
+
+class McpServer(TypedDict, total=False):
+ """Reference to an MCP server attached to an assistant.
+
+ Create and manage MCP servers with the `/ai/mcp_servers` endpoints, then attach them to assistants by ID.
+ """
+
+ id: Required[str]
+ """ID of the MCP server to attach.
+
+ This must be the `id` of an MCP server returned by the `/ai/mcp_servers`
+ endpoints.
+ """
+
+ allowed_tools: SequenceNotStr[str]
+ """Optional per-assistant allowlist of MCP tool names.
+
+ When omitted, the assistant uses the MCP server's configured `allowed_tools`.
+ """
+
+
+class PostConversationSettings(TypedDict, total=False):
+ """Configuration for post-conversation processing.
+
+ When enabled, the assistant receives one additional LLM turn after the conversation ends, allowing it to execute tool calls such as logging to a CRM or sending a summary. The assistant can execute multiple parallel or sequential tools during this phase. Telephony-control tools (e.g. hangup, transfer) are unavailable post-conversation. Beta feature.
+ """
+
+ enabled: bool
+ """Whether post-conversation processing is enabled.
+
+ When true, the assistant will be invoked after the conversation ends to perform
+ any final tool calls. Defaults to false.
+ """
diff --git a/src/telnyx/types/ai/assistants/__init__.py b/src/telnyx/types/ai/assistants/__init__.py
index 3e584a53..406ed42f 100644
--- a/src/telnyx/types/ai/assistants/__init__.py
+++ b/src/telnyx/types/ai/assistants/__init__.py
@@ -2,21 +2,13 @@
from __future__ import annotations
-from .serve import Serve as Serve
-from .clause import Clause as Clause
-from .rule_output import RuleOutput as RuleOutput
-from .serve_param import ServeParam as ServeParam
-from .clause_param import ClauseParam as ClauseParam
from .event_status import EventStatus as EventStatus
-from .rollout_slot import RolloutSlot as RolloutSlot
from .assistant_test import AssistantTest as AssistantTest
from .tag_add_params import TagAddParams as TagAddParams
-from .rule_input_param import RuleInputParam as RuleInputParam
from .tag_add_response import TagAddResponse as TagAddResponse
from .test_list_params import TestListParams as TestListParams
from .tool_test_params import ToolTestParams as ToolTestParams
from .tag_list_response import TagListResponse as TagListResponse
-from .rollout_slot_param import RolloutSlotParam as RolloutSlotParam
from .test_create_params import TestCreateParams as TestCreateParams
from .test_update_params import TestUpdateParams as TestUpdateParams
from .tool_test_response import ToolTestResponse as ToolTestResponse
diff --git a/src/telnyx/types/ai/assistants/canary_deploy_create_params.py b/src/telnyx/types/ai/assistants/canary_deploy_create_params.py
index 98f22d12..df481a3f 100644
--- a/src/telnyx/types/ai/assistants/canary_deploy_create_params.py
+++ b/src/telnyx/types/ai/assistants/canary_deploy_create_params.py
@@ -3,12 +3,69 @@
from __future__ import annotations
from typing import Iterable
-from typing_extensions import TypedDict
+from typing_extensions import Literal, Required, TypedDict
-from .rule_input_param import RuleInputParam
+from ...._types import SequenceNotStr
-__all__ = ["CanaryDeployCreateParams"]
+__all__ = ["CanaryDeployCreateParams", "Rule", "RuleServe", "RuleServeRollout", "RuleMatch"]
class CanaryDeployCreateParams(TypedDict, total=False):
- rules: Iterable[RuleInputParam]
+ rules: Iterable[Rule]
+
+
+class RuleServeRollout(TypedDict, total=False):
+ """One slot in a percentage rollout."""
+
+ version_id: Required[str]
+
+ weight: Required[float]
+
+
+class RuleServe(TypedDict, total=False):
+ """What a rule serves when matched.
+
+ Exactly one of:
+ - ``version_id`` — serve a specific version
+ - ``rollout`` — weighted random across versions; weights must sum to
+ less than 100, with the leftover routing to the main version
+ """
+
+ rollout: Iterable[RuleServeRollout]
+
+ version_id: str
+
+
+class RuleMatch(TypedDict, total=False):
+ """A single attribute/operator/values check.
+
+ A clause matches when the routing context's value for ``attribute``
+ satisfies ``operator`` against any of ``values``.
+ """
+
+ attribute: Required[str]
+ """Attribute name from the routing context"""
+
+ operator: Required[Literal["in", "not_in", "starts_with"]]
+ """Match operator"""
+
+ values: Required[SequenceNotStr[str]]
+
+
+class Rule(TypedDict, total=False):
+ """A targeting rule: ``match`` clauses (AND) gate ``serve``.
+
+ An empty ``match`` is a catch-all (always fires).
+ """
+
+ serve: Required[RuleServe]
+ """What a rule serves when matched.
+
+ Exactly one of:
+
+ - `version_id` — serve a specific version
+ - `rollout` — weighted random across versions; weights must sum to less than
+ 100, with the leftover routing to the main version
+ """
+
+ match: Iterable[RuleMatch]
diff --git a/src/telnyx/types/ai/assistants/canary_deploy_response.py b/src/telnyx/types/ai/assistants/canary_deploy_response.py
index 86975189..7c649bbf 100644
--- a/src/telnyx/types/ai/assistants/canary_deploy_response.py
+++ b/src/telnyx/types/ai/assistants/canary_deploy_response.py
@@ -1,12 +1,69 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List
+from typing import List, Optional
from datetime import datetime
+from typing_extensions import Literal
from ...._models import BaseModel
-from .rule_output import RuleOutput
-__all__ = ["CanaryDeployResponse"]
+__all__ = ["CanaryDeployResponse", "Rule", "RuleServe", "RuleServeRollout", "RuleMatch"]
+
+
+class RuleServeRollout(BaseModel):
+ """One slot in a percentage rollout."""
+
+ version_id: str
+
+ weight: float
+
+
+class RuleServe(BaseModel):
+ """What a rule serves when matched.
+
+ Exactly one of:
+ - ``version_id`` — serve a specific version
+ - ``rollout`` — weighted random across versions; weights must sum to
+ less than 100, with the leftover routing to the main version
+ """
+
+ rollout: Optional[List[RuleServeRollout]] = None
+
+ version_id: Optional[str] = None
+
+
+class RuleMatch(BaseModel):
+ """A single attribute/operator/values check.
+
+ A clause matches when the routing context's value for ``attribute``
+ satisfies ``operator`` against any of ``values``.
+ """
+
+ attribute: str
+ """Attribute name from the routing context"""
+
+ operator: Literal["in", "not_in", "starts_with"]
+ """Match operator"""
+
+ values: List[str]
+
+
+class Rule(BaseModel):
+ """A targeting rule: ``match`` clauses (AND) gate ``serve``.
+
+ An empty ``match`` is a catch-all (always fires).
+ """
+
+ serve: RuleServe
+ """What a rule serves when matched.
+
+ Exactly one of:
+
+ - `version_id` — serve a specific version
+ - `rollout` — weighted random across versions; weights must sum to less than
+ 100, with the leftover routing to the main version
+ """
+
+ match: Optional[List[RuleMatch]] = None
class CanaryDeployResponse(BaseModel):
@@ -19,6 +76,6 @@ class CanaryDeployResponse(BaseModel):
created_at: datetime
- rules: List[RuleOutput]
+ rules: List[Rule]
updated_at: datetime
diff --git a/src/telnyx/types/ai/assistants/canary_deploy_update_params.py b/src/telnyx/types/ai/assistants/canary_deploy_update_params.py
index 28148415..c2c4a85f 100644
--- a/src/telnyx/types/ai/assistants/canary_deploy_update_params.py
+++ b/src/telnyx/types/ai/assistants/canary_deploy_update_params.py
@@ -3,12 +3,69 @@
from __future__ import annotations
from typing import Iterable
-from typing_extensions import TypedDict
+from typing_extensions import Literal, Required, TypedDict
-from .rule_input_param import RuleInputParam
+from ...._types import SequenceNotStr
-__all__ = ["CanaryDeployUpdateParams"]
+__all__ = ["CanaryDeployUpdateParams", "Rule", "RuleServe", "RuleServeRollout", "RuleMatch"]
class CanaryDeployUpdateParams(TypedDict, total=False):
- rules: Iterable[RuleInputParam]
+ rules: Iterable[Rule]
+
+
+class RuleServeRollout(TypedDict, total=False):
+ """One slot in a percentage rollout."""
+
+ version_id: Required[str]
+
+ weight: Required[float]
+
+
+class RuleServe(TypedDict, total=False):
+ """What a rule serves when matched.
+
+ Exactly one of:
+ - ``version_id`` — serve a specific version
+ - ``rollout`` — weighted random across versions; weights must sum to
+ less than 100, with the leftover routing to the main version
+ """
+
+ rollout: Iterable[RuleServeRollout]
+
+ version_id: str
+
+
+class RuleMatch(TypedDict, total=False):
+ """A single attribute/operator/values check.
+
+ A clause matches when the routing context's value for ``attribute``
+ satisfies ``operator`` against any of ``values``.
+ """
+
+ attribute: Required[str]
+ """Attribute name from the routing context"""
+
+ operator: Required[Literal["in", "not_in", "starts_with"]]
+ """Match operator"""
+
+ values: Required[SequenceNotStr[str]]
+
+
+class Rule(TypedDict, total=False):
+ """A targeting rule: ``match`` clauses (AND) gate ``serve``.
+
+ An empty ``match`` is a catch-all (always fires).
+ """
+
+ serve: Required[RuleServe]
+ """What a rule serves when matched.
+
+ Exactly one of:
+
+ - `version_id` — serve a specific version
+ - `rollout` — weighted random across versions; weights must sum to less than
+ 100, with the leftover routing to the main version
+ """
+
+ match: Iterable[RuleMatch]
diff --git a/src/telnyx/types/ai/assistants/clause.py b/src/telnyx/types/ai/assistants/clause.py
deleted file mode 100644
index 45adbc16..00000000
--- a/src/telnyx/types/ai/assistants/clause.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List
-from typing_extensions import Literal
-
-from ...._models import BaseModel
-
-__all__ = ["Clause"]
-
-
-class Clause(BaseModel):
- """A single attribute/operator/values check.
-
- A clause matches when the routing context's value for ``attribute``
- satisfies ``operator`` against any of ``values``.
- """
-
- attribute: str
- """Attribute name from the routing context"""
-
- operator: Literal["in", "not_in", "starts_with"]
- """Match operator"""
-
- values: List[str]
diff --git a/src/telnyx/types/ai/assistants/clause_param.py b/src/telnyx/types/ai/assistants/clause_param.py
deleted file mode 100644
index 9686b62d..00000000
--- a/src/telnyx/types/ai/assistants/clause_param.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-from ...._types import SequenceNotStr
-
-__all__ = ["ClauseParam"]
-
-
-class ClauseParam(TypedDict, total=False):
- """A single attribute/operator/values check.
-
- A clause matches when the routing context's value for ``attribute``
- satisfies ``operator`` against any of ``values``.
- """
-
- attribute: Required[str]
- """Attribute name from the routing context"""
-
- operator: Required[Literal["in", "not_in", "starts_with"]]
- """Match operator"""
-
- values: Required[SequenceNotStr[str]]
diff --git a/src/telnyx/types/ai/assistants/rollout_slot.py b/src/telnyx/types/ai/assistants/rollout_slot.py
deleted file mode 100644
index 7e79586b..00000000
--- a/src/telnyx/types/ai/assistants/rollout_slot.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from ...._models import BaseModel
-
-__all__ = ["RolloutSlot"]
-
-
-class RolloutSlot(BaseModel):
- """One slot in a percentage rollout."""
-
- version_id: str
-
- weight: float
diff --git a/src/telnyx/types/ai/assistants/rollout_slot_param.py b/src/telnyx/types/ai/assistants/rollout_slot_param.py
deleted file mode 100644
index b793001a..00000000
--- a/src/telnyx/types/ai/assistants/rollout_slot_param.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Required, TypedDict
-
-__all__ = ["RolloutSlotParam"]
-
-
-class RolloutSlotParam(TypedDict, total=False):
- """One slot in a percentage rollout."""
-
- version_id: Required[str]
-
- weight: Required[float]
diff --git a/src/telnyx/types/ai/assistants/rule_input_param.py b/src/telnyx/types/ai/assistants/rule_input_param.py
deleted file mode 100644
index 05f3d15d..00000000
--- a/src/telnyx/types/ai/assistants/rule_input_param.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Iterable
-from typing_extensions import Required, TypedDict
-
-from .serve_param import ServeParam
-from .clause_param import ClauseParam
-
-__all__ = ["RuleInputParam"]
-
-
-class RuleInputParam(TypedDict, total=False):
- """A targeting rule: ``match`` clauses (AND) gate ``serve``.
-
- An empty ``match`` is a catch-all (always fires).
- """
-
- serve: Required[ServeParam]
- """What a rule serves when matched.
-
- Exactly one of:
-
- - `version_id` — serve a specific version
- - `rollout` — weighted random across versions; weights must sum to less than
- 100, with the leftover routing to the main version
- """
-
- match: Iterable[ClauseParam]
diff --git a/src/telnyx/types/ai/assistants/rule_output.py b/src/telnyx/types/ai/assistants/rule_output.py
deleted file mode 100644
index d445b592..00000000
--- a/src/telnyx/types/ai/assistants/rule_output.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-
-from .serve import Serve
-from .clause import Clause
-from ...._models import BaseModel
-
-__all__ = ["RuleOutput"]
-
-
-class RuleOutput(BaseModel):
- """A targeting rule: ``match`` clauses (AND) gate ``serve``.
-
- An empty ``match`` is a catch-all (always fires).
- """
-
- serve: Serve
- """What a rule serves when matched.
-
- Exactly one of:
-
- - `version_id` — serve a specific version
- - `rollout` — weighted random across versions; weights must sum to less than
- 100, with the leftover routing to the main version
- """
-
- match: Optional[List[Clause]] = None
diff --git a/src/telnyx/types/ai/assistants/serve.py b/src/telnyx/types/ai/assistants/serve.py
deleted file mode 100644
index be641a46..00000000
--- a/src/telnyx/types/ai/assistants/serve.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-
-from ...._models import BaseModel
-from .rollout_slot import RolloutSlot
-
-__all__ = ["Serve"]
-
-
-class Serve(BaseModel):
- """What a rule serves when matched.
-
- Exactly one of:
- - ``version_id`` — serve a specific version
- - ``rollout`` — weighted random across versions; weights must sum to
- less than 100, with the leftover routing to the main version
- """
-
- rollout: Optional[List[RolloutSlot]] = None
-
- version_id: Optional[str] = None
diff --git a/src/telnyx/types/ai/assistants/serve_param.py b/src/telnyx/types/ai/assistants/serve_param.py
deleted file mode 100644
index 167c02a7..00000000
--- a/src/telnyx/types/ai/assistants/serve_param.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Iterable
-from typing_extensions import TypedDict
-
-from .rollout_slot_param import RolloutSlotParam
-
-__all__ = ["ServeParam"]
-
-
-class ServeParam(TypedDict, total=False):
- """What a rule serves when matched.
-
- Exactly one of:
- - ``version_id`` — serve a specific version
- - ``rollout`` — weighted random across versions; weights must sum to
- less than 100, with the leftover routing to the main version
- """
-
- rollout: Iterable[RolloutSlotParam]
-
- version_id: str
diff --git a/src/telnyx/types/ai/assistants/version_update_params.py b/src/telnyx/types/ai/assistants/version_update_params.py
index 13f9cde0..fc19ddfc 100644
--- a/src/telnyx/types/ai/assistants/version_update_params.py
+++ b/src/telnyx/types/ai/assistants/version_update_params.py
@@ -10,24 +10,19 @@
from ..assistant_tool_param import AssistantToolParam
from ..voice_settings_param import VoiceSettingsParam
from ..widget_settings_param import WidgetSettingsParam
-from ..external_llm_req_param import ExternalLlmReqParam
from ..insight_settings_param import InsightSettingsParam
from ..privacy_settings_param import PrivacySettingsParam
from ..observability_req_param import ObservabilityReqParam
from ..messaging_settings_param import MessagingSettingsParam
from ..telephony_settings_param import TelephonySettingsParam
-from ..fallback_config_req_param import FallbackConfigReqParam
-from ..assistant_mcp_server_param import AssistantMcpServerParam
-from ..assistant_integration_param import AssistantIntegrationParam
from ..transcription_settings_param import TranscriptionSettingsParam
-from ..post_conversation_settings_req_param import PostConversationSettingsReqParam
-from ..inference_embedding_interruption_settings_param import InferenceEmbeddingInterruptionSettingsParam
__all__ = [
"VersionUpdateParams",
"ConversationFlow",
"ConversationFlowNode",
"ConversationFlowNodeFlowNodeReq",
+ "ConversationFlowNodeFlowNodeReqExternalLlm",
"ConversationFlowNodeFlowNodeReqPosition",
"ConversationFlowNodeToolNodeReq",
"ConversationFlowNodeToolNodeReqPosition",
@@ -47,6 +42,15 @@
"ConversationFlowEdgeTargetNodeTarget",
"ConversationFlowEdgeTargetAssistantTarget",
"ConversationFlowEdgeTargetAssistantTargetPosition",
+ "ExternalLlm",
+ "FallbackConfig",
+ "FallbackConfigExternalLlm",
+ "Integration",
+ "InterruptionSettings",
+ "InterruptionSettingsStartSpeakingPlan",
+ "InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan",
+ "McpServer",
+ "PostConversationSettings",
]
@@ -88,9 +92,9 @@ class VersionUpdateParams(TypedDict, total=False):
enabled_features: List[EnabledFeatures]
- external_llm: ExternalLlmReqParam
+ external_llm: ExternalLlm
- fallback_config: FallbackConfigReqParam
+ fallback_config: FallbackConfig
greeting: str
"""Text that the assistant will use to start the conversation.
@@ -111,7 +115,7 @@ class VersionUpdateParams(TypedDict, total=False):
[dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables)
"""
- integrations: Iterable[AssistantIntegrationParam]
+ integrations: Iterable[Integration]
"""Connected integrations attached to the assistant.
The catalog of available integrations is at `/ai/integrations`; the user's
@@ -119,7 +123,7 @@ class VersionUpdateParams(TypedDict, total=False):
references a catalog integration by `integration_id`.
"""
- interruption_settings: InferenceEmbeddingInterruptionSettingsParam
+ interruption_settings: InterruptionSettings
"""
Settings for interruptions and how the assistant decides the user has finished
speaking. These timings are most relevant when using non turn-taking
@@ -139,7 +143,7 @@ class VersionUpdateParams(TypedDict, total=False):
are unlikely to work with this integration.
"""
- mcp_servers: Iterable[AssistantMcpServerParam]
+ mcp_servers: Iterable[McpServer]
"""MCP servers attached to the assistant.
Create MCP servers with `/ai/mcp_servers`, then reference them by `id` here.
@@ -161,7 +165,7 @@ class VersionUpdateParams(TypedDict, total=False):
observability_settings: ObservabilityReqParam
- post_conversation_settings: PostConversationSettingsReqParam
+ post_conversation_settings: PostConversationSettings
"""Configuration for post-conversation processing.
When enabled, the assistant receives one additional LLM turn after the
@@ -205,6 +209,47 @@ class VersionUpdateParams(TypedDict, total=False):
"""Configuration settings for the assistant's web widget."""
+class ConversationFlowNodeFlowNodeReqExternalLlm(TypedDict, total=False):
+ """Override for `Assistant.external_llm` while this node is active.
+
+ Use this to route a node's turns to a different external LLM (different `model`, `base_url`, credentials). Part of the LLM bundle — see `model` for cascade semantics. Mutually exclusive with `model` on the node (a single LLM identity per node).
+ """
+
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
class ConversationFlowNodeFlowNodeReqPosition(TypedDict, total=False):
"""Optional canvas coordinates used by authoring UIs to lay out the graph.
@@ -231,7 +276,7 @@ class ConversationFlowNodeFlowNodeReq(TypedDict, total=False):
instructions: Required[str]
"""Prompt that drives the LLM while this node is active. Required."""
- external_llm: ExternalLlmReqParam
+ external_llm: ConversationFlowNodeFlowNodeReqExternalLlm
"""Override for `Assistant.external_llm` while this node is active.
Use this to route a node's turns to a different external LLM (different `model`,
@@ -632,3 +677,199 @@ class ConversationFlow(TypedDict, total=False):
edges: Iterable[ConversationFlowEdge]
"""Directed transitions between nodes. May be empty for a single-node flow."""
+
+
+class ExternalLlm(TypedDict, total=False):
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
+class FallbackConfigExternalLlm(TypedDict, total=False):
+ base_url: Required[str]
+ """Base URL for the external LLM endpoint."""
+
+ model: Required[str]
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Literal["token", "certificate"]
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: str
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: bool
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: str
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
+class FallbackConfig(TypedDict, total=False):
+ external_llm: FallbackConfigExternalLlm
+
+ llm_api_key_ref: str
+ """Integration secret identifier for the fallback model API key."""
+
+ model: str
+ """
+ Fallback Telnyx-hosted model to use when the primary LLM provider is
+ unavailable.
+ """
+
+
+class Integration(TypedDict, total=False):
+ """Reference to a connected integration attached to an assistant.
+
+ Discover available integrations with `/ai/integrations` and connected integrations with `/ai/integrations/connections`.
+ """
+
+ integration_id: Required[str]
+ """Catalog integration ID to attach.
+
+ This is the `id` from the integrations catalog at `/ai/integrations` (the same
+ value also appears as `integration_id` on entries returned by
+ `/ai/integrations/connections`). It is **not** the connection-level `id` from
+ `/ai/integrations/connections`.
+ """
+
+ allowed_list: SequenceNotStr[str]
+ """Optional per-assistant allowlist of integration tool names.
+
+ When omitted or empty, all tools allowed by the connected integration are
+ available to the assistant.
+ """
+
+
+class InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan(TypedDict, total=False):
+ """Endpointing thresholds used to decide when the user has finished speaking.
+
+ Applies to non turn-taking transcription models. For `deepgram/flux`, use `transcription.settings.eot_threshold` / `eot_timeout_ms` / `eager_eot_threshold`.
+ """
+
+ on_no_punctuation_seconds: float
+ """Seconds to wait after the transcript ends without punctuation."""
+
+ on_number_seconds: float
+ """Seconds to wait after the transcript ends with a number."""
+
+ on_punctuation_seconds: float
+ """Seconds to wait after the transcript ends with punctuation."""
+
+
+class InterruptionSettingsStartSpeakingPlan(TypedDict, total=False):
+ """Controls when the assistant starts speaking after the user stops.
+
+ These thresholds primarily apply to non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the transcription end-of-turn settings under `transcription.settings` instead.
+ """
+
+ transcription_endpointing_plan: InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan
+ """Endpointing thresholds used to decide when the user has finished speaking.
+
+ Applies to non turn-taking transcription models. For `deepgram/flux`, use
+ `transcription.settings.eot_threshold` / `eot_timeout_ms` /
+ `eager_eot_threshold`.
+ """
+
+ wait_seconds: float
+ """Minimum seconds to wait before the assistant starts speaking."""
+
+
+class InterruptionSettings(TypedDict, total=False):
+ """
+ Settings for interruptions and how the assistant decides the user has finished speaking. These timings are most relevant when using non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn behavior is controlled by the transcription end-of-turn settings under `transcription.settings` (`eot_threshold`, `eot_timeout_ms`, `eager_eot_threshold`).
+ """
+
+ disable_greeting_interruption: bool
+ """When true, disables user interruptions while the assistant greeting is playing."""
+
+ enable: bool
+ """Whether users can interrupt the assistant while it is speaking."""
+
+ start_speaking_plan: InterruptionSettingsStartSpeakingPlan
+ """Controls when the assistant starts speaking after the user stops.
+
+ These thresholds primarily apply to non turn-taking transcription models. For
+ turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the
+ transcription end-of-turn settings under `transcription.settings` instead.
+ """
+
+
+class McpServer(TypedDict, total=False):
+ """Reference to an MCP server attached to an assistant.
+
+ Create and manage MCP servers with the `/ai/mcp_servers` endpoints, then attach them to assistants by ID.
+ """
+
+ id: Required[str]
+ """ID of the MCP server to attach.
+
+ This must be the `id` of an MCP server returned by the `/ai/mcp_servers`
+ endpoints.
+ """
+
+ allowed_tools: SequenceNotStr[str]
+ """Optional per-assistant allowlist of MCP tool names.
+
+ When omitted, the assistant uses the MCP server's configured `allowed_tools`.
+ """
+
+
+class PostConversationSettings(TypedDict, total=False):
+ """Configuration for post-conversation processing.
+
+ When enabled, the assistant receives one additional LLM turn after the conversation ends, allowing it to execute tool calls such as logging to a CRM or sending a summary. The assistant can execute multiple parallel or sequential tools during this phase. Telephony-control tools (e.g. hangup, transfer) are unavailable post-conversation. Beta feature.
+ """
+
+ enabled: bool
+ """Whether post-conversation processing is enabled.
+
+ When true, the assistant will be invoked after the conversation ends to perform
+ any final tool calls. Defaults to false.
+ """
diff --git a/src/telnyx/types/ai/external_llm.py b/src/telnyx/types/ai/external_llm.py
deleted file mode 100644
index 36332eb5..00000000
--- a/src/telnyx/types/ai/external_llm.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["ExternalLlm"]
-
-
-class ExternalLlm(BaseModel):
- base_url: str
- """Base URL for the external LLM endpoint."""
-
- model: str
- """Model identifier to use with the external LLM endpoint."""
-
- authentication_method: Optional[Literal["token", "certificate"]] = None
- """Authentication method used when connecting to the external LLM endpoint."""
-
- certificate_ref: Optional[str] = None
- """
- Integration secret identifier for the client certificate used with certificate
- authentication.
- """
-
- forward_metadata: Optional[bool] = None
- """
- When `true`, Telnyx forwards the assistant's dynamic variables to the external
- LLM endpoint as a top-level `extra_metadata` object on the chat completion
- request body. Defaults to `false`. Example payload sent to the external
- endpoint:
- `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
- Distinct from OpenAI's native `metadata` field, which has its own size and type
- limits.
- """
-
- llm_api_key_ref: Optional[str] = None
- """Integration secret identifier for the external LLM API key."""
-
- token_retrieval_url: Optional[str] = None
- """
- URL used to retrieve an access token when certificate authentication is enabled.
- """
diff --git a/src/telnyx/types/ai/external_llm_req_param.py b/src/telnyx/types/ai/external_llm_req_param.py
deleted file mode 100644
index ea863952..00000000
--- a/src/telnyx/types/ai/external_llm_req_param.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["ExternalLlmReqParam"]
-
-
-class ExternalLlmReqParam(TypedDict, total=False):
- base_url: Required[str]
- """Base URL for the external LLM endpoint."""
-
- model: Required[str]
- """Model identifier to use with the external LLM endpoint."""
-
- authentication_method: Literal["token", "certificate"]
- """Authentication method used when connecting to the external LLM endpoint."""
-
- certificate_ref: str
- """
- Integration secret identifier for the client certificate used with certificate
- authentication.
- """
-
- forward_metadata: bool
- """
- When `true`, Telnyx forwards the assistant's dynamic variables to the external
- LLM endpoint as a top-level `extra_metadata` object on the chat completion
- request body. Defaults to `false`. Example payload sent to the external
- endpoint:
- `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
- Distinct from OpenAI's native `metadata` field, which has its own size and type
- limits.
- """
-
- llm_api_key_ref: str
- """Integration secret identifier for the external LLM API key."""
-
- token_retrieval_url: str
- """
- URL used to retrieve an access token when certificate authentication is enabled.
- """
diff --git a/src/telnyx/types/ai/fallback_config.py b/src/telnyx/types/ai/fallback_config.py
deleted file mode 100644
index d929cec8..00000000
--- a/src/telnyx/types/ai/fallback_config.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from ..._models import BaseModel
-from .external_llm import ExternalLlm
-
-__all__ = ["FallbackConfig"]
-
-
-class FallbackConfig(BaseModel):
- external_llm: Optional[ExternalLlm] = None
-
- llm_api_key_ref: Optional[str] = None
- """Integration secret identifier for the fallback model API key."""
-
- model: Optional[str] = None
- """
- Fallback Telnyx-hosted model to use when the primary LLM provider is
- unavailable.
- """
diff --git a/src/telnyx/types/ai/fallback_config_req_param.py b/src/telnyx/types/ai/fallback_config_req_param.py
deleted file mode 100644
index 69b14470..00000000
--- a/src/telnyx/types/ai/fallback_config_req_param.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-from .external_llm_req_param import ExternalLlmReqParam
-
-__all__ = ["FallbackConfigReqParam"]
-
-
-class FallbackConfigReqParam(TypedDict, total=False):
- external_llm: ExternalLlmReqParam
-
- llm_api_key_ref: str
- """Integration secret identifier for the fallback model API key."""
-
- model: str
- """
- Fallback Telnyx-hosted model to use when the primary LLM provider is
- unavailable.
- """
diff --git a/src/telnyx/types/ai/inference_embedding.py b/src/telnyx/types/ai/inference_embedding.py
index a9fa32e1..8ef6cc2b 100644
--- a/src/telnyx/types/ai/inference_embedding.py
+++ b/src/telnyx/types/ai/inference_embedding.py
@@ -6,11 +6,9 @@
from ..._utils import PropertyInfo
from ..._models import BaseModel
-from .external_llm import ExternalLlm
from .observability import Observability
from .assistant_tool import AssistantTool
from .voice_settings import VoiceSettings
-from .fallback_config import FallbackConfig
from .import_metadata import ImportMetadata
from .widget_settings import WidgetSettings
from .enabled_features import EnabledFeatures
@@ -18,17 +16,14 @@
from .privacy_settings import PrivacySettings
from .messaging_settings import MessagingSettings
from .telephony_settings import TelephonySettings
-from .assistant_mcp_server import AssistantMcpServer
-from .assistant_integration import AssistantIntegration
from .transcription_settings import TranscriptionSettings
-from .post_conversation_settings import PostConversationSettings
-from .inference_embedding_interruption_settings import InferenceEmbeddingInterruptionSettings
__all__ = [
"InferenceEmbedding",
"ConversationFlow",
"ConversationFlowNode",
"ConversationFlowNodeFlowNode",
+ "ConversationFlowNodeFlowNodeExternalLlm",
"ConversationFlowNodeFlowNodePosition",
"ConversationFlowNodeToolNode",
"ConversationFlowNodeToolNodePosition",
@@ -48,9 +43,59 @@
"ConversationFlowEdgeTargetNodeTarget",
"ConversationFlowEdgeTargetAssistantTarget",
"ConversationFlowEdgeTargetAssistantTargetPosition",
+ "ExternalLlm",
+ "FallbackConfig",
+ "FallbackConfigExternalLlm",
+ "Integration",
+ "InterruptionSettings",
+ "InterruptionSettingsStartSpeakingPlan",
+ "InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan",
+ "McpServer",
+ "PostConversationSettings",
]
+class ConversationFlowNodeFlowNodeExternalLlm(BaseModel):
+ """Override for `Assistant.external_llm` while this node is active.
+
+ Use this to route a node's turns to a different external LLM (different `model`, `base_url`, credentials). Part of the LLM bundle — see `model` for cascade semantics. Mutually exclusive with `model` on the node (a single LLM identity per node).
+ """
+
+ base_url: str
+ """Base URL for the external LLM endpoint."""
+
+ model: str
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Optional[Literal["token", "certificate"]] = None
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: Optional[str] = None
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: Optional[bool] = None
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: Optional[str] = None
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: Optional[str] = None
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
class ConversationFlowNodeFlowNodePosition(BaseModel):
"""Optional canvas coordinates used by authoring UIs to lay out the graph.
@@ -73,7 +118,7 @@ class ConversationFlowNodeFlowNode(BaseModel):
instructions: str
"""Prompt that drives the LLM while this node is active. Required."""
- external_llm: Optional[ExternalLlm] = None
+ external_llm: Optional[ConversationFlowNodeFlowNodeExternalLlm] = None
"""Override for `Assistant.external_llm` while this node is active.
Use this to route a node's turns to a different external LLM (different `model`,
@@ -465,6 +510,202 @@ class ConversationFlow(BaseModel):
"""Directed transitions between nodes."""
+class ExternalLlm(BaseModel):
+ base_url: str
+ """Base URL for the external LLM endpoint."""
+
+ model: str
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Optional[Literal["token", "certificate"]] = None
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: Optional[str] = None
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: Optional[bool] = None
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: Optional[str] = None
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: Optional[str] = None
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
+class FallbackConfigExternalLlm(BaseModel):
+ base_url: str
+ """Base URL for the external LLM endpoint."""
+
+ model: str
+ """Model identifier to use with the external LLM endpoint."""
+
+ authentication_method: Optional[Literal["token", "certificate"]] = None
+ """Authentication method used when connecting to the external LLM endpoint."""
+
+ certificate_ref: Optional[str] = None
+ """
+ Integration secret identifier for the client certificate used with certificate
+ authentication.
+ """
+
+ forward_metadata: Optional[bool] = None
+ """
+ When `true`, Telnyx forwards the assistant's dynamic variables to the external
+ LLM endpoint as a top-level `extra_metadata` object on the chat completion
+ request body. Defaults to `false`. Example payload sent to the external
+ endpoint:
+ `{"extra_metadata": {"customer_name": "Jane", "account_id": "acct_789", "telnyx_agent_target": "+13125550100", "telnyx_end_user_target": "+13125550123"}}`.
+ Distinct from OpenAI's native `metadata` field, which has its own size and type
+ limits.
+ """
+
+ llm_api_key_ref: Optional[str] = None
+ """Integration secret identifier for the external LLM API key."""
+
+ token_retrieval_url: Optional[str] = None
+ """
+ URL used to retrieve an access token when certificate authentication is enabled.
+ """
+
+
+class FallbackConfig(BaseModel):
+ external_llm: Optional[FallbackConfigExternalLlm] = None
+
+ llm_api_key_ref: Optional[str] = None
+ """Integration secret identifier for the fallback model API key."""
+
+ model: Optional[str] = None
+ """
+ Fallback Telnyx-hosted model to use when the primary LLM provider is
+ unavailable.
+ """
+
+
+class Integration(BaseModel):
+ """Reference to a connected integration attached to an assistant.
+
+ Discover available integrations with `/ai/integrations` and connected integrations with `/ai/integrations/connections`.
+ """
+
+ integration_id: str
+ """Catalog integration ID to attach.
+
+ This is the `id` from the integrations catalog at `/ai/integrations` (the same
+ value also appears as `integration_id` on entries returned by
+ `/ai/integrations/connections`). It is **not** the connection-level `id` from
+ `/ai/integrations/connections`.
+ """
+
+ allowed_list: Optional[List[str]] = None
+ """Optional per-assistant allowlist of integration tool names.
+
+ When omitted or empty, all tools allowed by the connected integration are
+ available to the assistant.
+ """
+
+
+class InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan(BaseModel):
+ """Endpointing thresholds used to decide when the user has finished speaking.
+
+ Applies to non turn-taking transcription models. For `deepgram/flux`, use `transcription.settings.eot_threshold` / `eot_timeout_ms` / `eager_eot_threshold`.
+ """
+
+ on_no_punctuation_seconds: Optional[float] = None
+ """Seconds to wait after the transcript ends without punctuation."""
+
+ on_number_seconds: Optional[float] = None
+ """Seconds to wait after the transcript ends with a number."""
+
+ on_punctuation_seconds: Optional[float] = None
+ """Seconds to wait after the transcript ends with punctuation."""
+
+
+class InterruptionSettingsStartSpeakingPlan(BaseModel):
+ """Controls when the assistant starts speaking after the user stops.
+
+ These thresholds primarily apply to non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the transcription end-of-turn settings under `transcription.settings` instead.
+ """
+
+ transcription_endpointing_plan: Optional[InterruptionSettingsStartSpeakingPlanTranscriptionEndpointingPlan] = None
+ """Endpointing thresholds used to decide when the user has finished speaking.
+
+ Applies to non turn-taking transcription models. For `deepgram/flux`, use
+ `transcription.settings.eot_threshold` / `eot_timeout_ms` /
+ `eager_eot_threshold`.
+ """
+
+ wait_seconds: Optional[float] = None
+ """Minimum seconds to wait before the assistant starts speaking."""
+
+
+class InterruptionSettings(BaseModel):
+ """
+ Settings for interruptions and how the assistant decides the user has finished speaking. These timings are most relevant when using non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn behavior is controlled by the transcription end-of-turn settings under `transcription.settings` (`eot_threshold`, `eot_timeout_ms`, `eager_eot_threshold`).
+ """
+
+ disable_greeting_interruption: Optional[bool] = None
+ """When true, disables user interruptions while the assistant greeting is playing."""
+
+ enable: Optional[bool] = None
+ """Whether users can interrupt the assistant while it is speaking."""
+
+ start_speaking_plan: Optional[InterruptionSettingsStartSpeakingPlan] = None
+ """Controls when the assistant starts speaking after the user stops.
+
+ These thresholds primarily apply to non turn-taking transcription models. For
+ turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the
+ transcription end-of-turn settings under `transcription.settings` instead.
+ """
+
+
+class McpServer(BaseModel):
+ """Reference to an MCP server attached to an assistant.
+
+ Create and manage MCP servers with the `/ai/mcp_servers` endpoints, then attach them to assistants by ID.
+ """
+
+ id: str
+ """ID of the MCP server to attach.
+
+ This must be the `id` of an MCP server returned by the `/ai/mcp_servers`
+ endpoints.
+ """
+
+ allowed_tools: Optional[List[str]] = None
+ """Optional per-assistant allowlist of MCP tool names.
+
+ When omitted, the assistant uses the MCP server's configured `allowed_tools`.
+ """
+
+
+class PostConversationSettings(BaseModel):
+ """Configuration for post-conversation processing.
+
+ When enabled, the assistant receives one additional LLM turn after the conversation ends, allowing it to execute tool calls such as logging to a CRM or sending a summary. The assistant can execute multiple parallel or sequential tools during this phase. Telephony-control tools (e.g. hangup, transfer) are unavailable post-conversation. Beta feature.
+ """
+
+ enabled: Optional[bool] = None
+ """Whether post-conversation processing is enabled.
+
+ When true, the assistant will be invoked after the conversation ends to perform
+ any final tool calls. Defaults to false.
+ """
+
+
class InferenceEmbedding(BaseModel):
id: str
@@ -537,7 +778,7 @@ class InferenceEmbedding(BaseModel):
insight_settings: Optional[InsightSettings] = None
- integrations: Optional[List[AssistantIntegration]] = None
+ integrations: Optional[List[Integration]] = None
"""Connected integrations attached to the assistant.
The catalog of available integrations is at `/ai/integrations`; the user's
@@ -545,7 +786,7 @@ class InferenceEmbedding(BaseModel):
references a catalog integration by `integration_id`.
"""
- interruption_settings: Optional[InferenceEmbeddingInterruptionSettings] = None
+ interruption_settings: Optional[InterruptionSettings] = None
"""
Settings for interruptions and how the assistant decides the user has finished
speaking. These timings are most relevant when using non turn-taking
@@ -565,7 +806,7 @@ class InferenceEmbedding(BaseModel):
are unlikely to work with this integration.
"""
- mcp_servers: Optional[List[AssistantMcpServer]] = None
+ mcp_servers: Optional[List[McpServer]] = None
"""MCP servers attached to the assistant.
Create MCP servers with `/ai/mcp_servers`, then reference them by `id` here.
diff --git a/src/telnyx/types/ai/inference_embedding_interruption_settings.py b/src/telnyx/types/ai/inference_embedding_interruption_settings.py
deleted file mode 100644
index b7a216ee..00000000
--- a/src/telnyx/types/ai/inference_embedding_interruption_settings.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from ..._models import BaseModel
-from .start_speaking_plan import StartSpeakingPlan
-
-__all__ = ["InferenceEmbeddingInterruptionSettings"]
-
-
-class InferenceEmbeddingInterruptionSettings(BaseModel):
- """
- Settings for interruptions and how the assistant decides the user has finished speaking. These timings are most relevant when using non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn behavior is controlled by the transcription end-of-turn settings under `transcription.settings` (`eot_threshold`, `eot_timeout_ms`, `eager_eot_threshold`).
- """
-
- disable_greeting_interruption: Optional[bool] = None
- """When true, disables user interruptions while the assistant greeting is playing."""
-
- enable: Optional[bool] = None
- """Whether users can interrupt the assistant while it is speaking."""
-
- start_speaking_plan: Optional[StartSpeakingPlan] = None
- """Controls when the assistant starts speaking after the user stops.
-
- These thresholds primarily apply to non turn-taking transcription models. For
- turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the
- transcription end-of-turn settings under `transcription.settings` instead.
- """
diff --git a/src/telnyx/types/ai/inference_embedding_interruption_settings_param.py b/src/telnyx/types/ai/inference_embedding_interruption_settings_param.py
deleted file mode 100644
index 25a9c767..00000000
--- a/src/telnyx/types/ai/inference_embedding_interruption_settings_param.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-from .start_speaking_plan_param import StartSpeakingPlanParam
-
-__all__ = ["InferenceEmbeddingInterruptionSettingsParam"]
-
-
-class InferenceEmbeddingInterruptionSettingsParam(TypedDict, total=False):
- """
- Settings for interruptions and how the assistant decides the user has finished speaking. These timings are most relevant when using non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn behavior is controlled by the transcription end-of-turn settings under `transcription.settings` (`eot_threshold`, `eot_timeout_ms`, `eager_eot_threshold`).
- """
-
- disable_greeting_interruption: bool
- """When true, disables user interruptions while the assistant greeting is playing."""
-
- enable: bool
- """Whether users can interrupt the assistant while it is speaking."""
-
- start_speaking_plan: StartSpeakingPlanParam
- """Controls when the assistant starts speaking after the user stops.
-
- These thresholds primarily apply to non turn-taking transcription models. For
- turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the
- transcription end-of-turn settings under `transcription.settings` instead.
- """
diff --git a/src/telnyx/types/ai/openai_list_models_response.py b/src/telnyx/types/ai/openai_list_models_response.py
index 6710b3cd..d3eb4b54 100644
--- a/src/telnyx/types/ai/openai_list_models_response.py
+++ b/src/telnyx/types/ai/openai_list_models_response.py
@@ -1,14 +1,130 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import Dict, List, Optional
+from datetime import datetime
+from typing_extensions import Literal
from ..._models import BaseModel
-from ..model_metadata import ModelMetadata
-__all__ = ["OpenAIListModelsResponse"]
+__all__ = ["OpenAIListModelsResponse", "Data"]
+
+
+class Data(BaseModel):
+ """Metadata for a model available on Telnyx Inference.
+
+ Returned by `GET /v2/ai/openai/models` (and the deprecated `GET /v2/ai/models`). Open-source models live under their Hugging Face organization (e.g. `moonshotai/Kimi-K2.6`, `zai-org/GLM-5.1-FP8`, `MiniMaxAI/MiniMax-M2.7`); fine-tuned models are owned by the Telnyx organization that trained them.
+ """
+
+ id: str
+ """Model identifier.
+
+ For open-source models, follows the `{organization}/{model_name}` convention
+ from Hugging Face (e.g. `moonshotai/Kimi-K2.6`).
+ """
+
+ context_length: int
+ """
+ Maximum total tokens (prompt + completion) supported by the model in a single
+ request.
+ """
+
+ created: datetime
+ """Timestamp at which the model was registered on Telnyx Inference (ISO 8601)."""
+
+ languages: List[str]
+ """ISO language codes the model supports (e.g. `en`, `es`)."""
+
+ license: str
+ """License the model is distributed under, e.g.
+
+ `Apache 2.0`, `MIT`, `Llama 3 Community License`.
+ """
+
+ organization: str
+ """
+ Organization that originally published the model, matching the prefix of `id`
+ for open-source models.
+ """
+
+ owned_by: str
+ """Owner of the model.
+
+ `Telnyx` for Telnyx-hosted open-source models, the upstream provider name for
+ proxied models, or the Telnyx organization id for fine-tuned models.
+ """
+
+ parameters: int
+ """Total parameter count of the model."""
+
+ tier: Literal["small", "medium", "large", "unlisted"]
+ """Billing tier the model belongs to.
+
+ Used together with `pricing` to determine cost per 1M tokens.
+ """
+
+ base_model: Optional[str] = None
+ """Base model the fine-tuned model was trained from.
+
+ Only set for fine-tuned models.
+ """
+
+ description: Optional[str] = None
+ """Short, human-readable summary of what the model is best suited for."""
+
+ is_fine_tunable: Optional[bool] = None
+ """
+ Whether the model can be used as a base for a fine-tuning job via
+ `POST /v2/ai/fine_tuning/jobs`.
+ """
+
+ is_vision_supported: Optional[bool] = None
+ """
+ Whether the model accepts image inputs in chat completions (multimodal vision
+ support).
+ """
+
+ max_completion_tokens: Optional[int] = None
+ """Maximum number of completion (output) tokens the model will generate per
+ request.
+
+ `null` if unconstrained beyond `context_length`.
+ """
+
+ object: Optional[str] = None
+ """Object type. Always `model`."""
+
+ parameters_str: Optional[str] = None
+ """Human-readable parameter count, e.g. `1.0T`, `753.9B`, `8B`."""
+
+ pricing: Optional[Dict[str, str]] = None
+ """Mapping of token kind to price, as strings to preserve precision.
+
+ Typical keys are `prompt`, `cached_prompt`, and `completion`. When pricing is
+ available the block also includes `currency` (ISO 4217 code matching the
+ account's configured billing currency) and `unit` (the denomination the prices
+ are quoted in, currently always `1M_tokens` for token-priced models).
+ """
+
+ recommended_for_assistants: Optional[bool] = None
+ """
+ Whether Telnyx currently recommends this model as the LLM powering a Telnyx AI
+ Assistant.
+ """
+
+ regions: Optional[List[str]] = None
+ """Public region names where the model is currently deployed (e.g.
+
+ `us-central-1`, `eu-central-1`).
+ """
+
+ task: Optional[str] = None
+ """Primary task the model is intended for, e.g.
+
+ `text-generation`, `audio-text-to-text`, `feature-extraction` (embeddings).
+ """
class OpenAIListModelsResponse(BaseModel):
- data: List[ModelMetadata]
+ data: List[Data]
object: Optional[str] = None
diff --git a/src/telnyx/types/ai/post_conversation_settings.py b/src/telnyx/types/ai/post_conversation_settings.py
deleted file mode 100644
index d26676d9..00000000
--- a/src/telnyx/types/ai/post_conversation_settings.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from ..._models import BaseModel
-
-__all__ = ["PostConversationSettings"]
-
-
-class PostConversationSettings(BaseModel):
- """Configuration for post-conversation processing.
-
- When enabled, the assistant receives one additional LLM turn after the conversation ends, allowing it to execute tool calls such as logging to a CRM or sending a summary. The assistant can execute multiple parallel or sequential tools during this phase. Telephony-control tools (e.g. hangup, transfer) are unavailable post-conversation. Beta feature.
- """
-
- enabled: Optional[bool] = None
- """Whether post-conversation processing is enabled.
-
- When true, the assistant will be invoked after the conversation ends to perform
- any final tool calls. Defaults to false.
- """
diff --git a/src/telnyx/types/ai/post_conversation_settings_req_param.py b/src/telnyx/types/ai/post_conversation_settings_req_param.py
deleted file mode 100644
index 1198ac71..00000000
--- a/src/telnyx/types/ai/post_conversation_settings_req_param.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["PostConversationSettingsReqParam"]
-
-
-class PostConversationSettingsReqParam(TypedDict, total=False):
- """Configuration for post-conversation processing.
-
- When enabled, the assistant receives one additional LLM turn after the conversation ends, allowing it to execute tool calls such as logging to a CRM or sending a summary. The assistant can execute multiple parallel or sequential tools during this phase. Telephony-control tools (e.g. hangup, transfer) are unavailable post-conversation. Beta feature.
- """
-
- enabled: bool
- """Whether post-conversation processing is enabled.
-
- When true, the assistant will be invoked after the conversation ends to perform
- any final tool calls. Defaults to false.
- """
diff --git a/src/telnyx/types/ai/start_speaking_plan.py b/src/telnyx/types/ai/start_speaking_plan.py
deleted file mode 100644
index 318e8b41..00000000
--- a/src/telnyx/types/ai/start_speaking_plan.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from ..._models import BaseModel
-from .transcription_endpointing_plan import TranscriptionEndpointingPlan
-
-__all__ = ["StartSpeakingPlan"]
-
-
-class StartSpeakingPlan(BaseModel):
- """Controls when the assistant starts speaking after the user stops.
-
- These thresholds primarily apply to non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the transcription end-of-turn settings under `transcription.settings` instead.
- """
-
- transcription_endpointing_plan: Optional[TranscriptionEndpointingPlan] = None
- """Endpointing thresholds used to decide when the user has finished speaking.
-
- Applies to non turn-taking transcription models. For `deepgram/flux`, use
- `transcription.settings.eot_threshold` / `eot_timeout_ms` /
- `eager_eot_threshold`.
- """
-
- wait_seconds: Optional[float] = None
- """Minimum seconds to wait before the assistant starts speaking."""
diff --git a/src/telnyx/types/ai/start_speaking_plan_param.py b/src/telnyx/types/ai/start_speaking_plan_param.py
deleted file mode 100644
index eddc939e..00000000
--- a/src/telnyx/types/ai/start_speaking_plan_param.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-from .transcription_endpointing_plan_param import TranscriptionEndpointingPlanParam
-
-__all__ = ["StartSpeakingPlanParam"]
-
-
-class StartSpeakingPlanParam(TypedDict, total=False):
- """Controls when the assistant starts speaking after the user stops.
-
- These thresholds primarily apply to non turn-taking transcription models. For turn-taking models like `deepgram/flux`, end-of-turn detection is driven by the transcription end-of-turn settings under `transcription.settings` instead.
- """
-
- transcription_endpointing_plan: TranscriptionEndpointingPlanParam
- """Endpointing thresholds used to decide when the user has finished speaking.
-
- Applies to non turn-taking transcription models. For `deepgram/flux`, use
- `transcription.settings.eot_threshold` / `eot_timeout_ms` /
- `eager_eot_threshold`.
- """
-
- wait_seconds: float
- """Minimum seconds to wait before the assistant starts speaking."""
diff --git a/src/telnyx/types/ai/transcription_endpointing_plan.py b/src/telnyx/types/ai/transcription_endpointing_plan.py
deleted file mode 100644
index b8db019b..00000000
--- a/src/telnyx/types/ai/transcription_endpointing_plan.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from ..._models import BaseModel
-
-__all__ = ["TranscriptionEndpointingPlan"]
-
-
-class TranscriptionEndpointingPlan(BaseModel):
- """Endpointing thresholds used to decide when the user has finished speaking.
-
- Applies to non turn-taking transcription models. For `deepgram/flux`, use `transcription.settings.eot_threshold` / `eot_timeout_ms` / `eager_eot_threshold`.
- """
-
- on_no_punctuation_seconds: Optional[float] = None
- """Seconds to wait after the transcript ends without punctuation."""
-
- on_number_seconds: Optional[float] = None
- """Seconds to wait after the transcript ends with a number."""
-
- on_punctuation_seconds: Optional[float] = None
- """Seconds to wait after the transcript ends with punctuation."""
diff --git a/src/telnyx/types/ai/transcription_endpointing_plan_param.py b/src/telnyx/types/ai/transcription_endpointing_plan_param.py
deleted file mode 100644
index 7cb66dc7..00000000
--- a/src/telnyx/types/ai/transcription_endpointing_plan_param.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["TranscriptionEndpointingPlanParam"]
-
-
-class TranscriptionEndpointingPlanParam(TypedDict, total=False):
- """Endpointing thresholds used to decide when the user has finished speaking.
-
- Applies to non turn-taking transcription models. For `deepgram/flux`, use `transcription.settings.eot_threshold` / `eot_timeout_ms` / `eager_eot_threshold`.
- """
-
- on_no_punctuation_seconds: float
- """Seconds to wait after the transcript ends without punctuation."""
-
- on_number_seconds: float
- """Seconds to wait after the transcript ends with a number."""
-
- on_punctuation_seconds: float
- """Seconds to wait after the transcript ends with punctuation."""
diff --git a/src/telnyx/types/ai/transfer_tool_param.py b/src/telnyx/types/ai/transfer_tool_param.py
index d8d95a8f..67d21b67 100644
--- a/src/telnyx/types/ai/transfer_tool_param.py
+++ b/src/telnyx/types/ai/transfer_tool_param.py
@@ -5,10 +5,10 @@
from typing import Union, Iterable
from typing_extensions import Literal, Required, TypedDict
-__all__ = ["TransferToolParam", "Transfer", "TransferTargetsTargetsList"]
+__all__ = ["TransferToolParam", "Transfer", "TransferTargetsUnionMember0"]
-class TransferTargetsTargetsList(TypedDict, total=False):
+class TransferTargetsUnionMember0(TypedDict, total=False):
to: Required[str]
"""The destination number or SIP URI of the call."""
@@ -26,7 +26,7 @@ class TransferTargetsTargetsList(TypedDict, total=False):
class Transfer(_TransferReservedKeywords, total=False):
- targets: Required[Union[Iterable[TransferTargetsTargetsList], str]]
+ targets: Required[Union[Iterable[TransferTargetsUnionMember0], str]]
"""The different possible targets of the transfer.
The assistant will be able to choose one of the targets to transfer the call to.
diff --git a/src/telnyx/types/ai_retrieve_models_response.py b/src/telnyx/types/ai_retrieve_models_response.py
index db67e0f0..30331107 100644
--- a/src/telnyx/types/ai_retrieve_models_response.py
+++ b/src/telnyx/types/ai_retrieve_models_response.py
@@ -1,14 +1,130 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import List, Optional
+from typing import Dict, List, Optional
+from datetime import datetime
+from typing_extensions import Literal
from .._models import BaseModel
-from .model_metadata import ModelMetadata
-__all__ = ["AIRetrieveModelsResponse"]
+__all__ = ["AIRetrieveModelsResponse", "Data"]
+
+
+class Data(BaseModel):
+ """Metadata for a model available on Telnyx Inference.
+
+ Returned by `GET /v2/ai/openai/models` (and the deprecated `GET /v2/ai/models`). Open-source models live under their Hugging Face organization (e.g. `moonshotai/Kimi-K2.6`, `zai-org/GLM-5.1-FP8`, `MiniMaxAI/MiniMax-M2.7`); fine-tuned models are owned by the Telnyx organization that trained them.
+ """
+
+ id: str
+ """Model identifier.
+
+ For open-source models, follows the `{organization}/{model_name}` convention
+ from Hugging Face (e.g. `moonshotai/Kimi-K2.6`).
+ """
+
+ context_length: int
+ """
+ Maximum total tokens (prompt + completion) supported by the model in a single
+ request.
+ """
+
+ created: datetime
+ """Timestamp at which the model was registered on Telnyx Inference (ISO 8601)."""
+
+ languages: List[str]
+ """ISO language codes the model supports (e.g. `en`, `es`)."""
+
+ license: str
+ """License the model is distributed under, e.g.
+
+ `Apache 2.0`, `MIT`, `Llama 3 Community License`.
+ """
+
+ organization: str
+ """
+ Organization that originally published the model, matching the prefix of `id`
+ for open-source models.
+ """
+
+ owned_by: str
+ """Owner of the model.
+
+ `Telnyx` for Telnyx-hosted open-source models, the upstream provider name for
+ proxied models, or the Telnyx organization id for fine-tuned models.
+ """
+
+ parameters: int
+ """Total parameter count of the model."""
+
+ tier: Literal["small", "medium", "large", "unlisted"]
+ """Billing tier the model belongs to.
+
+ Used together with `pricing` to determine cost per 1M tokens.
+ """
+
+ base_model: Optional[str] = None
+ """Base model the fine-tuned model was trained from.
+
+ Only set for fine-tuned models.
+ """
+
+ description: Optional[str] = None
+ """Short, human-readable summary of what the model is best suited for."""
+
+ is_fine_tunable: Optional[bool] = None
+ """
+ Whether the model can be used as a base for a fine-tuning job via
+ `POST /v2/ai/fine_tuning/jobs`.
+ """
+
+ is_vision_supported: Optional[bool] = None
+ """
+ Whether the model accepts image inputs in chat completions (multimodal vision
+ support).
+ """
+
+ max_completion_tokens: Optional[int] = None
+ """Maximum number of completion (output) tokens the model will generate per
+ request.
+
+ `null` if unconstrained beyond `context_length`.
+ """
+
+ object: Optional[str] = None
+ """Object type. Always `model`."""
+
+ parameters_str: Optional[str] = None
+ """Human-readable parameter count, e.g. `1.0T`, `753.9B`, `8B`."""
+
+ pricing: Optional[Dict[str, str]] = None
+ """Mapping of token kind to price, as strings to preserve precision.
+
+ Typical keys are `prompt`, `cached_prompt`, and `completion`. When pricing is
+ available the block also includes `currency` (ISO 4217 code matching the
+ account's configured billing currency) and `unit` (the denomination the prices
+ are quoted in, currently always `1M_tokens` for token-priced models).
+ """
+
+ recommended_for_assistants: Optional[bool] = None
+ """
+ Whether Telnyx currently recommends this model as the LLM powering a Telnyx AI
+ Assistant.
+ """
+
+ regions: Optional[List[str]] = None
+ """Public region names where the model is currently deployed (e.g.
+
+ `us-central-1`, `eu-central-1`).
+ """
+
+ task: Optional[str] = None
+ """Primary task the model is intended for, e.g.
+
+ `text-generation`, `audio-text-to-text`, `feature-extraction` (embeddings).
+ """
class AIRetrieveModelsResponse(BaseModel):
- data: List[ModelMetadata]
+ data: List[Data]
object: Optional[str] = None
diff --git a/src/telnyx/types/billing_address.py b/src/telnyx/types/billing_address.py
index 5253582e..2384e5bd 100644
--- a/src/telnyx/types/billing_address.py
+++ b/src/telnyx/types/billing_address.py
@@ -9,19 +9,15 @@
class BillingAddress(BaseModel):
administrative_area: str
- """State or province"""
+ """State or province code (e.g. `IL`, `ON`)."""
city: str
- """City name"""
country: str
- """Country name (e.g., United States)"""
+ """ISO 3166-1 alpha-2 code (currently `US` or `CA`)."""
postal_code: str
- """ZIP or postal code"""
street_address: str
- """Street address"""
extended_address: Optional[str] = None
- """Additional address line (suite, apt, etc.)"""
diff --git a/src/telnyx/types/billing_address_param.py b/src/telnyx/types/billing_address_param.py
index 075b2663..db99536f 100644
--- a/src/telnyx/types/billing_address_param.py
+++ b/src/telnyx/types/billing_address_param.py
@@ -10,19 +10,15 @@
class BillingAddressParam(TypedDict, total=False):
administrative_area: Required[str]
- """State or province"""
+ """State or province code (e.g. `IL`, `ON`)."""
city: Required[str]
- """City name"""
country: Required[str]
- """Country name (e.g., United States)"""
+ """ISO 3166-1 alpha-2 code (currently `US` or `CA`)."""
postal_code: Required[str]
- """ZIP or postal code"""
street_address: Required[str]
- """Street address"""
extended_address: Optional[str]
- """Additional address line (suite, apt, etc.)"""
diff --git a/src/telnyx/types/billing_contact.py b/src/telnyx/types/billing_contact.py
index 88da12be..904a223f 100644
--- a/src/telnyx/types/billing_contact.py
+++ b/src/telnyx/types/billing_contact.py
@@ -7,13 +7,10 @@
class BillingContact(BaseModel):
email: str
- """Contact's email address"""
first_name: str
- """Contact's first name"""
last_name: str
- """Contact's last name"""
phone_number: str
- """Contact's phone number (10-15 digits)"""
+ """E.164 format with leading `+`."""
diff --git a/src/telnyx/types/billing_contact_param.py b/src/telnyx/types/billing_contact_param.py
index 5bee10ba..bbe2c83f 100644
--- a/src/telnyx/types/billing_contact_param.py
+++ b/src/telnyx/types/billing_contact_param.py
@@ -9,13 +9,10 @@
class BillingContactParam(TypedDict, total=False):
email: Required[str]
- """Contact's email address"""
first_name: Required[str]
- """Contact's first name"""
last_name: Required[str]
- """Contact's last name"""
phone_number: Required[str]
- """Contact's phone number (10-15 digits)"""
+ """E.164 format with leading `+`."""
diff --git a/src/telnyx/types/call_dial_params.py b/src/telnyx/types/call_dial_params.py
index 002139c4..f8f2bf1d 100644
--- a/src/telnyx/types/call_dial_params.py
+++ b/src/telnyx/types/call_dial_params.py
@@ -16,7 +16,6 @@
from .stream_bidirectional_codec import StreamBidirectionalCodec
from .call_assistant_request_param import CallAssistantRequestParam
from .calls.aws_voice_settings_param import AwsVoiceSettingsParam
-from .shared_params.xai_voice_settings import XaiVoiceSettings
from .stream_bidirectional_target_legs import StreamBidirectionalTargetLegs
from .calls.telnyx_voice_settings_param import TelnyxVoiceSettingsParam
from .shared_params.rime_voice_settings import RimeVoiceSettings
@@ -36,8 +35,10 @@
"ConversationRelayConfigLanguage",
"ConversationRelayConfigLanguageVoiceSettings",
"ConversationRelayConfigLanguageVoiceSettingsInworldVoiceSettings",
+ "ConversationRelayConfigLanguageVoiceSettingsXaiVoiceSettings",
"ConversationRelayConfigVoiceSettings",
"ConversationRelayConfigVoiceSettingsInworldVoiceSettings",
+ "ConversationRelayConfigVoiceSettingsXaiVoiceSettings",
"DeepfakeDetection",
"WebhookRetriesPolicies",
]
@@ -604,6 +605,14 @@ class ConversationRelayConfigLanguageVoiceSettingsInworldVoiceSettings(TypedDict
"""Voice settings provider type"""
+class ConversationRelayConfigLanguageVoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
ConversationRelayConfigLanguageVoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -613,7 +622,7 @@ class ConversationRelayConfigLanguageVoiceSettingsInworldVoiceSettings(TypedDict
RimeVoiceSettings,
ResembleVoiceSettings,
ConversationRelayConfigLanguageVoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ ConversationRelayConfigLanguageVoiceSettingsXaiVoiceSettings,
]
@@ -673,6 +682,14 @@ class ConversationRelayConfigVoiceSettingsInworldVoiceSettings(TypedDict, total=
"""Voice settings provider type"""
+class ConversationRelayConfigVoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
ConversationRelayConfigVoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -682,7 +699,7 @@ class ConversationRelayConfigVoiceSettingsInworldVoiceSettings(TypedDict, total=
RimeVoiceSettings,
ResembleVoiceSettings,
ConversationRelayConfigVoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ ConversationRelayConfigVoiceSettingsXaiVoiceSettings,
]
diff --git a/src/telnyx/types/call_reason_list_params.py b/src/telnyx/types/call_reason_list_params.py
new file mode 100644
index 00000000..911d8730
--- /dev/null
+++ b/src/telnyx/types/call_reason_list_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_extensions import Annotated, TypedDict
+
+from .._utils import PropertyInfo
+
+__all__ = ["CallReasonListParams"]
+
+
+class CallReasonListParams(TypedDict, total=False):
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """Items per page.
+
+ Default `100` for this endpoint (the call-reason library is small and most
+ callers want the whole list in one call). Maximum 250; values above are clamped
+ to 250.
+ """
diff --git a/src/telnyx/types/call_reason_list_response.py b/src/telnyx/types/call_reason_list_response.py
new file mode 100644
index 00000000..16f098a0
--- /dev/null
+++ b/src/telnyx/types/call_reason_list_response.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from .._models import BaseModel
+
+__all__ = ["CallReasonListResponse"]
+
+
+class CallReasonListResponse(BaseModel):
+ """Pre-vetted call-reason library entry."""
+
+ id: Optional[str] = None
+
+ description: Optional[str] = None
+
+ reason: Optional[str] = None
diff --git a/src/telnyx/types/call_reason_validate_params.py b/src/telnyx/types/call_reason_validate_params.py
new file mode 100644
index 00000000..519ea332
--- /dev/null
+++ b/src/telnyx/types/call_reason_validate_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from .._types import SequenceNotStr
+
+__all__ = ["CallReasonValidateParams"]
+
+
+class CallReasonValidateParams(TypedDict, total=False):
+ body: Required[SequenceNotStr[str]]
+ """
+ **Bare JSON array** of candidate call-reason strings (NOT an object — there is
+ no top-level `call_reasons` key on this endpoint). 1–10 strings, each ≤64
+ characters.
+ """
diff --git a/src/telnyx/types/call_reason_validate_response.py b/src/telnyx/types/call_reason_validate_response.py
new file mode 100644
index 00000000..e6d9bd46
--- /dev/null
+++ b/src/telnyx/types/call_reason_validate_response.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+
+from .._models import BaseModel
+
+__all__ = ["CallReasonValidateResponse", "Data"]
+
+
+class Data(BaseModel):
+ all_pre_approved: bool
+ """
+ `true` when every supplied reason matches a pre-vetted entry in the call-reason
+ library. When `true`, the DIR will sail through the call-reasons portion of
+ vetting.
+ """
+
+ non_approved_reasons: List[str]
+ """Subset of the input that does NOT match the pre-vetted library.
+
+ The DIR can still be submitted with these — they will go through manual review.
+ """
+
+ requires_manual_vetting: bool
+ """`true` when at least one supplied reason is in `non_approved_reasons`.
+
+ Equivalent to `non_approved_reasons.length > 0` and the inverse of
+ `all_pre_approved`.
+ """
+
+
+class CallReasonValidateResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/calls/__init__.py b/src/telnyx/types/calls/__init__.py
index 16251b0a..42cb8b84 100644
--- a/src/telnyx/types/calls/__init__.py
+++ b/src/telnyx/types/calls/__init__.py
@@ -92,9 +92,6 @@
from .action_stop_conversation_relay_params import (
ActionStopConversationRelayParams as ActionStopConversationRelayParams,
)
-from .transcription_engine_xai_config_param import (
- TranscriptionEngineXaiConfigParam as TranscriptionEngineXaiConfigParam,
-)
from .action_start_conversation_relay_params import (
ActionStartConversationRelayParams as ActionStartConversationRelayParams,
)
@@ -128,9 +125,6 @@
from .action_add_ai_assistant_messages_response import (
ActionAddAIAssistantMessagesResponse as ActionAddAIAssistantMessagesResponse,
)
-from .transcription_engine_assemblyai_config_param import (
- TranscriptionEngineAssemblyaiConfigParam as TranscriptionEngineAssemblyaiConfigParam,
-)
from .call_control_command_result_with_conversation_id import (
CallControlCommandResultWithConversationID as CallControlCommandResultWithConversationID,
)
diff --git a/src/telnyx/types/calls/action_answer_params.py b/src/telnyx/types/calls/action_answer_params.py
index 24526519..399b89b3 100644
--- a/src/telnyx/types/calls/action_answer_params.py
+++ b/src/telnyx/types/calls/action_answer_params.py
@@ -15,7 +15,6 @@
from .telnyx_voice_settings_param import TelnyxVoiceSettingsParam
from ..call_assistant_request_param import CallAssistantRequestParam
from .eleven_labs_voice_settings_param import ElevenLabsVoiceSettingsParam
-from ..shared_params.xai_voice_settings import XaiVoiceSettings
from ..stream_bidirectional_target_legs import StreamBidirectionalTargetLegs
from .transcription_start_request_param import TranscriptionStartRequestParam
from ..shared_params.rime_voice_settings import RimeVoiceSettings
@@ -30,8 +29,10 @@
"ConversationRelayConfigLanguage",
"ConversationRelayConfigLanguageVoiceSettings",
"ConversationRelayConfigLanguageVoiceSettingsInworldVoiceSettings",
+ "ConversationRelayConfigLanguageVoiceSettingsXaiVoiceSettings",
"ConversationRelayConfigVoiceSettings",
"ConversationRelayConfigVoiceSettingsInworldVoiceSettings",
+ "ConversationRelayConfigVoiceSettingsXaiVoiceSettings",
"DeepfakeDetection",
"WebhookRetriesPolicies",
]
@@ -249,6 +250,14 @@ class ConversationRelayConfigLanguageVoiceSettingsInworldVoiceSettings(TypedDict
"""Voice settings provider type"""
+class ConversationRelayConfigLanguageVoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
ConversationRelayConfigLanguageVoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -258,7 +267,7 @@ class ConversationRelayConfigLanguageVoiceSettingsInworldVoiceSettings(TypedDict
RimeVoiceSettings,
ResembleVoiceSettings,
ConversationRelayConfigLanguageVoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ ConversationRelayConfigLanguageVoiceSettingsXaiVoiceSettings,
]
@@ -318,6 +327,14 @@ class ConversationRelayConfigVoiceSettingsInworldVoiceSettings(TypedDict, total=
"""Voice settings provider type"""
+class ConversationRelayConfigVoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
ConversationRelayConfigVoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -327,7 +344,7 @@ class ConversationRelayConfigVoiceSettingsInworldVoiceSettings(TypedDict, total=
RimeVoiceSettings,
ResembleVoiceSettings,
ConversationRelayConfigVoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ ConversationRelayConfigVoiceSettingsXaiVoiceSettings,
]
diff --git a/src/telnyx/types/calls/action_gather_using_ai_params.py b/src/telnyx/types/calls/action_gather_using_ai_params.py
index 7441288a..b50c83d5 100644
--- a/src/telnyx/types/calls/action_gather_using_ai_params.py
+++ b/src/telnyx/types/calls/action_gather_using_ai_params.py
@@ -12,12 +12,11 @@
from .telnyx_voice_settings_param import TelnyxVoiceSettingsParam
from .google_transcription_language import GoogleTranscriptionLanguage
from .eleven_labs_voice_settings_param import ElevenLabsVoiceSettingsParam
-from ..shared_params.xai_voice_settings import XaiVoiceSettings
from ..shared_params.rime_voice_settings import RimeVoiceSettings
from ..shared_params.azure_voice_settings import AzureVoiceSettings
from ..shared_params.resemble_voice_settings import ResembleVoiceSettings
-__all__ = ["ActionGatherUsingAIParams", "MessageHistory", "VoiceSettings"]
+__all__ = ["ActionGatherUsingAIParams", "MessageHistory", "VoiceSettings", "VoiceSettingsXaiVoiceSettings"]
class ActionGatherUsingAIParams(TypedDict, total=False):
@@ -143,6 +142,14 @@ class MessageHistory(TypedDict, total=False):
"""The role of the message sender"""
+class VoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
VoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -150,5 +157,5 @@ class MessageHistory(TypedDict, total=False):
AzureVoiceSettings,
RimeVoiceSettings,
ResembleVoiceSettings,
- XaiVoiceSettings,
+ VoiceSettingsXaiVoiceSettings,
]
diff --git a/src/telnyx/types/calls/action_gather_using_speak_params.py b/src/telnyx/types/calls/action_gather_using_speak_params.py
index 6d0cc32d..9d2de400 100644
--- a/src/telnyx/types/calls/action_gather_using_speak_params.py
+++ b/src/telnyx/types/calls/action_gather_using_speak_params.py
@@ -8,13 +8,17 @@
from .aws_voice_settings_param import AwsVoiceSettingsParam
from .telnyx_voice_settings_param import TelnyxVoiceSettingsParam
from .eleven_labs_voice_settings_param import ElevenLabsVoiceSettingsParam
-from ..shared_params.xai_voice_settings import XaiVoiceSettings
from ..shared_params.rime_voice_settings import RimeVoiceSettings
from ..shared_params.azure_voice_settings import AzureVoiceSettings
from ..shared_params.minimax_voice_settings import MinimaxVoiceSettings
from ..shared_params.resemble_voice_settings import ResembleVoiceSettings
-__all__ = ["ActionGatherUsingSpeakParams", "VoiceSettings", "VoiceSettingsInworldVoiceSettings"]
+__all__ = [
+ "ActionGatherUsingSpeakParams",
+ "VoiceSettings",
+ "VoiceSettingsInworldVoiceSettings",
+ "VoiceSettingsXaiVoiceSettings",
+]
class ActionGatherUsingSpeakParams(TypedDict, total=False):
@@ -180,6 +184,14 @@ class VoiceSettingsInworldVoiceSettings(TypedDict, total=False):
"""Voice settings provider type"""
+class VoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
VoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -189,5 +201,5 @@ class VoiceSettingsInworldVoiceSettings(TypedDict, total=False):
RimeVoiceSettings,
ResembleVoiceSettings,
VoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ VoiceSettingsXaiVoiceSettings,
]
diff --git a/src/telnyx/types/calls/action_speak_params.py b/src/telnyx/types/calls/action_speak_params.py
index 3d1629e1..b2f34204 100644
--- a/src/telnyx/types/calls/action_speak_params.py
+++ b/src/telnyx/types/calls/action_speak_params.py
@@ -9,13 +9,12 @@
from .aws_voice_settings_param import AwsVoiceSettingsParam
from .telnyx_voice_settings_param import TelnyxVoiceSettingsParam
from .eleven_labs_voice_settings_param import ElevenLabsVoiceSettingsParam
-from ..shared_params.xai_voice_settings import XaiVoiceSettings
from ..shared_params.rime_voice_settings import RimeVoiceSettings
from ..shared_params.azure_voice_settings import AzureVoiceSettings
from ..shared_params.minimax_voice_settings import MinimaxVoiceSettings
from ..shared_params.resemble_voice_settings import ResembleVoiceSettings
-__all__ = ["ActionSpeakParams", "VoiceSettings", "VoiceSettingsInworldVoiceSettings"]
+__all__ = ["ActionSpeakParams", "VoiceSettings", "VoiceSettingsInworldVoiceSettings", "VoiceSettingsXaiVoiceSettings"]
class ActionSpeakParams(TypedDict, total=False):
@@ -158,6 +157,14 @@ class VoiceSettingsInworldVoiceSettings(TypedDict, total=False):
"""Voice settings provider type"""
+class VoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
VoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -167,5 +174,5 @@ class VoiceSettingsInworldVoiceSettings(TypedDict, total=False):
RimeVoiceSettings,
ResembleVoiceSettings,
VoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ VoiceSettingsXaiVoiceSettings,
]
diff --git a/src/telnyx/types/calls/action_start_ai_assistant_params.py b/src/telnyx/types/calls/action_start_ai_assistant_params.py
index 87a41a79..b00900db 100644
--- a/src/telnyx/types/calls/action_start_ai_assistant_params.py
+++ b/src/telnyx/types/calls/action_start_ai_assistant_params.py
@@ -11,7 +11,6 @@
from .telnyx_voice_settings_param import TelnyxVoiceSettingsParam
from ..call_assistant_request_param import CallAssistantRequestParam
from .eleven_labs_voice_settings_param import ElevenLabsVoiceSettingsParam
-from ..shared_params.xai_voice_settings import XaiVoiceSettings
from ..shared_params.rime_voice_settings import RimeVoiceSettings
from ..shared_params.azure_voice_settings import AzureVoiceSettings
from ..shared_params.resemble_voice_settings import ResembleVoiceSettings
@@ -28,6 +27,7 @@
"MessageHistoryDeveloperMessage",
"Participant",
"VoiceSettings",
+ "VoiceSettingsXaiVoiceSettings",
]
@@ -235,6 +235,14 @@ class Participant(TypedDict, total=False):
"""Determines what happens to the conversation when this participant hangs up."""
+class VoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
VoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -242,5 +250,5 @@ class Participant(TypedDict, total=False):
AzureVoiceSettings,
RimeVoiceSettings,
ResembleVoiceSettings,
- XaiVoiceSettings,
+ VoiceSettingsXaiVoiceSettings,
]
diff --git a/src/telnyx/types/calls/action_start_conversation_relay_params.py b/src/telnyx/types/calls/action_start_conversation_relay_params.py
index b92342e0..f303b736 100644
--- a/src/telnyx/types/calls/action_start_conversation_relay_params.py
+++ b/src/telnyx/types/calls/action_start_conversation_relay_params.py
@@ -8,7 +8,6 @@
from .aws_voice_settings_param import AwsVoiceSettingsParam
from .telnyx_voice_settings_param import TelnyxVoiceSettingsParam
from .eleven_labs_voice_settings_param import ElevenLabsVoiceSettingsParam
-from ..shared_params.xai_voice_settings import XaiVoiceSettings
from ..shared_params.rime_voice_settings import RimeVoiceSettings
from ..shared_params.azure_voice_settings import AzureVoiceSettings
from ..shared_params.minimax_voice_settings import MinimaxVoiceSettings
@@ -21,12 +20,15 @@
"ConversationRelaySettingsLanguage",
"ConversationRelaySettingsLanguageVoiceSettings",
"ConversationRelaySettingsLanguageVoiceSettingsInworldVoiceSettings",
+ "ConversationRelaySettingsLanguageVoiceSettingsXaiVoiceSettings",
"InterruptionSettings",
"Language",
"LanguageVoiceSettings",
"LanguageVoiceSettingsInworldVoiceSettings",
+ "LanguageVoiceSettingsXaiVoiceSettings",
"VoiceSettings",
"VoiceSettingsInworldVoiceSettings",
+ "VoiceSettingsXaiVoiceSettings",
]
@@ -208,6 +210,14 @@ class ConversationRelaySettingsLanguageVoiceSettingsInworldVoiceSettings(TypedDi
"""Voice settings provider type"""
+class ConversationRelaySettingsLanguageVoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
ConversationRelaySettingsLanguageVoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -217,7 +227,7 @@ class ConversationRelaySettingsLanguageVoiceSettingsInworldVoiceSettings(TypedDi
RimeVoiceSettings,
ResembleVoiceSettings,
ConversationRelaySettingsLanguageVoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ ConversationRelaySettingsLanguageVoiceSettingsXaiVoiceSettings,
]
@@ -342,6 +352,14 @@ class LanguageVoiceSettingsInworldVoiceSettings(TypedDict, total=False):
"""Voice settings provider type"""
+class LanguageVoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
LanguageVoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -351,7 +369,7 @@ class LanguageVoiceSettingsInworldVoiceSettings(TypedDict, total=False):
RimeVoiceSettings,
ResembleVoiceSettings,
LanguageVoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ LanguageVoiceSettingsXaiVoiceSettings,
]
@@ -411,6 +429,14 @@ class VoiceSettingsInworldVoiceSettings(TypedDict, total=False):
"""Voice settings provider type"""
+class VoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
VoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -420,5 +446,5 @@ class VoiceSettingsInworldVoiceSettings(TypedDict, total=False):
RimeVoiceSettings,
ResembleVoiceSettings,
VoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ VoiceSettingsXaiVoiceSettings,
]
diff --git a/src/telnyx/types/calls/action_start_transcription_params.py b/src/telnyx/types/calls/action_start_transcription_params.py
index fb113b5f..a665fbf6 100644
--- a/src/telnyx/types/calls/action_start_transcription_params.py
+++ b/src/telnyx/types/calls/action_start_transcription_params.py
@@ -9,15 +9,15 @@
from .deepgram_nova3_config_param import DeepgramNova3ConfigParam
from .transcription_engine_a_config_param import TranscriptionEngineAConfigParam
from .transcription_engine_b_config_param import TranscriptionEngineBConfigParam
-from .transcription_engine_xai_config_param import TranscriptionEngineXaiConfigParam
from .transcription_engine_azure_config_param import TranscriptionEngineAzureConfigParam
from .transcription_engine_google_config_param import TranscriptionEngineGoogleConfigParam
from .transcription_engine_telnyx_config_param import TranscriptionEngineTelnyxConfigParam
-from .transcription_engine_assemblyai_config_param import TranscriptionEngineAssemblyaiConfigParam
__all__ = [
"ActionStartTranscriptionParams",
"TranscriptionEngineConfig",
+ "TranscriptionEngineConfigTranscriptionEngineXaiConfig",
+ "TranscriptionEngineConfigTranscriptionEngineAssemblyaiConfig",
"TranscriptionEngineConfigTranscriptionEngineSpeechmaticsConfig",
"TranscriptionEngineConfigTranscriptionEngineSonioxConfig",
]
@@ -56,6 +56,63 @@ class ActionStartTranscriptionParams(TypedDict, total=False):
"""
+class TranscriptionEngineConfigTranscriptionEngineXaiConfig(TypedDict, total=False):
+ interim_results: bool
+ """Whether to send also interim results.
+
+ If set to false, only final results will be sent.
+ """
+
+ language: Literal[
+ "ar",
+ "cs",
+ "da",
+ "de",
+ "en",
+ "es",
+ "fa",
+ "fil",
+ "fr",
+ "hi",
+ "id",
+ "it",
+ "ja",
+ "ko",
+ "mk",
+ "ms",
+ "nl",
+ "pl",
+ "pt",
+ "ro",
+ "ru",
+ "sv",
+ "th",
+ "tr",
+ "vi",
+ ]
+ """Language to use for speech recognition"""
+
+ transcription_engine: Literal["xAI"]
+ """Engine identifier for xAI transcription service"""
+
+ transcription_model: Literal["xai/grok-stt"]
+ """The model to use for transcription."""
+
+
+class TranscriptionEngineConfigTranscriptionEngineAssemblyaiConfig(TypedDict, total=False):
+ interim_results: bool
+ """Whether to send also interim results.
+
+ If set to false, only final results will be sent.
+ """
+
+ transcription_engine: Literal["AssemblyAI"]
+ """Engine identifier for AssemblyAI transcription service"""
+
+ transcription_model: Literal["assemblyai/universal-streaming"]
+ """The model to use for transcription."""
+
+
class TranscriptionEngineConfigTranscriptionEngineSpeechmaticsConfig(TypedDict, total=False):
interim_results: bool
"""Whether to send also interim results.
@@ -128,8 +185,8 @@ class TranscriptionEngineConfigTranscriptionEngineSonioxConfig(TypedDict, total=
TranscriptionEngineGoogleConfigParam,
TranscriptionEngineTelnyxConfigParam,
TranscriptionEngineAzureConfigParam,
- TranscriptionEngineXaiConfigParam,
- TranscriptionEngineAssemblyaiConfigParam,
+ TranscriptionEngineConfigTranscriptionEngineXaiConfig,
+ TranscriptionEngineConfigTranscriptionEngineAssemblyaiConfig,
TranscriptionEngineConfigTranscriptionEngineSpeechmaticsConfig,
TranscriptionEngineConfigTranscriptionEngineSonioxConfig,
TranscriptionEngineAConfigParam,
diff --git a/src/telnyx/types/calls/transcription_engine_assemblyai_config_param.py b/src/telnyx/types/calls/transcription_engine_assemblyai_config_param.py
deleted file mode 100644
index b5f62f19..00000000
--- a/src/telnyx/types/calls/transcription_engine_assemblyai_config_param.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, TypedDict
-
-__all__ = ["TranscriptionEngineAssemblyaiConfigParam"]
-
-
-class TranscriptionEngineAssemblyaiConfigParam(TypedDict, total=False):
- interim_results: bool
- """Whether to send also interim results.
-
- If set to false, only final results will be sent.
- """
-
- transcription_engine: Literal["AssemblyAI"]
- """Engine identifier for AssemblyAI transcription service"""
-
- transcription_model: Literal["assemblyai/universal-streaming"]
- """The model to use for transcription."""
diff --git a/src/telnyx/types/calls/transcription_engine_xai_config_param.py b/src/telnyx/types/calls/transcription_engine_xai_config_param.py
deleted file mode 100644
index 66256ff0..00000000
--- a/src/telnyx/types/calls/transcription_engine_xai_config_param.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, TypedDict
-
-__all__ = ["TranscriptionEngineXaiConfigParam"]
-
-
-class TranscriptionEngineXaiConfigParam(TypedDict, total=False):
- interim_results: bool
- """Whether to send also interim results.
-
- If set to false, only final results will be sent.
- """
-
- language: Literal[
- "ar",
- "cs",
- "da",
- "de",
- "en",
- "es",
- "fa",
- "fil",
- "fr",
- "hi",
- "id",
- "it",
- "ja",
- "ko",
- "mk",
- "ms",
- "nl",
- "pl",
- "pt",
- "ro",
- "ru",
- "sv",
- "th",
- "tr",
- "vi",
- ]
- """Language to use for speech recognition"""
-
- transcription_engine: Literal["xAI"]
- """Engine identifier for xAI transcription service"""
-
- transcription_model: Literal["xai/grok-stt"]
- """The model to use for transcription."""
diff --git a/src/telnyx/types/calls/transcription_start_request_param.py b/src/telnyx/types/calls/transcription_start_request_param.py
index 8b6e8ce5..d52231be 100644
--- a/src/telnyx/types/calls/transcription_start_request_param.py
+++ b/src/telnyx/types/calls/transcription_start_request_param.py
@@ -9,20 +9,77 @@
from .deepgram_nova3_config_param import DeepgramNova3ConfigParam
from .transcription_engine_a_config_param import TranscriptionEngineAConfigParam
from .transcription_engine_b_config_param import TranscriptionEngineBConfigParam
-from .transcription_engine_xai_config_param import TranscriptionEngineXaiConfigParam
from .transcription_engine_azure_config_param import TranscriptionEngineAzureConfigParam
from .transcription_engine_google_config_param import TranscriptionEngineGoogleConfigParam
from .transcription_engine_telnyx_config_param import TranscriptionEngineTelnyxConfigParam
-from .transcription_engine_assemblyai_config_param import TranscriptionEngineAssemblyaiConfigParam
__all__ = [
"TranscriptionStartRequestParam",
"TranscriptionEngineConfig",
+ "TranscriptionEngineConfigTranscriptionEngineXaiConfig",
+ "TranscriptionEngineConfigTranscriptionEngineAssemblyaiConfig",
"TranscriptionEngineConfigTranscriptionEngineSpeechmaticsConfig",
"TranscriptionEngineConfigTranscriptionEngineSonioxConfig",
]
+class TranscriptionEngineConfigTranscriptionEngineXaiConfig(TypedDict, total=False):
+ interim_results: bool
+ """Whether to send also interim results.
+
+ If set to false, only final results will be sent.
+ """
+
+ language: Literal[
+ "ar",
+ "cs",
+ "da",
+ "de",
+ "en",
+ "es",
+ "fa",
+ "fil",
+ "fr",
+ "hi",
+ "id",
+ "it",
+ "ja",
+ "ko",
+ "mk",
+ "ms",
+ "nl",
+ "pl",
+ "pt",
+ "ro",
+ "ru",
+ "sv",
+ "th",
+ "tr",
+ "vi",
+ ]
+ """Language to use for speech recognition"""
+
+ transcription_engine: Literal["xAI"]
+ """Engine identifier for xAI transcription service"""
+
+ transcription_model: Literal["xai/grok-stt"]
+ """The model to use for transcription."""
+
+
+class TranscriptionEngineConfigTranscriptionEngineAssemblyaiConfig(TypedDict, total=False):
+ interim_results: bool
+ """Whether to send also interim results.
+
+ If set to false, only final results will be sent.
+ """
+
+ transcription_engine: Literal["AssemblyAI"]
+ """Engine identifier for AssemblyAI transcription service"""
+
+ transcription_model: Literal["assemblyai/universal-streaming"]
+ """The model to use for transcription."""
+
+
class TranscriptionEngineConfigTranscriptionEngineSpeechmaticsConfig(TypedDict, total=False):
interim_results: bool
"""Whether to send also interim results.
@@ -95,8 +152,8 @@ class TranscriptionEngineConfigTranscriptionEngineSonioxConfig(TypedDict, total=
TranscriptionEngineGoogleConfigParam,
TranscriptionEngineTelnyxConfigParam,
TranscriptionEngineAzureConfigParam,
- TranscriptionEngineXaiConfigParam,
- TranscriptionEngineAssemblyaiConfigParam,
+ TranscriptionEngineConfigTranscriptionEngineXaiConfig,
+ TranscriptionEngineConfigTranscriptionEngineAssemblyaiConfig,
TranscriptionEngineConfigTranscriptionEngineSpeechmaticsConfig,
TranscriptionEngineConfigTranscriptionEngineSonioxConfig,
TranscriptionEngineAConfigParam,
diff --git a/src/telnyx/types/conferences/action_speak_params.py b/src/telnyx/types/conferences/action_speak_params.py
index 99490c47..c6d0ce88 100644
--- a/src/telnyx/types/conferences/action_speak_params.py
+++ b/src/telnyx/types/conferences/action_speak_params.py
@@ -7,7 +7,6 @@
from ..._types import SequenceNotStr
from ..calls.aws_voice_settings_param import AwsVoiceSettingsParam
-from ..shared_params.xai_voice_settings import XaiVoiceSettings
from ..calls.telnyx_voice_settings_param import TelnyxVoiceSettingsParam
from ..shared_params.rime_voice_settings import RimeVoiceSettings
from ..shared_params.azure_voice_settings import AzureVoiceSettings
@@ -15,7 +14,7 @@
from ..shared_params.resemble_voice_settings import ResembleVoiceSettings
from ..calls.eleven_labs_voice_settings_param import ElevenLabsVoiceSettingsParam
-__all__ = ["ActionSpeakParams", "VoiceSettings", "VoiceSettingsInworldVoiceSettings"]
+__all__ = ["ActionSpeakParams", "VoiceSettings", "VoiceSettingsInworldVoiceSettings", "VoiceSettingsXaiVoiceSettings"]
class ActionSpeakParams(TypedDict, total=False):
@@ -140,6 +139,14 @@ class VoiceSettingsInworldVoiceSettings(TypedDict, total=False):
"""Voice settings provider type"""
+class VoiceSettingsXaiVoiceSettings(TypedDict, total=False):
+ type: Required[Literal["xai"]]
+ """Voice settings provider type"""
+
+ language: str
+ """Language code, or `auto` to detect automatically."""
+
+
VoiceSettings: TypeAlias = Union[
ElevenLabsVoiceSettingsParam,
TelnyxVoiceSettingsParam,
@@ -149,5 +156,5 @@ class VoiceSettingsInworldVoiceSettings(TypedDict, total=False):
RimeVoiceSettings,
ResembleVoiceSettings,
VoiceSettingsInworldVoiceSettings,
- XaiVoiceSettings,
+ VoiceSettingsXaiVoiceSettings,
]
diff --git a/src/telnyx/types/dir/__init__.py b/src/telnyx/types/dir/__init__.py
new file mode 100644
index 00000000..948ad449
--- /dev/null
+++ b/src/telnyx/types/dir/__init__.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .comment_list_params import CommentListParams as CommentListParams
+from .comment_create_params import CommentCreateParams as CommentCreateParams
+from .comment_list_response import CommentListResponse as CommentListResponse
+from .comment_create_response import CommentCreateResponse as CommentCreateResponse
+from .phone_number_add_params import PhoneNumberAddParams as PhoneNumberAddParams
+from .phone_number_list_params import PhoneNumberListParams as PhoneNumberListParams
+from .phone_number_add_response import PhoneNumberAddResponse as PhoneNumberAddResponse
+from .phone_number_list_response import PhoneNumberListResponse as PhoneNumberListResponse
+from .phone_number_remove_params import PhoneNumberRemoveParams as PhoneNumberRemoveParams
+from .phone_number_remove_response import PhoneNumberRemoveResponse as PhoneNumberRemoveResponse
+from .phone_number_batch_list_params import PhoneNumberBatchListParams as PhoneNumberBatchListParams
+from .phone_number_batch_list_response import PhoneNumberBatchListResponse as PhoneNumberBatchListResponse
+from .phone_number_batch_retrieve_response import PhoneNumberBatchRetrieveResponse as PhoneNumberBatchRetrieveResponse
diff --git a/src/telnyx/types/dir/comment_create_params.py b/src/telnyx/types/dir/comment_create_params.py
new file mode 100644
index 00000000..a2bc419b
--- /dev/null
+++ b/src/telnyx/types/dir/comment_create_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 Required, TypedDict
+
+__all__ = ["CommentCreateParams"]
+
+
+class CommentCreateParams(TypedDict, total=False):
+ content: Required[str]
+ """Comment body. 1–5000 characters."""
+
+ parent_comment_id: str
+ """Optional parent comment id to thread this reply under."""
diff --git a/src/telnyx/types/dir/comment_create_response.py b/src/telnyx/types/dir/comment_create_response.py
new file mode 100644
index 00000000..0664c1e2
--- /dev/null
+++ b/src/telnyx/types/dir/comment_create_response.py
@@ -0,0 +1,51 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["CommentCreateResponse", "Data"]
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ author_name: Optional[str] = None
+ """Display name of the author. May be `null`."""
+
+ author_role: Optional[Literal["customer", "admin"]] = None
+ """Who wrote the comment. `admin` covers the Telnyx vetting team."""
+
+ comment_type: Optional[
+ Literal[
+ "vetting_comment",
+ "rejection_reason",
+ "internal_note",
+ "notification",
+ "status_update",
+ "customer_inquiry",
+ "admin_response",
+ ]
+ ] = None
+ """Comment categorisation.
+
+ Customers post `customer_inquiry`. The Telnyx team posts `vetting_comment`,
+ `rejection_reason`, `notification`, `status_update`, or `admin_response`.
+ `internal_note` is filtered out of customer-visible responses.
+ """
+
+ content: Optional[str] = None
+
+ created_at: Optional[datetime] = None
+
+ entity_type: Optional[Literal["dir"]] = None
+ """Resource the comment is attached to. Always `dir` on this endpoint."""
+
+ visibility: Optional[Literal["customer"]] = None
+ """Always `customer` on this endpoint — internal-only comments are filtered out."""
+
+
+class CommentCreateResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/dir/comment_list_params.py b/src/telnyx/types/dir/comment_list_params.py
new file mode 100644
index 00000000..2d718f27
--- /dev/null
+++ b/src/telnyx/types/dir/comment_list_params.py
@@ -0,0 +1,35 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["CommentListParams"]
+
+
+class CommentListParams(TypedDict, total=False):
+ comment_type: Literal[
+ "vetting_comment",
+ "rejection_reason",
+ "internal_note",
+ "notification",
+ "status_update",
+ "customer_inquiry",
+ "admin_response",
+ ]
+ """Restrict to comments of this category.
+
+ Customer-visible categories only: internal-only comments are filtered out
+ regardless of this filter.
+ """
+
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """Items per page. Maximum 250; values above are clamped to 250."""
diff --git a/src/telnyx/types/dir/comment_list_response.py b/src/telnyx/types/dir/comment_list_response.py
new file mode 100644
index 00000000..6becf4f2
--- /dev/null
+++ b/src/telnyx/types/dir/comment_list_response.py
@@ -0,0 +1,47 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["CommentListResponse"]
+
+
+class CommentListResponse(BaseModel):
+ id: Optional[str] = None
+
+ author_name: Optional[str] = None
+ """Display name of the author. May be `null`."""
+
+ author_role: Optional[Literal["customer", "admin"]] = None
+ """Who wrote the comment. `admin` covers the Telnyx vetting team."""
+
+ comment_type: Optional[
+ Literal[
+ "vetting_comment",
+ "rejection_reason",
+ "internal_note",
+ "notification",
+ "status_update",
+ "customer_inquiry",
+ "admin_response",
+ ]
+ ] = None
+ """Comment categorisation.
+
+ Customers post `customer_inquiry`. The Telnyx team posts `vetting_comment`,
+ `rejection_reason`, `notification`, `status_update`, or `admin_response`.
+ `internal_note` is filtered out of customer-visible responses.
+ """
+
+ content: Optional[str] = None
+
+ created_at: Optional[datetime] = None
+
+ entity_type: Optional[Literal["dir"]] = None
+ """Resource the comment is attached to. Always `dir` on this endpoint."""
+
+ visibility: Optional[Literal["customer"]] = None
+ """Always `customer` on this endpoint — internal-only comments are filtered out."""
diff --git a/src/telnyx/types/dir/phone_number_add_params.py b/src/telnyx/types/dir/phone_number_add_params.py
new file mode 100644
index 00000000..d19f394a
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_add_params.py
@@ -0,0 +1,61 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Literal, Required, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = ["PhoneNumberAddParams", "Document"]
+
+
+class PhoneNumberAddParams(TypedDict, total=False):
+ documents: Required[Iterable[Document]]
+ """Supporting documents covering this batch.
+
+ At least one entry with `document_type: letter_of_authorization` is required —
+ the LOA authorises Telnyx to register these numbers under the DIR. Each
+ `document_id` must come from the Telnyx Documents API. Additional document types
+ (e.g. business registration) may be included alongside the LOA.
+ """
+
+ phone_numbers: Required[SequenceNotStr[str]]
+ """1–15 phone numbers in E.164 format.
+
+ 10-digit US numbers are auto-prefixed with `1`.
+ """
+
+
+class Document(TypedDict, total=False):
+ document_id: Required[str]
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Required[
+ Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: str
diff --git a/src/telnyx/types/dir/phone_number_add_response.py b/src/telnyx/types/dir/phone_number_add_response.py
new file mode 100644
index 00000000..8bafc2aa
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_add_response.py
@@ -0,0 +1,82 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["PhoneNumberAddResponse", "Data", "DataRejectionReason"]
+
+
+class DataRejectionReason(BaseModel):
+ """Populated when `status` is `unsuccessful` or `permanently_rejected`."""
+
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ batch_id: Optional[str] = None
+ """Id of the batch this number was vetted as part of."""
+
+ created_at: Optional[datetime] = None
+
+ dir_id: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ loa_document_id: Optional[str] = None
+ """Id of the Letter of Authorization document attached to this number's batch."""
+
+ phone_number: Optional[str] = None
+ """E.164 with leading `+`."""
+
+ rejection_reason: Optional[DataRejectionReason] = None
+ """Populated when `status` is `unsuccessful` or `permanently_rejected`."""
+
+ status: Optional[
+ Literal["submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"]
+ ] = None
+ """Phone-number lifecycle status.
+
+ - `submitted` / `in_review` — Telnyx is reviewing the batch this number belongs
+ to.
+ - `verified` — approved; the DIR's display identity will be shown on outbound
+ calls from this number.
+ - `unsuccessful` — Telnyx rejected this submission; the customer may re-add to
+ retry.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim on
+ the DIR).
+ - `expired` — verification expired; re-add to renew.
+ - `permanently_rejected` — terminal; cannot be re-added on this or any other DIR
+ you own.
+ """
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
+
+
+class PhoneNumberAddResponse(BaseModel):
+ """Bulk-add success response (HTTP 201).
+
+ All numbers in the request were accepted into a single new batch. Every entry in `data` shares the same `batch_id` — read it from any element to obtain the batch id for subsequent `GET .../phone_number_batches/{batch_id}` calls. If any number in the request fails (schema-invalid, not in inventory, already attached to another DIR, etc.) the entire request is rejected with HTTP 400 and the canonical Telnyx error envelope; the success body described here is therefore an all-or-nothing payload.
+ """
+
+ data: List[Data]
+ """Phone numbers accepted into the new batch.
+
+ List order mirrors the request order. Each element shares the same `batch_id`.
+ """
diff --git a/src/telnyx/types/dir/phone_number_batch_list_params.py b/src/telnyx/types/dir/phone_number_batch_list_params.py
new file mode 100644
index 00000000..606c5ca0
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_batch_list_params.py
@@ -0,0 +1,26 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["PhoneNumberBatchListParams"]
+
+
+class PhoneNumberBatchListParams(TypedDict, total=False):
+ filter_status: Annotated[
+ Literal["submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"],
+ PropertyInfo(alias="filter[status]"),
+ ]
+ """Restrict to batches whose aggregate status equals this value."""
+
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """Items per page. Maximum 250; values above are clamped to 250."""
diff --git a/src/telnyx/types/dir/phone_number_batch_list_response.py b/src/telnyx/types/dir/phone_number_batch_list_response.py
new file mode 100644
index 00000000..0139f9b5
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_batch_list_response.py
@@ -0,0 +1,141 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["PhoneNumberBatchListResponse", "Document", "PhoneNumber", "PhoneNumberRejectionReason"]
+
+
+class Document(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class PhoneNumberRejectionReason(BaseModel):
+ """Populated when `status` is `unsuccessful` or `permanently_rejected`."""
+
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class PhoneNumber(BaseModel):
+ id: Optional[str] = None
+
+ batch_id: Optional[str] = None
+ """Id of the batch this number was vetted as part of."""
+
+ created_at: Optional[datetime] = None
+
+ dir_id: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ loa_document_id: Optional[str] = None
+ """Id of the Letter of Authorization document attached to this number's batch."""
+
+ phone_number: Optional[str] = None
+ """E.164 with leading `+`."""
+
+ rejection_reason: Optional[PhoneNumberRejectionReason] = None
+ """Populated when `status` is `unsuccessful` or `permanently_rejected`."""
+
+ status: Optional[
+ Literal["submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"]
+ ] = None
+ """Phone-number lifecycle status.
+
+ - `submitted` / `in_review` — Telnyx is reviewing the batch this number belongs
+ to.
+ - `verified` — approved; the DIR's display identity will be shown on outbound
+ calls from this number.
+ - `unsuccessful` — Telnyx rejected this submission; the customer may re-add to
+ retry.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim on
+ the DIR).
+ - `expired` — verification expired; re-add to renew.
+ - `permanently_rejected` — terminal; cannot be re-added on this or any other DIR
+ you own.
+ """
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
+
+
+class PhoneNumberBatchListResponse(BaseModel):
+ """A phone-number batch groups all numbers added in a single bulk-add request.
+
+ Telnyx vets the batch as a unit. The response embeds the full `phone_numbers` array so you can read per-number status without a separate call, plus a batch-level `status` summarising the unit's progress.
+ """
+
+ batch_id: Optional[str] = None
+
+ dir_display_name: Optional[str] = None
+ """The DIR's display name at the time the batch was read."""
+
+ dir_id: Optional[str] = None
+
+ documents: Optional[List[Document]] = None
+ """Documents attached to this batch (e.g.
+
+ a Letter of Authorization). Empty when none were supplied at add time.
+ """
+
+ enterprise_id: Optional[str] = None
+
+ phone_numbers: Optional[List[PhoneNumber]] = None
+ """All phone numbers in this batch, with per-number status."""
+
+ status: Optional[
+ Literal["submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"]
+ ] = None
+ """Aggregate batch status.
+
+ Mirrors the values used on individual phone numbers (`submitted`, `in_review`,
+ `verified`, `unsuccessful`, `permanently_rejected`, etc.).
+ """
+
+ submitted_at: Optional[datetime] = None
+ """When the batch was created (and implicitly submitted for vetting)."""
+
+ total_count: Optional[int] = None
+ """Number of phone numbers in this batch (length of `phone_numbers`)."""
diff --git a/src/telnyx/types/dir/phone_number_batch_retrieve_response.py b/src/telnyx/types/dir/phone_number_batch_retrieve_response.py
new file mode 100644
index 00000000..76d62b70
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_batch_retrieve_response.py
@@ -0,0 +1,157 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = [
+ "PhoneNumberBatchRetrieveResponse",
+ "Data",
+ "DataDocument",
+ "DataPhoneNumber",
+ "DataPhoneNumberRejectionReason",
+]
+
+
+class DataDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class DataPhoneNumberRejectionReason(BaseModel):
+ """Populated when `status` is `unsuccessful` or `permanently_rejected`."""
+
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class DataPhoneNumber(BaseModel):
+ id: Optional[str] = None
+
+ batch_id: Optional[str] = None
+ """Id of the batch this number was vetted as part of."""
+
+ created_at: Optional[datetime] = None
+
+ dir_id: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ loa_document_id: Optional[str] = None
+ """Id of the Letter of Authorization document attached to this number's batch."""
+
+ phone_number: Optional[str] = None
+ """E.164 with leading `+`."""
+
+ rejection_reason: Optional[DataPhoneNumberRejectionReason] = None
+ """Populated when `status` is `unsuccessful` or `permanently_rejected`."""
+
+ status: Optional[
+ Literal["submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"]
+ ] = None
+ """Phone-number lifecycle status.
+
+ - `submitted` / `in_review` — Telnyx is reviewing the batch this number belongs
+ to.
+ - `verified` — approved; the DIR's display identity will be shown on outbound
+ calls from this number.
+ - `unsuccessful` — Telnyx rejected this submission; the customer may re-add to
+ retry.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim on
+ the DIR).
+ - `expired` — verification expired; re-add to renew.
+ - `permanently_rejected` — terminal; cannot be re-added on this or any other DIR
+ you own.
+ """
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
+
+
+class Data(BaseModel):
+ """A phone-number batch groups all numbers added in a single bulk-add request.
+
+ Telnyx vets the batch as a unit. The response embeds the full `phone_numbers` array so you can read per-number status without a separate call, plus a batch-level `status` summarising the unit's progress.
+ """
+
+ batch_id: Optional[str] = None
+
+ dir_display_name: Optional[str] = None
+ """The DIR's display name at the time the batch was read."""
+
+ dir_id: Optional[str] = None
+
+ documents: Optional[List[DataDocument]] = None
+ """Documents attached to this batch (e.g.
+
+ a Letter of Authorization). Empty when none were supplied at add time.
+ """
+
+ enterprise_id: Optional[str] = None
+
+ phone_numbers: Optional[List[DataPhoneNumber]] = None
+ """All phone numbers in this batch, with per-number status."""
+
+ status: Optional[
+ Literal["submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"]
+ ] = None
+ """Aggregate batch status.
+
+ Mirrors the values used on individual phone numbers (`submitted`, `in_review`,
+ `verified`, `unsuccessful`, `permanently_rejected`, etc.).
+ """
+
+ submitted_at: Optional[datetime] = None
+ """When the batch was created (and implicitly submitted for vetting)."""
+
+ total_count: Optional[int] = None
+ """Number of phone numbers in this batch (length of `phone_numbers`)."""
+
+
+class PhoneNumberBatchRetrieveResponse(BaseModel):
+ data: Data
+ """A phone-number batch groups all numbers added in a single bulk-add request.
+
+ Telnyx vets the batch as a unit. The response embeds the full `phone_numbers`
+ array so you can read per-number status without a separate call, plus a
+ batch-level `status` summarising the unit's progress.
+ """
diff --git a/src/telnyx/types/dir/phone_number_list_params.py b/src/telnyx/types/dir/phone_number_list_params.py
new file mode 100644
index 00000000..5d4ff87f
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_list_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_extensions import Literal, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["PhoneNumberListParams"]
+
+
+class PhoneNumberListParams(TypedDict, total=False):
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """Items per page. Maximum 250; values above are clamped to 250."""
+
+ status: Literal[
+ "submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"
+ ]
+ """Filter by phone-number status."""
diff --git a/src/telnyx/types/dir/phone_number_list_response.py b/src/telnyx/types/dir/phone_number_list_response.py
new file mode 100644
index 00000000..d7c59404
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_list_response.py
@@ -0,0 +1,69 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["PhoneNumberListResponse", "RejectionReason"]
+
+
+class RejectionReason(BaseModel):
+ """Populated when `status` is `unsuccessful` or `permanently_rejected`."""
+
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class PhoneNumberListResponse(BaseModel):
+ id: Optional[str] = None
+
+ batch_id: Optional[str] = None
+ """Id of the batch this number was vetted as part of."""
+
+ created_at: Optional[datetime] = None
+
+ dir_id: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ loa_document_id: Optional[str] = None
+ """Id of the Letter of Authorization document attached to this number's batch."""
+
+ phone_number: Optional[str] = None
+ """E.164 with leading `+`."""
+
+ rejection_reason: Optional[RejectionReason] = None
+ """Populated when `status` is `unsuccessful` or `permanently_rejected`."""
+
+ status: Optional[
+ Literal["submitted", "in_review", "verified", "unsuccessful", "suspended", "expired", "permanently_rejected"]
+ ] = None
+ """Phone-number lifecycle status.
+
+ - `submitted` / `in_review` — Telnyx is reviewing the batch this number belongs
+ to.
+ - `verified` — approved; the DIR's display identity will be shown on outbound
+ calls from this number.
+ - `unsuccessful` — Telnyx rejected this submission; the customer may re-add to
+ retry.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim on
+ the DIR).
+ - `expired` — verification expired; re-add to renew.
+ - `permanently_rejected` — terminal; cannot be re-added on this or any other DIR
+ you own.
+ """
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
diff --git a/src/telnyx/types/dir/phone_number_remove_params.py b/src/telnyx/types/dir/phone_number_remove_params.py
new file mode 100644
index 00000000..1e695d95
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_remove_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = ["PhoneNumberRemoveParams"]
+
+
+class PhoneNumberRemoveParams(TypedDict, total=False):
+ phone_numbers: Required[SequenceNotStr[str]]
diff --git a/src/telnyx/types/dir/phone_number_remove_response.py b/src/telnyx/types/dir/phone_number_remove_response.py
new file mode 100644
index 00000000..a69d231c
--- /dev/null
+++ b/src/telnyx/types/dir/phone_number_remove_response.py
@@ -0,0 +1,48 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["PhoneNumberRemoveResponse", "Meta", "MetaError"]
+
+
+class MetaError(BaseModel):
+ """Per-number error returned by the bulk-delete endpoint.
+
+ Bulk-add does not use this shape — it returns a 400 with the canonical envelope grouping numbers by failure category.
+ """
+
+ code: Literal["not_associated"]
+ """Stable per-number error code.
+
+ Currently only `not_associated` is emitted, when the number is not attached to
+ this DIR.
+ """
+
+ detail: str
+
+ phone_number: str
+
+ title: str
+
+
+class Meta(BaseModel):
+ errors: List[MetaError]
+ """Per-number failures that did not block the call.
+
+ Each entry has `phone_number`, `code`, `title`, `detail`.
+ """
+
+
+class PhoneNumberRemoveResponse(BaseModel):
+ """Bulk-delete partial-success response.
+
+ `data` is the list of phone numbers that were soft-deleted. `meta.errors` holds per-number failures (e.g. number not associated with this DIR). When EVERY number in the request fails, the endpoint instead returns 400 with the canonical Telnyx error envelope and `data`/`meta` are absent.
+ """
+
+ data: List[str]
+ """Phone numbers that were successfully soft-deleted. Bare E.164 strings."""
+
+ meta: Meta
diff --git a/src/telnyx/types/dir_list_document_types_response.py b/src/telnyx/types/dir_list_document_types_response.py
new file mode 100644
index 00000000..636035d3
--- /dev/null
+++ b/src/telnyx/types/dir_list_document_types_response.py
@@ -0,0 +1,50 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from .._models import BaseModel
+
+__all__ = ["DirListDocumentTypesResponse", "Data", "Meta"]
+
+
+class Data(BaseModel):
+ """Single supported document type."""
+
+ description: Optional[str] = None
+
+ short_name: Optional[str] = None
+ """Stable identifier passed to `Document.document_type`."""
+
+
+class Meta(BaseModel):
+ """JSON:API pagination metadata returned with every paginated list response.
+
+ Page numbering is 1-based. `page_size` reports the number of items actually returned in `data` for this page; the requested size is taken from the `page[size]` query parameter.
+ """
+
+ page_number: int
+ """1-based index of this page.
+
+ Echoes the `page[number]` query parameter (default `1`).
+ """
+
+ page_size: int
+ """Number of items returned in this page's `data` array. Capped at 250."""
+
+ total_pages: int
+ """Total number of pages available given the current `page_size`."""
+
+ total_results: int
+ """Total number of items across all pages (excludes soft-deleted rows)."""
+
+
+class DirListDocumentTypesResponse(BaseModel):
+ data: List[Data]
+
+ meta: Meta
+ """JSON:API pagination metadata returned with every paginated list response.
+
+ Page numbering is 1-based. `page_size` reports the number of items actually
+ returned in `data` for this page; the requested size is taken from the
+ `page[size]` query parameter.
+ """
diff --git a/src/telnyx/types/dir_list_infringement_claims_params.py b/src/telnyx/types/dir_list_infringement_claims_params.py
new file mode 100644
index 00000000..930ed1f3
--- /dev/null
+++ b/src/telnyx/types/dir_list_infringement_claims_params.py
@@ -0,0 +1,20 @@
+# 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__ = ["DirListInfringementClaimsParams"]
+
+
+class DirListInfringementClaimsParams(TypedDict, total=False):
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """Items per page. Maximum 250; values above are clamped to 250."""
diff --git a/src/telnyx/types/dir_list_infringement_claims_response.py b/src/telnyx/types/dir_list_infringement_claims_response.py
new file mode 100644
index 00000000..fc33b3b1
--- /dev/null
+++ b/src/telnyx/types/dir_list_infringement_claims_response.py
@@ -0,0 +1,145 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DirListInfringementClaimsResponse", "ContestDocument", "ContestHistory", "Dir"]
+
+
+class ContestDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class ContestHistory(BaseModel):
+ """One round of customer contest evidence on an infringement claim.
+
+ The aggregated documents across rounds live on the parent claim's `contest_documents`; this submission record carries only the per-round notes and document count.
+ """
+
+ document_count: Optional[int] = None
+
+ notes: Optional[str] = None
+
+ submitted_at: Optional[datetime] = None
+
+
+class Dir(BaseModel):
+ """Snapshot of the DIR the claim is filed against, embedded for convenience."""
+
+ id: Optional[str] = None
+
+ display_name: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+
+class DirListInfringementClaimsResponse(BaseModel):
+ id: Optional[str] = None
+
+ claim_date: Optional[datetime] = None
+ """When the claim was filed (set by the claimant's representative at file time)."""
+
+ claim_description: Optional[str] = None
+
+ claim_type: Optional[Literal["trademark", "copyright"]] = None
+ """Category of infringement being claimed."""
+
+ claimant_contact: Optional[str] = None
+
+ claimant_name: Optional[str] = None
+
+ contest_documents: Optional[List[ContestDocument]] = None
+ """Aggregated across all customer contest submissions on this claim."""
+
+ contest_history: Optional[List[ContestHistory]] = None
+ """Per-round submission audit trail.
+
+ Each entry records one `POST /infringement_claims/{id}/contest` call (notes,
+ timestamp, document count). Aggregated documents live on `contest_documents`.
+ """
+
+ created_at: Optional[datetime] = None
+
+ dir: Optional[Dir] = None
+ """Snapshot of the DIR the claim is filed against, embedded for convenience."""
+
+ dir_id: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ resolution: Optional[Literal["upheld", "rejected", "modified"]] = None
+ """Set only when `status` is `resolved`."""
+
+ resolution_date: Optional[datetime] = None
+
+ resolution_notes: Optional[str] = None
+
+ status: Optional[Literal["pending", "contested", "resolved"]] = None
+ """Lifecycle status.
+
+ `pending` — newly filed; the DIR is auto-suspended. `contested` — you have
+ submitted contest evidence; awaiting Telnyx review. `resolved` — final.
+ """
+
+ updated_at: Optional[datetime] = None
diff --git a/src/telnyx/types/dir_list_params.py b/src/telnyx/types/dir_list_params.py
new file mode 100644
index 00000000..ed19064c
--- /dev/null
+++ b/src/telnyx/types/dir_list_params.py
@@ -0,0 +1,64 @@
+# 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__ = ["DirListParams"]
+
+
+class DirListParams(TypedDict, total=False):
+ enterprise_id: str
+ """Restrict results to a single enterprise."""
+
+ filter_expiring_at_gte: Annotated[
+ Union[str, datetime], PropertyInfo(alias="filter[expiring_at][gte]", format="iso8601")
+ ]
+ """Return only DIRs whose `expiring_at` is at or after this ISO-8601 timestamp.
+
+ Pairs with the `[lte]` variant to build renewal-window dashboards.
+ """
+
+ filter_expiring_at_lte: Annotated[
+ Union[str, datetime], PropertyInfo(alias="filter[expiring_at][lte]", format="iso8601")
+ ]
+ """Return only DIRs whose `expiring_at` is at or before this ISO-8601 timestamp."""
+
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """Items per page. Maximum 250; values above are clamped to 250."""
+
+ search: str
+ """Case-insensitive partial match on `display_name` or call reason."""
+
+ sort: Literal[
+ "created_at", "-created_at", "updated_at", "-updated_at", "display_name", "-display_name", "status", "-status"
+ ]
+ """Sort field.
+
+ Allowed values: `created_at`, `updated_at`, `display_name`, `status`. Prefix
+ with `-` for descending. Default `-created_at`.
+ """
+
+ status: Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ """Filter by DIR status."""
diff --git a/src/telnyx/types/dir_list_response.py b/src/telnyx/types/dir_list_response.py
new file mode 100644
index 00000000..4954d44d
--- /dev/null
+++ b/src/telnyx/types/dir_list_response.py
@@ -0,0 +1,135 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DirListResponse", "CallReason", "Document", "RejectionReason"]
+
+
+class CallReason(BaseModel):
+ created_at: Optional[datetime] = None
+
+ reason: Optional[str] = None
+
+
+class Document(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class RejectionReason(BaseModel):
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class DirListResponse(BaseModel):
+ id: Optional[str] = None
+
+ authorizer_email: Optional[str] = None
+
+ authorizer_name: Optional[str] = None
+
+ call_reasons: Optional[List[CallReason]] = None
+
+ certify_brand_is_accurate: Optional[bool] = None
+
+ certify_ip_ownership: Optional[bool] = None
+
+ certify_no_shaft_content: Optional[bool] = None
+
+ created_at: Optional[datetime] = None
+
+ display_name: Optional[str] = None
+
+ documents: Optional[List[Document]] = None
+
+ enterprise_id: Optional[str] = None
+
+ expiring_at: Optional[datetime] = None
+
+ logo_url: Optional[str] = None
+
+ rejected_at: Optional[datetime] = None
+
+ rejection_reasons: Optional[List[RejectionReason]] = None
+ """
+ Populated when `status` is `rejected`; cleared on `/submit` or successful
+ approval.
+ """
+
+ reselling: Optional[bool] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+ submitted_at: Optional[datetime] = None
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
diff --git a/src/telnyx/types/dir_retrieve_response.py b/src/telnyx/types/dir_retrieve_response.py
new file mode 100644
index 00000000..f0558c73
--- /dev/null
+++ b/src/telnyx/types/dir_retrieve_response.py
@@ -0,0 +1,139 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DirRetrieveResponse", "Data", "DataCallReason", "DataDocument", "DataRejectionReason"]
+
+
+class DataCallReason(BaseModel):
+ created_at: Optional[datetime] = None
+
+ reason: Optional[str] = None
+
+
+class DataDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class DataRejectionReason(BaseModel):
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ authorizer_email: Optional[str] = None
+
+ authorizer_name: Optional[str] = None
+
+ call_reasons: Optional[List[DataCallReason]] = None
+
+ certify_brand_is_accurate: Optional[bool] = None
+
+ certify_ip_ownership: Optional[bool] = None
+
+ certify_no_shaft_content: Optional[bool] = None
+
+ created_at: Optional[datetime] = None
+
+ display_name: Optional[str] = None
+
+ documents: Optional[List[DataDocument]] = None
+
+ enterprise_id: Optional[str] = None
+
+ expiring_at: Optional[datetime] = None
+
+ logo_url: Optional[str] = None
+
+ rejected_at: Optional[datetime] = None
+
+ rejection_reasons: Optional[List[DataRejectionReason]] = None
+ """
+ Populated when `status` is `rejected`; cleared on `/submit` or successful
+ approval.
+ """
+
+ reselling: Optional[bool] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+ submitted_at: Optional[datetime] = None
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
+
+
+class DirRetrieveResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/dir_submit_response.py b/src/telnyx/types/dir_submit_response.py
new file mode 100644
index 00000000..89e5ce38
--- /dev/null
+++ b/src/telnyx/types/dir_submit_response.py
@@ -0,0 +1,139 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DirSubmitResponse", "Data", "DataCallReason", "DataDocument", "DataRejectionReason"]
+
+
+class DataCallReason(BaseModel):
+ created_at: Optional[datetime] = None
+
+ reason: Optional[str] = None
+
+
+class DataDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class DataRejectionReason(BaseModel):
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ authorizer_email: Optional[str] = None
+
+ authorizer_name: Optional[str] = None
+
+ call_reasons: Optional[List[DataCallReason]] = None
+
+ certify_brand_is_accurate: Optional[bool] = None
+
+ certify_ip_ownership: Optional[bool] = None
+
+ certify_no_shaft_content: Optional[bool] = None
+
+ created_at: Optional[datetime] = None
+
+ display_name: Optional[str] = None
+
+ documents: Optional[List[DataDocument]] = None
+
+ enterprise_id: Optional[str] = None
+
+ expiring_at: Optional[datetime] = None
+
+ logo_url: Optional[str] = None
+
+ rejected_at: Optional[datetime] = None
+
+ rejection_reasons: Optional[List[DataRejectionReason]] = None
+ """
+ Populated when `status` is `rejected`; cleared on `/submit` or successful
+ approval.
+ """
+
+ reselling: Optional[bool] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+ submitted_at: Optional[datetime] = None
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
+
+
+class DirSubmitResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/dir_update_infringement_params.py b/src/telnyx/types/dir_update_infringement_params.py
new file mode 100644
index 00000000..b59eaf10
--- /dev/null
+++ b/src/telnyx/types/dir_update_infringement_params.py
@@ -0,0 +1,71 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable, Optional
+from typing_extensions import Literal, Required, TypedDict
+
+from .._types import SequenceNotStr
+
+__all__ = ["DirUpdateInfringementParams", "Document"]
+
+
+class DirUpdateInfringementParams(TypedDict, total=False):
+ certify_brand_is_accurate: Required[Literal[True]]
+ """Must be `true`."""
+
+ certify_ip_ownership: Required[Literal[True]]
+ """Must be `true`."""
+
+ certify_no_infringement: Required[Literal[True]]
+ """Must be `true`."""
+
+ certify_no_shaft_content: Required[Literal[True]]
+ """Must be `true`."""
+
+ infringement_resolution_notes: Required[str]
+ """Explanation of how the infringement concern was addressed."""
+
+ call_reasons: Optional[SequenceNotStr[str]]
+
+ display_name: Optional[str]
+
+ documents: Optional[Iterable[Document]]
+ """Append-only supporting documents."""
+
+ logo_url: Optional[str]
+ """Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB)."""
+
+
+class Document(TypedDict, total=False):
+ document_id: Required[str]
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Required[
+ Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: str
diff --git a/src/telnyx/types/dir_update_infringement_response.py b/src/telnyx/types/dir_update_infringement_response.py
new file mode 100644
index 00000000..f86071fa
--- /dev/null
+++ b/src/telnyx/types/dir_update_infringement_response.py
@@ -0,0 +1,139 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DirUpdateInfringementResponse", "Data", "DataCallReason", "DataDocument", "DataRejectionReason"]
+
+
+class DataCallReason(BaseModel):
+ created_at: Optional[datetime] = None
+
+ reason: Optional[str] = None
+
+
+class DataDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class DataRejectionReason(BaseModel):
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ authorizer_email: Optional[str] = None
+
+ authorizer_name: Optional[str] = None
+
+ call_reasons: Optional[List[DataCallReason]] = None
+
+ certify_brand_is_accurate: Optional[bool] = None
+
+ certify_ip_ownership: Optional[bool] = None
+
+ certify_no_shaft_content: Optional[bool] = None
+
+ created_at: Optional[datetime] = None
+
+ display_name: Optional[str] = None
+
+ documents: Optional[List[DataDocument]] = None
+
+ enterprise_id: Optional[str] = None
+
+ expiring_at: Optional[datetime] = None
+
+ logo_url: Optional[str] = None
+
+ rejected_at: Optional[datetime] = None
+
+ rejection_reasons: Optional[List[DataRejectionReason]] = None
+ """
+ Populated when `status` is `rejected`; cleared on `/submit` or successful
+ approval.
+ """
+
+ reselling: Optional[bool] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+ submitted_at: Optional[datetime] = None
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
+
+
+class DirUpdateInfringementResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/dir_update_params.py b/src/telnyx/types/dir_update_params.py
new file mode 100644
index 00000000..e82265e7
--- /dev/null
+++ b/src/telnyx/types/dir_update_params.py
@@ -0,0 +1,41 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+from .._types import SequenceNotStr
+
+__all__ = ["DirUpdateParams"]
+
+
+class DirUpdateParams(TypedDict, total=False):
+ authorizer_email: str
+ """Contact email of the authorizer.
+
+ Telnyx may send verification or infringement notices here.
+ """
+
+ authorizer_name: str
+ """Name of the person at your enterprise authorizing this DIR.
+
+ Must be a real individual.
+ """
+
+ call_reasons: SequenceNotStr[str]
+ """1–10 reasons your business calls customers.
+
+ Validate phrasing against `POST /call_reasons/validate`.
+ """
+
+ display_name: str
+ """Name shown to call recipients. 1–35 characters, no emoji, not whitespace-only."""
+
+ logo_url: str
+ """Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB)."""
+
+ reselling: bool
+ """
+ Set to true if your organization places calls on behalf of other enterprises
+ (BPO/reseller). Updating this triggers re-vetting on next submit.
+ """
diff --git a/src/telnyx/types/dir_update_response.py b/src/telnyx/types/dir_update_response.py
new file mode 100644
index 00000000..555c5dc6
--- /dev/null
+++ b/src/telnyx/types/dir_update_response.py
@@ -0,0 +1,139 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["DirUpdateResponse", "Data", "DataCallReason", "DataDocument", "DataRejectionReason"]
+
+
+class DataCallReason(BaseModel):
+ created_at: Optional[datetime] = None
+
+ reason: Optional[str] = None
+
+
+class DataDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class DataRejectionReason(BaseModel):
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ authorizer_email: Optional[str] = None
+
+ authorizer_name: Optional[str] = None
+
+ call_reasons: Optional[List[DataCallReason]] = None
+
+ certify_brand_is_accurate: Optional[bool] = None
+
+ certify_ip_ownership: Optional[bool] = None
+
+ certify_no_shaft_content: Optional[bool] = None
+
+ created_at: Optional[datetime] = None
+
+ display_name: Optional[str] = None
+
+ documents: Optional[List[DataDocument]] = None
+
+ enterprise_id: Optional[str] = None
+
+ expiring_at: Optional[datetime] = None
+
+ logo_url: Optional[str] = None
+
+ rejected_at: Optional[datetime] = None
+
+ rejection_reasons: Optional[List[DataRejectionReason]] = None
+ """
+ Populated when `status` is `rejected`; cleared on `/submit` or successful
+ approval.
+ """
+
+ reselling: Optional[bool] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+ submitted_at: Optional[datetime] = None
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
+
+
+class DirUpdateResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/enterprise_activate_branded_calling_response.py b/src/telnyx/types/enterprise_activate_branded_calling_response.py
new file mode 100644
index 00000000..7d8b87f3
--- /dev/null
+++ b/src/telnyx/types/enterprise_activate_branded_calling_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .._models import BaseModel
+from .enterprise_public import EnterprisePublic
+
+__all__ = ["EnterpriseActivateBrandedCallingResponse"]
+
+
+class EnterpriseActivateBrandedCallingResponse(BaseModel):
+ data: EnterprisePublic
diff --git a/src/telnyx/types/enterprise_create_params.py b/src/telnyx/types/enterprise_create_params.py
index eb3c61b3..96c9e5aa 100644
--- a/src/telnyx/types/enterprise_create_params.py
+++ b/src/telnyx/types/enterprise_create_params.py
@@ -2,6 +2,7 @@
from __future__ import annotations
+from typing import Optional
from typing_extensions import Literal, Required, TypedDict
from .billing_address_param import BillingAddressParam
@@ -18,67 +19,124 @@ class EnterpriseCreateParams(TypedDict, total=False):
billing_contact: Required[BillingContactParam]
country_code: Required[str]
- """Country code. Currently only 'US' is accepted."""
+ """ISO 3166-1 alpha-2 country code. Currently `US` and `CA` are supported."""
doing_business_as: Required[str]
- """Primary business name / DBA name"""
fein: Required[str]
- """Federal Employer Identification Number.
-
- Format: XX-XXXXXXX or 9-digit number (minimum 9 digits).
"""
-
- industry: Required[str]
- """Industry classification.
-
- Case-insensitive. Accepted values: accounting, finance, billing, collections,
- business, charity, nonprofit, communications, telecom, customer service,
- support, delivery, shipping, logistics, education, financial, banking,
- government, public, healthcare, health, pharmacy, medical, insurance, legal,
- law, notifications, scheduling, real estate, property, retail, ecommerce, sales,
- marketing, software, technology, tech, media, surveys, market research, travel,
- hospitality, hotel
+ US Federal Employer Identification Number (`NN-NNNNNNN`) or Canadian equivalent.
"""
+ industry: Required[
+ Literal[
+ "accounting",
+ "finance",
+ "billing",
+ "collections",
+ "business",
+ "charity",
+ "nonprofit",
+ "communications",
+ "telecom",
+ "customer service",
+ "support",
+ "delivery",
+ "shipping",
+ "logistics",
+ "education",
+ "financial",
+ "banking",
+ "government",
+ "public",
+ "healthcare",
+ "health",
+ "pharmacy",
+ "medical",
+ "insurance",
+ "legal",
+ "law",
+ "notifications",
+ "scheduling",
+ "real estate",
+ "property",
+ "retail",
+ "ecommerce",
+ "sales",
+ "marketing",
+ "software",
+ "technology",
+ "tech",
+ "media",
+ "surveys",
+ "market research",
+ "travel",
+ "hospitality",
+ "hotel",
+ ]
+ ]
+ """Industry classification."""
+
+ jurisdiction_of_incorporation: Required[str]
+
legal_name: Required[str]
- """Legal name of the enterprise"""
+ """Legal name of the enterprise."""
number_of_employees: Required[Literal["1-10", "11-50", "51-200", "201-500", "501-2000", "2001-10000", "10001+"]]
- """Employee count range"""
+ """Approximate headcount range.
- organization_contact: Required[OrganizationContactParam]
- """Organization contact information.
-
- Note: the response returns this object with the phone field as 'phone' (not
- 'phone_number').
+ Used for vetting heuristics; pick the bucket that contains your current employee
+ count.
"""
+ organization_contact: Required[OrganizationContactParam]
+
organization_legal_type: Required[Literal["corporation", "llc", "partnership", "nonprofit", "other"]]
- """Legal structure type"""
+ """Legal-entity form. Pick the form that matches your incorporation documents:
+
+ - `corporation` — C-corp or S-corp.
+ - `llc` — limited liability company.
+ - `partnership` — general/limited partnership.
+ - `nonprofit` — non-profit corporation, charitable trust, or
+ 501(c)(3)/equivalent.
+ - `other` — anything else (sole proprietorships, government bodies, DBAs, etc.).
+ You may be asked for additional documents during vetting.
+ """
organization_physical_address: Required[PhysicalAddressParam]
organization_type: Required[Literal["commercial", "government", "non_profit"]]
- """Type of organization"""
+ """Organization category for vetting purposes:
+
+ - `commercial` — for-profit business entities (LLC, corp, partnership, sole
+ proprietorship). Most callers fall here.
+ - `government` — federal/state/local government bodies.
+ - `non_profit` — registered 501(c)(3)/equivalent (incl. educational
+ institutions, charities, religious organisations).
+ """
website: Required[str]
- """Enterprise website URL. Accepts any string — no URL format validation enforced."""
- corporate_registration_number: str
- """Corporate registration number (optional)"""
+ corporate_registration_number: Optional[str]
+ """Optional corporate-registration / company-number identifier."""
customer_reference: str
- """Optional customer reference identifier for your own tracking"""
+ """Optional free-form string the caller can attach for their own bookkeeping.
- dun_bradstreet_number: str
- """D-U-N-S Number (optional)"""
+ Telnyx does not interpret it.
+ """
- primary_business_domain_sic_code: str
- """SIC Code (optional)"""
+ dun_bradstreet_number: Optional[str]
+ """Optional D-U-N-S Number."""
- professional_license_number: str
- """Professional license number (optional)"""
+ primary_business_domain_sic_code: Optional[str]
+ """Optional SIC code for the primary line of business."""
+
+ professional_license_number: Optional[str]
+ """Optional professional-license number for regulated industries."""
role_type: Literal["enterprise", "bpo"]
- """Role type in Branded Calling / Number Reputation services"""
+ """
+ `enterprise` for an organization registering its own DIRs; `bpo` for a Business
+ Process Outsourcer placing calls on behalf of one or more enterprises.
+ """
diff --git a/src/telnyx/types/enterprise_create_response.py b/src/telnyx/types/enterprise_create_response.py
index 82ff1b5f..1b551042 100644
--- a/src/telnyx/types/enterprise_create_response.py
+++ b/src/telnyx/types/enterprise_create_response.py
@@ -1,7 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
-
from .._models import BaseModel
from .enterprise_public import EnterprisePublic
@@ -9,4 +7,4 @@
class EnterpriseCreateResponse(BaseModel):
- data: Optional[EnterprisePublic] = None
+ data: EnterprisePublic
diff --git a/src/telnyx/types/enterprise_list_params.py b/src/telnyx/types/enterprise_list_params.py
index f36a17c5..12f42899 100644
--- a/src/telnyx/types/enterprise_list_params.py
+++ b/src/telnyx/types/enterprise_list_params.py
@@ -11,10 +11,13 @@
class EnterpriseListParams(TypedDict, total=False):
legal_name: str
- """Filter by legal name (partial match)"""
+ """Filter by legal name (partial match)."""
page_number: Annotated[int, PropertyInfo(alias="page[number]")]
- """Page number (1-indexed)"""
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
page_size: Annotated[int, PropertyInfo(alias="page[size]")]
- """Number of items per page"""
+ """Items per page. Default 10. Maximum 250; values above are clamped to 250."""
diff --git a/src/telnyx/types/enterprise_public.py b/src/telnyx/types/enterprise_public.py
index 0ff758c4..2a5665f1 100644
--- a/src/telnyx/types/enterprise_public.py
+++ b/src/telnyx/types/enterprise_public.py
@@ -2,7 +2,6 @@
from typing import Optional
from datetime import datetime
-from typing_extensions import Literal
from .._models import BaseModel
from .billing_address import BillingAddress
@@ -15,70 +14,63 @@
class EnterprisePublic(BaseModel):
id: Optional[str] = None
- """Unique identifier of the enterprise"""
billing_address: Optional[BillingAddress] = None
billing_contact: Optional[BillingContact] = None
+ branded_calling_enabled: Optional[bool] = None
+ """
+ True once Branded Calling has been activated on this enterprise (see
+ `POST /enterprises/{id}/branded_calling`).
+ """
+
corporate_registration_number: Optional[str] = None
- """Corporate registration number"""
+ """Optional corporate-registration / company-number identifier."""
country_code: Optional[str] = None
- """ISO 3166-1 alpha-2 country code"""
created_at: Optional[datetime] = None
- """When the enterprise was created"""
customer_reference: Optional[str] = None
- """Customer reference identifier"""
doing_business_as: Optional[str] = None
- """DBA name"""
dun_bradstreet_number: Optional[str] = None
- """D-U-N-S Number"""
+ """Optional D-U-N-S Number issued by Dun & Bradstreet."""
fein: Optional[str] = None
- """Federal Employer Identification Number"""
industry: Optional[str] = None
- """Industry classification"""
+
+ jurisdiction_of_incorporation: Optional[str] = None
legal_name: Optional[str] = None
- """Legal name of the enterprise"""
- number_of_employees: Optional[Literal["1-10", "11-50", "51-200", "201-500", "501-2000", "2001-10000", "10001+"]] = (
- None
- )
- """Employee count range"""
+ number_of_employees: Optional[str] = None
- organization_contact: Optional[OrganizationContact] = None
- """Organization contact information.
-
- Note: the response returns this object with the phone field as 'phone' (not
- 'phone_number').
+ number_reputation_enabled: Optional[bool] = None
+ """
+ True once Phone Number Reputation has been enabled on this enterprise (see
+ `POST /enterprises/{id}/reputation`).
"""
- organization_legal_type: Optional[Literal["corporation", "llc", "partnership", "nonprofit", "other"]] = None
- """Legal structure type"""
+ organization_contact: Optional[OrganizationContact] = None
+
+ organization_legal_type: Optional[str] = None
organization_physical_address: Optional[PhysicalAddress] = None
- organization_type: Optional[Literal["commercial", "government", "non_profit"]] = None
- """Type of organization"""
+ organization_type: Optional[str] = None
primary_business_domain_sic_code: Optional[str] = None
- """SIC Code"""
+ """Optional SIC code for the primary line of business."""
professional_license_number: Optional[str] = None
- """Professional license number"""
+ """Optional professional-license number for regulated industries."""
- role_type: Optional[Literal["enterprise", "bpo"]] = None
- """Role type in Branded Calling / Number Reputation services"""
+ role_type: Optional[str] = None
updated_at: Optional[datetime] = None
- """When the enterprise was last updated"""
website: Optional[str] = None
- """Company website URL"""
diff --git a/src/telnyx/types/enterprise_retrieve_response.py b/src/telnyx/types/enterprise_retrieve_response.py
index 7ad609fd..10335698 100644
--- a/src/telnyx/types/enterprise_retrieve_response.py
+++ b/src/telnyx/types/enterprise_retrieve_response.py
@@ -1,7 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
-
from .._models import BaseModel
from .enterprise_public import EnterprisePublic
@@ -9,4 +7,4 @@
class EnterpriseRetrieveResponse(BaseModel):
- data: Optional[EnterprisePublic] = None
+ data: EnterprisePublic
diff --git a/src/telnyx/types/enterprise_update_params.py b/src/telnyx/types/enterprise_update_params.py
index d5fde94c..0a452e92 100644
--- a/src/telnyx/types/enterprise_update_params.py
+++ b/src/telnyx/types/enterprise_update_params.py
@@ -2,6 +2,7 @@
from __future__ import annotations
+from typing import Optional
from typing_extensions import Literal, TypedDict
from .billing_address_param import BillingAddressParam
@@ -17,47 +18,78 @@ class EnterpriseUpdateParams(TypedDict, total=False):
billing_contact: BillingContactParam
- corporate_registration_number: str
- """Corporate registration number"""
+ corporate_registration_number: Optional[str]
customer_reference: str
- """Customer reference identifier"""
doing_business_as: str
- """DBA name"""
- dun_bradstreet_number: str
- """D-U-N-S Number"""
+ dun_bradstreet_number: Optional[str]
fein: str
- """Federal Employer Identification Number. Format: XX-XXXXXXX or XXXXXXXXX"""
- industry: str
- """Industry classification"""
+ industry: Literal[
+ "accounting",
+ "finance",
+ "billing",
+ "collections",
+ "business",
+ "charity",
+ "nonprofit",
+ "communications",
+ "telecom",
+ "customer service",
+ "support",
+ "delivery",
+ "shipping",
+ "logistics",
+ "education",
+ "financial",
+ "banking",
+ "government",
+ "public",
+ "healthcare",
+ "health",
+ "pharmacy",
+ "medical",
+ "insurance",
+ "legal",
+ "law",
+ "notifications",
+ "scheduling",
+ "real estate",
+ "property",
+ "retail",
+ "ecommerce",
+ "sales",
+ "marketing",
+ "software",
+ "technology",
+ "tech",
+ "media",
+ "surveys",
+ "market research",
+ "travel",
+ "hospitality",
+ "hotel",
+ ]
+
+ jurisdiction_of_incorporation: str
+ """Updated state/province/country of incorporation. Optional on update."""
legal_name: str
- """Legal name of the enterprise"""
+ """Legal name of the enterprise."""
- number_of_employees: Literal["1-10", "11-50", "51-200", "201-500", "501-2000", "2001-10000", "10001+"]
- """Employee count range"""
+ number_of_employees: str
organization_contact: OrganizationContactParam
- """Organization contact information.
- Note: the response returns this object with the phone field as 'phone' (not
- 'phone_number').
- """
-
- organization_legal_type: Literal["corporation", "llc", "partnership", "nonprofit", "other"]
- """Legal structure type"""
+ organization_legal_type: str
organization_physical_address: PhysicalAddressParam
- primary_business_domain_sic_code: str
- """SIC Code"""
+ primary_business_domain_sic_code: Optional[str]
- professional_license_number: str
- """Professional license number"""
+ professional_license_number: Optional[str]
website: str
- """Company website URL"""
diff --git a/src/telnyx/types/enterprise_update_response.py b/src/telnyx/types/enterprise_update_response.py
index 8ec5e815..ba6e1ac7 100644
--- a/src/telnyx/types/enterprise_update_response.py
+++ b/src/telnyx/types/enterprise_update_response.py
@@ -1,7 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
-
from .._models import BaseModel
from .enterprise_public import EnterprisePublic
@@ -9,4 +7,4 @@
class EnterpriseUpdateResponse(BaseModel):
- data: Optional[EnterprisePublic] = None
+ data: EnterprisePublic
diff --git a/src/telnyx/types/enterprises/__init__.py b/src/telnyx/types/enterprises/__init__.py
index b0427e0f..46601025 100644
--- a/src/telnyx/types/enterprises/__init__.py
+++ b/src/telnyx/types/enterprises/__init__.py
@@ -2,6 +2,10 @@
from __future__ import annotations
+from .dir_list_params import DirListParams as DirListParams
+from .dir_create_params import DirCreateParams as DirCreateParams
+from .dir_list_response import DirListResponse as DirListResponse
+from .dir_create_response import DirCreateResponse as DirCreateResponse
from .reputation_enable_params import ReputationEnableParams as ReputationEnableParams
from .reputation_enable_response import ReputationEnableResponse as ReputationEnableResponse
from .enterprise_reputation_public import EnterpriseReputationPublic as EnterpriseReputationPublic
diff --git a/src/telnyx/types/enterprises/dir/__init__.py b/src/telnyx/types/enterprises/dir/__init__.py
new file mode 100644
index 00000000..f8ee8b14
--- /dev/null
+++ b/src/telnyx/types/enterprises/dir/__init__.py
@@ -0,0 +1,3 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
diff --git a/src/telnyx/types/enterprises/dir_create_params.py b/src/telnyx/types/enterprises/dir_create_params.py
new file mode 100644
index 00000000..00cf1e5a
--- /dev/null
+++ b/src/telnyx/types/enterprises/dir_create_params.py
@@ -0,0 +1,93 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Literal, Required, TypedDict
+
+from ..._types import SequenceNotStr
+
+__all__ = ["DirCreateParams", "Document"]
+
+
+class DirCreateParams(TypedDict, total=False):
+ authorizer_email: Required[str]
+ """Contact email of the authorizer.
+
+ Telnyx may send verification or infringement-notice email here; use a monitored
+ mailbox.
+ """
+
+ authorizer_name: Required[str]
+ """Name of the person at your enterprise who is authorizing this DIR registration.
+
+ Must be a real individual (used for audit and trademark-claim contests).
+ """
+
+ certify_brand_is_accurate: Required[Literal[True]]
+ """Must be `true`."""
+
+ certify_ip_ownership: Required[Literal[True]]
+ """Must be `true`. Confirms ownership of any logos/trademarks shown."""
+
+ certify_no_shaft_content: Required[Literal[True]]
+ """Must be `true`.
+
+ Confirms this DIR is not used for SHAFT content (Sex, Hate, Alcohol, Firearms,
+ Tobacco) where prohibited.
+ """
+
+ display_name: Required[str]
+ """Name shown to call recipients. No emoji; not whitespace-only."""
+
+ call_reasons: SequenceNotStr[str]
+ """1–10 reasons your business calls customers.
+
+ Validate phrasing against `POST /call_reasons/validate`.
+ """
+
+ documents: Iterable[Document]
+ """Supporting documents. Each `document_id` may appear at most once on a DIR."""
+
+ logo_url: str
+ """Publicly accessible HTTPS URL (max 128 chars) to a 256x256 BMP logo (max 1 MB)."""
+
+ reselling: bool
+ """
+ Set to true if your organization places calls on behalf of other enterprises
+ (BPO/reseller).
+ """
+
+
+class Document(TypedDict, total=False):
+ document_id: Required[str]
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Required[
+ Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: str
diff --git a/src/telnyx/types/enterprises/dir_create_response.py b/src/telnyx/types/enterprises/dir_create_response.py
new file mode 100644
index 00000000..403ef5a1
--- /dev/null
+++ b/src/telnyx/types/enterprises/dir_create_response.py
@@ -0,0 +1,139 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["DirCreateResponse", "Data", "DataCallReason", "DataDocument", "DataRejectionReason"]
+
+
+class DataCallReason(BaseModel):
+ created_at: Optional[datetime] = None
+
+ reason: Optional[str] = None
+
+
+class DataDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class DataRejectionReason(BaseModel):
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ authorizer_email: Optional[str] = None
+
+ authorizer_name: Optional[str] = None
+
+ call_reasons: Optional[List[DataCallReason]] = None
+
+ certify_brand_is_accurate: Optional[bool] = None
+
+ certify_ip_ownership: Optional[bool] = None
+
+ certify_no_shaft_content: Optional[bool] = None
+
+ created_at: Optional[datetime] = None
+
+ display_name: Optional[str] = None
+
+ documents: Optional[List[DataDocument]] = None
+
+ enterprise_id: Optional[str] = None
+
+ expiring_at: Optional[datetime] = None
+
+ logo_url: Optional[str] = None
+
+ rejected_at: Optional[datetime] = None
+
+ rejection_reasons: Optional[List[DataRejectionReason]] = None
+ """
+ Populated when `status` is `rejected`; cleared on `/submit` or successful
+ approval.
+ """
+
+ reselling: Optional[bool] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+ submitted_at: Optional[datetime] = None
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
+
+
+class DirCreateResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/enterprises/dir_list_params.py b/src/telnyx/types/enterprises/dir_list_params.py
new file mode 100644
index 00000000..b9a63156
--- /dev/null
+++ b/src/telnyx/types/enterprises/dir_list_params.py
@@ -0,0 +1,80 @@
+# 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__ = ["DirListParams"]
+
+
+class DirListParams(TypedDict, total=False):
+ filter_expiring_at_gte: Annotated[
+ Union[str, datetime], PropertyInfo(alias="filter[expiring_at][gte]", format="iso8601")
+ ]
+ """Return only DIRs whose `expiring_at` is at or after this ISO-8601 timestamp."""
+
+ filter_expiring_at_lte: Annotated[
+ Union[str, datetime], PropertyInfo(alias="filter[expiring_at][lte]", format="iso8601")
+ ]
+ """Return only DIRs whose `expiring_at` is at or before this ISO-8601 timestamp."""
+
+ filter_expiring_within_days: Annotated[int, PropertyInfo(alias="filter[expiring_within_days]")]
+ """
+ Convenience: returns DIRs whose `expiring_at` falls within the next N days
+ (1–365). Equivalent to setting `filter[expiring_at][gte]=` +
+ `filter[expiring_at][lte]=`. Mutually exclusive with the explicit
+ `[gte]`/`[lte]` filters — combining returns 400.
+ """
+
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """Items per page. Maximum 250; values above are clamped to 250."""
+
+ search: str
+ """Case-insensitive partial match on `display_name`."""
+
+ sort: Literal[
+ "created_at",
+ "-created_at",
+ "updated_at",
+ "-updated_at",
+ "display_name",
+ "-display_name",
+ "status",
+ "-status",
+ "submitted_at",
+ "-submitted_at",
+ "verified_at",
+ "-verified_at",
+ "expiring_at",
+ "-expiring_at",
+ ]
+ """Sort field.
+
+ Allowed: `created_at`, `updated_at`, `display_name`, `status`, `submitted_at`,
+ `verified_at`, `expiring_at`. Prefix with `-` for descending. Default
+ `-created_at`.
+ """
+
+ status: Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ """Filter by DIR status."""
diff --git a/src/telnyx/types/enterprises/dir_list_response.py b/src/telnyx/types/enterprises/dir_list_response.py
new file mode 100644
index 00000000..36e25043
--- /dev/null
+++ b/src/telnyx/types/enterprises/dir_list_response.py
@@ -0,0 +1,135 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["DirListResponse", "CallReason", "Document", "RejectionReason"]
+
+
+class CallReason(BaseModel):
+ created_at: Optional[datetime] = None
+
+ reason: Optional[str] = None
+
+
+class Document(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class RejectionReason(BaseModel):
+ code: Optional[str] = None
+
+ detail: Optional[str] = None
+
+ message: Optional[str] = None
+ """Customer-visible free-text comment from the Telnyx vetting team.
+
+ Only the first entry of `rejection_reasons` carries this; the rest are `null`.
+ """
+
+ title: Optional[str] = None
+
+
+class DirListResponse(BaseModel):
+ id: Optional[str] = None
+
+ authorizer_email: Optional[str] = None
+
+ authorizer_name: Optional[str] = None
+
+ call_reasons: Optional[List[CallReason]] = None
+
+ certify_brand_is_accurate: Optional[bool] = None
+
+ certify_ip_ownership: Optional[bool] = None
+
+ certify_no_shaft_content: Optional[bool] = None
+
+ created_at: Optional[datetime] = None
+
+ display_name: Optional[str] = None
+
+ documents: Optional[List[Document]] = None
+
+ enterprise_id: Optional[str] = None
+
+ expiring_at: Optional[datetime] = None
+
+ logo_url: Optional[str] = None
+
+ rejected_at: Optional[datetime] = None
+
+ rejection_reasons: Optional[List[RejectionReason]] = None
+ """
+ Populated when `status` is `rejected`; cleared on `/submit` or successful
+ approval.
+ """
+
+ reselling: Optional[bool] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+ submitted_at: Optional[datetime] = None
+
+ updated_at: Optional[datetime] = None
+
+ verified_at: Optional[datetime] = None
diff --git a/src/telnyx/types/enterprises/enterprise_reputation_public.py b/src/telnyx/types/enterprises/enterprise_reputation_public.py
index c44093e1..4b119427 100644
--- a/src/telnyx/types/enterprises/enterprise_reputation_public.py
+++ b/src/telnyx/types/enterprises/enterprise_reputation_public.py
@@ -11,22 +11,29 @@
class EnterpriseReputationPublic(BaseModel):
check_frequency: Optional[Literal["business_daily", "daily", "weekly", "biweekly", "monthly", "never"]] = None
- """Frequency for refreshing reputation data"""
+ """
+ How often Telnyx refreshes the stored reputation data for this enterprise's
+ registered numbers.
+ """
created_at: Optional[datetime] = None
- """When the reputation settings were created"""
enterprise_id: Optional[str] = None
- """ID of the associated enterprise"""
loa_document_id: Optional[str] = None
- """ID of the signed LOA document"""
+ """Id of the signed LOA document."""
+
+ loa_status: Optional[Literal["pending", "approved", "rejected"]] = None
+ """Customer-facing Letter-of-Authorization verification state.
+
+ `approved` is required (alongside reputation status) before phone numbers can be
+ added.
+ """
rejection_reasons: Optional[List[str]] = None
- """Reasons for rejection (present when status is rejected)"""
+ """Populated when `status` is `rejected`."""
- status: Optional[Literal["pending", "approved", "rejected", "deleted"]] = None
- """Current enrollment status"""
+ status: Optional[Literal["pending", "approved", "deleted", "rejected"]] = None
+ """Lifecycle status of the enterprise's Phone Number Reputation activation."""
updated_at: Optional[datetime] = None
- """When the reputation settings were last updated"""
diff --git a/src/telnyx/types/enterprises/reputation/__init__.py b/src/telnyx/types/enterprises/reputation/__init__.py
index e47c43b9..1566b521 100644
--- a/src/telnyx/types/enterprises/reputation/__init__.py
+++ b/src/telnyx/types/enterprises/reputation/__init__.py
@@ -2,8 +2,14 @@
from __future__ import annotations
+from .loa_render_params import LoaRenderParams as LoaRenderParams
+from .loa_update_params import LoaUpdateParams as LoaUpdateParams
from .number_list_params import NumberListParams as NumberListParams
+from .loa_update_response import LoaUpdateResponse as LoaUpdateResponse
+from .number_list_response import NumberListResponse as NumberListResponse
+from .number_refresh_params import NumberRefreshParams as NumberRefreshParams
from .number_retrieve_params import NumberRetrieveParams as NumberRetrieveParams
from .number_associate_params import NumberAssociateParams as NumberAssociateParams
+from .number_refresh_response import NumberRefreshResponse as NumberRefreshResponse
from .number_retrieve_response import NumberRetrieveResponse as NumberRetrieveResponse
from .number_associate_response import NumberAssociateResponse as NumberAssociateResponse
diff --git a/src/telnyx/types/enterprises/reputation/loa_render_params.py b/src/telnyx/types/enterprises/reputation/loa_render_params.py
new file mode 100644
index 00000000..f30109d7
--- /dev/null
+++ b/src/telnyx/types/enterprises/reputation/loa_render_params.py
@@ -0,0 +1,65 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Required, TypedDict
+
+__all__ = ["LoaRenderParams", "Agent", "Signature"]
+
+
+class LoaRenderParams(TypedDict, total=False):
+ agent: Agent
+ """Third-party reseller / partner managing the enterprise's phone numbers.
+
+ Omit when the enterprise works directly with Telnyx.
+ """
+
+ signature: Signature
+ """Optional signature embedded in the rendered PDF.
+
+ When omitted the PDF is returned unsigned for the customer to sign and upload.
+ """
+
+
+class Agent(TypedDict, total=False):
+ """Third-party reseller / partner managing the enterprise's phone numbers.
+
+ Omit when the enterprise works directly with Telnyx.
+ """
+
+ administrative_area: Required[str]
+
+ city: Required[str]
+
+ contact_email: Required[str]
+
+ contact_name: Required[str]
+
+ contact_phone: Required[str]
+
+ contact_title: Required[str]
+
+ country: Required[str]
+
+ legal_name: Required[str]
+
+ postal_code: Required[str]
+
+ street_address: Required[str]
+
+ dba: Optional[str]
+
+ extended_address: Optional[str]
+
+
+class Signature(TypedDict, total=False):
+ """Optional signature embedded in the rendered PDF.
+
+ When omitted the PDF is returned unsigned for the customer to sign and upload.
+ """
+
+ image_base64: Required[str]
+ """Base64-encoded signature image."""
+
+ signer_name: Optional[str]
diff --git a/src/telnyx/types/enterprises/reputation/loa_update_params.py b/src/telnyx/types/enterprises/reputation/loa_update_params.py
new file mode 100644
index 00000000..5984f41f
--- /dev/null
+++ b/src/telnyx/types/enterprises/reputation/loa_update_params.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["LoaUpdateParams"]
+
+
+class LoaUpdateParams(TypedDict, total=False):
+ loa_document_id: Required[str]
+ """Id of the new signed LOA document (from the Telnyx Documents API).
+
+ Changing it resets LOA approval; the new document must be approved before more
+ numbers can be added.
+ """
diff --git a/src/telnyx/types/enterprises/reputation/loa_update_response.py b/src/telnyx/types/enterprises/reputation/loa_update_response.py
new file mode 100644
index 00000000..836d71a3
--- /dev/null
+++ b/src/telnyx/types/enterprises/reputation/loa_update_response.py
@@ -0,0 +1,10 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from ...._models import BaseModel
+from ..enterprise_reputation_public import EnterpriseReputationPublic
+
+__all__ = ["LoaUpdateResponse"]
+
+
+class LoaUpdateResponse(BaseModel):
+ data: EnterpriseReputationPublic
diff --git a/src/telnyx/types/enterprises/reputation/number_associate_params.py b/src/telnyx/types/enterprises/reputation/number_associate_params.py
index 56cf75ad..31831e53 100644
--- a/src/telnyx/types/enterprises/reputation/number_associate_params.py
+++ b/src/telnyx/types/enterprises/reputation/number_associate_params.py
@@ -11,4 +11,4 @@
class NumberAssociateParams(TypedDict, total=False):
phone_numbers: Required[SequenceNotStr[str]]
- """List of phone numbers to associate for reputation monitoring (max 100)"""
+ """1–100 phone numbers in E.164 format with a leading `+`."""
diff --git a/src/telnyx/types/enterprises/reputation/number_associate_response.py b/src/telnyx/types/enterprises/reputation/number_associate_response.py
index e1fd5fb4..7d3444de 100644
--- a/src/telnyx/types/enterprises/reputation/number_associate_response.py
+++ b/src/telnyx/types/enterprises/reputation/number_associate_response.py
@@ -4,29 +4,56 @@
from datetime import datetime
from ...._models import BaseModel
-from ...shared.meta_info import MetaInfo
+from ...shared.reputation_data import ReputationData
-__all__ = ["NumberAssociateResponse", "Data"]
+__all__ = ["NumberAssociateResponse", "Data", "Meta"]
class Data(BaseModel):
id: Optional[str] = None
- """Unique identifier"""
created_at: Optional[datetime] = None
- """When the number was associated"""
enterprise_id: Optional[str] = None
- """ID of the associated enterprise"""
phone_number: Optional[str] = None
- """Phone number in E.164 format"""
+ """E.164 with leading `+`."""
+
+ reputation_data: Optional[ReputationData] = None
+ """`null` until the first refresh has been collected for this number."""
updated_at: Optional[datetime] = None
- """When the record was last updated"""
+
+
+class Meta(BaseModel):
+ """JSON:API pagination metadata returned with every paginated list response.
+
+ Page numbering is 1-based. `page_size` reports the number of items actually returned in `data` for this page; the requested size is taken from the `page[size]` query parameter.
+ """
+
+ page_number: int
+ """1-based index of this page.
+
+ Echoes the `page[number]` query parameter (default `1`).
+ """
+
+ page_size: int
+ """Number of items returned in this page's `data` array. Capped at 250."""
+
+ total_pages: int
+ """Total number of pages available given the current `page_size`."""
+
+ total_results: int
+ """Total number of items across all pages (excludes soft-deleted rows)."""
class NumberAssociateResponse(BaseModel):
- data: Optional[List[Data]] = None
+ data: List[Data]
+
+ meta: Meta
+ """JSON:API pagination metadata returned with every paginated list response.
- meta: Optional[MetaInfo] = None
+ Page numbering is 1-based. `page_size` reports the number of items actually
+ returned in `data` for this page; the requested size is taken from the
+ `page[size]` query parameter.
+ """
diff --git a/src/telnyx/types/enterprises/reputation/number_list_params.py b/src/telnyx/types/enterprises/reputation/number_list_params.py
index 26426662..46dd4bee 100644
--- a/src/telnyx/types/enterprises/reputation/number_list_params.py
+++ b/src/telnyx/types/enterprises/reputation/number_list_params.py
@@ -11,10 +11,13 @@
class NumberListParams(TypedDict, total=False):
page_number: Annotated[int, PropertyInfo(alias="page[number]")]
- """Page number (1-indexed)"""
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
page_size: Annotated[int, PropertyInfo(alias="page[size]")]
- """Number of items per page"""
+ """Items per page. Default 10. Maximum 250; values above are clamped to 250."""
phone_number: str
- """Filter by specific phone number (E.164 format)"""
+ """Filter by specific phone number (E.164 format)."""
diff --git a/src/telnyx/types/enterprises/reputation/number_list_response.py b/src/telnyx/types/enterprises/reputation/number_list_response.py
new file mode 100644
index 00000000..016cdfb6
--- /dev/null
+++ b/src/telnyx/types/enterprises/reputation/number_list_response.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+
+from ...._models import BaseModel
+from ...shared.reputation_data import ReputationData
+
+__all__ = ["NumberListResponse"]
+
+
+class NumberListResponse(BaseModel):
+ id: Optional[str] = None
+
+ created_at: Optional[datetime] = None
+
+ enterprise_id: Optional[str] = None
+
+ phone_number: Optional[str] = None
+ """E.164 with leading `+`."""
+
+ reputation_data: Optional[ReputationData] = None
+ """`null` until the first refresh has been collected for this number."""
+
+ updated_at: Optional[datetime] = None
diff --git a/src/telnyx/types/enterprises/reputation/number_refresh_params.py b/src/telnyx/types/enterprises/reputation/number_refresh_params.py
new file mode 100644
index 00000000..c8d0cced
--- /dev/null
+++ b/src/telnyx/types/enterprises/reputation/number_refresh_params.py
@@ -0,0 +1,18 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+from ...._types import SequenceNotStr
+
+__all__ = ["NumberRefreshParams"]
+
+
+class NumberRefreshParams(TypedDict, total=False):
+ phone_numbers: Required[SequenceNotStr[str]]
+ """Phone numbers to refresh reputation data for.
+
+ 1–100 numbers per request, each in E.164 format. Reputation refreshes are
+ subject to per-enterprise rate limits.
+ """
diff --git a/src/telnyx/types/enterprises/reputation/number_refresh_response.py b/src/telnyx/types/enterprises/reputation/number_refresh_response.py
new file mode 100644
index 00000000..0b92103c
--- /dev/null
+++ b/src/telnyx/types/enterprises/reputation/number_refresh_response.py
@@ -0,0 +1,31 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+
+from ...._models import BaseModel
+
+__all__ = ["NumberRefreshResponse", "Data", "DataResult"]
+
+
+class DataResult(BaseModel):
+ phone_number: str
+
+ success: bool
+
+ error: Optional[str] = None
+ """`null` when `success` is `true`; carries an error message otherwise."""
+
+
+class Data(BaseModel):
+ results: List[DataResult]
+ """Per-number outcome of the refresh."""
+
+ total_failed: int
+
+ total_requested: int
+
+ total_successful: int
+
+
+class NumberRefreshResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/enterprises/reputation/number_retrieve_params.py b/src/telnyx/types/enterprises/reputation/number_retrieve_params.py
index 5d1e7c69..f7bf00f4 100644
--- a/src/telnyx/types/enterprises/reputation/number_retrieve_params.py
+++ b/src/telnyx/types/enterprises/reputation/number_retrieve_params.py
@@ -13,5 +13,5 @@ class NumberRetrieveParams(TypedDict, total=False):
fresh: bool
"""When true, fetches fresh reputation data (incurs API cost).
- When false, returns cached data.
+ When false (default), returns cached data.
"""
diff --git a/src/telnyx/types/enterprises/reputation/number_retrieve_response.py b/src/telnyx/types/enterprises/reputation/number_retrieve_response.py
index 3fabc71c..9bcccafb 100644
--- a/src/telnyx/types/enterprises/reputation/number_retrieve_response.py
+++ b/src/telnyx/types/enterprises/reputation/number_retrieve_response.py
@@ -1,12 +1,29 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from datetime import datetime
from ...._models import BaseModel
-from ...shared.reputation_phone_number_with_reputation_data import ReputationPhoneNumberWithReputationData
+from ...shared.reputation_data import ReputationData
-__all__ = ["NumberRetrieveResponse"]
+__all__ = ["NumberRetrieveResponse", "Data"]
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ created_at: Optional[datetime] = None
+
+ enterprise_id: Optional[str] = None
+
+ phone_number: Optional[str] = None
+ """E.164 with leading `+`."""
+
+ reputation_data: Optional[ReputationData] = None
+ """`null` until the first refresh has been collected for this number."""
+
+ updated_at: Optional[datetime] = None
class NumberRetrieveResponse(BaseModel):
- data: Optional[ReputationPhoneNumberWithReputationData] = None
+ data: Data
diff --git a/src/telnyx/types/enterprises/reputation_enable_params.py b/src/telnyx/types/enterprises/reputation_enable_params.py
index c0894e37..cbe35f87 100644
--- a/src/telnyx/types/enterprises/reputation_enable_params.py
+++ b/src/telnyx/types/enterprises/reputation_enable_params.py
@@ -10,9 +10,13 @@
class ReputationEnableParams(TypedDict, total=False):
loa_document_id: Required[str]
"""
- ID of the signed Letter of Authorization (LOA) document uploaded to the document
- service
+ Id of the signed Letter of Authorization document, returned by the Telnyx
+ Documents API after upload (upload via `POST /v2/documents`; see
+ https://developers.telnyx.com/api/documents).
"""
check_frequency: Literal["business_daily", "daily", "weekly", "biweekly", "monthly", "never"]
- """Frequency for automatically refreshing reputation data"""
+ """
+ How often Telnyx refreshes the stored reputation data for this enterprise's
+ registered numbers.
+ """
diff --git a/src/telnyx/types/enterprises/reputation_enable_response.py b/src/telnyx/types/enterprises/reputation_enable_response.py
index c22a6292..281c1780 100644
--- a/src/telnyx/types/enterprises/reputation_enable_response.py
+++ b/src/telnyx/types/enterprises/reputation_enable_response.py
@@ -1,7 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
-
from ..._models import BaseModel
from .enterprise_reputation_public import EnterpriseReputationPublic
@@ -9,4 +7,4 @@
class ReputationEnableResponse(BaseModel):
- data: Optional[EnterpriseReputationPublic] = None
+ data: EnterpriseReputationPublic
diff --git a/src/telnyx/types/enterprises/reputation_retrieve_response.py b/src/telnyx/types/enterprises/reputation_retrieve_response.py
index abb44ffb..98d61de8 100644
--- a/src/telnyx/types/enterprises/reputation_retrieve_response.py
+++ b/src/telnyx/types/enterprises/reputation_retrieve_response.py
@@ -1,7 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
-
from ..._models import BaseModel
from .enterprise_reputation_public import EnterpriseReputationPublic
@@ -9,4 +7,4 @@
class ReputationRetrieveResponse(BaseModel):
- data: Optional[EnterpriseReputationPublic] = None
+ data: EnterpriseReputationPublic
diff --git a/src/telnyx/types/enterprises/reputation_update_frequency_params.py b/src/telnyx/types/enterprises/reputation_update_frequency_params.py
index a3fd2f6b..9dca829a 100644
--- a/src/telnyx/types/enterprises/reputation_update_frequency_params.py
+++ b/src/telnyx/types/enterprises/reputation_update_frequency_params.py
@@ -9,4 +9,7 @@
class ReputationUpdateFrequencyParams(TypedDict, total=False):
check_frequency: Required[Literal["business_daily", "daily", "weekly", "biweekly", "monthly", "never"]]
- """New frequency for refreshing reputation data"""
+ """
+ How often Telnyx refreshes the stored reputation data for this enterprise's
+ registered numbers.
+ """
diff --git a/src/telnyx/types/enterprises/reputation_update_frequency_response.py b/src/telnyx/types/enterprises/reputation_update_frequency_response.py
index c1119c77..febe619f 100644
--- a/src/telnyx/types/enterprises/reputation_update_frequency_response.py
+++ b/src/telnyx/types/enterprises/reputation_update_frequency_response.py
@@ -1,7 +1,5 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
-
from ..._models import BaseModel
from .enterprise_reputation_public import EnterpriseReputationPublic
@@ -9,4 +7,4 @@
class ReputationUpdateFrequencyResponse(BaseModel):
- data: Optional[EnterpriseReputationPublic] = None
+ data: EnterpriseReputationPublic
diff --git a/src/telnyx/types/infringement_claim_contest_params.py b/src/telnyx/types/infringement_claim_contest_params.py
new file mode 100644
index 00000000..45c8ff2a
--- /dev/null
+++ b/src/telnyx/types/infringement_claim_contest_params.py
@@ -0,0 +1,54 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Iterable
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["InfringementClaimContestParams", "Document"]
+
+
+class InfringementClaimContestParams(TypedDict, total=False):
+ contest_notes: Required[str]
+ """Customer's response to the claim. 10–2000 characters."""
+
+ documents: Iterable[Document]
+ """Up to 20 supporting documents per submission.
+
+ `document_id` must be unique within this submission. Documents are aggregated
+ into the claim's `contest_documents` across all submissions.
+ """
+
+
+class Document(TypedDict, total=False):
+ document_id: Required[str]
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Required[
+ Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: str
diff --git a/src/telnyx/types/infringement_claim_contest_response.py b/src/telnyx/types/infringement_claim_contest_response.py
new file mode 100644
index 00000000..ada12724
--- /dev/null
+++ b/src/telnyx/types/infringement_claim_contest_response.py
@@ -0,0 +1,149 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["InfringementClaimContestResponse", "Data", "DataContestDocument", "DataContestHistory", "DataDir"]
+
+
+class DataContestDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class DataContestHistory(BaseModel):
+ """One round of customer contest evidence on an infringement claim.
+
+ The aggregated documents across rounds live on the parent claim's `contest_documents`; this submission record carries only the per-round notes and document count.
+ """
+
+ document_count: Optional[int] = None
+
+ notes: Optional[str] = None
+
+ submitted_at: Optional[datetime] = None
+
+
+class DataDir(BaseModel):
+ """Snapshot of the DIR the claim is filed against, embedded for convenience."""
+
+ id: Optional[str] = None
+
+ display_name: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ claim_date: Optional[datetime] = None
+ """When the claim was filed (set by the claimant's representative at file time)."""
+
+ claim_description: Optional[str] = None
+
+ claim_type: Optional[Literal["trademark", "copyright"]] = None
+ """Category of infringement being claimed."""
+
+ claimant_contact: Optional[str] = None
+
+ claimant_name: Optional[str] = None
+
+ contest_documents: Optional[List[DataContestDocument]] = None
+ """Aggregated across all customer contest submissions on this claim."""
+
+ contest_history: Optional[List[DataContestHistory]] = None
+ """Per-round submission audit trail.
+
+ Each entry records one `POST /infringement_claims/{id}/contest` call (notes,
+ timestamp, document count). Aggregated documents live on `contest_documents`.
+ """
+
+ created_at: Optional[datetime] = None
+
+ dir: Optional[DataDir] = None
+ """Snapshot of the DIR the claim is filed against, embedded for convenience."""
+
+ dir_id: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ resolution: Optional[Literal["upheld", "rejected", "modified"]] = None
+ """Set only when `status` is `resolved`."""
+
+ resolution_date: Optional[datetime] = None
+
+ resolution_notes: Optional[str] = None
+
+ status: Optional[Literal["pending", "contested", "resolved"]] = None
+ """Lifecycle status.
+
+ `pending` — newly filed; the DIR is auto-suspended. `contested` — you have
+ submitted contest evidence; awaiting Telnyx review. `resolved` — final.
+ """
+
+ updated_at: Optional[datetime] = None
+
+
+class InfringementClaimContestResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/infringement_claim_retrieve_response.py b/src/telnyx/types/infringement_claim_retrieve_response.py
new file mode 100644
index 00000000..fb57b8fd
--- /dev/null
+++ b/src/telnyx/types/infringement_claim_retrieve_response.py
@@ -0,0 +1,149 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["InfringementClaimRetrieveResponse", "Data", "DataContestDocument", "DataContestHistory", "DataDir"]
+
+
+class DataContestDocument(BaseModel):
+ document_id: str
+ """
+ Id returned by the Telnyx Documents API after you upload the file (upload via
+ `POST /v2/documents`; see https://developers.telnyx.com/api/documents).
+ """
+
+ document_type: Literal[
+ "letter_of_authorization",
+ "business_registration",
+ "articles_of_incorporation",
+ "tax_document",
+ "ein_letter",
+ "trademark_registration",
+ "website_ownership",
+ "business_license",
+ "professional_license",
+ "government_id",
+ "utility_bill",
+ "bank_statement",
+ "other",
+ ]
+ """Type of supporting document.
+
+ Pick the closest match to what the file actually contains; `other` triggers
+ manual vetting and may slow approval. The matching short_name reference list is
+ at `GET /v2/dir/document_types`.
+ """
+
+ description: Optional[str] = None
+
+
+class DataContestHistory(BaseModel):
+ """One round of customer contest evidence on an infringement claim.
+
+ The aggregated documents across rounds live on the parent claim's `contest_documents`; this submission record carries only the per-round notes and document count.
+ """
+
+ document_count: Optional[int] = None
+
+ notes: Optional[str] = None
+
+ submitted_at: Optional[datetime] = None
+
+
+class DataDir(BaseModel):
+ """Snapshot of the DIR the claim is filed against, embedded for convenience."""
+
+ id: Optional[str] = None
+
+ display_name: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ status: Optional[
+ Literal[
+ "draft",
+ "submitted",
+ "in_review",
+ "verified",
+ "rejected",
+ "unsuccessful",
+ "suspended",
+ "expired",
+ "infringement_claimed",
+ "permanently_rejected",
+ ]
+ ] = None
+ """DIR lifecycle status.
+
+ - `draft` — newly created; editable; not yet submitted.
+ - `submitted` / `in_review` — Telnyx is reviewing.
+ - `verified` — approved; phone numbers may be attached.
+ - `rejected` — Telnyx rejected this submission; `rejection_reasons` is
+ populated; customer can edit and resubmit.
+ - `unsuccessful` — system-side error during processing; customer can edit and
+ resubmit.
+ - `suspended` — temporarily disabled (e.g. by an active infringement claim).
+ - `expired` — verification expired; customer must resubmit.
+ - `infringement_claimed` — a trademark/impersonation claim is open against this
+ DIR.
+ - `permanently_rejected` — terminal; cannot be resubmitted.
+ """
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ claim_date: Optional[datetime] = None
+ """When the claim was filed (set by the claimant's representative at file time)."""
+
+ claim_description: Optional[str] = None
+
+ claim_type: Optional[Literal["trademark", "copyright"]] = None
+ """Category of infringement being claimed."""
+
+ claimant_contact: Optional[str] = None
+
+ claimant_name: Optional[str] = None
+
+ contest_documents: Optional[List[DataContestDocument]] = None
+ """Aggregated across all customer contest submissions on this claim."""
+
+ contest_history: Optional[List[DataContestHistory]] = None
+ """Per-round submission audit trail.
+
+ Each entry records one `POST /infringement_claims/{id}/contest` call (notes,
+ timestamp, document count). Aggregated documents live on `contest_documents`.
+ """
+
+ created_at: Optional[datetime] = None
+
+ dir: Optional[DataDir] = None
+ """Snapshot of the DIR the claim is filed against, embedded for convenience."""
+
+ dir_id: Optional[str] = None
+
+ enterprise_id: Optional[str] = None
+
+ resolution: Optional[Literal["upheld", "rejected", "modified"]] = None
+ """Set only when `status` is `resolved`."""
+
+ resolution_date: Optional[datetime] = None
+
+ resolution_notes: Optional[str] = None
+
+ status: Optional[Literal["pending", "contested", "resolved"]] = None
+ """Lifecycle status.
+
+ `pending` — newly filed; the DIR is auto-suspended. `contested` — you have
+ submitted contest evidence; awaiting Telnyx review. `resolved` — final.
+ """
+
+ updated_at: Optional[datetime] = None
+
+
+class InfringementClaimRetrieveResponse(BaseModel):
+ data: Data
diff --git a/src/telnyx/types/model_metadata.py b/src/telnyx/types/model_metadata.py
deleted file mode 100644
index 465f1372..00000000
--- a/src/telnyx/types/model_metadata.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Dict, List, Optional
-from datetime import datetime
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["ModelMetadata"]
-
-
-class ModelMetadata(BaseModel):
- """Metadata for a model available on Telnyx Inference.
-
- Returned by `GET /v2/ai/openai/models` (and the deprecated `GET /v2/ai/models`). Open-source models live under their Hugging Face organization (e.g. `moonshotai/Kimi-K2.6`, `zai-org/GLM-5.1-FP8`, `MiniMaxAI/MiniMax-M2.7`); fine-tuned models are owned by the Telnyx organization that trained them.
- """
-
- id: str
- """Model identifier.
-
- For open-source models, follows the `{organization}/{model_name}` convention
- from Hugging Face (e.g. `moonshotai/Kimi-K2.6`).
- """
-
- context_length: int
- """
- Maximum total tokens (prompt + completion) supported by the model in a single
- request.
- """
-
- created: datetime
- """Timestamp at which the model was registered on Telnyx Inference (ISO 8601)."""
-
- languages: List[str]
- """ISO language codes the model supports (e.g. `en`, `es`)."""
-
- license: str
- """License the model is distributed under, e.g.
-
- `Apache 2.0`, `MIT`, `Llama 3 Community License`.
- """
-
- organization: str
- """
- Organization that originally published the model, matching the prefix of `id`
- for open-source models.
- """
-
- owned_by: str
- """Owner of the model.
-
- `Telnyx` for Telnyx-hosted open-source models, the upstream provider name for
- proxied models, or the Telnyx organization id for fine-tuned models.
- """
-
- parameters: int
- """Total parameter count of the model."""
-
- tier: Literal["small", "medium", "large", "unlisted"]
- """Billing tier the model belongs to.
-
- Used together with `pricing` to determine cost per 1M tokens.
- """
-
- base_model: Optional[str] = None
- """Base model the fine-tuned model was trained from.
-
- Only set for fine-tuned models.
- """
-
- description: Optional[str] = None
- """Short, human-readable summary of what the model is best suited for."""
-
- is_fine_tunable: Optional[bool] = None
- """
- Whether the model can be used as a base for a fine-tuning job via
- `POST /v2/ai/fine_tuning/jobs`.
- """
-
- is_vision_supported: Optional[bool] = None
- """
- Whether the model accepts image inputs in chat completions (multimodal vision
- support).
- """
-
- max_completion_tokens: Optional[int] = None
- """Maximum number of completion (output) tokens the model will generate per
- request.
-
- `null` if unconstrained beyond `context_length`.
- """
-
- object: Optional[str] = None
- """Object type. Always `model`."""
-
- parameters_str: Optional[str] = None
- """Human-readable parameter count, e.g. `1.0T`, `753.9B`, `8B`."""
-
- pricing: Optional[Dict[str, str]] = None
- """Mapping of token kind to price, as strings to preserve precision.
-
- Typical keys are `prompt`, `cached_prompt`, and `completion`. When pricing is
- available the block also includes `currency` (ISO 4217 code matching the
- account's configured billing currency) and `unit` (the denomination the prices
- are quoted in, currently always `1M_tokens` for token-priced models).
- """
-
- recommended_for_assistants: Optional[bool] = None
- """
- Whether Telnyx currently recommends this model as the LLM powering a Telnyx AI
- Assistant.
- """
-
- regions: Optional[List[str]] = None
- """Public region names where the model is currently deployed (e.g.
-
- `us-central-1`, `eu-central-1`).
- """
-
- task: Optional[str] = None
- """Primary task the model is intended for, e.g.
-
- `text-generation`, `audio-text-to-text`, `feature-extraction` (embeddings).
- """
diff --git a/src/telnyx/types/network_interface.py b/src/telnyx/types/network_interface.py
new file mode 100644
index 00000000..f133b69d
--- /dev/null
+++ b/src/telnyx/types/network_interface.py
@@ -0,0 +1,19 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from .._models import BaseModel
+from .interface_status import InterfaceStatus
+
+__all__ = ["NetworkInterface"]
+
+
+class NetworkInterface(BaseModel):
+ name: Optional[str] = None
+ """A user specified name for the interface."""
+
+ network_id: Optional[str] = None
+ """The id of the network associated with the interface."""
+
+ status: Optional[InterfaceStatus] = None
+ """The current status of the interface deployment."""
diff --git a/src/telnyx/types/network_list_interfaces_response.py b/src/telnyx/types/network_list_interfaces_response.py
index ebf8ccec..e045dd1f 100644
--- a/src/telnyx/types/network_list_interfaces_response.py
+++ b/src/telnyx/types/network_list_interfaces_response.py
@@ -2,13 +2,14 @@
from typing import Optional
+from .record import Record
from .._models import BaseModel
-from .interface_status import InterfaceStatus
+from .network_interface import NetworkInterface
-__all__ = ["NetworkListInterfacesResponse", "Region"]
+__all__ = ["NetworkListInterfacesResponse", "NetworkListInterfacesResponseRegion"]
-class Region(BaseModel):
+class NetworkListInterfacesResponseRegion(BaseModel):
code: Optional[str] = None
"""Region code of the interface."""
@@ -19,32 +20,14 @@ class Region(BaseModel):
"""Identifies the type of the resource."""
-class NetworkListInterfacesResponse(BaseModel):
- id: Optional[str] = None
- """Identifies the resource."""
-
- created_at: Optional[str] = None
- """ISO 8601 formatted date-time indicating when the resource was created."""
-
- name: Optional[str] = None
- """A user specified name for the interface."""
-
- network_id: Optional[str] = None
- """The id of the network associated with the interface."""
-
- record_type: Optional[str] = None
+class NetworkListInterfacesResponse(Record, NetworkInterface):
+ record_type: Optional[str] = None # type: ignore
"""Identifies the type of the resource."""
- region: Optional[Region] = None
+ region: Optional[NetworkListInterfacesResponseRegion] = None
region_code: Optional[str] = None
"""The region interface is deployed to."""
- status: Optional[InterfaceStatus] = None
- """The current status of the interface deployment."""
-
type: Optional[str] = None
"""Identifies the type of the interface."""
-
- updated_at: Optional[str] = None
- """ISO 8601 formatted date-time indicating when the resource was updated."""
diff --git a/src/telnyx/types/organization_contact.py b/src/telnyx/types/organization_contact.py
index 7f26ac77..3bc69298 100644
--- a/src/telnyx/types/organization_contact.py
+++ b/src/telnyx/types/organization_contact.py
@@ -6,22 +6,13 @@
class OrganizationContact(BaseModel):
- """Organization contact information.
-
- Note: the response returns this object with the phone field as 'phone' (not 'phone_number').
- """
-
email: str
- """Contact's email address"""
first_name: str
- """Contact's first name"""
job_title: str
- """Contact's job title (required)"""
last_name: str
- """Contact's last name"""
- phone: str
- """Contact's phone number in E.164 format"""
+ phone_number: str
+ """E.164 format with leading `+`."""
diff --git a/src/telnyx/types/organization_contact_param.py b/src/telnyx/types/organization_contact_param.py
index 623a5779..7948928a 100644
--- a/src/telnyx/types/organization_contact_param.py
+++ b/src/telnyx/types/organization_contact_param.py
@@ -8,22 +8,13 @@
class OrganizationContactParam(TypedDict, total=False):
- """Organization contact information.
-
- Note: the response returns this object with the phone field as 'phone' (not 'phone_number').
- """
-
email: Required[str]
- """Contact's email address"""
first_name: Required[str]
- """Contact's first name"""
job_title: Required[str]
- """Contact's job title (required)"""
last_name: Required[str]
- """Contact's last name"""
- phone: Required[str]
- """Contact's phone number in E.164 format"""
+ phone_number: Required[str]
+ """E.164 format with leading `+`."""
diff --git a/src/telnyx/types/physical_address.py b/src/telnyx/types/physical_address.py
index c700580e..77c1c437 100644
--- a/src/telnyx/types/physical_address.py
+++ b/src/telnyx/types/physical_address.py
@@ -9,19 +9,15 @@
class PhysicalAddress(BaseModel):
administrative_area: str
- """State or province"""
+ """State or province code (e.g. `IL`, `ON`)."""
city: str
- """City name"""
country: str
- """Country name (e.g., United States)"""
+ """ISO 3166-1 alpha-2 code (currently `US` or `CA`)."""
postal_code: str
- """ZIP or postal code"""
street_address: str
- """Street address"""
extended_address: Optional[str] = None
- """Additional address line (suite, apt, etc.)"""
diff --git a/src/telnyx/types/physical_address_param.py b/src/telnyx/types/physical_address_param.py
index 951e6b31..b0fd0c4d 100644
--- a/src/telnyx/types/physical_address_param.py
+++ b/src/telnyx/types/physical_address_param.py
@@ -10,19 +10,15 @@
class PhysicalAddressParam(TypedDict, total=False):
administrative_area: Required[str]
- """State or province"""
+ """State or province code (e.g. `IL`, `ON`)."""
city: Required[str]
- """City name"""
country: Required[str]
- """Country name (e.g., United States)"""
+ """ISO 3166-1 alpha-2 code (currently `US` or `CA`)."""
postal_code: Required[str]
- """ZIP or postal code"""
street_address: Required[str]
- """Street address"""
extended_address: Optional[str]
- """Additional address line (suite, apt, etc.)"""
diff --git a/src/telnyx/types/public_internet_gateway_create_response.py b/src/telnyx/types/public_internet_gateway_create_response.py
index 76e78efa..11e16259 100644
--- a/src/telnyx/types/public_internet_gateway_create_response.py
+++ b/src/telnyx/types/public_internet_gateway_create_response.py
@@ -2,11 +2,20 @@
from typing import Optional
+from .record import Record
from .._models import BaseModel
-from .public_internet_gateway_read import PublicInternetGatewayRead
+from .network_interface import NetworkInterface
-__all__ = ["PublicInternetGatewayCreateResponse"]
+__all__ = ["PublicInternetGatewayCreateResponse", "Data"]
+
+
+class Data(Record, NetworkInterface):
+ public_ip: Optional[str] = None
+ """The publically accessible ip for this interface."""
+
+ region_code: Optional[str] = None
+ """The region interface is deployed to."""
class PublicInternetGatewayCreateResponse(BaseModel):
- data: Optional[PublicInternetGatewayRead] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/public_internet_gateway_delete_response.py b/src/telnyx/types/public_internet_gateway_delete_response.py
index 1935227e..8bc2e312 100644
--- a/src/telnyx/types/public_internet_gateway_delete_response.py
+++ b/src/telnyx/types/public_internet_gateway_delete_response.py
@@ -2,11 +2,20 @@
from typing import Optional
+from .record import Record
from .._models import BaseModel
-from .public_internet_gateway_read import PublicInternetGatewayRead
+from .network_interface import NetworkInterface
-__all__ = ["PublicInternetGatewayDeleteResponse"]
+__all__ = ["PublicInternetGatewayDeleteResponse", "Data"]
+
+
+class Data(Record, NetworkInterface):
+ public_ip: Optional[str] = None
+ """The publically accessible ip for this interface."""
+
+ region_code: Optional[str] = None
+ """The region interface is deployed to."""
class PublicInternetGatewayDeleteResponse(BaseModel):
- data: Optional[PublicInternetGatewayRead] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/public_internet_gateway_list_response.py b/src/telnyx/types/public_internet_gateway_list_response.py
new file mode 100644
index 00000000..ac8fa8a6
--- /dev/null
+++ b/src/telnyx/types/public_internet_gateway_list_response.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from .record import Record
+from .network_interface import NetworkInterface
+
+__all__ = ["PublicInternetGatewayListResponse"]
+
+
+class PublicInternetGatewayListResponse(Record, NetworkInterface):
+ public_ip: Optional[str] = None
+ """The publically accessible ip for this interface."""
+
+ region_code: Optional[str] = None
+ """The region interface is deployed to."""
diff --git a/src/telnyx/types/public_internet_gateway_read.py b/src/telnyx/types/public_internet_gateway_read.py
deleted file mode 100644
index 88d1785f..00000000
--- a/src/telnyx/types/public_internet_gateway_read.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from .._models import BaseModel
-from .interface_status import InterfaceStatus
-
-__all__ = ["PublicInternetGatewayRead"]
-
-
-class PublicInternetGatewayRead(BaseModel):
- id: Optional[str] = None
- """Identifies the resource."""
-
- created_at: Optional[str] = None
- """ISO 8601 formatted date-time indicating when the resource was created."""
-
- name: Optional[str] = None
- """A user specified name for the interface."""
-
- network_id: Optional[str] = None
- """The id of the network associated with the interface."""
-
- public_ip: Optional[str] = None
- """The publically accessible ip for this interface."""
-
- record_type: Optional[str] = None
- """Identifies the type of the resource."""
-
- region_code: Optional[str] = None
- """The region interface is deployed to."""
-
- status: Optional[InterfaceStatus] = None
- """The current status of the interface deployment."""
-
- updated_at: Optional[str] = None
- """ISO 8601 formatted date-time indicating when the resource was updated."""
diff --git a/src/telnyx/types/public_internet_gateway_retrieve_response.py b/src/telnyx/types/public_internet_gateway_retrieve_response.py
index 5c95dcce..c1b162e1 100644
--- a/src/telnyx/types/public_internet_gateway_retrieve_response.py
+++ b/src/telnyx/types/public_internet_gateway_retrieve_response.py
@@ -2,11 +2,20 @@
from typing import Optional
+from .record import Record
from .._models import BaseModel
-from .public_internet_gateway_read import PublicInternetGatewayRead
+from .network_interface import NetworkInterface
-__all__ = ["PublicInternetGatewayRetrieveResponse"]
+__all__ = ["PublicInternetGatewayRetrieveResponse", "Data"]
+
+
+class Data(Record, NetworkInterface):
+ public_ip: Optional[str] = None
+ """The publically accessible ip for this interface."""
+
+ region_code: Optional[str] = None
+ """The region interface is deployed to."""
class PublicInternetGatewayRetrieveResponse(BaseModel):
- data: Optional[PublicInternetGatewayRead] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/reputation/__init__.py b/src/telnyx/types/reputation/__init__.py
index 480b014b..9c9276a5 100644
--- a/src/telnyx/types/reputation/__init__.py
+++ b/src/telnyx/types/reputation/__init__.py
@@ -3,5 +3,6 @@
from __future__ import annotations
from .number_list_params import NumberListParams as NumberListParams
+from .number_list_response import NumberListResponse as NumberListResponse
from .number_retrieve_params import NumberRetrieveParams as NumberRetrieveParams
from .number_retrieve_response import NumberRetrieveResponse as NumberRetrieveResponse
diff --git a/src/telnyx/types/reputation/number_list_params.py b/src/telnyx/types/reputation/number_list_params.py
index 6091dce7..545ae09f 100644
--- a/src/telnyx/types/reputation/number_list_params.py
+++ b/src/telnyx/types/reputation/number_list_params.py
@@ -11,10 +11,13 @@
class NumberListParams(TypedDict, total=False):
page_number: Annotated[int, PropertyInfo(alias="page[number]")]
- """Page number (1-indexed)"""
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
page_size: Annotated[int, PropertyInfo(alias="page[size]")]
- """Number of items per page"""
+ """Items per page. Maximum 250; values above are clamped to 250."""
phone_number: str
- """Filter by specific phone number (E.164 format)"""
+ """Filter by specific phone number (E.164 format)."""
diff --git a/src/telnyx/types/shared/reputation_phone_number_with_reputation_data.py b/src/telnyx/types/reputation/number_list_response.py
similarity index 53%
rename from src/telnyx/types/shared/reputation_phone_number_with_reputation_data.py
rename to src/telnyx/types/reputation/number_list_response.py
index 2099474d..2ba40d46 100644
--- a/src/telnyx/types/shared/reputation_phone_number_with_reputation_data.py
+++ b/src/telnyx/types/reputation/number_list_response.py
@@ -4,26 +4,22 @@
from datetime import datetime
from ..._models import BaseModel
-from .reputation_data import ReputationData
+from ..shared.reputation_data import ReputationData
-__all__ = ["ReputationPhoneNumberWithReputationData"]
+__all__ = ["NumberListResponse"]
-class ReputationPhoneNumberWithReputationData(BaseModel):
+class NumberListResponse(BaseModel):
id: Optional[str] = None
- """Unique identifier"""
created_at: Optional[datetime] = None
- """When the number was associated"""
enterprise_id: Optional[str] = None
- """ID of the associated enterprise"""
phone_number: Optional[str] = None
- """Phone number in E.164 format"""
+ """E.164 with leading `+`."""
reputation_data: Optional[ReputationData] = None
- """Reputation metrics"""
+ """`null` until the first refresh has been collected for this number."""
updated_at: Optional[datetime] = None
- """When the record was last updated"""
diff --git a/src/telnyx/types/reputation/number_retrieve_params.py b/src/telnyx/types/reputation/number_retrieve_params.py
index 3c27c672..aa635b30 100644
--- a/src/telnyx/types/reputation/number_retrieve_params.py
+++ b/src/telnyx/types/reputation/number_retrieve_params.py
@@ -11,5 +11,5 @@ class NumberRetrieveParams(TypedDict, total=False):
fresh: bool
"""When true, fetches fresh reputation data (incurs API cost).
- When false, returns cached data.
+ When false (default), returns cached data.
"""
diff --git a/src/telnyx/types/reputation/number_retrieve_response.py b/src/telnyx/types/reputation/number_retrieve_response.py
index ddc5a7bf..a44ae4e7 100644
--- a/src/telnyx/types/reputation/number_retrieve_response.py
+++ b/src/telnyx/types/reputation/number_retrieve_response.py
@@ -1,12 +1,29 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from datetime import datetime
from ..._models import BaseModel
-from ..shared.reputation_phone_number_with_reputation_data import ReputationPhoneNumberWithReputationData
+from ..shared.reputation_data import ReputationData
-__all__ = ["NumberRetrieveResponse"]
+__all__ = ["NumberRetrieveResponse", "Data"]
+
+
+class Data(BaseModel):
+ id: Optional[str] = None
+
+ created_at: Optional[datetime] = None
+
+ enterprise_id: Optional[str] = None
+
+ phone_number: Optional[str] = None
+ """E.164 with leading `+`."""
+
+ reputation_data: Optional[ReputationData] = None
+ """`null` until the first refresh has been collected for this number."""
+
+ updated_at: Optional[datetime] = None
class NumberRetrieveResponse(BaseModel):
- data: Optional[ReputationPhoneNumberWithReputationData] = None
+ data: Data
diff --git a/src/telnyx/types/shared/__init__.py b/src/telnyx/types/shared/__init__.py
index 5c06c0cc..92f4ac00 100644
--- a/src/telnyx/types/shared/__init__.py
+++ b/src/telnyx/types/shared/__init__.py
@@ -4,7 +4,6 @@
from .feature import Feature as Feature
from .metadata import Metadata as Metadata
from .api_error import APIError as APIError
-from .meta_info import MetaInfo as MetaInfo
from .short_code import ShortCode as ShortCode
from .hosted_number import HostedNumber as HostedNumber
from .reputation_data import ReputationData as ReputationData
@@ -14,7 +13,6 @@
from .netapps_location import NetappsLocation as NetappsLocation
from .room_participant import RoomParticipant as RoomParticipant
from .region_information import RegionInformation as RegionInformation
-from .xai_voice_settings import XaiVoiceSettings as XaiVoiceSettings
from .rime_voice_settings import RimeVoiceSettings as RimeVoiceSettings
from .azure_voice_settings import AzureVoiceSettings as AzureVoiceSettings
from .porting_order_status import PortingOrderStatus as PortingOrderStatus
@@ -40,9 +38,6 @@
from .available_phone_numbers_metadata import AvailablePhoneNumbersMetadata as AvailablePhoneNumbersMetadata
from .connection_noise_suppression_details import ConnectionNoiseSuppressionDetails as ConnectionNoiseSuppressionDetails
from .phone_number_with_messaging_settings import PhoneNumberWithMessagingSettings as PhoneNumberWithMessagingSettings
-from .reputation_phone_number_with_reputation_data import (
- ReputationPhoneNumberWithReputationData as ReputationPhoneNumberWithReputationData,
-)
from .sub_number_order_regulatory_requirement_with_value import (
SubNumberOrderRegulatoryRequirementWithValue as SubNumberOrderRegulatoryRequirementWithValue,
)
diff --git a/src/telnyx/types/shared/meta_info.py b/src/telnyx/types/shared/meta_info.py
deleted file mode 100644
index 6066280d..00000000
--- a/src/telnyx/types/shared/meta_info.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from ..._models import BaseModel
-
-__all__ = ["MetaInfo"]
-
-
-class MetaInfo(BaseModel):
- page_number: Optional[int] = None
- """Current page number"""
-
- page_size: Optional[int] = None
- """Items per page"""
-
- total_pages: Optional[int] = None
- """Total number of pages"""
-
- total_results: Optional[int] = None
- """Total number of results"""
diff --git a/src/telnyx/types/shared/reputation_data.py b/src/telnyx/types/shared/reputation_data.py
index 46f61348..2602ea52 100644
--- a/src/telnyx/types/shared/reputation_data.py
+++ b/src/telnyx/types/shared/reputation_data.py
@@ -10,25 +10,23 @@
class ReputationData(BaseModel):
- """Reputation metrics"""
+ """Reputation snapshot for a phone number.
+
+ Each metric is a 0–100 score; `spam_risk` is a coarse bucket. Field set may grow over time — read by key.
+ """
connection_score: Optional[int] = None
- """Connection quality metric (0–100)"""
engagement_score: Optional[int] = None
- """Engagement metric (0–100). Higher = more positive engagement"""
last_refreshed_at: Optional[datetime] = None
- """Timestamp of the last reputation data refresh"""
maturity_score: Optional[int] = None
- """Maturity metric (0–100). Higher = more established number"""
sentiment_score: Optional[int] = None
- """Sentiment metric (0–100). Higher = more positive sentiment"""
spam_category: Optional[str] = None
- """Spam category classification (e.g., Telemarketing, Debt Collector)"""
+ """Category label from the reputation feed when the number is flagged."""
spam_risk: Optional[Literal["low", "medium", "high"]] = None
- """Overall spam risk level"""
+ """Overall spam-risk classification."""
diff --git a/src/telnyx/types/shared/xai_voice_settings.py b/src/telnyx/types/shared/xai_voice_settings.py
deleted file mode 100644
index 3ad6ade7..00000000
--- a/src/telnyx/types/shared/xai_voice_settings.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from ..._models import BaseModel
-
-__all__ = ["XaiVoiceSettings"]
-
-
-class XaiVoiceSettings(BaseModel):
- type: Literal["xai"]
- """Voice settings provider type"""
-
- language: Optional[str] = None
- """Language code, or `auto` to detect automatically."""
diff --git a/src/telnyx/types/shared_params/__init__.py b/src/telnyx/types/shared_params/__init__.py
index 277b4842..1143dd3d 100644
--- a/src/telnyx/types/shared_params/__init__.py
+++ b/src/telnyx/types/shared_params/__init__.py
@@ -1,7 +1,6 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from .sim_card_status import SimCardStatus as SimCardStatus
-from .xai_voice_settings import XaiVoiceSettings as XaiVoiceSettings
from .rime_voice_settings import RimeVoiceSettings as RimeVoiceSettings
from .azure_voice_settings import AzureVoiceSettings as AzureVoiceSettings
from .book_appointment_tool import BookAppointmentTool as BookAppointmentTool
diff --git a/src/telnyx/types/shared_params/xai_voice_settings.py b/src/telnyx/types/shared_params/xai_voice_settings.py
deleted file mode 100644
index 522c82e7..00000000
--- a/src/telnyx/types/shared_params/xai_voice_settings.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import Literal, Required, TypedDict
-
-__all__ = ["XaiVoiceSettings"]
-
-
-class XaiVoiceSettings(TypedDict, total=False):
- type: Required[Literal["xai"]]
- """Voice settings provider type"""
-
- language: str
- """Language code, or `auto` to detect automatically."""
diff --git a/src/telnyx/types/terms_of_service/__init__.py b/src/telnyx/types/terms_of_service/__init__.py
index f8ee8b14..2a11efeb 100644
--- a/src/telnyx/types/terms_of_service/__init__.py
+++ b/src/telnyx/types/terms_of_service/__init__.py
@@ -1,3 +1,9 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from __future__ import annotations
+
+from .agreement_list_params import AgreementListParams as AgreementListParams
+from .agreement_list_response import AgreementListResponse as AgreementListResponse
+from .agreement_retrieve_response import AgreementRetrieveResponse as AgreementRetrieveResponse
+from .branded_calling_agree_response import BrandedCallingAgreeResponse as BrandedCallingAgreeResponse
+from .number_reputation_agree_response import NumberReputationAgreeResponse as NumberReputationAgreeResponse
diff --git a/src/telnyx/types/terms_of_service/agreement_list_params.py b/src/telnyx/types/terms_of_service/agreement_list_params.py
new file mode 100644
index 00000000..b0b99e32
--- /dev/null
+++ b/src/telnyx/types/terms_of_service/agreement_list_params.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Annotated, TypedDict
+
+from ..._utils import PropertyInfo
+
+__all__ = ["AgreementListParams"]
+
+
+class AgreementListParams(TypedDict, total=False):
+ page_number: Annotated[int, PropertyInfo(alias="page[number]")]
+ """1-based page number.
+
+ Out-of-range values return an empty page with correct meta.
+ """
+
+ page_size: Annotated[int, PropertyInfo(alias="page[size]")]
+ """Items per page. Maximum 250; values above are clamped to 250."""
+
+ product_type: Literal["branded_calling", "number_reputation"]
+ """Optional filter.
+
+ Omit to list the user's agreements for **every** product (branded_calling and
+ number_reputation); pass a value to return only that product's agreements.
+ """
diff --git a/src/telnyx/types/terms_of_service/agreement_list_response.py b/src/telnyx/types/terms_of_service/agreement_list_response.py
new file mode 100644
index 00000000..611a9894
--- /dev/null
+++ b/src/telnyx/types/terms_of_service/agreement_list_response.py
@@ -0,0 +1,30 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["AgreementListResponse"]
+
+
+class AgreementListResponse(BaseModel):
+ """A recorded user agreement to a product's Terms of Service.
+
+ The `user_id` is intentionally NOT echoed back on this public surface — the caller already knows their own identity.
+ """
+
+ id: Optional[str] = None
+
+ agreed_at: Optional[datetime] = None
+
+ created_at: Optional[datetime] = None
+
+ product_type: Optional[Literal["branded_calling", "number_reputation"]] = None
+ """Telnyx product the Terms of Service apply to."""
+
+ terms_version: Optional[str] = None
+
+ version: Optional[str] = None
+ """Convenience alias of `terms_version`. Both keys are present on every response."""
diff --git a/src/telnyx/types/terms_of_service/agreement_retrieve_response.py b/src/telnyx/types/terms_of_service/agreement_retrieve_response.py
new file mode 100644
index 00000000..3d01ad90
--- /dev/null
+++ b/src/telnyx/types/terms_of_service/agreement_retrieve_response.py
@@ -0,0 +1,39 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["AgreementRetrieveResponse", "Data"]
+
+
+class Data(BaseModel):
+ """A recorded user agreement to a product's Terms of Service.
+
+ The `user_id` is intentionally NOT echoed back on this public surface — the caller already knows their own identity.
+ """
+
+ id: Optional[str] = None
+
+ agreed_at: Optional[datetime] = None
+
+ created_at: Optional[datetime] = None
+
+ product_type: Optional[Literal["branded_calling", "number_reputation"]] = None
+ """Telnyx product the Terms of Service apply to."""
+
+ terms_version: Optional[str] = None
+
+ version: Optional[str] = None
+ """Convenience alias of `terms_version`. Both keys are present on every response."""
+
+
+class AgreementRetrieveResponse(BaseModel):
+ data: Data
+ """A recorded user agreement to a product's Terms of Service.
+
+ The `user_id` is intentionally NOT echoed back on this public surface — the
+ caller already knows their own identity.
+ """
diff --git a/src/telnyx/types/terms_of_service/branded_calling_agree_response.py b/src/telnyx/types/terms_of_service/branded_calling_agree_response.py
new file mode 100644
index 00000000..62dc120d
--- /dev/null
+++ b/src/telnyx/types/terms_of_service/branded_calling_agree_response.py
@@ -0,0 +1,39 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["BrandedCallingAgreeResponse", "Data"]
+
+
+class Data(BaseModel):
+ """A recorded user agreement to a product's Terms of Service.
+
+ The `user_id` is intentionally NOT echoed back on this public surface — the caller already knows their own identity.
+ """
+
+ id: Optional[str] = None
+
+ agreed_at: Optional[datetime] = None
+
+ created_at: Optional[datetime] = None
+
+ product_type: Optional[Literal["branded_calling", "number_reputation"]] = None
+ """Telnyx product the Terms of Service apply to."""
+
+ terms_version: Optional[str] = None
+
+ version: Optional[str] = None
+ """Convenience alias of `terms_version`. Both keys are present on every response."""
+
+
+class BrandedCallingAgreeResponse(BaseModel):
+ data: Data
+ """A recorded user agreement to a product's Terms of Service.
+
+ The `user_id` is intentionally NOT echoed back on this public surface — the
+ caller already knows their own identity.
+ """
diff --git a/src/telnyx/types/terms_of_service/number_reputation_agree_response.py b/src/telnyx/types/terms_of_service/number_reputation_agree_response.py
new file mode 100644
index 00000000..c6d38ce8
--- /dev/null
+++ b/src/telnyx/types/terms_of_service/number_reputation_agree_response.py
@@ -0,0 +1,39 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["NumberReputationAgreeResponse", "Data"]
+
+
+class Data(BaseModel):
+ """A recorded user agreement to a product's Terms of Service.
+
+ The `user_id` is intentionally NOT echoed back on this public surface — the caller already knows their own identity.
+ """
+
+ id: Optional[str] = None
+
+ agreed_at: Optional[datetime] = None
+
+ created_at: Optional[datetime] = None
+
+ product_type: Optional[Literal["branded_calling", "number_reputation"]] = None
+ """Telnyx product the Terms of Service apply to."""
+
+ terms_version: Optional[str] = None
+
+ version: Optional[str] = None
+ """Convenience alias of `terms_version`. Both keys are present on every response."""
+
+
+class NumberReputationAgreeResponse(BaseModel):
+ data: Data
+ """A recorded user agreement to a product's Terms of Service.
+
+ The `user_id` is intentionally NOT echoed back on this public surface — the
+ caller already knows their own identity.
+ """
diff --git a/src/telnyx/types/terms_of_service_status_params.py b/src/telnyx/types/terms_of_service_status_params.py
new file mode 100644
index 00000000..25fe5ccb
--- /dev/null
+++ b/src/telnyx/types/terms_of_service_status_params.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["TermsOfServiceStatusParams"]
+
+
+class TermsOfServiceStatusParams(TypedDict, total=False):
+ product_type: Literal["branded_calling", "number_reputation"]
+ """Which product's ToS to check.
+
+ Defaults to `branded_calling`; pass `number_reputation` to check the Number
+ Reputation Terms of Service.
+ """
diff --git a/src/telnyx/types/terms_of_service_status_response.py b/src/telnyx/types/terms_of_service_status_response.py
new file mode 100644
index 00000000..7e0d1eff
--- /dev/null
+++ b/src/telnyx/types/terms_of_service_status_response.py
@@ -0,0 +1,47 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from datetime import datetime
+from typing_extensions import Literal
+
+from .._models import BaseModel
+
+__all__ = ["TermsOfServiceStatusResponse", "Data"]
+
+
+class Data(BaseModel):
+ """Whether the calling user has agreed to a product's current Terms of Service.
+
+ The `user_id` is intentionally omitted on this public surface.
+ """
+
+ agreement_required: bool
+ """`true` when the user must agree to the latest version before using the product.
+
+ Equivalent to `!has_agreed`.
+ """
+
+ current_terms_version: str
+ """Latest published version of the ToS for this product."""
+
+ has_agreed: bool
+ """`true` if the user has agreed to the latest version."""
+
+ product_type: Literal["branded_calling", "number_reputation"]
+ """Telnyx product the Terms of Service apply to."""
+
+ agreed_at: Optional[datetime] = None
+
+ agreed_version: Optional[str] = None
+ """
+ Version the user previously agreed to (may be older than
+ `current_terms_version`). `null` if the user has never agreed.
+ """
+
+
+class TermsOfServiceStatusResponse(BaseModel):
+ data: Data
+ """Whether the calling user has agreed to a product's current Terms of Service.
+
+ The `user_id` is intentionally omitted on this public surface.
+ """
diff --git a/src/telnyx/types/uac_connection.py b/src/telnyx/types/uac_connection.py
deleted file mode 100644
index 65a32656..00000000
--- a/src/telnyx/types/uac_connection.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from typing_extensions import Literal
-
-from .fqdn import Fqdn
-from .._models import BaseModel
-from .dtmf_type import DtmfType
-from .uac_inbound import UacInbound
-from .uac_outbound import UacOutbound
-from .encrypted_media import EncryptedMedia
-from .anchorsite_override import AnchorsiteOverride
-from .uac_external_settings import UacExternalSettings
-from .uac_internal_settings import UacInternalSettings
-from .connection_rtcp_settings import ConnectionRtcpSettings
-from .shared.connection_jitter_buffer import ConnectionJitterBuffer
-from .shared.connection_noise_suppression_details import ConnectionNoiseSuppressionDetails
-
-__all__ = ["UacConnection"]
-
-
-class UacConnection(BaseModel):
- """
- A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your PBX doesn’t support outbound SIP registration or you need Telnyx to maintain the registration.
- """
-
- id: Optional[str] = None
- """Identifies the type of resource."""
-
- active: Optional[bool] = None
- """Defaults to true"""
-
- anchorsite_override: Optional[AnchorsiteOverride] = None
- """
- `Latency` directs Telnyx to route media through the site with the lowest
- round-trip time to the user's connection. Telnyx calculates this time using ICMP
- ping messages. This can be disabled by specifying a site to handle all media.
- """
-
- android_push_credential_id: Optional[str] = None
- """The uuid of the push credential for Android"""
-
- authentication: Optional[Literal["uac-authentication"]] = None
- """The authentication strategy used by this connection."""
-
- call_cost_in_webhooks: Optional[bool] = None
- """Specifies if call cost webhooks should be sent for this connection."""
-
- connection_name: Optional[str] = None
-
- created_at: Optional[str] = None
- """ISO-8601 formatted date indicating when the resource was created."""
-
- default_on_hold_comfort_noise_enabled: Optional[bool] = None
- """When enabled, Telnyx will generate comfort noise when you place the call on
- hold.
-
- If disabled, you will need to generate comfort noise or on hold music to avoid
- RTP timeout.
- """
-
- dtmf_type: Optional[DtmfType] = None
- """Sets the type of DTMF digits sent from Telnyx to this Connection.
-
- Note that DTMF digits sent to Telnyx will be accepted in all formats.
- """
-
- encode_contact_header_enabled: Optional[bool] = None
- """
- Encode the SIP contact header sent by Telnyx to avoid issues for NAT or ALG
- scenarios.
- """
-
- encrypted_media: Optional[EncryptedMedia] = None
- """Enable use of SRTP for encryption.
-
- Cannot be set if the transport_portocol is TLS.
- """
-
- external_uac_settings: Optional[UacExternalSettings] = None
- """
- External SIP peer settings used by Telnyx when registering to your PBX and
- routing outbound calls.
- """
-
- fqdn: Optional[str] = None
- """The Telnyx-managed FQDN generated for the UAC connection."""
-
- fqdn_outbound_authentication: Optional[Literal["credential-authentication"]] = None
- """The fixed outbound authentication mode used by UAC FQDN records."""
-
- fqdns: Optional[List[Fqdn]] = None
- """FQDN records managed automatically by the UAC connection lifecycle."""
-
- inbound: Optional[UacInbound] = None
-
- internal_uac_settings: Optional[UacInternalSettings] = None
- """Internal Telnyx-side settings for a UAC connection."""
-
- ios_push_credential_id: Optional[str] = None
- """The uuid of the push credential for Ios"""
-
- jitter_buffer: Optional[ConnectionJitterBuffer] = None
- """Configuration options for Jitter Buffer.
-
- Enables Jitter Buffer for RTP streams of SIP Trunking calls. The feature is off
- unless enabled. You may define min and max values in msec for customized
- buffering behaviors. Larger values add latency but tolerate more jitter, while
- smaller values reduce latency but are more sensitive to jitter and reordering.
- """
-
- noise_suppression: Optional[Literal["inbound", "outbound", "both", "disabled"]] = None
- """Controls when noise suppression is applied to calls.
-
- When set to 'inbound', noise suppression is applied to incoming audio. When set
- to 'outbound', it's applied to outgoing audio. When set to 'both', it's applied
- in both directions. When set to 'disabled', noise suppression is turned off.
- """
-
- noise_suppression_details: Optional[ConnectionNoiseSuppressionDetails] = None
- """Configuration options for noise suppression.
-
- These settings are stored regardless of the noise_suppression value, but only
- take effect when noise_suppression is not 'disabled'. If you disable noise
- suppression and later re-enable it, the previously configured settings will be
- used.
- """
-
- onnet_t38_passthrough_enabled: Optional[bool] = None
- """
- Enable on-net T38 if you prefer the sender and receiver negotiating T38 directly
- if both are on the Telnyx network. If this is disabled, Telnyx will be able to
- use T38 on just one leg of the call depending on each leg's settings.
- """
-
- outbound: Optional[UacOutbound] = None
-
- password: Optional[str] = None
- """The password to be used as part of the credentials.
-
- Must be 8 to 128 characters long.
- """
-
- record_type: Optional[str] = None
- """Identifies the type of the resource."""
-
- registration_status: Optional[str] = None
- """The most recently known SIP registration status for this UAC connection."""
-
- registration_status_updated_at: Optional[str] = None
- """
- ISO 8601 formatted date indicating when the registration status was last
- updated.
- """
-
- rtcp_settings: Optional[ConnectionRtcpSettings] = None
-
- sip_uri_calling_preference: Optional[Literal["disabled", "unrestricted", "internal"]] = None
- """This feature enables inbound SIP URI calls to your Credential Auth Connection.
-
- If enabled for all (unrestricted) then anyone who calls the SIP URI
- @telnyx.com will be connected to your Connection. You can also
- choose to allow only calls that are originated on any Connections under your
- account (internal).
- """
-
- tags: Optional[List[str]] = None
- """Tags associated with the connection."""
-
- updated_at: Optional[str] = None
- """ISO-8601 formatted date indicating when the resource was updated."""
-
- user_name: Optional[str] = None
- """The user name to be used as part of the credentials.
-
- Must be 4-32 characters long and alphanumeric values only (no spaces or special
- characters). At least one of the first 5 characters must be a letter.
- """
-
- webhook_api_version: Optional[Literal["1", "2"]] = None
- """Determines which webhook format will be used, Telnyx API v1 or v2."""
-
- webhook_event_failover_url: Optional[str] = None
- """
- The failover URL where webhooks related to this connection will be sent if
- sending to the primary URL fails. Must include a scheme, such as 'https'.
- """
-
- webhook_event_url: Optional[str] = None
- """The URL where webhooks related to this connection will be sent.
-
- Must include a scheme, such as 'https'.
- """
-
- webhook_timeout_secs: Optional[int] = None
- """Specifies how many seconds to wait before timing out a webhook."""
diff --git a/src/telnyx/types/uac_connection_create_params.py b/src/telnyx/types/uac_connection_create_params.py
index 60b9ee3d..527ec344 100644
--- a/src/telnyx/types/uac_connection_create_params.py
+++ b/src/telnyx/types/uac_connection_create_params.py
@@ -8,15 +8,12 @@
from .._types import SequenceNotStr
from .dtmf_type import DtmfType
from .encrypted_media import EncryptedMedia
-from .uac_outbound_param import UacOutboundParam
from .anchorsite_override import AnchorsiteOverride
-from .uac_external_settings_param import UacExternalSettingsParam
-from .uac_internal_settings_param import UacInternalSettingsParam
from .connection_rtcp_settings_param import ConnectionRtcpSettingsParam
from .shared_params.connection_jitter_buffer import ConnectionJitterBuffer
from .shared_params.connection_noise_suppression_details import ConnectionNoiseSuppressionDetails
-__all__ = ["UacConnectionCreateParams", "Inbound"]
+__all__ = ["UacConnectionCreateParams", "ExternalUacSettings", "Inbound", "InternalUacSettings", "Outbound"]
class UacConnectionCreateParams(TypedDict, total=False):
@@ -65,7 +62,7 @@ class UacConnectionCreateParams(TypedDict, total=False):
Cannot be set if the transport_portocol is TLS.
"""
- external_uac_settings: UacExternalSettingsParam
+ external_uac_settings: ExternalUacSettings
"""
External SIP peer settings used by Telnyx when registering to your PBX and
routing outbound calls.
@@ -79,7 +76,7 @@ class UacConnectionCreateParams(TypedDict, total=False):
Telnyx and are not accepted as request parameters.
"""
- internal_uac_settings: UacInternalSettingsParam
+ internal_uac_settings: InternalUacSettings
"""Internal Telnyx-side settings for a UAC connection."""
ios_push_credential_id: Optional[str]
@@ -118,7 +115,7 @@ class UacConnectionCreateParams(TypedDict, total=False):
use T38 on just one leg of the call depending on each leg's settings.
"""
- outbound: UacOutboundParam
+ outbound: Outbound
password: str
"""The password to be used as part of the credentials.
@@ -170,6 +167,58 @@ class UacConnectionCreateParams(TypedDict, total=False):
"""Specifies how many seconds to wait before timing out a webhook."""
+class ExternalUacSettings(TypedDict, total=False):
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
+ """
+
+ auth_username: Optional[str]
+ """The authentication username used in SIP digest authentication.
+
+ If not set, the Username value will be used.
+ """
+
+ expiration_sec: Optional[int]
+ """
+ The registration interval, in seconds, indicating how often the system refreshes
+ the SIP registration with the external SIP peer.
+ """
+
+ from_user: Optional[str]
+ """The user portion of the SIP From header used in outbound requests.
+
+ This controls the caller identity presented to the external SIP peer.
+ """
+
+ outbound_proxy: Optional[str]
+ """
+ An optional SIP proxy used to route outbound requests before reaching the
+ external SIP peer.
+ """
+
+ password: str
+ """The SIP password used for digest authentication with the external SIP peer."""
+
+ proxy: str
+ """
+ The SIP proxy address of the external SIP peer used for registrations and
+ outbound call routing.
+ """
+
+ transport: Optional[Literal["UDP", "TLS", "TCP"]]
+ """
+ The transport protocol used for SIP signaling when communicating with the
+ external SIP peer. One of UDP, TLS, or TCP.
+ """
+
+ username: str
+ """
+ The SIP username used to authenticate with the external SIP peer for
+ registrations and outbound calls. Must start with a letter or number and contain
+ only letters, numbers, hyphens, and underscores.
+ """
+
+
class Inbound(TypedDict, total=False):
"""Inbound settings that can be supplied when creating or updating a UAC connection.
@@ -235,3 +284,72 @@ class Inbound(TypedDict, total=False):
timeout_2xx_secs: int
"""Time(sec) before aborting if call is unanswered (min: 1, max: 600)."""
+
+
+class InternalUacSettings(TypedDict, total=False):
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ destination_uri: str
+ """
+ The SIP URI that Telnyx will call when handling an inbound request from the
+ external peer. Do not include a `sip:` prefix. The value must be in the format
+ `userinfo@sip.telnyx.com` or
+ `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
+ letters, digits, hyphens, and underscores.
+ """
+
+
+class Outbound(TypedDict, total=False):
+ ani_override: str
+ """
+ Set a phone number as the ani_override value to override caller id number on
+ outbound calls.
+ """
+
+ ani_override_type: Literal["always", "normal", "emergency"]
+ """Specifies when we apply your ani_override setting.
+
+ Only applies when ani_override is not blank.
+ """
+
+ call_parking_enabled: Optional[bool]
+ """
+ Forces all SIP calls originated on this connection to be "parked" instead of
+ "bridged" to the destination specified on the URI. Parked calls will return
+ ringback to the caller and will await for a Call Control command to define which
+ action will be taken next.
+ """
+
+ channel_limit: int
+ """
+ When set, this will limit the total number of outbound calls to phone numbers
+ associated with this connection.
+ """
+
+ generate_ringback_tone: bool
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ instant_ringback_enabled: bool
+ """
+ When set, ringback will not wait for indication before sending ringback tone to
+ calling party.
+ """
+
+ localization: str
+ """
+ A 2-character country code specifying the country whose national dialing rules
+ should be used. For example, if set to `US` then any US number can be dialed
+ without preprending +1 to the number. When left blank, Telnyx will try US and GB
+ dialing rules, in that order, by default.
+ """
+
+ outbound_voice_profile_id: str
+ """Identifies the associated outbound voice profile."""
+
+ t38_reinvite_source: Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
+ """This setting only affects connections with Fax-type Outbound Voice Profiles.
+
+ The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
+ default, Telnyx will send the re-invite. If set to `customer`, the caller is
+ expected to send the t.38 reinvite.
+ """
diff --git a/src/telnyx/types/uac_connection_create_response.py b/src/telnyx/types/uac_connection_create_response.py
index 53442510..3b26c2e3 100644
--- a/src/telnyx/types/uac_connection_create_response.py
+++ b/src/telnyx/types/uac_connection_create_response.py
@@ -1,15 +1,397 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import List, Optional
+from typing_extensions import Literal
+from .fqdn import Fqdn
from .._models import BaseModel
-from .uac_connection import UacConnection
+from .dtmf_type import DtmfType
+from .encrypted_media import EncryptedMedia
+from .anchorsite_override import AnchorsiteOverride
+from .connection_rtcp_settings import ConnectionRtcpSettings
+from .shared.connection_jitter_buffer import ConnectionJitterBuffer
+from .shared.connection_noise_suppression_details import ConnectionNoiseSuppressionDetails
-__all__ = ["UacConnectionCreateResponse"]
+__all__ = [
+ "UacConnectionCreateResponse",
+ "Data",
+ "DataExternalUacSettings",
+ "DataInbound",
+ "DataInternalUacSettings",
+ "DataOutbound",
+]
+
+
+class DataExternalUacSettings(BaseModel):
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
+ """
+
+ auth_username: Optional[str] = None
+ """The authentication username used in SIP digest authentication.
+
+ If not set, the Username value will be used.
+ """
+
+ expiration_sec: Optional[int] = None
+ """
+ The registration interval, in seconds, indicating how often the system refreshes
+ the SIP registration with the external SIP peer.
+ """
+
+ from_user: Optional[str] = None
+ """The user portion of the SIP From header used in outbound requests.
+
+ This controls the caller identity presented to the external SIP peer.
+ """
+
+ outbound_proxy: Optional[str] = None
+ """
+ An optional SIP proxy used to route outbound requests before reaching the
+ external SIP peer.
+ """
+
+ password: Optional[str] = None
+ """The SIP password used for digest authentication with the external SIP peer."""
+
+ proxy: Optional[str] = None
+ """
+ The SIP proxy address of the external SIP peer used for registrations and
+ outbound call routing.
+ """
+
+ transport: Optional[Literal["UDP", "TLS", "TCP"]] = None
+ """
+ The transport protocol used for SIP signaling when communicating with the
+ external SIP peer. One of UDP, TLS, or TCP.
+ """
+
+ username: Optional[str] = None
+ """
+ The SIP username used to authenticate with the external SIP peer for
+ registrations and outbound calls. Must start with a letter or number and contain
+ only letters, numbers, hyphens, and underscores.
+ """
+
+
+class DataInbound(BaseModel):
+ ani_number_format: Optional[Literal["+E.164", "E.164", "+E.164-national", "E.164-national"]] = None
+ """
+ This setting allows you to set the format with which the caller's number (ANI)
+ is sent for inbound phone calls.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of inbound calls to phone numbers
+ associated with this connection.
+ """
+
+ codecs: Optional[List[str]] = None
+ """
+ Defines the list of codecs that Telnyx will send for inbound calls to a specific
+ number on your portal account, in priority order. This only works when the
+ Connection the number is assigned to uses Media Handling mode: default. OPUS and
+ H.264 codecs are available only when using TCP or TLS transport for SIP.
+ """
+
+ default_routing_method: Optional[Literal["sequential", "round-robin"]] = None
+ """
+ Default routing method to be used when a number is associated with the
+ connection. Must be one of the routing method types or left blank, other values
+ are not allowed.
+ """
+
+ dnis_number_format: Optional[Literal["+e164", "e164", "national", "sip_username"]] = None
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ isup_headers_enabled: Optional[bool] = None
+ """When set, inbound phone calls will receive ISUP parameters via SIP headers.
+
+ (Only when available and only when using TCP or TLS transport.)
+ """
+
+ prack_enabled: Optional[bool] = None
+ """Enable PRACK messages as defined in RFC3262."""
+
+ shaken_stir_enabled: Optional[bool] = None
+ """
+ When enabled the SIP Connection will receive the Identity header with
+ Shaken/Stir data in the SIP INVITE message of inbound calls, even when using UDP
+ transport.
+ """
+
+ simultaneous_ringing: Optional[Literal["disabled", "enabled"]] = None
+ """When enabled, allows multiple devices to ring simultaneously on incoming calls."""
+
+ sip_compact_headers_enabled: Optional[bool] = None
+ """Defaults to true."""
+
+ sip_subdomain: Optional[str] = None
+ """The Telnyx-generated SIP subdomain for this UAC connection."""
+
+ sip_subdomain_receive_settings: Optional[Literal["only_my_connections", "from_anyone"]] = None
+ """Controls which SIP URI callers may reach this connection."""
+
+ timeout_1xx_secs: Optional[int] = None
+ """Time(sec) before aborting if connection is not made."""
+
+ timeout_2xx_secs: Optional[int] = None
+ """Time(sec) before aborting if call is unanswered (min: 1, max: 600)."""
+
+
+class DataInternalUacSettings(BaseModel):
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ destination_uri: Optional[str] = None
+ """
+ The SIP URI that Telnyx will call when handling an inbound request from the
+ external peer. Do not include a `sip:` prefix. The value must be in the format
+ `userinfo@sip.telnyx.com` or
+ `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
+ letters, digits, hyphens, and underscores.
+ """
+
+
+class DataOutbound(BaseModel):
+ ani_override: Optional[str] = None
+ """
+ Set a phone number as the ani_override value to override caller id number on
+ outbound calls.
+ """
+
+ ani_override_type: Optional[Literal["always", "normal", "emergency"]] = None
+ """Specifies when we apply your ani_override setting.
+
+ Only applies when ani_override is not blank.
+ """
+
+ call_parking_enabled: Optional[bool] = None
+ """
+ Forces all SIP calls originated on this connection to be "parked" instead of
+ "bridged" to the destination specified on the URI. Parked calls will return
+ ringback to the caller and will await for a Call Control command to define which
+ action will be taken next.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of outbound calls to phone numbers
+ associated with this connection.
+ """
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ instant_ringback_enabled: Optional[bool] = None
+ """
+ When set, ringback will not wait for indication before sending ringback tone to
+ calling party.
+ """
+
+ localization: Optional[str] = None
+ """
+ A 2-character country code specifying the country whose national dialing rules
+ should be used. For example, if set to `US` then any US number can be dialed
+ without preprending +1 to the number. When left blank, Telnyx will try US and GB
+ dialing rules, in that order, by default.
+ """
+
+ outbound_voice_profile_id: Optional[str] = None
+ """Identifies the associated outbound voice profile."""
+
+ t38_reinvite_source: Optional[
+ Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
+ ] = None
+ """This setting only affects connections with Fax-type Outbound Voice Profiles.
+
+ The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
+ default, Telnyx will send the re-invite. If set to `customer`, the caller is
+ expected to send the t.38 reinvite.
+ """
+
+
+class Data(BaseModel):
+ """
+ A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your PBX doesn’t support outbound SIP registration or you need Telnyx to maintain the registration.
+ """
+
+ id: Optional[str] = None
+ """Identifies the type of resource."""
+
+ active: Optional[bool] = None
+ """Defaults to true"""
+
+ anchorsite_override: Optional[AnchorsiteOverride] = None
+ """
+ `Latency` directs Telnyx to route media through the site with the lowest
+ round-trip time to the user's connection. Telnyx calculates this time using ICMP
+ ping messages. This can be disabled by specifying a site to handle all media.
+ """
+
+ android_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Android"""
+
+ authentication: Optional[Literal["uac-authentication"]] = None
+ """The authentication strategy used by this connection."""
+
+ call_cost_in_webhooks: Optional[bool] = None
+ """Specifies if call cost webhooks should be sent for this connection."""
+
+ connection_name: Optional[str] = None
+
+ created_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was created."""
+
+ default_on_hold_comfort_noise_enabled: Optional[bool] = None
+ """When enabled, Telnyx will generate comfort noise when you place the call on
+ hold.
+
+ If disabled, you will need to generate comfort noise or on hold music to avoid
+ RTP timeout.
+ """
+
+ dtmf_type: Optional[DtmfType] = None
+ """Sets the type of DTMF digits sent from Telnyx to this Connection.
+
+ Note that DTMF digits sent to Telnyx will be accepted in all formats.
+ """
+
+ encode_contact_header_enabled: Optional[bool] = None
+ """
+ Encode the SIP contact header sent by Telnyx to avoid issues for NAT or ALG
+ scenarios.
+ """
+
+ encrypted_media: Optional[EncryptedMedia] = None
+ """Enable use of SRTP for encryption.
+
+ Cannot be set if the transport_portocol is TLS.
+ """
+
+ external_uac_settings: Optional[DataExternalUacSettings] = None
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and
+ routing outbound calls.
+ """
+
+ fqdn: Optional[str] = None
+ """The Telnyx-managed FQDN generated for the UAC connection."""
+
+ fqdn_outbound_authentication: Optional[Literal["credential-authentication"]] = None
+ """The fixed outbound authentication mode used by UAC FQDN records."""
+
+ fqdns: Optional[List[Fqdn]] = None
+ """FQDN records managed automatically by the UAC connection lifecycle."""
+
+ inbound: Optional[DataInbound] = None
+
+ internal_uac_settings: Optional[DataInternalUacSettings] = None
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ ios_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Ios"""
+
+ jitter_buffer: Optional[ConnectionJitterBuffer] = None
+ """Configuration options for Jitter Buffer.
+
+ Enables Jitter Buffer for RTP streams of SIP Trunking calls. The feature is off
+ unless enabled. You may define min and max values in msec for customized
+ buffering behaviors. Larger values add latency but tolerate more jitter, while
+ smaller values reduce latency but are more sensitive to jitter and reordering.
+ """
+
+ noise_suppression: Optional[Literal["inbound", "outbound", "both", "disabled"]] = None
+ """Controls when noise suppression is applied to calls.
+
+ When set to 'inbound', noise suppression is applied to incoming audio. When set
+ to 'outbound', it's applied to outgoing audio. When set to 'both', it's applied
+ in both directions. When set to 'disabled', noise suppression is turned off.
+ """
+
+ noise_suppression_details: Optional[ConnectionNoiseSuppressionDetails] = None
+ """Configuration options for noise suppression.
+
+ These settings are stored regardless of the noise_suppression value, but only
+ take effect when noise_suppression is not 'disabled'. If you disable noise
+ suppression and later re-enable it, the previously configured settings will be
+ used.
+ """
+
+ onnet_t38_passthrough_enabled: Optional[bool] = None
+ """
+ Enable on-net T38 if you prefer the sender and receiver negotiating T38 directly
+ if both are on the Telnyx network. If this is disabled, Telnyx will be able to
+ use T38 on just one leg of the call depending on each leg's settings.
+ """
+
+ outbound: Optional[DataOutbound] = None
+
+ password: Optional[str] = None
+ """The password to be used as part of the credentials.
+
+ Must be 8 to 128 characters long.
+ """
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+ registration_status: Optional[str] = None
+ """The most recently known SIP registration status for this UAC connection."""
+
+ registration_status_updated_at: Optional[str] = None
+ """
+ ISO 8601 formatted date indicating when the registration status was last
+ updated.
+ """
+
+ rtcp_settings: Optional[ConnectionRtcpSettings] = None
+
+ sip_uri_calling_preference: Optional[Literal["disabled", "unrestricted", "internal"]] = None
+ """This feature enables inbound SIP URI calls to your Credential Auth Connection.
+
+ If enabled for all (unrestricted) then anyone who calls the SIP URI
+ @telnyx.com will be connected to your Connection. You can also
+ choose to allow only calls that are originated on any Connections under your
+ account (internal).
+ """
+
+ tags: Optional[List[str]] = None
+ """Tags associated with the connection."""
+
+ updated_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was updated."""
+
+ user_name: Optional[str] = None
+ """The user name to be used as part of the credentials.
+
+ Must be 4-32 characters long and alphanumeric values only (no spaces or special
+ characters). At least one of the first 5 characters must be a letter.
+ """
+
+ webhook_api_version: Optional[Literal["1", "2"]] = None
+ """Determines which webhook format will be used, Telnyx API v1 or v2."""
+
+ webhook_event_failover_url: Optional[str] = None
+ """
+ The failover URL where webhooks related to this connection will be sent if
+ sending to the primary URL fails. Must include a scheme, such as 'https'.
+ """
+
+ webhook_event_url: Optional[str] = None
+ """The URL where webhooks related to this connection will be sent.
+
+ Must include a scheme, such as 'https'.
+ """
+
+ webhook_timeout_secs: Optional[int] = None
+ """Specifies how many seconds to wait before timing out a webhook."""
class UacConnectionCreateResponse(BaseModel):
- data: Optional[UacConnection] = None
+ data: Optional[Data] = None
"""
A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite
of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your
diff --git a/src/telnyx/types/uac_connection_delete_response.py b/src/telnyx/types/uac_connection_delete_response.py
index f21476d0..48377528 100644
--- a/src/telnyx/types/uac_connection_delete_response.py
+++ b/src/telnyx/types/uac_connection_delete_response.py
@@ -1,15 +1,397 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import List, Optional
+from typing_extensions import Literal
+from .fqdn import Fqdn
from .._models import BaseModel
-from .uac_connection import UacConnection
+from .dtmf_type import DtmfType
+from .encrypted_media import EncryptedMedia
+from .anchorsite_override import AnchorsiteOverride
+from .connection_rtcp_settings import ConnectionRtcpSettings
+from .shared.connection_jitter_buffer import ConnectionJitterBuffer
+from .shared.connection_noise_suppression_details import ConnectionNoiseSuppressionDetails
-__all__ = ["UacConnectionDeleteResponse"]
+__all__ = [
+ "UacConnectionDeleteResponse",
+ "Data",
+ "DataExternalUacSettings",
+ "DataInbound",
+ "DataInternalUacSettings",
+ "DataOutbound",
+]
+
+
+class DataExternalUacSettings(BaseModel):
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
+ """
+
+ auth_username: Optional[str] = None
+ """The authentication username used in SIP digest authentication.
+
+ If not set, the Username value will be used.
+ """
+
+ expiration_sec: Optional[int] = None
+ """
+ The registration interval, in seconds, indicating how often the system refreshes
+ the SIP registration with the external SIP peer.
+ """
+
+ from_user: Optional[str] = None
+ """The user portion of the SIP From header used in outbound requests.
+
+ This controls the caller identity presented to the external SIP peer.
+ """
+
+ outbound_proxy: Optional[str] = None
+ """
+ An optional SIP proxy used to route outbound requests before reaching the
+ external SIP peer.
+ """
+
+ password: Optional[str] = None
+ """The SIP password used for digest authentication with the external SIP peer."""
+
+ proxy: Optional[str] = None
+ """
+ The SIP proxy address of the external SIP peer used for registrations and
+ outbound call routing.
+ """
+
+ transport: Optional[Literal["UDP", "TLS", "TCP"]] = None
+ """
+ The transport protocol used for SIP signaling when communicating with the
+ external SIP peer. One of UDP, TLS, or TCP.
+ """
+
+ username: Optional[str] = None
+ """
+ The SIP username used to authenticate with the external SIP peer for
+ registrations and outbound calls. Must start with a letter or number and contain
+ only letters, numbers, hyphens, and underscores.
+ """
+
+
+class DataInbound(BaseModel):
+ ani_number_format: Optional[Literal["+E.164", "E.164", "+E.164-national", "E.164-national"]] = None
+ """
+ This setting allows you to set the format with which the caller's number (ANI)
+ is sent for inbound phone calls.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of inbound calls to phone numbers
+ associated with this connection.
+ """
+
+ codecs: Optional[List[str]] = None
+ """
+ Defines the list of codecs that Telnyx will send for inbound calls to a specific
+ number on your portal account, in priority order. This only works when the
+ Connection the number is assigned to uses Media Handling mode: default. OPUS and
+ H.264 codecs are available only when using TCP or TLS transport for SIP.
+ """
+
+ default_routing_method: Optional[Literal["sequential", "round-robin"]] = None
+ """
+ Default routing method to be used when a number is associated with the
+ connection. Must be one of the routing method types or left blank, other values
+ are not allowed.
+ """
+
+ dnis_number_format: Optional[Literal["+e164", "e164", "national", "sip_username"]] = None
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ isup_headers_enabled: Optional[bool] = None
+ """When set, inbound phone calls will receive ISUP parameters via SIP headers.
+
+ (Only when available and only when using TCP or TLS transport.)
+ """
+
+ prack_enabled: Optional[bool] = None
+ """Enable PRACK messages as defined in RFC3262."""
+
+ shaken_stir_enabled: Optional[bool] = None
+ """
+ When enabled the SIP Connection will receive the Identity header with
+ Shaken/Stir data in the SIP INVITE message of inbound calls, even when using UDP
+ transport.
+ """
+
+ simultaneous_ringing: Optional[Literal["disabled", "enabled"]] = None
+ """When enabled, allows multiple devices to ring simultaneously on incoming calls."""
+
+ sip_compact_headers_enabled: Optional[bool] = None
+ """Defaults to true."""
+
+ sip_subdomain: Optional[str] = None
+ """The Telnyx-generated SIP subdomain for this UAC connection."""
+
+ sip_subdomain_receive_settings: Optional[Literal["only_my_connections", "from_anyone"]] = None
+ """Controls which SIP URI callers may reach this connection."""
+
+ timeout_1xx_secs: Optional[int] = None
+ """Time(sec) before aborting if connection is not made."""
+
+ timeout_2xx_secs: Optional[int] = None
+ """Time(sec) before aborting if call is unanswered (min: 1, max: 600)."""
+
+
+class DataInternalUacSettings(BaseModel):
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ destination_uri: Optional[str] = None
+ """
+ The SIP URI that Telnyx will call when handling an inbound request from the
+ external peer. Do not include a `sip:` prefix. The value must be in the format
+ `userinfo@sip.telnyx.com` or
+ `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
+ letters, digits, hyphens, and underscores.
+ """
+
+
+class DataOutbound(BaseModel):
+ ani_override: Optional[str] = None
+ """
+ Set a phone number as the ani_override value to override caller id number on
+ outbound calls.
+ """
+
+ ani_override_type: Optional[Literal["always", "normal", "emergency"]] = None
+ """Specifies when we apply your ani_override setting.
+
+ Only applies when ani_override is not blank.
+ """
+
+ call_parking_enabled: Optional[bool] = None
+ """
+ Forces all SIP calls originated on this connection to be "parked" instead of
+ "bridged" to the destination specified on the URI. Parked calls will return
+ ringback to the caller and will await for a Call Control command to define which
+ action will be taken next.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of outbound calls to phone numbers
+ associated with this connection.
+ """
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ instant_ringback_enabled: Optional[bool] = None
+ """
+ When set, ringback will not wait for indication before sending ringback tone to
+ calling party.
+ """
+
+ localization: Optional[str] = None
+ """
+ A 2-character country code specifying the country whose national dialing rules
+ should be used. For example, if set to `US` then any US number can be dialed
+ without preprending +1 to the number. When left blank, Telnyx will try US and GB
+ dialing rules, in that order, by default.
+ """
+
+ outbound_voice_profile_id: Optional[str] = None
+ """Identifies the associated outbound voice profile."""
+
+ t38_reinvite_source: Optional[
+ Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
+ ] = None
+ """This setting only affects connections with Fax-type Outbound Voice Profiles.
+
+ The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
+ default, Telnyx will send the re-invite. If set to `customer`, the caller is
+ expected to send the t.38 reinvite.
+ """
+
+
+class Data(BaseModel):
+ """
+ A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your PBX doesn’t support outbound SIP registration or you need Telnyx to maintain the registration.
+ """
+
+ id: Optional[str] = None
+ """Identifies the type of resource."""
+
+ active: Optional[bool] = None
+ """Defaults to true"""
+
+ anchorsite_override: Optional[AnchorsiteOverride] = None
+ """
+ `Latency` directs Telnyx to route media through the site with the lowest
+ round-trip time to the user's connection. Telnyx calculates this time using ICMP
+ ping messages. This can be disabled by specifying a site to handle all media.
+ """
+
+ android_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Android"""
+
+ authentication: Optional[Literal["uac-authentication"]] = None
+ """The authentication strategy used by this connection."""
+
+ call_cost_in_webhooks: Optional[bool] = None
+ """Specifies if call cost webhooks should be sent for this connection."""
+
+ connection_name: Optional[str] = None
+
+ created_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was created."""
+
+ default_on_hold_comfort_noise_enabled: Optional[bool] = None
+ """When enabled, Telnyx will generate comfort noise when you place the call on
+ hold.
+
+ If disabled, you will need to generate comfort noise or on hold music to avoid
+ RTP timeout.
+ """
+
+ dtmf_type: Optional[DtmfType] = None
+ """Sets the type of DTMF digits sent from Telnyx to this Connection.
+
+ Note that DTMF digits sent to Telnyx will be accepted in all formats.
+ """
+
+ encode_contact_header_enabled: Optional[bool] = None
+ """
+ Encode the SIP contact header sent by Telnyx to avoid issues for NAT or ALG
+ scenarios.
+ """
+
+ encrypted_media: Optional[EncryptedMedia] = None
+ """Enable use of SRTP for encryption.
+
+ Cannot be set if the transport_portocol is TLS.
+ """
+
+ external_uac_settings: Optional[DataExternalUacSettings] = None
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and
+ routing outbound calls.
+ """
+
+ fqdn: Optional[str] = None
+ """The Telnyx-managed FQDN generated for the UAC connection."""
+
+ fqdn_outbound_authentication: Optional[Literal["credential-authentication"]] = None
+ """The fixed outbound authentication mode used by UAC FQDN records."""
+
+ fqdns: Optional[List[Fqdn]] = None
+ """FQDN records managed automatically by the UAC connection lifecycle."""
+
+ inbound: Optional[DataInbound] = None
+
+ internal_uac_settings: Optional[DataInternalUacSettings] = None
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ ios_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Ios"""
+
+ jitter_buffer: Optional[ConnectionJitterBuffer] = None
+ """Configuration options for Jitter Buffer.
+
+ Enables Jitter Buffer for RTP streams of SIP Trunking calls. The feature is off
+ unless enabled. You may define min and max values in msec for customized
+ buffering behaviors. Larger values add latency but tolerate more jitter, while
+ smaller values reduce latency but are more sensitive to jitter and reordering.
+ """
+
+ noise_suppression: Optional[Literal["inbound", "outbound", "both", "disabled"]] = None
+ """Controls when noise suppression is applied to calls.
+
+ When set to 'inbound', noise suppression is applied to incoming audio. When set
+ to 'outbound', it's applied to outgoing audio. When set to 'both', it's applied
+ in both directions. When set to 'disabled', noise suppression is turned off.
+ """
+
+ noise_suppression_details: Optional[ConnectionNoiseSuppressionDetails] = None
+ """Configuration options for noise suppression.
+
+ These settings are stored regardless of the noise_suppression value, but only
+ take effect when noise_suppression is not 'disabled'. If you disable noise
+ suppression and later re-enable it, the previously configured settings will be
+ used.
+ """
+
+ onnet_t38_passthrough_enabled: Optional[bool] = None
+ """
+ Enable on-net T38 if you prefer the sender and receiver negotiating T38 directly
+ if both are on the Telnyx network. If this is disabled, Telnyx will be able to
+ use T38 on just one leg of the call depending on each leg's settings.
+ """
+
+ outbound: Optional[DataOutbound] = None
+
+ password: Optional[str] = None
+ """The password to be used as part of the credentials.
+
+ Must be 8 to 128 characters long.
+ """
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+ registration_status: Optional[str] = None
+ """The most recently known SIP registration status for this UAC connection."""
+
+ registration_status_updated_at: Optional[str] = None
+ """
+ ISO 8601 formatted date indicating when the registration status was last
+ updated.
+ """
+
+ rtcp_settings: Optional[ConnectionRtcpSettings] = None
+
+ sip_uri_calling_preference: Optional[Literal["disabled", "unrestricted", "internal"]] = None
+ """This feature enables inbound SIP URI calls to your Credential Auth Connection.
+
+ If enabled for all (unrestricted) then anyone who calls the SIP URI
+ @telnyx.com will be connected to your Connection. You can also
+ choose to allow only calls that are originated on any Connections under your
+ account (internal).
+ """
+
+ tags: Optional[List[str]] = None
+ """Tags associated with the connection."""
+
+ updated_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was updated."""
+
+ user_name: Optional[str] = None
+ """The user name to be used as part of the credentials.
+
+ Must be 4-32 characters long and alphanumeric values only (no spaces or special
+ characters). At least one of the first 5 characters must be a letter.
+ """
+
+ webhook_api_version: Optional[Literal["1", "2"]] = None
+ """Determines which webhook format will be used, Telnyx API v1 or v2."""
+
+ webhook_event_failover_url: Optional[str] = None
+ """
+ The failover URL where webhooks related to this connection will be sent if
+ sending to the primary URL fails. Must include a scheme, such as 'https'.
+ """
+
+ webhook_event_url: Optional[str] = None
+ """The URL where webhooks related to this connection will be sent.
+
+ Must include a scheme, such as 'https'.
+ """
+
+ webhook_timeout_secs: Optional[int] = None
+ """Specifies how many seconds to wait before timing out a webhook."""
class UacConnectionDeleteResponse(BaseModel):
- data: Optional[UacConnection] = None
+ data: Optional[Data] = None
"""
A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite
of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your
diff --git a/src/telnyx/types/uac_connection_list_response.py b/src/telnyx/types/uac_connection_list_response.py
new file mode 100644
index 00000000..cc6ef7d0
--- /dev/null
+++ b/src/telnyx/types/uac_connection_list_response.py
@@ -0,0 +1,383 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from .fqdn import Fqdn
+from .._models import BaseModel
+from .dtmf_type import DtmfType
+from .encrypted_media import EncryptedMedia
+from .anchorsite_override import AnchorsiteOverride
+from .connection_rtcp_settings import ConnectionRtcpSettings
+from .shared.connection_jitter_buffer import ConnectionJitterBuffer
+from .shared.connection_noise_suppression_details import ConnectionNoiseSuppressionDetails
+
+__all__ = ["UacConnectionListResponse", "ExternalUacSettings", "Inbound", "InternalUacSettings", "Outbound"]
+
+
+class ExternalUacSettings(BaseModel):
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
+ """
+
+ auth_username: Optional[str] = None
+ """The authentication username used in SIP digest authentication.
+
+ If not set, the Username value will be used.
+ """
+
+ expiration_sec: Optional[int] = None
+ """
+ The registration interval, in seconds, indicating how often the system refreshes
+ the SIP registration with the external SIP peer.
+ """
+
+ from_user: Optional[str] = None
+ """The user portion of the SIP From header used in outbound requests.
+
+ This controls the caller identity presented to the external SIP peer.
+ """
+
+ outbound_proxy: Optional[str] = None
+ """
+ An optional SIP proxy used to route outbound requests before reaching the
+ external SIP peer.
+ """
+
+ password: Optional[str] = None
+ """The SIP password used for digest authentication with the external SIP peer."""
+
+ proxy: Optional[str] = None
+ """
+ The SIP proxy address of the external SIP peer used for registrations and
+ outbound call routing.
+ """
+
+ transport: Optional[Literal["UDP", "TLS", "TCP"]] = None
+ """
+ The transport protocol used for SIP signaling when communicating with the
+ external SIP peer. One of UDP, TLS, or TCP.
+ """
+
+ username: Optional[str] = None
+ """
+ The SIP username used to authenticate with the external SIP peer for
+ registrations and outbound calls. Must start with a letter or number and contain
+ only letters, numbers, hyphens, and underscores.
+ """
+
+
+class Inbound(BaseModel):
+ ani_number_format: Optional[Literal["+E.164", "E.164", "+E.164-national", "E.164-national"]] = None
+ """
+ This setting allows you to set the format with which the caller's number (ANI)
+ is sent for inbound phone calls.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of inbound calls to phone numbers
+ associated with this connection.
+ """
+
+ codecs: Optional[List[str]] = None
+ """
+ Defines the list of codecs that Telnyx will send for inbound calls to a specific
+ number on your portal account, in priority order. This only works when the
+ Connection the number is assigned to uses Media Handling mode: default. OPUS and
+ H.264 codecs are available only when using TCP or TLS transport for SIP.
+ """
+
+ default_routing_method: Optional[Literal["sequential", "round-robin"]] = None
+ """
+ Default routing method to be used when a number is associated with the
+ connection. Must be one of the routing method types or left blank, other values
+ are not allowed.
+ """
+
+ dnis_number_format: Optional[Literal["+e164", "e164", "national", "sip_username"]] = None
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ isup_headers_enabled: Optional[bool] = None
+ """When set, inbound phone calls will receive ISUP parameters via SIP headers.
+
+ (Only when available and only when using TCP or TLS transport.)
+ """
+
+ prack_enabled: Optional[bool] = None
+ """Enable PRACK messages as defined in RFC3262."""
+
+ shaken_stir_enabled: Optional[bool] = None
+ """
+ When enabled the SIP Connection will receive the Identity header with
+ Shaken/Stir data in the SIP INVITE message of inbound calls, even when using UDP
+ transport.
+ """
+
+ simultaneous_ringing: Optional[Literal["disabled", "enabled"]] = None
+ """When enabled, allows multiple devices to ring simultaneously on incoming calls."""
+
+ sip_compact_headers_enabled: Optional[bool] = None
+ """Defaults to true."""
+
+ sip_subdomain: Optional[str] = None
+ """The Telnyx-generated SIP subdomain for this UAC connection."""
+
+ sip_subdomain_receive_settings: Optional[Literal["only_my_connections", "from_anyone"]] = None
+ """Controls which SIP URI callers may reach this connection."""
+
+ timeout_1xx_secs: Optional[int] = None
+ """Time(sec) before aborting if connection is not made."""
+
+ timeout_2xx_secs: Optional[int] = None
+ """Time(sec) before aborting if call is unanswered (min: 1, max: 600)."""
+
+
+class InternalUacSettings(BaseModel):
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ destination_uri: Optional[str] = None
+ """
+ The SIP URI that Telnyx will call when handling an inbound request from the
+ external peer. Do not include a `sip:` prefix. The value must be in the format
+ `userinfo@sip.telnyx.com` or
+ `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
+ letters, digits, hyphens, and underscores.
+ """
+
+
+class Outbound(BaseModel):
+ ani_override: Optional[str] = None
+ """
+ Set a phone number as the ani_override value to override caller id number on
+ outbound calls.
+ """
+
+ ani_override_type: Optional[Literal["always", "normal", "emergency"]] = None
+ """Specifies when we apply your ani_override setting.
+
+ Only applies when ani_override is not blank.
+ """
+
+ call_parking_enabled: Optional[bool] = None
+ """
+ Forces all SIP calls originated on this connection to be "parked" instead of
+ "bridged" to the destination specified on the URI. Parked calls will return
+ ringback to the caller and will await for a Call Control command to define which
+ action will be taken next.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of outbound calls to phone numbers
+ associated with this connection.
+ """
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ instant_ringback_enabled: Optional[bool] = None
+ """
+ When set, ringback will not wait for indication before sending ringback tone to
+ calling party.
+ """
+
+ localization: Optional[str] = None
+ """
+ A 2-character country code specifying the country whose national dialing rules
+ should be used. For example, if set to `US` then any US number can be dialed
+ without preprending +1 to the number. When left blank, Telnyx will try US and GB
+ dialing rules, in that order, by default.
+ """
+
+ outbound_voice_profile_id: Optional[str] = None
+ """Identifies the associated outbound voice profile."""
+
+ t38_reinvite_source: Optional[
+ Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
+ ] = None
+ """This setting only affects connections with Fax-type Outbound Voice Profiles.
+
+ The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
+ default, Telnyx will send the re-invite. If set to `customer`, the caller is
+ expected to send the t.38 reinvite.
+ """
+
+
+class UacConnectionListResponse(BaseModel):
+ """
+ A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your PBX doesn’t support outbound SIP registration or you need Telnyx to maintain the registration.
+ """
+
+ id: Optional[str] = None
+ """Identifies the type of resource."""
+
+ active: Optional[bool] = None
+ """Defaults to true"""
+
+ anchorsite_override: Optional[AnchorsiteOverride] = None
+ """
+ `Latency` directs Telnyx to route media through the site with the lowest
+ round-trip time to the user's connection. Telnyx calculates this time using ICMP
+ ping messages. This can be disabled by specifying a site to handle all media.
+ """
+
+ android_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Android"""
+
+ authentication: Optional[Literal["uac-authentication"]] = None
+ """The authentication strategy used by this connection."""
+
+ call_cost_in_webhooks: Optional[bool] = None
+ """Specifies if call cost webhooks should be sent for this connection."""
+
+ connection_name: Optional[str] = None
+
+ created_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was created."""
+
+ default_on_hold_comfort_noise_enabled: Optional[bool] = None
+ """When enabled, Telnyx will generate comfort noise when you place the call on
+ hold.
+
+ If disabled, you will need to generate comfort noise or on hold music to avoid
+ RTP timeout.
+ """
+
+ dtmf_type: Optional[DtmfType] = None
+ """Sets the type of DTMF digits sent from Telnyx to this Connection.
+
+ Note that DTMF digits sent to Telnyx will be accepted in all formats.
+ """
+
+ encode_contact_header_enabled: Optional[bool] = None
+ """
+ Encode the SIP contact header sent by Telnyx to avoid issues for NAT or ALG
+ scenarios.
+ """
+
+ encrypted_media: Optional[EncryptedMedia] = None
+ """Enable use of SRTP for encryption.
+
+ Cannot be set if the transport_portocol is TLS.
+ """
+
+ external_uac_settings: Optional[ExternalUacSettings] = None
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and
+ routing outbound calls.
+ """
+
+ fqdn: Optional[str] = None
+ """The Telnyx-managed FQDN generated for the UAC connection."""
+
+ fqdn_outbound_authentication: Optional[Literal["credential-authentication"]] = None
+ """The fixed outbound authentication mode used by UAC FQDN records."""
+
+ fqdns: Optional[List[Fqdn]] = None
+ """FQDN records managed automatically by the UAC connection lifecycle."""
+
+ inbound: Optional[Inbound] = None
+
+ internal_uac_settings: Optional[InternalUacSettings] = None
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ ios_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Ios"""
+
+ jitter_buffer: Optional[ConnectionJitterBuffer] = None
+ """Configuration options for Jitter Buffer.
+
+ Enables Jitter Buffer for RTP streams of SIP Trunking calls. The feature is off
+ unless enabled. You may define min and max values in msec for customized
+ buffering behaviors. Larger values add latency but tolerate more jitter, while
+ smaller values reduce latency but are more sensitive to jitter and reordering.
+ """
+
+ noise_suppression: Optional[Literal["inbound", "outbound", "both", "disabled"]] = None
+ """Controls when noise suppression is applied to calls.
+
+ When set to 'inbound', noise suppression is applied to incoming audio. When set
+ to 'outbound', it's applied to outgoing audio. When set to 'both', it's applied
+ in both directions. When set to 'disabled', noise suppression is turned off.
+ """
+
+ noise_suppression_details: Optional[ConnectionNoiseSuppressionDetails] = None
+ """Configuration options for noise suppression.
+
+ These settings are stored regardless of the noise_suppression value, but only
+ take effect when noise_suppression is not 'disabled'. If you disable noise
+ suppression and later re-enable it, the previously configured settings will be
+ used.
+ """
+
+ onnet_t38_passthrough_enabled: Optional[bool] = None
+ """
+ Enable on-net T38 if you prefer the sender and receiver negotiating T38 directly
+ if both are on the Telnyx network. If this is disabled, Telnyx will be able to
+ use T38 on just one leg of the call depending on each leg's settings.
+ """
+
+ outbound: Optional[Outbound] = None
+
+ password: Optional[str] = None
+ """The password to be used as part of the credentials.
+
+ Must be 8 to 128 characters long.
+ """
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+ registration_status: Optional[str] = None
+ """The most recently known SIP registration status for this UAC connection."""
+
+ registration_status_updated_at: Optional[str] = None
+ """
+ ISO 8601 formatted date indicating when the registration status was last
+ updated.
+ """
+
+ rtcp_settings: Optional[ConnectionRtcpSettings] = None
+
+ sip_uri_calling_preference: Optional[Literal["disabled", "unrestricted", "internal"]] = None
+ """This feature enables inbound SIP URI calls to your Credential Auth Connection.
+
+ If enabled for all (unrestricted) then anyone who calls the SIP URI
+ @telnyx.com will be connected to your Connection. You can also
+ choose to allow only calls that are originated on any Connections under your
+ account (internal).
+ """
+
+ tags: Optional[List[str]] = None
+ """Tags associated with the connection."""
+
+ updated_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was updated."""
+
+ user_name: Optional[str] = None
+ """The user name to be used as part of the credentials.
+
+ Must be 4-32 characters long and alphanumeric values only (no spaces or special
+ characters). At least one of the first 5 characters must be a letter.
+ """
+
+ webhook_api_version: Optional[Literal["1", "2"]] = None
+ """Determines which webhook format will be used, Telnyx API v1 or v2."""
+
+ webhook_event_failover_url: Optional[str] = None
+ """
+ The failover URL where webhooks related to this connection will be sent if
+ sending to the primary URL fails. Must include a scheme, such as 'https'.
+ """
+
+ webhook_event_url: Optional[str] = None
+ """The URL where webhooks related to this connection will be sent.
+
+ Must include a scheme, such as 'https'.
+ """
+
+ webhook_timeout_secs: Optional[int] = None
+ """Specifies how many seconds to wait before timing out a webhook."""
diff --git a/src/telnyx/types/uac_connection_retrieve_response.py b/src/telnyx/types/uac_connection_retrieve_response.py
index f48bcb8f..59e49d50 100644
--- a/src/telnyx/types/uac_connection_retrieve_response.py
+++ b/src/telnyx/types/uac_connection_retrieve_response.py
@@ -1,15 +1,397 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import List, Optional
+from typing_extensions import Literal
+from .fqdn import Fqdn
from .._models import BaseModel
-from .uac_connection import UacConnection
+from .dtmf_type import DtmfType
+from .encrypted_media import EncryptedMedia
+from .anchorsite_override import AnchorsiteOverride
+from .connection_rtcp_settings import ConnectionRtcpSettings
+from .shared.connection_jitter_buffer import ConnectionJitterBuffer
+from .shared.connection_noise_suppression_details import ConnectionNoiseSuppressionDetails
-__all__ = ["UacConnectionRetrieveResponse"]
+__all__ = [
+ "UacConnectionRetrieveResponse",
+ "Data",
+ "DataExternalUacSettings",
+ "DataInbound",
+ "DataInternalUacSettings",
+ "DataOutbound",
+]
+
+
+class DataExternalUacSettings(BaseModel):
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
+ """
+
+ auth_username: Optional[str] = None
+ """The authentication username used in SIP digest authentication.
+
+ If not set, the Username value will be used.
+ """
+
+ expiration_sec: Optional[int] = None
+ """
+ The registration interval, in seconds, indicating how often the system refreshes
+ the SIP registration with the external SIP peer.
+ """
+
+ from_user: Optional[str] = None
+ """The user portion of the SIP From header used in outbound requests.
+
+ This controls the caller identity presented to the external SIP peer.
+ """
+
+ outbound_proxy: Optional[str] = None
+ """
+ An optional SIP proxy used to route outbound requests before reaching the
+ external SIP peer.
+ """
+
+ password: Optional[str] = None
+ """The SIP password used for digest authentication with the external SIP peer."""
+
+ proxy: Optional[str] = None
+ """
+ The SIP proxy address of the external SIP peer used for registrations and
+ outbound call routing.
+ """
+
+ transport: Optional[Literal["UDP", "TLS", "TCP"]] = None
+ """
+ The transport protocol used for SIP signaling when communicating with the
+ external SIP peer. One of UDP, TLS, or TCP.
+ """
+
+ username: Optional[str] = None
+ """
+ The SIP username used to authenticate with the external SIP peer for
+ registrations and outbound calls. Must start with a letter or number and contain
+ only letters, numbers, hyphens, and underscores.
+ """
+
+
+class DataInbound(BaseModel):
+ ani_number_format: Optional[Literal["+E.164", "E.164", "+E.164-national", "E.164-national"]] = None
+ """
+ This setting allows you to set the format with which the caller's number (ANI)
+ is sent for inbound phone calls.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of inbound calls to phone numbers
+ associated with this connection.
+ """
+
+ codecs: Optional[List[str]] = None
+ """
+ Defines the list of codecs that Telnyx will send for inbound calls to a specific
+ number on your portal account, in priority order. This only works when the
+ Connection the number is assigned to uses Media Handling mode: default. OPUS and
+ H.264 codecs are available only when using TCP or TLS transport for SIP.
+ """
+
+ default_routing_method: Optional[Literal["sequential", "round-robin"]] = None
+ """
+ Default routing method to be used when a number is associated with the
+ connection. Must be one of the routing method types or left blank, other values
+ are not allowed.
+ """
+
+ dnis_number_format: Optional[Literal["+e164", "e164", "national", "sip_username"]] = None
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ isup_headers_enabled: Optional[bool] = None
+ """When set, inbound phone calls will receive ISUP parameters via SIP headers.
+
+ (Only when available and only when using TCP or TLS transport.)
+ """
+
+ prack_enabled: Optional[bool] = None
+ """Enable PRACK messages as defined in RFC3262."""
+
+ shaken_stir_enabled: Optional[bool] = None
+ """
+ When enabled the SIP Connection will receive the Identity header with
+ Shaken/Stir data in the SIP INVITE message of inbound calls, even when using UDP
+ transport.
+ """
+
+ simultaneous_ringing: Optional[Literal["disabled", "enabled"]] = None
+ """When enabled, allows multiple devices to ring simultaneously on incoming calls."""
+
+ sip_compact_headers_enabled: Optional[bool] = None
+ """Defaults to true."""
+
+ sip_subdomain: Optional[str] = None
+ """The Telnyx-generated SIP subdomain for this UAC connection."""
+
+ sip_subdomain_receive_settings: Optional[Literal["only_my_connections", "from_anyone"]] = None
+ """Controls which SIP URI callers may reach this connection."""
+
+ timeout_1xx_secs: Optional[int] = None
+ """Time(sec) before aborting if connection is not made."""
+
+ timeout_2xx_secs: Optional[int] = None
+ """Time(sec) before aborting if call is unanswered (min: 1, max: 600)."""
+
+
+class DataInternalUacSettings(BaseModel):
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ destination_uri: Optional[str] = None
+ """
+ The SIP URI that Telnyx will call when handling an inbound request from the
+ external peer. Do not include a `sip:` prefix. The value must be in the format
+ `userinfo@sip.telnyx.com` or
+ `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
+ letters, digits, hyphens, and underscores.
+ """
+
+
+class DataOutbound(BaseModel):
+ ani_override: Optional[str] = None
+ """
+ Set a phone number as the ani_override value to override caller id number on
+ outbound calls.
+ """
+
+ ani_override_type: Optional[Literal["always", "normal", "emergency"]] = None
+ """Specifies when we apply your ani_override setting.
+
+ Only applies when ani_override is not blank.
+ """
+
+ call_parking_enabled: Optional[bool] = None
+ """
+ Forces all SIP calls originated on this connection to be "parked" instead of
+ "bridged" to the destination specified on the URI. Parked calls will return
+ ringback to the caller and will await for a Call Control command to define which
+ action will be taken next.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of outbound calls to phone numbers
+ associated with this connection.
+ """
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ instant_ringback_enabled: Optional[bool] = None
+ """
+ When set, ringback will not wait for indication before sending ringback tone to
+ calling party.
+ """
+
+ localization: Optional[str] = None
+ """
+ A 2-character country code specifying the country whose national dialing rules
+ should be used. For example, if set to `US` then any US number can be dialed
+ without preprending +1 to the number. When left blank, Telnyx will try US and GB
+ dialing rules, in that order, by default.
+ """
+
+ outbound_voice_profile_id: Optional[str] = None
+ """Identifies the associated outbound voice profile."""
+
+ t38_reinvite_source: Optional[
+ Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
+ ] = None
+ """This setting only affects connections with Fax-type Outbound Voice Profiles.
+
+ The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
+ default, Telnyx will send the re-invite. If set to `customer`, the caller is
+ expected to send the t.38 reinvite.
+ """
+
+
+class Data(BaseModel):
+ """
+ A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your PBX doesn’t support outbound SIP registration or you need Telnyx to maintain the registration.
+ """
+
+ id: Optional[str] = None
+ """Identifies the type of resource."""
+
+ active: Optional[bool] = None
+ """Defaults to true"""
+
+ anchorsite_override: Optional[AnchorsiteOverride] = None
+ """
+ `Latency` directs Telnyx to route media through the site with the lowest
+ round-trip time to the user's connection. Telnyx calculates this time using ICMP
+ ping messages. This can be disabled by specifying a site to handle all media.
+ """
+
+ android_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Android"""
+
+ authentication: Optional[Literal["uac-authentication"]] = None
+ """The authentication strategy used by this connection."""
+
+ call_cost_in_webhooks: Optional[bool] = None
+ """Specifies if call cost webhooks should be sent for this connection."""
+
+ connection_name: Optional[str] = None
+
+ created_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was created."""
+
+ default_on_hold_comfort_noise_enabled: Optional[bool] = None
+ """When enabled, Telnyx will generate comfort noise when you place the call on
+ hold.
+
+ If disabled, you will need to generate comfort noise or on hold music to avoid
+ RTP timeout.
+ """
+
+ dtmf_type: Optional[DtmfType] = None
+ """Sets the type of DTMF digits sent from Telnyx to this Connection.
+
+ Note that DTMF digits sent to Telnyx will be accepted in all formats.
+ """
+
+ encode_contact_header_enabled: Optional[bool] = None
+ """
+ Encode the SIP contact header sent by Telnyx to avoid issues for NAT or ALG
+ scenarios.
+ """
+
+ encrypted_media: Optional[EncryptedMedia] = None
+ """Enable use of SRTP for encryption.
+
+ Cannot be set if the transport_portocol is TLS.
+ """
+
+ external_uac_settings: Optional[DataExternalUacSettings] = None
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and
+ routing outbound calls.
+ """
+
+ fqdn: Optional[str] = None
+ """The Telnyx-managed FQDN generated for the UAC connection."""
+
+ fqdn_outbound_authentication: Optional[Literal["credential-authentication"]] = None
+ """The fixed outbound authentication mode used by UAC FQDN records."""
+
+ fqdns: Optional[List[Fqdn]] = None
+ """FQDN records managed automatically by the UAC connection lifecycle."""
+
+ inbound: Optional[DataInbound] = None
+
+ internal_uac_settings: Optional[DataInternalUacSettings] = None
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ ios_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Ios"""
+
+ jitter_buffer: Optional[ConnectionJitterBuffer] = None
+ """Configuration options for Jitter Buffer.
+
+ Enables Jitter Buffer for RTP streams of SIP Trunking calls. The feature is off
+ unless enabled. You may define min and max values in msec for customized
+ buffering behaviors. Larger values add latency but tolerate more jitter, while
+ smaller values reduce latency but are more sensitive to jitter and reordering.
+ """
+
+ noise_suppression: Optional[Literal["inbound", "outbound", "both", "disabled"]] = None
+ """Controls when noise suppression is applied to calls.
+
+ When set to 'inbound', noise suppression is applied to incoming audio. When set
+ to 'outbound', it's applied to outgoing audio. When set to 'both', it's applied
+ in both directions. When set to 'disabled', noise suppression is turned off.
+ """
+
+ noise_suppression_details: Optional[ConnectionNoiseSuppressionDetails] = None
+ """Configuration options for noise suppression.
+
+ These settings are stored regardless of the noise_suppression value, but only
+ take effect when noise_suppression is not 'disabled'. If you disable noise
+ suppression and later re-enable it, the previously configured settings will be
+ used.
+ """
+
+ onnet_t38_passthrough_enabled: Optional[bool] = None
+ """
+ Enable on-net T38 if you prefer the sender and receiver negotiating T38 directly
+ if both are on the Telnyx network. If this is disabled, Telnyx will be able to
+ use T38 on just one leg of the call depending on each leg's settings.
+ """
+
+ outbound: Optional[DataOutbound] = None
+
+ password: Optional[str] = None
+ """The password to be used as part of the credentials.
+
+ Must be 8 to 128 characters long.
+ """
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+ registration_status: Optional[str] = None
+ """The most recently known SIP registration status for this UAC connection."""
+
+ registration_status_updated_at: Optional[str] = None
+ """
+ ISO 8601 formatted date indicating when the registration status was last
+ updated.
+ """
+
+ rtcp_settings: Optional[ConnectionRtcpSettings] = None
+
+ sip_uri_calling_preference: Optional[Literal["disabled", "unrestricted", "internal"]] = None
+ """This feature enables inbound SIP URI calls to your Credential Auth Connection.
+
+ If enabled for all (unrestricted) then anyone who calls the SIP URI
+ @telnyx.com will be connected to your Connection. You can also
+ choose to allow only calls that are originated on any Connections under your
+ account (internal).
+ """
+
+ tags: Optional[List[str]] = None
+ """Tags associated with the connection."""
+
+ updated_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was updated."""
+
+ user_name: Optional[str] = None
+ """The user name to be used as part of the credentials.
+
+ Must be 4-32 characters long and alphanumeric values only (no spaces or special
+ characters). At least one of the first 5 characters must be a letter.
+ """
+
+ webhook_api_version: Optional[Literal["1", "2"]] = None
+ """Determines which webhook format will be used, Telnyx API v1 or v2."""
+
+ webhook_event_failover_url: Optional[str] = None
+ """
+ The failover URL where webhooks related to this connection will be sent if
+ sending to the primary URL fails. Must include a scheme, such as 'https'.
+ """
+
+ webhook_event_url: Optional[str] = None
+ """The URL where webhooks related to this connection will be sent.
+
+ Must include a scheme, such as 'https'.
+ """
+
+ webhook_timeout_secs: Optional[int] = None
+ """Specifies how many seconds to wait before timing out a webhook."""
class UacConnectionRetrieveResponse(BaseModel):
- data: Optional[UacConnection] = None
+ data: Optional[Data] = None
"""
A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite
of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your
diff --git a/src/telnyx/types/uac_connection_update_params.py b/src/telnyx/types/uac_connection_update_params.py
index affb7b5b..222838d2 100644
--- a/src/telnyx/types/uac_connection_update_params.py
+++ b/src/telnyx/types/uac_connection_update_params.py
@@ -8,15 +8,12 @@
from .._types import SequenceNotStr
from .dtmf_type import DtmfType
from .encrypted_media import EncryptedMedia
-from .uac_outbound_param import UacOutboundParam
from .anchorsite_override import AnchorsiteOverride
-from .uac_external_settings_param import UacExternalSettingsParam
-from .uac_internal_settings_param import UacInternalSettingsParam
from .connection_rtcp_settings_param import ConnectionRtcpSettingsParam
from .shared_params.connection_jitter_buffer import ConnectionJitterBuffer
from .shared_params.connection_noise_suppression_details import ConnectionNoiseSuppressionDetails
-__all__ = ["UacConnectionUpdateParams", "Inbound"]
+__all__ = ["UacConnectionUpdateParams", "ExternalUacSettings", "Inbound", "InternalUacSettings", "Outbound"]
class UacConnectionUpdateParams(TypedDict, total=False):
@@ -65,7 +62,7 @@ class UacConnectionUpdateParams(TypedDict, total=False):
Cannot be set if the transport_portocol is TLS.
"""
- external_uac_settings: UacExternalSettingsParam
+ external_uac_settings: ExternalUacSettings
"""
External SIP peer settings used by Telnyx when registering to your PBX and
routing outbound calls.
@@ -79,7 +76,7 @@ class UacConnectionUpdateParams(TypedDict, total=False):
Telnyx and are not accepted as request parameters.
"""
- internal_uac_settings: UacInternalSettingsParam
+ internal_uac_settings: InternalUacSettings
"""Internal Telnyx-side settings for a UAC connection."""
ios_push_credential_id: Optional[str]
@@ -118,7 +115,7 @@ class UacConnectionUpdateParams(TypedDict, total=False):
use T38 on just one leg of the call depending on each leg's settings.
"""
- outbound: UacOutboundParam
+ outbound: Outbound
password: str
"""The password to be used as part of the credentials.
@@ -166,6 +163,58 @@ class UacConnectionUpdateParams(TypedDict, total=False):
"""Specifies how many seconds to wait before timing out a webhook."""
+class ExternalUacSettings(TypedDict, total=False):
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
+ """
+
+ auth_username: Optional[str]
+ """The authentication username used in SIP digest authentication.
+
+ If not set, the Username value will be used.
+ """
+
+ expiration_sec: Optional[int]
+ """
+ The registration interval, in seconds, indicating how often the system refreshes
+ the SIP registration with the external SIP peer.
+ """
+
+ from_user: Optional[str]
+ """The user portion of the SIP From header used in outbound requests.
+
+ This controls the caller identity presented to the external SIP peer.
+ """
+
+ outbound_proxy: Optional[str]
+ """
+ An optional SIP proxy used to route outbound requests before reaching the
+ external SIP peer.
+ """
+
+ password: str
+ """The SIP password used for digest authentication with the external SIP peer."""
+
+ proxy: str
+ """
+ The SIP proxy address of the external SIP peer used for registrations and
+ outbound call routing.
+ """
+
+ transport: Optional[Literal["UDP", "TLS", "TCP"]]
+ """
+ The transport protocol used for SIP signaling when communicating with the
+ external SIP peer. One of UDP, TLS, or TCP.
+ """
+
+ username: str
+ """
+ The SIP username used to authenticate with the external SIP peer for
+ registrations and outbound calls. Must start with a letter or number and contain
+ only letters, numbers, hyphens, and underscores.
+ """
+
+
class Inbound(TypedDict, total=False):
"""Inbound settings that can be supplied when creating or updating a UAC connection.
@@ -231,3 +280,72 @@ class Inbound(TypedDict, total=False):
timeout_2xx_secs: int
"""Time(sec) before aborting if call is unanswered (min: 1, max: 600)."""
+
+
+class InternalUacSettings(TypedDict, total=False):
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ destination_uri: str
+ """
+ The SIP URI that Telnyx will call when handling an inbound request from the
+ external peer. Do not include a `sip:` prefix. The value must be in the format
+ `userinfo@sip.telnyx.com` or
+ `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
+ letters, digits, hyphens, and underscores.
+ """
+
+
+class Outbound(TypedDict, total=False):
+ ani_override: str
+ """
+ Set a phone number as the ani_override value to override caller id number on
+ outbound calls.
+ """
+
+ ani_override_type: Literal["always", "normal", "emergency"]
+ """Specifies when we apply your ani_override setting.
+
+ Only applies when ani_override is not blank.
+ """
+
+ call_parking_enabled: Optional[bool]
+ """
+ Forces all SIP calls originated on this connection to be "parked" instead of
+ "bridged" to the destination specified on the URI. Parked calls will return
+ ringback to the caller and will await for a Call Control command to define which
+ action will be taken next.
+ """
+
+ channel_limit: int
+ """
+ When set, this will limit the total number of outbound calls to phone numbers
+ associated with this connection.
+ """
+
+ generate_ringback_tone: bool
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ instant_ringback_enabled: bool
+ """
+ When set, ringback will not wait for indication before sending ringback tone to
+ calling party.
+ """
+
+ localization: str
+ """
+ A 2-character country code specifying the country whose national dialing rules
+ should be used. For example, if set to `US` then any US number can be dialed
+ without preprending +1 to the number. When left blank, Telnyx will try US and GB
+ dialing rules, in that order, by default.
+ """
+
+ outbound_voice_profile_id: str
+ """Identifies the associated outbound voice profile."""
+
+ t38_reinvite_source: Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
+ """This setting only affects connections with Fax-type Outbound Voice Profiles.
+
+ The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
+ default, Telnyx will send the re-invite. If set to `customer`, the caller is
+ expected to send the t.38 reinvite.
+ """
diff --git a/src/telnyx/types/uac_connection_update_response.py b/src/telnyx/types/uac_connection_update_response.py
index 24090ac8..58e44a1b 100644
--- a/src/telnyx/types/uac_connection_update_response.py
+++ b/src/telnyx/types/uac_connection_update_response.py
@@ -1,15 +1,397 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-from typing import Optional
+from typing import List, Optional
+from typing_extensions import Literal
+from .fqdn import Fqdn
from .._models import BaseModel
-from .uac_connection import UacConnection
+from .dtmf_type import DtmfType
+from .encrypted_media import EncryptedMedia
+from .anchorsite_override import AnchorsiteOverride
+from .connection_rtcp_settings import ConnectionRtcpSettings
+from .shared.connection_jitter_buffer import ConnectionJitterBuffer
+from .shared.connection_noise_suppression_details import ConnectionNoiseSuppressionDetails
-__all__ = ["UacConnectionUpdateResponse"]
+__all__ = [
+ "UacConnectionUpdateResponse",
+ "Data",
+ "DataExternalUacSettings",
+ "DataInbound",
+ "DataInternalUacSettings",
+ "DataOutbound",
+]
+
+
+class DataExternalUacSettings(BaseModel):
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
+ """
+
+ auth_username: Optional[str] = None
+ """The authentication username used in SIP digest authentication.
+
+ If not set, the Username value will be used.
+ """
+
+ expiration_sec: Optional[int] = None
+ """
+ The registration interval, in seconds, indicating how often the system refreshes
+ the SIP registration with the external SIP peer.
+ """
+
+ from_user: Optional[str] = None
+ """The user portion of the SIP From header used in outbound requests.
+
+ This controls the caller identity presented to the external SIP peer.
+ """
+
+ outbound_proxy: Optional[str] = None
+ """
+ An optional SIP proxy used to route outbound requests before reaching the
+ external SIP peer.
+ """
+
+ password: Optional[str] = None
+ """The SIP password used for digest authentication with the external SIP peer."""
+
+ proxy: Optional[str] = None
+ """
+ The SIP proxy address of the external SIP peer used for registrations and
+ outbound call routing.
+ """
+
+ transport: Optional[Literal["UDP", "TLS", "TCP"]] = None
+ """
+ The transport protocol used for SIP signaling when communicating with the
+ external SIP peer. One of UDP, TLS, or TCP.
+ """
+
+ username: Optional[str] = None
+ """
+ The SIP username used to authenticate with the external SIP peer for
+ registrations and outbound calls. Must start with a letter or number and contain
+ only letters, numbers, hyphens, and underscores.
+ """
+
+
+class DataInbound(BaseModel):
+ ani_number_format: Optional[Literal["+E.164", "E.164", "+E.164-national", "E.164-national"]] = None
+ """
+ This setting allows you to set the format with which the caller's number (ANI)
+ is sent for inbound phone calls.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of inbound calls to phone numbers
+ associated with this connection.
+ """
+
+ codecs: Optional[List[str]] = None
+ """
+ Defines the list of codecs that Telnyx will send for inbound calls to a specific
+ number on your portal account, in priority order. This only works when the
+ Connection the number is assigned to uses Media Handling mode: default. OPUS and
+ H.264 codecs are available only when using TCP or TLS transport for SIP.
+ """
+
+ default_routing_method: Optional[Literal["sequential", "round-robin"]] = None
+ """
+ Default routing method to be used when a number is associated with the
+ connection. Must be one of the routing method types or left blank, other values
+ are not allowed.
+ """
+
+ dnis_number_format: Optional[Literal["+e164", "e164", "national", "sip_username"]] = None
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ isup_headers_enabled: Optional[bool] = None
+ """When set, inbound phone calls will receive ISUP parameters via SIP headers.
+
+ (Only when available and only when using TCP or TLS transport.)
+ """
+
+ prack_enabled: Optional[bool] = None
+ """Enable PRACK messages as defined in RFC3262."""
+
+ shaken_stir_enabled: Optional[bool] = None
+ """
+ When enabled the SIP Connection will receive the Identity header with
+ Shaken/Stir data in the SIP INVITE message of inbound calls, even when using UDP
+ transport.
+ """
+
+ simultaneous_ringing: Optional[Literal["disabled", "enabled"]] = None
+ """When enabled, allows multiple devices to ring simultaneously on incoming calls."""
+
+ sip_compact_headers_enabled: Optional[bool] = None
+ """Defaults to true."""
+
+ sip_subdomain: Optional[str] = None
+ """The Telnyx-generated SIP subdomain for this UAC connection."""
+
+ sip_subdomain_receive_settings: Optional[Literal["only_my_connections", "from_anyone"]] = None
+ """Controls which SIP URI callers may reach this connection."""
+
+ timeout_1xx_secs: Optional[int] = None
+ """Time(sec) before aborting if connection is not made."""
+
+ timeout_2xx_secs: Optional[int] = None
+ """Time(sec) before aborting if call is unanswered (min: 1, max: 600)."""
+
+
+class DataInternalUacSettings(BaseModel):
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ destination_uri: Optional[str] = None
+ """
+ The SIP URI that Telnyx will call when handling an inbound request from the
+ external peer. Do not include a `sip:` prefix. The value must be in the format
+ `userinfo@sip.telnyx.com` or
+ `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
+ letters, digits, hyphens, and underscores.
+ """
+
+
+class DataOutbound(BaseModel):
+ ani_override: Optional[str] = None
+ """
+ Set a phone number as the ani_override value to override caller id number on
+ outbound calls.
+ """
+
+ ani_override_type: Optional[Literal["always", "normal", "emergency"]] = None
+ """Specifies when we apply your ani_override setting.
+
+ Only applies when ani_override is not blank.
+ """
+
+ call_parking_enabled: Optional[bool] = None
+ """
+ Forces all SIP calls originated on this connection to be "parked" instead of
+ "bridged" to the destination specified on the URI. Parked calls will return
+ ringback to the caller and will await for a Call Control command to define which
+ action will be taken next.
+ """
+
+ channel_limit: Optional[int] = None
+ """
+ When set, this will limit the total number of outbound calls to phone numbers
+ associated with this connection.
+ """
+
+ generate_ringback_tone: Optional[bool] = None
+ """Generate ringback tone through 183 session progress message with early media."""
+
+ instant_ringback_enabled: Optional[bool] = None
+ """
+ When set, ringback will not wait for indication before sending ringback tone to
+ calling party.
+ """
+
+ localization: Optional[str] = None
+ """
+ A 2-character country code specifying the country whose national dialing rules
+ should be used. For example, if set to `US` then any US number can be dialed
+ without preprending +1 to the number. When left blank, Telnyx will try US and GB
+ dialing rules, in that order, by default.
+ """
+
+ outbound_voice_profile_id: Optional[str] = None
+ """Identifies the associated outbound voice profile."""
+
+ t38_reinvite_source: Optional[
+ Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
+ ] = None
+ """This setting only affects connections with Fax-type Outbound Voice Profiles.
+
+ The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
+ default, Telnyx will send the re-invite. If set to `customer`, the caller is
+ expected to send the t.38 reinvite.
+ """
+
+
+class Data(BaseModel):
+ """
+ A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your PBX doesn’t support outbound SIP registration or you need Telnyx to maintain the registration.
+ """
+
+ id: Optional[str] = None
+ """Identifies the type of resource."""
+
+ active: Optional[bool] = None
+ """Defaults to true"""
+
+ anchorsite_override: Optional[AnchorsiteOverride] = None
+ """
+ `Latency` directs Telnyx to route media through the site with the lowest
+ round-trip time to the user's connection. Telnyx calculates this time using ICMP
+ ping messages. This can be disabled by specifying a site to handle all media.
+ """
+
+ android_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Android"""
+
+ authentication: Optional[Literal["uac-authentication"]] = None
+ """The authentication strategy used by this connection."""
+
+ call_cost_in_webhooks: Optional[bool] = None
+ """Specifies if call cost webhooks should be sent for this connection."""
+
+ connection_name: Optional[str] = None
+
+ created_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was created."""
+
+ default_on_hold_comfort_noise_enabled: Optional[bool] = None
+ """When enabled, Telnyx will generate comfort noise when you place the call on
+ hold.
+
+ If disabled, you will need to generate comfort noise or on hold music to avoid
+ RTP timeout.
+ """
+
+ dtmf_type: Optional[DtmfType] = None
+ """Sets the type of DTMF digits sent from Telnyx to this Connection.
+
+ Note that DTMF digits sent to Telnyx will be accepted in all formats.
+ """
+
+ encode_contact_header_enabled: Optional[bool] = None
+ """
+ Encode the SIP contact header sent by Telnyx to avoid issues for NAT or ALG
+ scenarios.
+ """
+
+ encrypted_media: Optional[EncryptedMedia] = None
+ """Enable use of SRTP for encryption.
+
+ Cannot be set if the transport_portocol is TLS.
+ """
+
+ external_uac_settings: Optional[DataExternalUacSettings] = None
+ """
+ External SIP peer settings used by Telnyx when registering to your PBX and
+ routing outbound calls.
+ """
+
+ fqdn: Optional[str] = None
+ """The Telnyx-managed FQDN generated for the UAC connection."""
+
+ fqdn_outbound_authentication: Optional[Literal["credential-authentication"]] = None
+ """The fixed outbound authentication mode used by UAC FQDN records."""
+
+ fqdns: Optional[List[Fqdn]] = None
+ """FQDN records managed automatically by the UAC connection lifecycle."""
+
+ inbound: Optional[DataInbound] = None
+
+ internal_uac_settings: Optional[DataInternalUacSettings] = None
+ """Internal Telnyx-side settings for a UAC connection."""
+
+ ios_push_credential_id: Optional[str] = None
+ """The uuid of the push credential for Ios"""
+
+ jitter_buffer: Optional[ConnectionJitterBuffer] = None
+ """Configuration options for Jitter Buffer.
+
+ Enables Jitter Buffer for RTP streams of SIP Trunking calls. The feature is off
+ unless enabled. You may define min and max values in msec for customized
+ buffering behaviors. Larger values add latency but tolerate more jitter, while
+ smaller values reduce latency but are more sensitive to jitter and reordering.
+ """
+
+ noise_suppression: Optional[Literal["inbound", "outbound", "both", "disabled"]] = None
+ """Controls when noise suppression is applied to calls.
+
+ When set to 'inbound', noise suppression is applied to incoming audio. When set
+ to 'outbound', it's applied to outgoing audio. When set to 'both', it's applied
+ in both directions. When set to 'disabled', noise suppression is turned off.
+ """
+
+ noise_suppression_details: Optional[ConnectionNoiseSuppressionDetails] = None
+ """Configuration options for noise suppression.
+
+ These settings are stored regardless of the noise_suppression value, but only
+ take effect when noise_suppression is not 'disabled'. If you disable noise
+ suppression and later re-enable it, the previously configured settings will be
+ used.
+ """
+
+ onnet_t38_passthrough_enabled: Optional[bool] = None
+ """
+ Enable on-net T38 if you prefer the sender and receiver negotiating T38 directly
+ if both are on the Telnyx network. If this is disabled, Telnyx will be able to
+ use T38 on just one leg of the call depending on each leg's settings.
+ """
+
+ outbound: Optional[DataOutbound] = None
+
+ password: Optional[str] = None
+ """The password to be used as part of the credentials.
+
+ Must be 8 to 128 characters long.
+ """
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+ registration_status: Optional[str] = None
+ """The most recently known SIP registration status for this UAC connection."""
+
+ registration_status_updated_at: Optional[str] = None
+ """
+ ISO 8601 formatted date indicating when the registration status was last
+ updated.
+ """
+
+ rtcp_settings: Optional[ConnectionRtcpSettings] = None
+
+ sip_uri_calling_preference: Optional[Literal["disabled", "unrestricted", "internal"]] = None
+ """This feature enables inbound SIP URI calls to your Credential Auth Connection.
+
+ If enabled for all (unrestricted) then anyone who calls the SIP URI
+ @telnyx.com will be connected to your Connection. You can also
+ choose to allow only calls that are originated on any Connections under your
+ account (internal).
+ """
+
+ tags: Optional[List[str]] = None
+ """Tags associated with the connection."""
+
+ updated_at: Optional[str] = None
+ """ISO-8601 formatted date indicating when the resource was updated."""
+
+ user_name: Optional[str] = None
+ """The user name to be used as part of the credentials.
+
+ Must be 4-32 characters long and alphanumeric values only (no spaces or special
+ characters). At least one of the first 5 characters must be a letter.
+ """
+
+ webhook_api_version: Optional[Literal["1", "2"]] = None
+ """Determines which webhook format will be used, Telnyx API v1 or v2."""
+
+ webhook_event_failover_url: Optional[str] = None
+ """
+ The failover URL where webhooks related to this connection will be sent if
+ sending to the primary URL fails. Must include a scheme, such as 'https'.
+ """
+
+ webhook_event_url: Optional[str] = None
+ """The URL where webhooks related to this connection will be sent.
+
+ Must include a scheme, such as 'https'.
+ """
+
+ webhook_timeout_secs: Optional[int] = None
+ """Specifies how many seconds to wait before timing out a webhook."""
class UacConnectionUpdateResponse(BaseModel):
- data: Optional[UacConnection] = None
+ data: Optional[Data] = None
"""
A UAC (User Agent Client) Connection registers Telnyx to your PBX — the opposite
of a standard SIP trunk, where the PBX registers to Telnyx. Use UAC when your
diff --git a/src/telnyx/types/uac_external_settings.py b/src/telnyx/types/uac_external_settings.py
deleted file mode 100644
index e0c5feba..00000000
--- a/src/telnyx/types/uac_external_settings.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["UacExternalSettings"]
-
-
-class UacExternalSettings(BaseModel):
- """
- External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
- """
-
- auth_username: Optional[str] = None
- """The authentication username used in SIP digest authentication.
-
- If not set, the Username value will be used.
- """
-
- expiration_sec: Optional[int] = None
- """
- The registration interval, in seconds, indicating how often the system refreshes
- the SIP registration with the external SIP peer.
- """
-
- from_user: Optional[str] = None
- """The user portion of the SIP From header used in outbound requests.
-
- This controls the caller identity presented to the external SIP peer.
- """
-
- outbound_proxy: Optional[str] = None
- """
- An optional SIP proxy used to route outbound requests before reaching the
- external SIP peer.
- """
-
- password: Optional[str] = None
- """The SIP password used for digest authentication with the external SIP peer."""
-
- proxy: Optional[str] = None
- """
- The SIP proxy address of the external SIP peer used for registrations and
- outbound call routing.
- """
-
- transport: Optional[Literal["UDP", "TLS", "TCP"]] = None
- """
- The transport protocol used for SIP signaling when communicating with the
- external SIP peer. One of UDP, TLS, or TCP.
- """
-
- username: Optional[str] = None
- """
- The SIP username used to authenticate with the external SIP peer for
- registrations and outbound calls. Must start with a letter or number and contain
- only letters, numbers, hyphens, and underscores.
- """
diff --git a/src/telnyx/types/uac_external_settings_param.py b/src/telnyx/types/uac_external_settings_param.py
deleted file mode 100644
index e544ffdf..00000000
--- a/src/telnyx/types/uac_external_settings_param.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Literal, TypedDict
-
-__all__ = ["UacExternalSettingsParam"]
-
-
-class UacExternalSettingsParam(TypedDict, total=False):
- """
- External SIP peer settings used by Telnyx when registering to your PBX and routing outbound calls.
- """
-
- auth_username: Optional[str]
- """The authentication username used in SIP digest authentication.
-
- If not set, the Username value will be used.
- """
-
- expiration_sec: Optional[int]
- """
- The registration interval, in seconds, indicating how often the system refreshes
- the SIP registration with the external SIP peer.
- """
-
- from_user: Optional[str]
- """The user portion of the SIP From header used in outbound requests.
-
- This controls the caller identity presented to the external SIP peer.
- """
-
- outbound_proxy: Optional[str]
- """
- An optional SIP proxy used to route outbound requests before reaching the
- external SIP peer.
- """
-
- password: str
- """The SIP password used for digest authentication with the external SIP peer."""
-
- proxy: str
- """
- The SIP proxy address of the external SIP peer used for registrations and
- outbound call routing.
- """
-
- transport: Optional[Literal["UDP", "TLS", "TCP"]]
- """
- The transport protocol used for SIP signaling when communicating with the
- external SIP peer. One of UDP, TLS, or TCP.
- """
-
- username: str
- """
- The SIP username used to authenticate with the external SIP peer for
- registrations and outbound calls. Must start with a letter or number and contain
- only letters, numbers, hyphens, and underscores.
- """
diff --git a/src/telnyx/types/uac_inbound.py b/src/telnyx/types/uac_inbound.py
deleted file mode 100644
index 8266455b..00000000
--- a/src/telnyx/types/uac_inbound.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import List, Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["UacInbound"]
-
-
-class UacInbound(BaseModel):
- ani_number_format: Optional[Literal["+E.164", "E.164", "+E.164-national", "E.164-national"]] = None
- """
- This setting allows you to set the format with which the caller's number (ANI)
- is sent for inbound phone calls.
- """
-
- channel_limit: Optional[int] = None
- """
- When set, this will limit the total number of inbound calls to phone numbers
- associated with this connection.
- """
-
- codecs: Optional[List[str]] = None
- """
- Defines the list of codecs that Telnyx will send for inbound calls to a specific
- number on your portal account, in priority order. This only works when the
- Connection the number is assigned to uses Media Handling mode: default. OPUS and
- H.264 codecs are available only when using TCP or TLS transport for SIP.
- """
-
- default_routing_method: Optional[Literal["sequential", "round-robin"]] = None
- """
- Default routing method to be used when a number is associated with the
- connection. Must be one of the routing method types or left blank, other values
- are not allowed.
- """
-
- dnis_number_format: Optional[Literal["+e164", "e164", "national", "sip_username"]] = None
-
- generate_ringback_tone: Optional[bool] = None
- """Generate ringback tone through 183 session progress message with early media."""
-
- isup_headers_enabled: Optional[bool] = None
- """When set, inbound phone calls will receive ISUP parameters via SIP headers.
-
- (Only when available and only when using TCP or TLS transport.)
- """
-
- prack_enabled: Optional[bool] = None
- """Enable PRACK messages as defined in RFC3262."""
-
- shaken_stir_enabled: Optional[bool] = None
- """
- When enabled the SIP Connection will receive the Identity header with
- Shaken/Stir data in the SIP INVITE message of inbound calls, even when using UDP
- transport.
- """
-
- simultaneous_ringing: Optional[Literal["disabled", "enabled"]] = None
- """When enabled, allows multiple devices to ring simultaneously on incoming calls."""
-
- sip_compact_headers_enabled: Optional[bool] = None
- """Defaults to true."""
-
- sip_subdomain: Optional[str] = None
- """The Telnyx-generated SIP subdomain for this UAC connection."""
-
- sip_subdomain_receive_settings: Optional[Literal["only_my_connections", "from_anyone"]] = None
- """Controls which SIP URI callers may reach this connection."""
-
- timeout_1xx_secs: Optional[int] = None
- """Time(sec) before aborting if connection is not made."""
-
- timeout_2xx_secs: Optional[int] = None
- """Time(sec) before aborting if call is unanswered (min: 1, max: 600)."""
diff --git a/src/telnyx/types/uac_internal_settings.py b/src/telnyx/types/uac_internal_settings.py
deleted file mode 100644
index 799d1494..00000000
--- a/src/telnyx/types/uac_internal_settings.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from .._models import BaseModel
-
-__all__ = ["UacInternalSettings"]
-
-
-class UacInternalSettings(BaseModel):
- """Internal Telnyx-side settings for a UAC connection."""
-
- destination_uri: Optional[str] = None
- """
- The SIP URI that Telnyx will call when handling an inbound request from the
- external peer. Do not include a `sip:` prefix. The value must be in the format
- `userinfo@sip.telnyx.com` or
- `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
- letters, digits, hyphens, and underscores.
- """
diff --git a/src/telnyx/types/uac_internal_settings_param.py b/src/telnyx/types/uac_internal_settings_param.py
deleted file mode 100644
index 68ab4289..00000000
--- a/src/telnyx/types/uac_internal_settings_param.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing_extensions import TypedDict
-
-__all__ = ["UacInternalSettingsParam"]
-
-
-class UacInternalSettingsParam(TypedDict, total=False):
- """Internal Telnyx-side settings for a UAC connection."""
-
- destination_uri: str
- """
- The SIP URI that Telnyx will call when handling an inbound request from the
- external peer. Do not include a `sip:` prefix. The value must be in the format
- `userinfo@sip.telnyx.com` or
- `userinfo@sipdev.telnyx.com`; the userinfo portion may contain only
- letters, digits, hyphens, and underscores.
- """
diff --git a/src/telnyx/types/uac_outbound.py b/src/telnyx/types/uac_outbound.py
deleted file mode 100644
index 81dcae6d..00000000
--- a/src/telnyx/types/uac_outbound.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-
-__all__ = ["UacOutbound"]
-
-
-class UacOutbound(BaseModel):
- ani_override: Optional[str] = None
- """
- Set a phone number as the ani_override value to override caller id number on
- outbound calls.
- """
-
- ani_override_type: Optional[Literal["always", "normal", "emergency"]] = None
- """Specifies when we apply your ani_override setting.
-
- Only applies when ani_override is not blank.
- """
-
- call_parking_enabled: Optional[bool] = None
- """
- Forces all SIP calls originated on this connection to be "parked" instead of
- "bridged" to the destination specified on the URI. Parked calls will return
- ringback to the caller and will await for a Call Control command to define which
- action will be taken next.
- """
-
- channel_limit: Optional[int] = None
- """
- When set, this will limit the total number of outbound calls to phone numbers
- associated with this connection.
- """
-
- generate_ringback_tone: Optional[bool] = None
- """Generate ringback tone through 183 session progress message with early media."""
-
- instant_ringback_enabled: Optional[bool] = None
- """
- When set, ringback will not wait for indication before sending ringback tone to
- calling party.
- """
-
- localization: Optional[str] = None
- """
- A 2-character country code specifying the country whose national dialing rules
- should be used. For example, if set to `US` then any US number can be dialed
- without preprending +1 to the number. When left blank, Telnyx will try US and GB
- dialing rules, in that order, by default.
- """
-
- outbound_voice_profile_id: Optional[str] = None
- """Identifies the associated outbound voice profile."""
-
- t38_reinvite_source: Optional[
- Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
- ] = None
- """This setting only affects connections with Fax-type Outbound Voice Profiles.
-
- The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
- default, Telnyx will send the re-invite. If set to `customer`, the caller is
- expected to send the t.38 reinvite.
- """
diff --git a/src/telnyx/types/uac_outbound_param.py b/src/telnyx/types/uac_outbound_param.py
deleted file mode 100644
index c170e350..00000000
--- a/src/telnyx/types/uac_outbound_param.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from __future__ import annotations
-
-from typing import Optional
-from typing_extensions import Literal, TypedDict
-
-__all__ = ["UacOutboundParam"]
-
-
-class UacOutboundParam(TypedDict, total=False):
- ani_override: str
- """
- Set a phone number as the ani_override value to override caller id number on
- outbound calls.
- """
-
- ani_override_type: Literal["always", "normal", "emergency"]
- """Specifies when we apply your ani_override setting.
-
- Only applies when ani_override is not blank.
- """
-
- call_parking_enabled: Optional[bool]
- """
- Forces all SIP calls originated on this connection to be "parked" instead of
- "bridged" to the destination specified on the URI. Parked calls will return
- ringback to the caller and will await for a Call Control command to define which
- action will be taken next.
- """
-
- channel_limit: int
- """
- When set, this will limit the total number of outbound calls to phone numbers
- associated with this connection.
- """
-
- generate_ringback_tone: bool
- """Generate ringback tone through 183 session progress message with early media."""
-
- instant_ringback_enabled: bool
- """
- When set, ringback will not wait for indication before sending ringback tone to
- calling party.
- """
-
- localization: str
- """
- A 2-character country code specifying the country whose national dialing rules
- should be used. For example, if set to `US` then any US number can be dialed
- without preprending +1 to the number. When left blank, Telnyx will try US and GB
- dialing rules, in that order, by default.
- """
-
- outbound_voice_profile_id: str
- """Identifies the associated outbound voice profile."""
-
- t38_reinvite_source: Literal["telnyx", "customer", "disabled", "passthru", "caller-passthru", "callee-passthru"]
- """This setting only affects connections with Fax-type Outbound Voice Profiles.
-
- The setting dictates whether or not Telnyx sends a t.38 reinvite.
By
- default, Telnyx will send the re-invite. If set to `customer`, the caller is
- expected to send the t.38 reinvite.
- """
diff --git a/src/telnyx/types/virtual_cross_connect_combined.py b/src/telnyx/types/virtual_cross_connect_combined.py
deleted file mode 100644
index 595a3fb3..00000000
--- a/src/telnyx/types/virtual_cross_connect_combined.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-from typing_extensions import Literal
-
-from .._models import BaseModel
-from .interface_status import InterfaceStatus
-
-__all__ = ["VirtualCrossConnectCombined", "Region"]
-
-
-class Region(BaseModel):
- code: Optional[str] = None
- """Region code of the interface."""
-
- name: Optional[str] = None
- """Region name of the interface."""
-
- record_type: Optional[str] = None
- """Identifies the type of the resource."""
-
-
-class VirtualCrossConnectCombined(BaseModel):
- id: Optional[str] = None
- """Identifies the resource."""
-
- bandwidth_mbps: Optional[float] = None
- """
- The desired throughput in Megabits per Second (Mbps) for your Virtual Cross
- Connect.
- """
-
- bgp_asn: Optional[float] = None
- """The Border Gateway Protocol (BGP) Autonomous System Number (ASN)."""
-
- cloud_provider: Optional[Literal["aws", "azure", "gce"]] = None
- """
- The Virtual Private Cloud with which you would like to establish a cross
- connect.
- """
-
- cloud_provider_region: Optional[str] = None
- """The region where your Virtual Private Cloud hosts are located."""
-
- created_at: Optional[str] = None
- """ISO 8601 formatted date-time indicating when the resource was created."""
-
- name: Optional[str] = None
- """A user specified name for the interface."""
-
- network_id: Optional[str] = None
- """The id of the network associated with the interface."""
-
- primary_bgp_key: Optional[str] = None
- """The authentication key for BGP peer configuration."""
-
- primary_cloud_account_id: Optional[str] = None
- """The identifier for your Virtual Private Cloud."""
-
- primary_cloud_ip: Optional[str] = None
- """The IP address assigned for your side of the Virtual Cross Connect."""
-
- primary_enabled: Optional[bool] = None
- """Indicates whether the primary circuit is enabled."""
-
- primary_routing_announcement: Optional[bool] = None
- """Whether"""
-
- primary_telnyx_ip: Optional[str] = None
- """The IP address assigned to the Telnyx side of the Virtual Cross Connect."""
-
- record_type: Optional[str] = None
- """Identifies the type of the resource."""
-
- region: Optional[Region] = None
-
- region_code: Optional[str] = None
- """The region interface is deployed to."""
-
- status: Optional[InterfaceStatus] = None
- """The current status of the interface deployment."""
-
- updated_at: Optional[str] = None
- """ISO 8601 formatted date-time indicating when the resource was updated."""
diff --git a/src/telnyx/types/virtual_cross_connect_create_response.py b/src/telnyx/types/virtual_cross_connect_create_response.py
index 283ab4eb..31e99a85 100644
--- a/src/telnyx/types/virtual_cross_connect_create_response.py
+++ b/src/telnyx/types/virtual_cross_connect_create_response.py
@@ -1,12 +1,125 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from typing_extensions import Literal
+from .record import Record
from .._models import BaseModel
-from .virtual_cross_connect_combined import VirtualCrossConnectCombined
+from .network_interface import NetworkInterface
-__all__ = ["VirtualCrossConnectCreateResponse"]
+__all__ = ["VirtualCrossConnectCreateResponse", "Data", "DataRegion"]
+
+
+class DataRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class Data(Record, NetworkInterface):
+ region_code: str
+ """The region interface is deployed to."""
+
+ bandwidth_mbps: Optional[float] = None
+ """
+ The desired throughput in Megabits per Second (Mbps) for your Virtual Cross
+ Connect.
The available bandwidths can be found using the
+ /virtual_cross_connect_regions endpoint.
+ """
+
+ bgp_asn: Optional[float] = None
+ """The Border Gateway Protocol (BGP) Autonomous System Number (ASN).
+
+ If null, value will be assigned by Telnyx.
+ """
+
+ cloud_provider: Optional[Literal["aws", "azure", "gce"]] = None
+ """
+ The Virtual Private Cloud with which you would like to establish a cross
+ connect.
+ """
+
+ cloud_provider_region: Optional[str] = None
+ """
+ The region where your Virtual Private Cloud hosts are located.
The
+ available regions can be found using the /virtual_cross_connect_regions
+ endpoint.
+ """
+
+ primary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ primary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
+ """
+
+ primary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ primary_enabled: Optional[bool] = None
+ """Indicates whether the primary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ primary_routing_announcement: Optional[bool] = None
+ """Whether the primary BGP route is being announced."""
+
+ primary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
+
+ region: Optional[DataRegion] = None
+
+ secondary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ secondary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
This
+ attribute is only necessary for GCE.
+ """
+
+ secondary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ secondary_enabled: Optional[bool] = None
+ """Indicates whether the secondary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ secondary_routing_announcement: Optional[bool] = None
+ """Whether the secondary BGP route is being announced."""
+
+ secondary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
class VirtualCrossConnectCreateResponse(BaseModel):
- data: Optional[VirtualCrossConnectCombined] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/virtual_cross_connect_delete_response.py b/src/telnyx/types/virtual_cross_connect_delete_response.py
index 44177acf..3ade9098 100644
--- a/src/telnyx/types/virtual_cross_connect_delete_response.py
+++ b/src/telnyx/types/virtual_cross_connect_delete_response.py
@@ -1,12 +1,125 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from typing_extensions import Literal
+from .record import Record
from .._models import BaseModel
-from .virtual_cross_connect_combined import VirtualCrossConnectCombined
+from .network_interface import NetworkInterface
-__all__ = ["VirtualCrossConnectDeleteResponse"]
+__all__ = ["VirtualCrossConnectDeleteResponse", "Data", "DataRegion"]
+
+
+class DataRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class Data(Record, NetworkInterface):
+ region_code: str
+ """The region interface is deployed to."""
+
+ bandwidth_mbps: Optional[float] = None
+ """
+ The desired throughput in Megabits per Second (Mbps) for your Virtual Cross
+ Connect.
The available bandwidths can be found using the
+ /virtual_cross_connect_regions endpoint.
+ """
+
+ bgp_asn: Optional[float] = None
+ """The Border Gateway Protocol (BGP) Autonomous System Number (ASN).
+
+ If null, value will be assigned by Telnyx.
+ """
+
+ cloud_provider: Optional[Literal["aws", "azure", "gce"]] = None
+ """
+ The Virtual Private Cloud with which you would like to establish a cross
+ connect.
+ """
+
+ cloud_provider_region: Optional[str] = None
+ """
+ The region where your Virtual Private Cloud hosts are located.
The
+ available regions can be found using the /virtual_cross_connect_regions
+ endpoint.
+ """
+
+ primary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ primary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
+ """
+
+ primary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ primary_enabled: Optional[bool] = None
+ """Indicates whether the primary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ primary_routing_announcement: Optional[bool] = None
+ """Whether the primary BGP route is being announced."""
+
+ primary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
+
+ region: Optional[DataRegion] = None
+
+ secondary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ secondary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
This
+ attribute is only necessary for GCE.
+ """
+
+ secondary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ secondary_enabled: Optional[bool] = None
+ """Indicates whether the secondary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ secondary_routing_announcement: Optional[bool] = None
+ """Whether the secondary BGP route is being announced."""
+
+ secondary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
class VirtualCrossConnectDeleteResponse(BaseModel):
- data: Optional[VirtualCrossConnectCombined] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/virtual_cross_connect_list_response.py b/src/telnyx/types/virtual_cross_connect_list_response.py
new file mode 100644
index 00000000..68688e1b
--- /dev/null
+++ b/src/telnyx/types/virtual_cross_connect_list_response.py
@@ -0,0 +1,121 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+from typing_extensions import Literal
+
+from .record import Record
+from .._models import BaseModel
+from .network_interface import NetworkInterface
+
+__all__ = ["VirtualCrossConnectListResponse", "VirtualCrossConnectListResponseRegion"]
+
+
+class VirtualCrossConnectListResponseRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class VirtualCrossConnectListResponse(Record, NetworkInterface):
+ region_code: str
+ """The region interface is deployed to."""
+
+ bandwidth_mbps: Optional[float] = None
+ """
+ The desired throughput in Megabits per Second (Mbps) for your Virtual Cross
+ Connect.
The available bandwidths can be found using the
+ /virtual_cross_connect_regions endpoint.
+ """
+
+ bgp_asn: Optional[float] = None
+ """The Border Gateway Protocol (BGP) Autonomous System Number (ASN).
+
+ If null, value will be assigned by Telnyx.
+ """
+
+ cloud_provider: Optional[Literal["aws", "azure", "gce"]] = None
+ """
+ The Virtual Private Cloud with which you would like to establish a cross
+ connect.
+ """
+
+ cloud_provider_region: Optional[str] = None
+ """
+ The region where your Virtual Private Cloud hosts are located.
The
+ available regions can be found using the /virtual_cross_connect_regions
+ endpoint.
+ """
+
+ primary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ primary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
+ """
+
+ primary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ primary_enabled: Optional[bool] = None
+ """Indicates whether the primary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ primary_routing_announcement: Optional[bool] = None
+ """Whether the primary BGP route is being announced."""
+
+ primary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
+
+ region: Optional[VirtualCrossConnectListResponseRegion] = None
+
+ secondary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ secondary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
This
+ attribute is only necessary for GCE.
+ """
+
+ secondary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ secondary_enabled: Optional[bool] = None
+ """Indicates whether the secondary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ secondary_routing_announcement: Optional[bool] = None
+ """Whether the secondary BGP route is being announced."""
+
+ secondary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
diff --git a/src/telnyx/types/virtual_cross_connect_retrieve_response.py b/src/telnyx/types/virtual_cross_connect_retrieve_response.py
index 7a327afa..913747e3 100644
--- a/src/telnyx/types/virtual_cross_connect_retrieve_response.py
+++ b/src/telnyx/types/virtual_cross_connect_retrieve_response.py
@@ -1,12 +1,125 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from typing_extensions import Literal
+from .record import Record
from .._models import BaseModel
-from .virtual_cross_connect_combined import VirtualCrossConnectCombined
+from .network_interface import NetworkInterface
-__all__ = ["VirtualCrossConnectRetrieveResponse"]
+__all__ = ["VirtualCrossConnectRetrieveResponse", "Data", "DataRegion"]
+
+
+class DataRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class Data(Record, NetworkInterface):
+ region_code: str
+ """The region interface is deployed to."""
+
+ bandwidth_mbps: Optional[float] = None
+ """
+ The desired throughput in Megabits per Second (Mbps) for your Virtual Cross
+ Connect.
The available bandwidths can be found using the
+ /virtual_cross_connect_regions endpoint.
+ """
+
+ bgp_asn: Optional[float] = None
+ """The Border Gateway Protocol (BGP) Autonomous System Number (ASN).
+
+ If null, value will be assigned by Telnyx.
+ """
+
+ cloud_provider: Optional[Literal["aws", "azure", "gce"]] = None
+ """
+ The Virtual Private Cloud with which you would like to establish a cross
+ connect.
+ """
+
+ cloud_provider_region: Optional[str] = None
+ """
+ The region where your Virtual Private Cloud hosts are located.
The
+ available regions can be found using the /virtual_cross_connect_regions
+ endpoint.
+ """
+
+ primary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ primary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
+ """
+
+ primary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ primary_enabled: Optional[bool] = None
+ """Indicates whether the primary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ primary_routing_announcement: Optional[bool] = None
+ """Whether the primary BGP route is being announced."""
+
+ primary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
+
+ region: Optional[DataRegion] = None
+
+ secondary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ secondary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
This
+ attribute is only necessary for GCE.
+ """
+
+ secondary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ secondary_enabled: Optional[bool] = None
+ """Indicates whether the secondary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ secondary_routing_announcement: Optional[bool] = None
+ """Whether the secondary BGP route is being announced."""
+
+ secondary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
class VirtualCrossConnectRetrieveResponse(BaseModel):
- data: Optional[VirtualCrossConnectCombined] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/virtual_cross_connect_update_response.py b/src/telnyx/types/virtual_cross_connect_update_response.py
index 63532bf5..de0085e4 100644
--- a/src/telnyx/types/virtual_cross_connect_update_response.py
+++ b/src/telnyx/types/virtual_cross_connect_update_response.py
@@ -1,12 +1,125 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from typing import Optional
+from typing_extensions import Literal
+from .record import Record
from .._models import BaseModel
-from .virtual_cross_connect_combined import VirtualCrossConnectCombined
+from .network_interface import NetworkInterface
-__all__ = ["VirtualCrossConnectUpdateResponse"]
+__all__ = ["VirtualCrossConnectUpdateResponse", "Data", "DataRegion"]
+
+
+class DataRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class Data(Record, NetworkInterface):
+ region_code: str
+ """The region interface is deployed to."""
+
+ bandwidth_mbps: Optional[float] = None
+ """
+ The desired throughput in Megabits per Second (Mbps) for your Virtual Cross
+ Connect.
The available bandwidths can be found using the
+ /virtual_cross_connect_regions endpoint.
+ """
+
+ bgp_asn: Optional[float] = None
+ """The Border Gateway Protocol (BGP) Autonomous System Number (ASN).
+
+ If null, value will be assigned by Telnyx.
+ """
+
+ cloud_provider: Optional[Literal["aws", "azure", "gce"]] = None
+ """
+ The Virtual Private Cloud with which you would like to establish a cross
+ connect.
+ """
+
+ cloud_provider_region: Optional[str] = None
+ """
+ The region where your Virtual Private Cloud hosts are located.
The
+ available regions can be found using the /virtual_cross_connect_regions
+ endpoint.
+ """
+
+ primary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ primary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
+ """
+
+ primary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ primary_enabled: Optional[bool] = None
+ """Indicates whether the primary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ primary_routing_announcement: Optional[bool] = None
+ """Whether the primary BGP route is being announced."""
+
+ primary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
+
+ region: Optional[DataRegion] = None
+
+ secondary_bgp_key: Optional[str] = None
+ """The authentication key for BGP peer configuration."""
+
+ secondary_cloud_account_id: Optional[str] = None
+ """The identifier for your Virtual Private Cloud.
+
+ The number will be different based upon your Cloud provider.
This
+ attribute is only necessary for GCE.
+ """
+
+ secondary_cloud_ip: Optional[str] = None
+ """
+ The IP address assigned for your side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value can not be patched once the VXC has bene provisioned.
+ """
+
+ secondary_enabled: Optional[bool] = None
+ """Indicates whether the secondary circuit is enabled.
+
+ Setting this to `false` will disable the circuit.
+ """
+
+ secondary_routing_announcement: Optional[bool] = None
+ """Whether the secondary BGP route is being announced."""
+
+ secondary_telnyx_ip: Optional[str] = None
+ """
+ The IP address assigned to the Telnyx side of the Virtual Cross
+ Connect.
If none is provided, one will be generated for
+ you.
This value should be null for GCE as Google will only inform you
+ of your assigned IP once the connection has been accepted.
+ """
class VirtualCrossConnectUpdateResponse(BaseModel):
- data: Optional[VirtualCrossConnectCombined] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/wireguard_interface_create_response.py b/src/telnyx/types/wireguard_interface_create_response.py
index 73f8bd7f..458ea75d 100644
--- a/src/telnyx/types/wireguard_interface_create_response.py
+++ b/src/telnyx/types/wireguard_interface_create_response.py
@@ -2,11 +2,39 @@
from typing import Optional
+from .record import Record
from .._models import BaseModel
-from .wireguard_interface_read import WireguardInterfaceRead
+from .network_interface import NetworkInterface
-__all__ = ["WireguardInterfaceCreateResponse"]
+__all__ = ["WireguardInterfaceCreateResponse", "Data", "DataRegion"]
+
+
+class DataRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class Data(Record, NetworkInterface):
+ enable_sip_trunking: Optional[bool] = None
+ """Enable SIP traffic forwarding over VPN interface."""
+
+ endpoint: Optional[str] = None
+ """The Telnyx WireGuard peers `Peer.endpoint` value."""
+
+ public_key: Optional[str] = None
+ """The Telnyx WireGuard peers `Peer.PublicKey`."""
+
+ region: Optional[DataRegion] = None
+
+ region_code: Optional[str] = None
+ """The region interface is deployed to."""
class WireguardInterfaceCreateResponse(BaseModel):
- data: Optional[WireguardInterfaceRead] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/wireguard_interface_delete_response.py b/src/telnyx/types/wireguard_interface_delete_response.py
index d6638859..519a9b74 100644
--- a/src/telnyx/types/wireguard_interface_delete_response.py
+++ b/src/telnyx/types/wireguard_interface_delete_response.py
@@ -2,11 +2,39 @@
from typing import Optional
+from .record import Record
from .._models import BaseModel
-from .wireguard_interface_read import WireguardInterfaceRead
+from .network_interface import NetworkInterface
-__all__ = ["WireguardInterfaceDeleteResponse"]
+__all__ = ["WireguardInterfaceDeleteResponse", "Data", "DataRegion"]
+
+
+class DataRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class Data(Record, NetworkInterface):
+ enable_sip_trunking: Optional[bool] = None
+ """Enable SIP traffic forwarding over VPN interface."""
+
+ endpoint: Optional[str] = None
+ """The Telnyx WireGuard peers `Peer.endpoint` value."""
+
+ public_key: Optional[str] = None
+ """The Telnyx WireGuard peers `Peer.PublicKey`."""
+
+ region: Optional[DataRegion] = None
+
+ region_code: Optional[str] = None
+ """The region interface is deployed to."""
class WireguardInterfaceDeleteResponse(BaseModel):
- data: Optional[WireguardInterfaceRead] = None
+ data: Optional[Data] = None
diff --git a/src/telnyx/types/wireguard_interface_list_response.py b/src/telnyx/types/wireguard_interface_list_response.py
new file mode 100644
index 00000000..77fb1d5d
--- /dev/null
+++ b/src/telnyx/types/wireguard_interface_list_response.py
@@ -0,0 +1,36 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from .record import Record
+from .._models import BaseModel
+from .network_interface import NetworkInterface
+
+__all__ = ["WireguardInterfaceListResponse", "WireguardInterfaceListResponseRegion"]
+
+
+class WireguardInterfaceListResponseRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class WireguardInterfaceListResponse(Record, NetworkInterface):
+ enable_sip_trunking: Optional[bool] = None
+ """Enable SIP traffic forwarding over VPN interface."""
+
+ endpoint: Optional[str] = None
+ """The Telnyx WireGuard peers `Peer.endpoint` value."""
+
+ public_key: Optional[str] = None
+ """The Telnyx WireGuard peers `Peer.PublicKey`."""
+
+ region: Optional[WireguardInterfaceListResponseRegion] = None
+
+ region_code: Optional[str] = None
+ """The region interface is deployed to."""
diff --git a/src/telnyx/types/wireguard_interface_read.py b/src/telnyx/types/wireguard_interface_read.py
deleted file mode 100644
index 424ffc20..00000000
--- a/src/telnyx/types/wireguard_interface_read.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-from typing import Optional
-
-from .._models import BaseModel
-from .interface_status import InterfaceStatus
-
-__all__ = ["WireguardInterfaceRead", "Region"]
-
-
-class Region(BaseModel):
- code: Optional[str] = None
- """Region code of the interface."""
-
- name: Optional[str] = None
- """Region name of the interface."""
-
- record_type: Optional[str] = None
- """Identifies the type of the resource."""
-
-
-class WireguardInterfaceRead(BaseModel):
- id: Optional[str] = None
- """Identifies the resource."""
-
- created_at: Optional[str] = None
- """ISO 8601 formatted date-time indicating when the resource was created."""
-
- enable_sip_trunking: Optional[bool] = None
- """Enable SIP traffic forwarding over VPN interface."""
-
- endpoint: Optional[str] = None
- """The Telnyx WireGuard peers `Peer.endpoint` value."""
-
- name: Optional[str] = None
- """A user specified name for the interface."""
-
- network_id: Optional[str] = None
- """The id of the network associated with the interface."""
-
- public_key: Optional[str] = None
- """The Telnyx WireGuard peers `Peer.PublicKey`."""
-
- record_type: Optional[str] = None
- """Identifies the type of the resource."""
-
- region: Optional[Region] = None
-
- region_code: Optional[str] = None
- """The region interface is deployed to."""
-
- status: Optional[InterfaceStatus] = None
- """The current status of the interface deployment."""
-
- updated_at: Optional[str] = None
- """ISO 8601 formatted date-time indicating when the resource was updated."""
diff --git a/src/telnyx/types/wireguard_interface_retrieve_response.py b/src/telnyx/types/wireguard_interface_retrieve_response.py
index d4dced88..9816c28f 100644
--- a/src/telnyx/types/wireguard_interface_retrieve_response.py
+++ b/src/telnyx/types/wireguard_interface_retrieve_response.py
@@ -2,11 +2,39 @@
from typing import Optional
+from .record import Record
from .._models import BaseModel
-from .wireguard_interface_read import WireguardInterfaceRead
+from .network_interface import NetworkInterface
-__all__ = ["WireguardInterfaceRetrieveResponse"]
+__all__ = ["WireguardInterfaceRetrieveResponse", "Data", "DataRegion"]
+
+
+class DataRegion(BaseModel):
+ code: Optional[str] = None
+ """Region code of the interface."""
+
+ name: Optional[str] = None
+ """Region name of the interface."""
+
+ record_type: Optional[str] = None
+ """Identifies the type of the resource."""
+
+
+class Data(Record, NetworkInterface):
+ enable_sip_trunking: Optional[bool] = None
+ """Enable SIP traffic forwarding over VPN interface."""
+
+ endpoint: Optional[str] = None
+ """The Telnyx WireGuard peers `Peer.endpoint` value."""
+
+ public_key: Optional[str] = None
+ """The Telnyx WireGuard peers `Peer.PublicKey`."""
+
+ region: Optional[DataRegion] = None
+
+ region_code: Optional[str] = None
+ """The region interface is deployed to."""
class WireguardInterfaceRetrieveResponse(BaseModel):
- data: Optional[WireguardInterfaceRead] = None
+ data: Optional[Data] = None
diff --git a/tests/api_resources/dir/__init__.py b/tests/api_resources/dir/__init__.py
new file mode 100644
index 00000000..fd8019a9
--- /dev/null
+++ b/tests/api_resources/dir/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/dir/test_comments.py b/tests/api_resources/dir/test_comments.py
new file mode 100644
index 00000000..c66d908e
--- /dev/null
+++ b/tests/api_resources/dir/test_comments.py
@@ -0,0 +1,243 @@
+# 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.types.dir import CommentListResponse, CommentCreateResponse
+from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestComments:
+ 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_create(self, client: Telnyx) -> None:
+ comment = client.dir.comments.create(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ )
+ assert_matches_type(CommentCreateResponse, comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_with_all_params(self, client: Telnyx) -> None:
+ comment = client.dir.comments.create(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ parent_comment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(CommentCreateResponse, comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_create(self, client: Telnyx) -> None:
+ response = client.dir.comments.with_raw_response.create(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ comment = response.parse()
+ assert_matches_type(CommentCreateResponse, comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_create(self, client: Telnyx) -> None:
+ with client.dir.comments.with_streaming_response.create(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ comment = response.parse()
+ assert_matches_type(CommentCreateResponse, comment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_create(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.comments.with_raw_response.create(
+ dir_id="",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Telnyx) -> None:
+ comment = client.dir.comments.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(SyncDefaultFlatPagination[CommentListResponse], comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Telnyx) -> None:
+ comment = client.dir.comments.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ comment_type="vetting_comment",
+ page_number=1,
+ page_size=20,
+ )
+ assert_matches_type(SyncDefaultFlatPagination[CommentListResponse], comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Telnyx) -> None:
+ response = client.dir.comments.with_raw_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ comment = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[CommentListResponse], comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Telnyx) -> None:
+ with client.dir.comments.with_streaming_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ comment = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[CommentListResponse], comment, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_list(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.comments.with_raw_response.list(
+ dir_id="",
+ )
+
+
+class TestAsyncComments:
+ 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_create(self, async_client: AsyncTelnyx) -> None:
+ comment = await async_client.dir.comments.create(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ )
+ assert_matches_type(CommentCreateResponse, comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ comment = await async_client.dir.comments.create(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ parent_comment_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ )
+ assert_matches_type(CommentCreateResponse, comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.comments.with_raw_response.create(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ comment = await response.parse()
+ assert_matches_type(CommentCreateResponse, comment, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.comments.with_streaming_response.create(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ comment = await response.parse()
+ assert_matches_type(CommentCreateResponse, comment, 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_create(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.comments.with_raw_response.create(
+ dir_id="",
+ content="Re-uploaded the certificate. New document_id: 89450109-ee35-411c-b5bb-14f1d806fca2.",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncTelnyx) -> None:
+ comment = await async_client.dir.comments.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[CommentListResponse], comment, 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:
+ comment = await async_client.dir.comments.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ comment_type="vetting_comment",
+ page_number=1,
+ page_size=20,
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[CommentListResponse], comment, 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.dir.comments.with_raw_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ comment = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[CommentListResponse], comment, 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.dir.comments.with_streaming_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ comment = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[CommentListResponse], comment, 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_list(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.comments.with_raw_response.list(
+ dir_id="",
+ )
diff --git a/tests/api_resources/dir/test_phone_number_batches.py b/tests/api_resources/dir/test_phone_number_batches.py
new file mode 100644
index 00000000..10c3e3ce
--- /dev/null
+++ b/tests/api_resources/dir/test_phone_number_batches.py
@@ -0,0 +1,254 @@
+# 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.types.dir import (
+ PhoneNumberBatchListResponse,
+ PhoneNumberBatchRetrieveResponse,
+)
+from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestPhoneNumberBatches:
+ 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:
+ phone_number_batch = client.dir.phone_number_batches.retrieve(
+ batch_id="0a4b1f5e-2f12-4c0c-9a98-9b3a7d8b8e62",
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(PhoneNumberBatchRetrieveResponse, phone_number_batch, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: Telnyx) -> None:
+ response = client.dir.phone_number_batches.with_raw_response.retrieve(
+ batch_id="0a4b1f5e-2f12-4c0c-9a98-9b3a7d8b8e62",
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number_batch = response.parse()
+ assert_matches_type(PhoneNumberBatchRetrieveResponse, phone_number_batch, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Telnyx) -> None:
+ with client.dir.phone_number_batches.with_streaming_response.retrieve(
+ batch_id="0a4b1f5e-2f12-4c0c-9a98-9b3a7d8b8e62",
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number_batch = response.parse()
+ assert_matches_type(PhoneNumberBatchRetrieveResponse, phone_number_batch, 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 `dir_id` but received ''"):
+ client.dir.phone_number_batches.with_raw_response.retrieve(
+ batch_id="0a4b1f5e-2f12-4c0c-9a98-9b3a7d8b8e62",
+ dir_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `batch_id` but received ''"):
+ client.dir.phone_number_batches.with_raw_response.retrieve(
+ batch_id="",
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Telnyx) -> None:
+ phone_number_batch = client.dir.phone_number_batches.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(
+ SyncDefaultFlatPagination[PhoneNumberBatchListResponse], phone_number_batch, path=["response"]
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Telnyx) -> None:
+ phone_number_batch = client.dir.phone_number_batches.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ filter_status="submitted",
+ page_number=1,
+ page_size=20,
+ )
+ assert_matches_type(
+ SyncDefaultFlatPagination[PhoneNumberBatchListResponse], phone_number_batch, path=["response"]
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Telnyx) -> None:
+ response = client.dir.phone_number_batches.with_raw_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number_batch = response.parse()
+ assert_matches_type(
+ SyncDefaultFlatPagination[PhoneNumberBatchListResponse], phone_number_batch, path=["response"]
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Telnyx) -> None:
+ with client.dir.phone_number_batches.with_streaming_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number_batch = response.parse()
+ assert_matches_type(
+ SyncDefaultFlatPagination[PhoneNumberBatchListResponse], phone_number_batch, path=["response"]
+ )
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_list(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.phone_number_batches.with_raw_response.list(
+ dir_id="",
+ )
+
+
+class TestAsyncPhoneNumberBatches:
+ 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:
+ phone_number_batch = await async_client.dir.phone_number_batches.retrieve(
+ batch_id="0a4b1f5e-2f12-4c0c-9a98-9b3a7d8b8e62",
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(PhoneNumberBatchRetrieveResponse, phone_number_batch, 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.dir.phone_number_batches.with_raw_response.retrieve(
+ batch_id="0a4b1f5e-2f12-4c0c-9a98-9b3a7d8b8e62",
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number_batch = await response.parse()
+ assert_matches_type(PhoneNumberBatchRetrieveResponse, phone_number_batch, 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.dir.phone_number_batches.with_streaming_response.retrieve(
+ batch_id="0a4b1f5e-2f12-4c0c-9a98-9b3a7d8b8e62",
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number_batch = await response.parse()
+ assert_matches_type(PhoneNumberBatchRetrieveResponse, phone_number_batch, 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 `dir_id` but received ''"):
+ await async_client.dir.phone_number_batches.with_raw_response.retrieve(
+ batch_id="0a4b1f5e-2f12-4c0c-9a98-9b3a7d8b8e62",
+ dir_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `batch_id` but received ''"):
+ await async_client.dir.phone_number_batches.with_raw_response.retrieve(
+ batch_id="",
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncTelnyx) -> None:
+ phone_number_batch = await async_client.dir.phone_number_batches.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(
+ AsyncDefaultFlatPagination[PhoneNumberBatchListResponse], phone_number_batch, 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:
+ phone_number_batch = await async_client.dir.phone_number_batches.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ filter_status="submitted",
+ page_number=1,
+ page_size=20,
+ )
+ assert_matches_type(
+ AsyncDefaultFlatPagination[PhoneNumberBatchListResponse], phone_number_batch, 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.dir.phone_number_batches.with_raw_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number_batch = await response.parse()
+ assert_matches_type(
+ AsyncDefaultFlatPagination[PhoneNumberBatchListResponse], phone_number_batch, 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.dir.phone_number_batches.with_streaming_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number_batch = await response.parse()
+ assert_matches_type(
+ AsyncDefaultFlatPagination[PhoneNumberBatchListResponse], phone_number_batch, 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_list(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.phone_number_batches.with_raw_response.list(
+ dir_id="",
+ )
diff --git a/tests/api_resources/dir/test_phone_numbers.py b/tests/api_resources/dir/test_phone_numbers.py
new file mode 100644
index 00000000..9a384f12
--- /dev/null
+++ b/tests/api_resources/dir/test_phone_numbers.py
@@ -0,0 +1,367 @@
+# 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.types.dir import (
+ PhoneNumberAddResponse,
+ PhoneNumberListResponse,
+ PhoneNumberRemoveResponse,
+)
+from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestPhoneNumbers:
+ 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_list(self, client: Telnyx) -> None:
+ phone_number = client.dir.phone_numbers.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Telnyx) -> None:
+ phone_number = client.dir.phone_numbers.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ page_number=1,
+ page_size=20,
+ status="submitted",
+ )
+ assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Telnyx) -> None:
+ response = client.dir.phone_numbers.with_raw_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Telnyx) -> None:
+ with client.dir.phone_numbers.with_streaming_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[PhoneNumberListResponse], 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_list(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.phone_numbers.with_raw_response.list(
+ dir_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_add(self, client: Telnyx) -> None:
+ phone_number = client.dir.phone_numbers.add(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "letter_of_authorization",
+ }
+ ],
+ phone_numbers=["+19493253498", "+12134445566"],
+ )
+ assert_matches_type(PhoneNumberAddResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_add(self, client: Telnyx) -> None:
+ response = client.dir.phone_numbers.with_raw_response.add(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "letter_of_authorization",
+ }
+ ],
+ phone_numbers=["+19493253498", "+12134445566"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number = response.parse()
+ assert_matches_type(PhoneNumberAddResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_add(self, client: Telnyx) -> None:
+ with client.dir.phone_numbers.with_streaming_response.add(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "letter_of_authorization",
+ }
+ ],
+ phone_numbers=["+19493253498", "+12134445566"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number = response.parse()
+ assert_matches_type(PhoneNumberAddResponse, 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_add(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.phone_numbers.with_raw_response.add(
+ dir_id="",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "letter_of_authorization",
+ }
+ ],
+ phone_numbers=["+19493253498", "+12134445566"],
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_remove(self, client: Telnyx) -> None:
+ phone_number = client.dir.phone_numbers.remove(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ phone_numbers=["+19493253498"],
+ )
+ assert_matches_type(PhoneNumberRemoveResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_remove(self, client: Telnyx) -> None:
+ response = client.dir.phone_numbers.with_raw_response.remove(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ phone_numbers=["+19493253498"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number = response.parse()
+ assert_matches_type(PhoneNumberRemoveResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_remove(self, client: Telnyx) -> None:
+ with client.dir.phone_numbers.with_streaming_response.remove(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ phone_numbers=["+19493253498"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ phone_number = response.parse()
+ assert_matches_type(PhoneNumberRemoveResponse, 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_remove(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.phone_numbers.with_raw_response.remove(
+ dir_id="",
+ phone_numbers=["+19493253498"],
+ )
+
+
+class TestAsyncPhoneNumbers:
+ 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_list(self, async_client: AsyncTelnyx) -> None:
+ phone_number = await async_client.dir.phone_numbers.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, 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:
+ phone_number = await async_client.dir.phone_numbers.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ page_number=1,
+ page_size=20,
+ status="submitted",
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, 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.dir.phone_numbers.with_raw_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[PhoneNumberListResponse], phone_number, 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.dir.phone_numbers.with_streaming_response.list(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) 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(AsyncDefaultFlatPagination[PhoneNumberListResponse], 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_list(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.phone_numbers.with_raw_response.list(
+ dir_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_add(self, async_client: AsyncTelnyx) -> None:
+ phone_number = await async_client.dir.phone_numbers.add(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "letter_of_authorization",
+ }
+ ],
+ phone_numbers=["+19493253498", "+12134445566"],
+ )
+ assert_matches_type(PhoneNumberAddResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_add(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.phone_numbers.with_raw_response.add(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "letter_of_authorization",
+ }
+ ],
+ phone_numbers=["+19493253498", "+12134445566"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number = await response.parse()
+ assert_matches_type(PhoneNumberAddResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_add(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.phone_numbers.with_streaming_response.add(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "letter_of_authorization",
+ }
+ ],
+ phone_numbers=["+19493253498", "+12134445566"],
+ ) 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(PhoneNumberAddResponse, 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_add(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.phone_numbers.with_raw_response.add(
+ dir_id="",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "letter_of_authorization",
+ }
+ ],
+ phone_numbers=["+19493253498", "+12134445566"],
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_remove(self, async_client: AsyncTelnyx) -> None:
+ phone_number = await async_client.dir.phone_numbers.remove(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ phone_numbers=["+19493253498"],
+ )
+ assert_matches_type(PhoneNumberRemoveResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_remove(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.phone_numbers.with_raw_response.remove(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ phone_numbers=["+19493253498"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ phone_number = await response.parse()
+ assert_matches_type(PhoneNumberRemoveResponse, phone_number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_remove(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.phone_numbers.with_streaming_response.remove(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ phone_numbers=["+19493253498"],
+ ) 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(PhoneNumberRemoveResponse, 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_remove(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.phone_numbers.with_raw_response.remove(
+ dir_id="",
+ phone_numbers=["+19493253498"],
+ )
diff --git a/tests/api_resources/enterprises/reputation/test_loa.py b/tests/api_resources/enterprises/reputation/test_loa.py
new file mode 100644
index 00000000..2382dfc2
--- /dev/null
+++ b/tests/api_resources/enterprises/reputation/test_loa.py
@@ -0,0 +1,300 @@
+# 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 httpx
+import pytest
+from respx import MockRouter
+
+from telnyx import Telnyx, AsyncTelnyx
+from tests.utils import assert_matches_type
+from telnyx._response import (
+ BinaryAPIResponse,
+ AsyncBinaryAPIResponse,
+ StreamedBinaryAPIResponse,
+ AsyncStreamedBinaryAPIResponse,
+)
+from telnyx.types.enterprises.reputation import LoaUpdateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestLoa:
+ 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_update(self, client: Telnyx) -> None:
+ loa = client.enterprises.reputation.loa.update(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ )
+ assert_matches_type(LoaUpdateResponse, loa, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_update(self, client: Telnyx) -> None:
+ response = client.enterprises.reputation.loa.with_raw_response.update(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ loa = response.parse()
+ assert_matches_type(LoaUpdateResponse, loa, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_update(self, client: Telnyx) -> None:
+ with client.enterprises.reputation.loa.with_streaming_response.update(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ loa = response.parse()
+ assert_matches_type(LoaUpdateResponse, loa, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_update(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ client.enterprises.reputation.loa.with_raw_response.update(
+ enterprise_id="",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ )
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_render(self, client: Telnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/enterprises/4a6192a4-573d-446d-b3ce-aff9117272a6/reputation/loa").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ loa = client.enterprises.reputation.loa.render(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+ assert loa.is_closed
+ assert loa.json() == {"foo": "bar"}
+ assert cast(Any, loa.is_closed) is True
+ assert isinstance(loa, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_method_render_with_all_params(self, client: Telnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/enterprises/4a6192a4-573d-446d-b3ce-aff9117272a6/reputation/loa").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ loa = client.enterprises.reputation.loa.render(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ agent={
+ "administrative_area": "administrative_area",
+ "city": "city",
+ "contact_email": "dev@stainless.com",
+ "contact_name": "contact_name",
+ "contact_phone": "+13125550000",
+ "contact_title": "contact_title",
+ "country": "US",
+ "legal_name": "legal_name",
+ "postal_code": "postal_code",
+ "street_address": "street_address",
+ "dba": "dba",
+ "extended_address": "extended_address",
+ },
+ signature={
+ "image_base64": "image_base64",
+ "signer_name": "signer_name",
+ },
+ )
+ assert loa.is_closed
+ assert loa.json() == {"foo": "bar"}
+ assert cast(Any, loa.is_closed) is True
+ assert isinstance(loa, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_raw_response_render(self, client: Telnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/enterprises/4a6192a4-573d-446d-b3ce-aff9117272a6/reputation/loa").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+
+ loa = client.enterprises.reputation.loa.with_raw_response.render(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+
+ assert loa.is_closed is True
+ assert loa.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert loa.json() == {"foo": "bar"}
+ assert isinstance(loa, BinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_streaming_response_render(self, client: Telnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/enterprises/4a6192a4-573d-446d-b3ce-aff9117272a6/reputation/loa").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ with client.enterprises.reputation.loa.with_streaming_response.render(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ ) as loa:
+ assert not loa.is_closed
+ assert loa.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert loa.json() == {"foo": "bar"}
+ assert cast(Any, loa.is_closed) is True
+ assert isinstance(loa, StreamedBinaryAPIResponse)
+
+ assert cast(Any, loa.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ def test_path_params_render(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ client.enterprises.reputation.loa.with_raw_response.render(
+ enterprise_id="",
+ )
+
+
+class TestAsyncLoa:
+ 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_update(self, async_client: AsyncTelnyx) -> None:
+ loa = await async_client.enterprises.reputation.loa.update(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ )
+ assert_matches_type(LoaUpdateResponse, loa, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.enterprises.reputation.loa.with_raw_response.update(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ loa = await response.parse()
+ assert_matches_type(LoaUpdateResponse, loa, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.enterprises.reputation.loa.with_streaming_response.update(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ loa = await response.parse()
+ assert_matches_type(LoaUpdateResponse, loa, 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_update(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ await async_client.enterprises.reputation.loa.with_raw_response.update(
+ enterprise_id="",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ )
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_render(self, async_client: AsyncTelnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/enterprises/4a6192a4-573d-446d-b3ce-aff9117272a6/reputation/loa").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ loa = await async_client.enterprises.reputation.loa.render(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+ assert loa.is_closed
+ assert await loa.json() == {"foo": "bar"}
+ assert cast(Any, loa.is_closed) is True
+ assert isinstance(loa, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_method_render_with_all_params(self, async_client: AsyncTelnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/enterprises/4a6192a4-573d-446d-b3ce-aff9117272a6/reputation/loa").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ loa = await async_client.enterprises.reputation.loa.render(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ agent={
+ "administrative_area": "administrative_area",
+ "city": "city",
+ "contact_email": "dev@stainless.com",
+ "contact_name": "contact_name",
+ "contact_phone": "+13125550000",
+ "contact_title": "contact_title",
+ "country": "US",
+ "legal_name": "legal_name",
+ "postal_code": "postal_code",
+ "street_address": "street_address",
+ "dba": "dba",
+ "extended_address": "extended_address",
+ },
+ signature={
+ "image_base64": "image_base64",
+ "signer_name": "signer_name",
+ },
+ )
+ assert loa.is_closed
+ assert await loa.json() == {"foo": "bar"}
+ assert cast(Any, loa.is_closed) is True
+ assert isinstance(loa, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_raw_response_render(self, async_client: AsyncTelnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/enterprises/4a6192a4-573d-446d-b3ce-aff9117272a6/reputation/loa").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+
+ loa = await async_client.enterprises.reputation.loa.with_raw_response.render(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+
+ assert loa.is_closed is True
+ assert loa.http_request.headers.get("X-Stainless-Lang") == "python"
+ assert await loa.json() == {"foo": "bar"}
+ assert isinstance(loa, AsyncBinaryAPIResponse)
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_streaming_response_render(self, async_client: AsyncTelnyx, respx_mock: MockRouter) -> None:
+ respx_mock.post("/enterprises/4a6192a4-573d-446d-b3ce-aff9117272a6/reputation/loa").mock(
+ return_value=httpx.Response(200, json={"foo": "bar"})
+ )
+ async with async_client.enterprises.reputation.loa.with_streaming_response.render(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ ) as loa:
+ assert not loa.is_closed
+ assert loa.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ assert await loa.json() == {"foo": "bar"}
+ assert cast(Any, loa.is_closed) is True
+ assert isinstance(loa, AsyncStreamedBinaryAPIResponse)
+
+ assert cast(Any, loa.is_closed) is True
+
+ @parametrize
+ @pytest.mark.respx(base_url=base_url)
+ async def test_path_params_render(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ await async_client.enterprises.reputation.loa.with_raw_response.render(
+ enterprise_id="",
+ )
diff --git a/tests/api_resources/enterprises/reputation/test_numbers.py b/tests/api_resources/enterprises/reputation/test_numbers.py
index 584bea8d..00193d55 100644
--- a/tests/api_resources/enterprises/reputation/test_numbers.py
+++ b/tests/api_resources/enterprises/reputation/test_numbers.py
@@ -10,8 +10,9 @@
from telnyx import Telnyx, AsyncTelnyx
from tests.utils import assert_matches_type
from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
-from telnyx.types.shared import ReputationPhoneNumberWithReputationData
from telnyx.types.enterprises.reputation import (
+ NumberListResponse,
+ NumberRefreshResponse,
NumberRetrieveResponse,
NumberAssociateResponse,
)
@@ -26,8 +27,8 @@ class TestNumbers:
@parametrize
def test_method_retrieve(self, client: Telnyx) -> None:
number = client.enterprises.reputation.numbers.retrieve(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert_matches_type(NumberRetrieveResponse, number, path=["response"])
@@ -35,8 +36,8 @@ def test_method_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_method_retrieve_with_all_params(self, client: Telnyx) -> None:
number = client.enterprises.reputation.numbers.retrieve(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
fresh=True,
)
assert_matches_type(NumberRetrieveResponse, number, path=["response"])
@@ -45,8 +46,8 @@ def test_method_retrieve_with_all_params(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_retrieve(self, client: Telnyx) -> None:
response = client.enterprises.reputation.numbers.with_raw_response.retrieve(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -58,8 +59,8 @@ def test_raw_response_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: Telnyx) -> None:
with client.enterprises.reputation.numbers.with_streaming_response.retrieve(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -74,66 +75,58 @@ def test_streaming_response_retrieve(self, client: Telnyx) -> None:
def test_path_params_retrieve(self, client: Telnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
client.enterprises.reputation.numbers.with_raw_response.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
enterprise_id="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `phone_number` but received ''"):
client.enterprises.reputation.numbers.with_raw_response.retrieve(
phone_number="",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_list(self, client: Telnyx) -> None:
number = client.enterprises.reputation.numbers.list(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- )
- assert_matches_type(
- SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
+ assert_matches_type(SyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_list_with_all_params(self, client: Telnyx) -> None:
number = client.enterprises.reputation.numbers.list(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
page_number=1,
- page_size=1,
+ page_size=10,
phone_number="+16035551234",
)
- assert_matches_type(
- SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(SyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_raw_response_list(self, client: Telnyx) -> None:
response = client.enterprises.reputation.numbers.with_raw_response.list(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number = response.parse()
- assert_matches_type(
- SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(SyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_streaming_response_list(self, client: Telnyx) -> None:
with client.enterprises.reputation.numbers.with_streaming_response.list(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number = response.parse()
- assert_matches_type(
- SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(SyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -149,8 +142,8 @@ def test_path_params_list(self, client: Telnyx) -> None:
@parametrize
def test_method_associate(self, client: Telnyx) -> None:
number = client.enterprises.reputation.numbers.associate(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- phone_numbers=["+16035551234"],
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498", "+12134445566"],
)
assert_matches_type(NumberAssociateResponse, number, path=["response"])
@@ -158,8 +151,8 @@ def test_method_associate(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_associate(self, client: Telnyx) -> None:
response = client.enterprises.reputation.numbers.with_raw_response.associate(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- phone_numbers=["+16035551234"],
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498", "+12134445566"],
)
assert response.is_closed is True
@@ -171,8 +164,8 @@ def test_raw_response_associate(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_associate(self, client: Telnyx) -> None:
with client.enterprises.reputation.numbers.with_streaming_response.associate(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- phone_numbers=["+16035551234"],
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498", "+12134445566"],
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -188,15 +181,15 @@ def test_path_params_associate(self, client: Telnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
client.enterprises.reputation.numbers.with_raw_response.associate(
enterprise_id="",
- phone_numbers=["+16035551234"],
+ phone_numbers=["+19493253498", "+12134445566"],
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_disassociate(self, client: Telnyx) -> None:
number = client.enterprises.reputation.numbers.disassociate(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert number is None
@@ -204,8 +197,8 @@ def test_method_disassociate(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_disassociate(self, client: Telnyx) -> None:
response = client.enterprises.reputation.numbers.with_raw_response.disassociate(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -217,8 +210,8 @@ def test_raw_response_disassociate(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_disassociate(self, client: Telnyx) -> None:
with client.enterprises.reputation.numbers.with_streaming_response.disassociate(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -233,14 +226,60 @@ def test_streaming_response_disassociate(self, client: Telnyx) -> None:
def test_path_params_disassociate(self, client: Telnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
client.enterprises.reputation.numbers.with_raw_response.disassociate(
- phone_number="+16035551234",
+ phone_number="+19493253498",
enterprise_id="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `phone_number` but received ''"):
client.enterprises.reputation.numbers.with_raw_response.disassociate(
phone_number="",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_refresh(self, client: Telnyx) -> None:
+ number = client.enterprises.reputation.numbers.refresh(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498"],
+ )
+ assert_matches_type(NumberRefreshResponse, number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_refresh(self, client: Telnyx) -> None:
+ response = client.enterprises.reputation.numbers.with_raw_response.refresh(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ number = response.parse()
+ assert_matches_type(NumberRefreshResponse, number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_refresh(self, client: Telnyx) -> None:
+ with client.enterprises.reputation.numbers.with_streaming_response.refresh(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ number = response.parse()
+ assert_matches_type(NumberRefreshResponse, 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_refresh(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ client.enterprises.reputation.numbers.with_raw_response.refresh(
+ enterprise_id="",
+ phone_numbers=["+19493253498"],
)
@@ -253,8 +292,8 @@ class TestAsyncNumbers:
@parametrize
async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
number = await async_client.enterprises.reputation.numbers.retrieve(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert_matches_type(NumberRetrieveResponse, number, path=["response"])
@@ -262,8 +301,8 @@ async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_retrieve_with_all_params(self, async_client: AsyncTelnyx) -> None:
number = await async_client.enterprises.reputation.numbers.retrieve(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
fresh=True,
)
assert_matches_type(NumberRetrieveResponse, number, path=["response"])
@@ -272,8 +311,8 @@ async def test_method_retrieve_with_all_params(self, async_client: AsyncTelnyx)
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.reputation.numbers.with_raw_response.retrieve(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -285,8 +324,8 @@ async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.reputation.numbers.with_streaming_response.retrieve(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -301,66 +340,58 @@ async def test_streaming_response_retrieve(self, async_client: AsyncTelnyx) -> N
async def test_path_params_retrieve(self, async_client: AsyncTelnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
await async_client.enterprises.reputation.numbers.with_raw_response.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
enterprise_id="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `phone_number` but received ''"):
await async_client.enterprises.reputation.numbers.with_raw_response.retrieve(
phone_number="",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_list(self, async_client: AsyncTelnyx) -> None:
number = await async_client.enterprises.reputation.numbers.list(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- )
- assert_matches_type(
- AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
+ assert_matches_type(AsyncDefaultFlatPagination[NumberListResponse], number, 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:
number = await async_client.enterprises.reputation.numbers.list(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
page_number=1,
- page_size=1,
+ page_size=10,
phone_number="+16035551234",
)
- assert_matches_type(
- AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(AsyncDefaultFlatPagination[NumberListResponse], number, 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.enterprises.reputation.numbers.with_raw_response.list(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number = await response.parse()
- assert_matches_type(
- AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(AsyncDefaultFlatPagination[NumberListResponse], number, 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.enterprises.reputation.numbers.with_streaming_response.list(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number = await response.parse()
- assert_matches_type(
- AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(AsyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -376,8 +407,8 @@ async def test_path_params_list(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_associate(self, async_client: AsyncTelnyx) -> None:
number = await async_client.enterprises.reputation.numbers.associate(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- phone_numbers=["+16035551234"],
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498", "+12134445566"],
)
assert_matches_type(NumberAssociateResponse, number, path=["response"])
@@ -385,8 +416,8 @@ async def test_method_associate(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_raw_response_associate(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.reputation.numbers.with_raw_response.associate(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- phone_numbers=["+16035551234"],
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498", "+12134445566"],
)
assert response.is_closed is True
@@ -398,8 +429,8 @@ async def test_raw_response_associate(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_associate(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.reputation.numbers.with_streaming_response.associate(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- phone_numbers=["+16035551234"],
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498", "+12134445566"],
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -415,15 +446,15 @@ async def test_path_params_associate(self, async_client: AsyncTelnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
await async_client.enterprises.reputation.numbers.with_raw_response.associate(
enterprise_id="",
- phone_numbers=["+16035551234"],
+ phone_numbers=["+19493253498", "+12134445566"],
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_disassociate(self, async_client: AsyncTelnyx) -> None:
number = await async_client.enterprises.reputation.numbers.disassociate(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert number is None
@@ -431,8 +462,8 @@ async def test_method_disassociate(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_raw_response_disassociate(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.reputation.numbers.with_raw_response.disassociate(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -444,8 +475,8 @@ async def test_raw_response_disassociate(self, async_client: AsyncTelnyx) -> Non
@parametrize
async def test_streaming_response_disassociate(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.reputation.numbers.with_streaming_response.disassociate(
- phone_number="+16035551234",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ phone_number="+19493253498",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -460,12 +491,58 @@ async def test_streaming_response_disassociate(self, async_client: AsyncTelnyx)
async def test_path_params_disassociate(self, async_client: AsyncTelnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
await async_client.enterprises.reputation.numbers.with_raw_response.disassociate(
- phone_number="+16035551234",
+ phone_number="+19493253498",
enterprise_id="",
)
with pytest.raises(ValueError, match=r"Expected a non-empty value for `phone_number` but received ''"):
await async_client.enterprises.reputation.numbers.with_raw_response.disassociate(
phone_number="",
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_refresh(self, async_client: AsyncTelnyx) -> None:
+ number = await async_client.enterprises.reputation.numbers.refresh(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498"],
+ )
+ assert_matches_type(NumberRefreshResponse, number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_refresh(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.enterprises.reputation.numbers.with_raw_response.refresh(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ number = await response.parse()
+ assert_matches_type(NumberRefreshResponse, number, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_refresh(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.enterprises.reputation.numbers.with_streaming_response.refresh(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ phone_numbers=["+19493253498"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ number = await response.parse()
+ assert_matches_type(NumberRefreshResponse, 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_refresh(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ await async_client.enterprises.reputation.numbers.with_raw_response.refresh(
+ enterprise_id="",
+ phone_numbers=["+19493253498"],
)
diff --git a/tests/api_resources/enterprises/test_dir.py b/tests/api_resources/enterprises/test_dir.py
new file mode 100644
index 00000000..c0056cb6
--- /dev/null
+++ b/tests/api_resources/enterprises/test_dir.py
@@ -0,0 +1,322 @@
+# 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.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+from telnyx.types.enterprises import DirListResponse, DirCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestDir:
+ 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_create(self, client: Telnyx) -> None:
+ dir = client.enterprises.dir.create(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ )
+ assert_matches_type(DirCreateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_create_with_all_params(self, client: Telnyx) -> None:
+ dir = client.enterprises.dir.create(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ call_reasons=["Appointment reminders", "Billing inquiries"],
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "business_registration",
+ "description": "Certificate of incorporation.",
+ }
+ ],
+ logo_url="https://acmeplumbing.example.com/logo-256.bmp",
+ reselling=False,
+ )
+ assert_matches_type(DirCreateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_create(self, client: Telnyx) -> None:
+ response = client.enterprises.dir.with_raw_response.create(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(DirCreateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_create(self, client: Telnyx) -> None:
+ with client.enterprises.dir.with_streaming_response.create(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(DirCreateResponse, dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_create(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ client.enterprises.dir.with_raw_response.create(
+ enterprise_id="",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Telnyx) -> None:
+ dir = client.enterprises.dir.list(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+ assert_matches_type(SyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Telnyx) -> None:
+ dir = client.enterprises.dir.list(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ filter_expiring_at_gte=parse_datetime("2019-12-27T18:11:19.117Z"),
+ filter_expiring_at_lte=parse_datetime("2019-12-27T18:11:19.117Z"),
+ filter_expiring_within_days=1,
+ page_number=1,
+ page_size=20,
+ search="search",
+ sort="created_at",
+ status="draft",
+ )
+ assert_matches_type(SyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Telnyx) -> None:
+ response = client.enterprises.dir.with_raw_response.list(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Telnyx) -> None:
+ with client.enterprises.dir.with_streaming_response.list(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_list(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ client.enterprises.dir.with_raw_response.list(
+ enterprise_id="",
+ )
+
+
+class TestAsyncDir:
+ 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_create(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.enterprises.dir.create(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ )
+ assert_matches_type(DirCreateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.enterprises.dir.create(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ call_reasons=["Appointment reminders", "Billing inquiries"],
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "business_registration",
+ "description": "Certificate of incorporation.",
+ }
+ ],
+ logo_url="https://acmeplumbing.example.com/logo-256.bmp",
+ reselling=False,
+ )
+ assert_matches_type(DirCreateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_create(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.enterprises.dir.with_raw_response.create(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(DirCreateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_create(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.enterprises.dir.with_streaming_response.create(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(DirCreateResponse, dir, 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_create(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ await async_client.enterprises.dir.with_raw_response.create(
+ enterprise_id="",
+ authorizer_email="sam@acmeplumbing.example.com",
+ authorizer_name="Sam Owner",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_shaft_content=True,
+ display_name="Acme Plumbing",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.enterprises.dir.list(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[DirListResponse], dir, 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:
+ dir = await async_client.enterprises.dir.list(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ filter_expiring_at_gte=parse_datetime("2019-12-27T18:11:19.117Z"),
+ filter_expiring_at_lte=parse_datetime("2019-12-27T18:11:19.117Z"),
+ filter_expiring_within_days=1,
+ page_number=1,
+ page_size=20,
+ search="search",
+ sort="created_at",
+ status="draft",
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[DirListResponse], dir, 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.enterprises.dir.with_raw_response.list(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[DirListResponse], dir, 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.enterprises.dir.with_streaming_response.list(
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[DirListResponse], dir, 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_list(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ await async_client.enterprises.dir.with_raw_response.list(
+ enterprise_id="",
+ )
diff --git a/tests/api_resources/enterprises/test_reputation.py b/tests/api_resources/enterprises/test_reputation.py
index 50b78d98..09254b23 100644
--- a/tests/api_resources/enterprises/test_reputation.py
+++ b/tests/api_resources/enterprises/test_reputation.py
@@ -25,7 +25,7 @@ class TestReputation:
@parametrize
def test_method_retrieve(self, client: Telnyx) -> None:
reputation = client.enterprises.reputation.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert_matches_type(ReputationRetrieveResponse, reputation, path=["response"])
@@ -33,7 +33,7 @@ def test_method_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_retrieve(self, client: Telnyx) -> None:
response = client.enterprises.reputation.with_raw_response.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -45,7 +45,7 @@ def test_raw_response_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: Telnyx) -> None:
with client.enterprises.reputation.with_streaming_response.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -67,7 +67,7 @@ def test_path_params_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_method_disable(self, client: Telnyx) -> None:
reputation = client.enterprises.reputation.disable(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert reputation is None
@@ -75,7 +75,7 @@ def test_method_disable(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_disable(self, client: Telnyx) -> None:
response = client.enterprises.reputation.with_raw_response.disable(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -87,7 +87,7 @@ def test_raw_response_disable(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_disable(self, client: Telnyx) -> None:
with client.enterprises.reputation.with_streaming_response.disable(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -109,8 +109,8 @@ def test_path_params_disable(self, client: Telnyx) -> None:
@parametrize
def test_method_enable(self, client: Telnyx) -> None:
reputation = client.enterprises.reputation.enable(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
)
assert_matches_type(ReputationEnableResponse, reputation, path=["response"])
@@ -118,8 +118,8 @@ def test_method_enable(self, client: Telnyx) -> None:
@parametrize
def test_method_enable_with_all_params(self, client: Telnyx) -> None:
reputation = client.enterprises.reputation.enable(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
check_frequency="business_daily",
)
assert_matches_type(ReputationEnableResponse, reputation, path=["response"])
@@ -128,8 +128,8 @@ def test_method_enable_with_all_params(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_enable(self, client: Telnyx) -> None:
response = client.enterprises.reputation.with_raw_response.enable(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
)
assert response.is_closed is True
@@ -141,8 +141,8 @@ def test_raw_response_enable(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_enable(self, client: Telnyx) -> None:
with client.enterprises.reputation.with_streaming_response.enable(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -158,15 +158,15 @@ def test_path_params_enable(self, client: Telnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
client.enterprises.reputation.with_raw_response.enable(
enterprise_id="",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_update_frequency(self, client: Telnyx) -> None:
reputation = client.enterprises.reputation.update_frequency(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- check_frequency="business_daily",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ check_frequency="weekly",
)
assert_matches_type(ReputationUpdateFrequencyResponse, reputation, path=["response"])
@@ -174,8 +174,8 @@ def test_method_update_frequency(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_update_frequency(self, client: Telnyx) -> None:
response = client.enterprises.reputation.with_raw_response.update_frequency(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- check_frequency="business_daily",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ check_frequency="weekly",
)
assert response.is_closed is True
@@ -187,8 +187,8 @@ def test_raw_response_update_frequency(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_update_frequency(self, client: Telnyx) -> None:
with client.enterprises.reputation.with_streaming_response.update_frequency(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- check_frequency="business_daily",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ check_frequency="weekly",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -204,7 +204,7 @@ def test_path_params_update_frequency(self, client: Telnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
client.enterprises.reputation.with_raw_response.update_frequency(
enterprise_id="",
- check_frequency="business_daily",
+ check_frequency="weekly",
)
@@ -217,7 +217,7 @@ class TestAsyncReputation:
@parametrize
async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
reputation = await async_client.enterprises.reputation.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert_matches_type(ReputationRetrieveResponse, reputation, path=["response"])
@@ -225,7 +225,7 @@ async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.reputation.with_raw_response.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -237,7 +237,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.reputation.with_streaming_response.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -259,7 +259,7 @@ async def test_path_params_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_disable(self, async_client: AsyncTelnyx) -> None:
reputation = await async_client.enterprises.reputation.disable(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert reputation is None
@@ -267,7 +267,7 @@ async def test_method_disable(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_raw_response_disable(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.reputation.with_raw_response.disable(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -279,7 +279,7 @@ async def test_raw_response_disable(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_disable(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.reputation.with_streaming_response.disable(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -301,8 +301,8 @@ async def test_path_params_disable(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_enable(self, async_client: AsyncTelnyx) -> None:
reputation = await async_client.enterprises.reputation.enable(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
)
assert_matches_type(ReputationEnableResponse, reputation, path=["response"])
@@ -310,8 +310,8 @@ async def test_method_enable(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_enable_with_all_params(self, async_client: AsyncTelnyx) -> None:
reputation = await async_client.enterprises.reputation.enable(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
check_frequency="business_daily",
)
assert_matches_type(ReputationEnableResponse, reputation, path=["response"])
@@ -320,8 +320,8 @@ async def test_method_enable_with_all_params(self, async_client: AsyncTelnyx) ->
@parametrize
async def test_raw_response_enable(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.reputation.with_raw_response.enable(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
)
assert response.is_closed is True
@@ -333,8 +333,8 @@ async def test_raw_response_enable(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_enable(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.reputation.with_streaming_response.enable(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -350,15 +350,15 @@ async def test_path_params_enable(self, async_client: AsyncTelnyx) -> None:
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
await async_client.enterprises.reputation.with_raw_response.enable(
enterprise_id="",
- loa_document_id="doc_01HXYZ1234ABCDEF",
+ loa_document_id="2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_method_update_frequency(self, async_client: AsyncTelnyx) -> None:
reputation = await async_client.enterprises.reputation.update_frequency(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- check_frequency="business_daily",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ check_frequency="weekly",
)
assert_matches_type(ReputationUpdateFrequencyResponse, reputation, path=["response"])
@@ -366,8 +366,8 @@ async def test_method_update_frequency(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_raw_response_update_frequency(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.reputation.with_raw_response.update_frequency(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- check_frequency="business_daily",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ check_frequency="weekly",
)
assert response.is_closed is True
@@ -379,8 +379,8 @@ async def test_raw_response_update_frequency(self, async_client: AsyncTelnyx) ->
@parametrize
async def test_streaming_response_update_frequency(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.reputation.with_streaming_response.update_frequency(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
- check_frequency="business_daily",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
+ check_frequency="weekly",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -396,5 +396,5 @@ async def test_path_params_update_frequency(self, async_client: AsyncTelnyx) ->
with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
await async_client.enterprises.reputation.with_raw_response.update_frequency(
enterprise_id="",
- check_frequency="business_daily",
+ check_frequency="weekly",
)
diff --git a/tests/api_resources/reputation/test_numbers.py b/tests/api_resources/reputation/test_numbers.py
index e94b9fc6..23c1bed3 100644
--- a/tests/api_resources/reputation/test_numbers.py
+++ b/tests/api_resources/reputation/test_numbers.py
@@ -10,8 +10,10 @@
from telnyx import Telnyx, AsyncTelnyx
from tests.utils import assert_matches_type
from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
-from telnyx.types.shared import ReputationPhoneNumberWithReputationData
-from telnyx.types.reputation import NumberRetrieveResponse
+from telnyx.types.reputation import (
+ NumberListResponse,
+ NumberRetrieveResponse,
+)
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -23,7 +25,7 @@ class TestNumbers:
@parametrize
def test_method_retrieve(self, client: Telnyx) -> None:
number = client.reputation.numbers.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
)
assert_matches_type(NumberRetrieveResponse, number, path=["response"])
@@ -31,7 +33,7 @@ def test_method_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_method_retrieve_with_all_params(self, client: Telnyx) -> None:
number = client.reputation.numbers.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
fresh=True,
)
assert_matches_type(NumberRetrieveResponse, number, path=["response"])
@@ -40,7 +42,7 @@ def test_method_retrieve_with_all_params(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_retrieve(self, client: Telnyx) -> None:
response = client.reputation.numbers.with_raw_response.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
)
assert response.is_closed is True
@@ -52,7 +54,7 @@ def test_raw_response_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: Telnyx) -> None:
with client.reputation.numbers.with_streaming_response.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -74,21 +76,17 @@ def test_path_params_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_method_list(self, client: Telnyx) -> None:
number = client.reputation.numbers.list()
- assert_matches_type(
- SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(SyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_method_list_with_all_params(self, client: Telnyx) -> None:
number = client.reputation.numbers.list(
page_number=1,
- page_size=1,
+ page_size=20,
phone_number="+16035551234",
)
- assert_matches_type(
- SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(SyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -98,9 +96,7 @@ def test_raw_response_list(self, client: Telnyx) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number = response.parse()
- assert_matches_type(
- SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(SyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -110,9 +106,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number = response.parse()
- assert_matches_type(
- SyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(SyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -120,7 +114,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None:
@parametrize
def test_method_delete(self, client: Telnyx) -> None:
number = client.reputation.numbers.delete(
- "+16035551234",
+ "+19493253498",
)
assert number is None
@@ -128,7 +122,7 @@ def test_method_delete(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_delete(self, client: Telnyx) -> None:
response = client.reputation.numbers.with_raw_response.delete(
- "+16035551234",
+ "+19493253498",
)
assert response.is_closed is True
@@ -140,7 +134,7 @@ def test_raw_response_delete(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_delete(self, client: Telnyx) -> None:
with client.reputation.numbers.with_streaming_response.delete(
- "+16035551234",
+ "+19493253498",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -168,7 +162,7 @@ class TestAsyncNumbers:
@parametrize
async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
number = await async_client.reputation.numbers.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
)
assert_matches_type(NumberRetrieveResponse, number, path=["response"])
@@ -176,7 +170,7 @@ async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_retrieve_with_all_params(self, async_client: AsyncTelnyx) -> None:
number = await async_client.reputation.numbers.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
fresh=True,
)
assert_matches_type(NumberRetrieveResponse, number, path=["response"])
@@ -185,7 +179,7 @@ async def test_method_retrieve_with_all_params(self, async_client: AsyncTelnyx)
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
response = await async_client.reputation.numbers.with_raw_response.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
)
assert response.is_closed is True
@@ -197,7 +191,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncTelnyx) -> None:
async with async_client.reputation.numbers.with_streaming_response.retrieve(
- phone_number="+16035551234",
+ phone_number="+19493253498",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -219,21 +213,17 @@ async def test_path_params_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_list(self, async_client: AsyncTelnyx) -> None:
number = await async_client.reputation.numbers.list()
- assert_matches_type(
- AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(AsyncDefaultFlatPagination[NumberListResponse], number, 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:
number = await async_client.reputation.numbers.list(
page_number=1,
- page_size=1,
+ page_size=20,
phone_number="+16035551234",
)
- assert_matches_type(
- AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(AsyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -243,9 +233,7 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number = await response.parse()
- assert_matches_type(
- AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(AsyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -255,9 +243,7 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number = await response.parse()
- assert_matches_type(
- AsyncDefaultFlatPagination[ReputationPhoneNumberWithReputationData], number, path=["response"]
- )
+ assert_matches_type(AsyncDefaultFlatPagination[NumberListResponse], number, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -265,7 +251,7 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_delete(self, async_client: AsyncTelnyx) -> None:
number = await async_client.reputation.numbers.delete(
- "+16035551234",
+ "+19493253498",
)
assert number is None
@@ -273,7 +259,7 @@ async def test_method_delete(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_raw_response_delete(self, async_client: AsyncTelnyx) -> None:
response = await async_client.reputation.numbers.with_raw_response.delete(
- "+16035551234",
+ "+19493253498",
)
assert response.is_closed is True
@@ -285,7 +271,7 @@ async def test_raw_response_delete(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncTelnyx) -> None:
async with async_client.reputation.numbers.with_streaming_response.delete(
- "+16035551234",
+ "+19493253498",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
diff --git a/tests/api_resources/terms_of_service/test_agreements.py b/tests/api_resources/terms_of_service/test_agreements.py
new file mode 100644
index 00000000..1722ab6d
--- /dev/null
+++ b/tests/api_resources/terms_of_service/test_agreements.py
@@ -0,0 +1,185 @@
+# 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.terms_of_service import AgreementListResponse, AgreementRetrieveResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestAgreements:
+ 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:
+ agreement = client.terms_of_service.agreements.retrieve(
+ "550e8400-e29b-41d4-a716-446655440000",
+ )
+ assert_matches_type(AgreementRetrieveResponse, agreement, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: Telnyx) -> None:
+ response = client.terms_of_service.agreements.with_raw_response.retrieve(
+ "550e8400-e29b-41d4-a716-446655440000",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ agreement = response.parse()
+ assert_matches_type(AgreementRetrieveResponse, agreement, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Telnyx) -> None:
+ with client.terms_of_service.agreements.with_streaming_response.retrieve(
+ "550e8400-e29b-41d4-a716-446655440000",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ agreement = response.parse()
+ assert_matches_type(AgreementRetrieveResponse, agreement, 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 `agreement_id` but received ''"):
+ client.terms_of_service.agreements.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Telnyx) -> None:
+ agreement = client.terms_of_service.agreements.list()
+ assert_matches_type(SyncDefaultFlatPagination[AgreementListResponse], agreement, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Telnyx) -> None:
+ agreement = client.terms_of_service.agreements.list(
+ page_number=1,
+ page_size=20,
+ product_type="branded_calling",
+ )
+ assert_matches_type(SyncDefaultFlatPagination[AgreementListResponse], agreement, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Telnyx) -> None:
+ response = client.terms_of_service.agreements.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ agreement = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[AgreementListResponse], agreement, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Telnyx) -> None:
+ with client.terms_of_service.agreements.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ agreement = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[AgreementListResponse], agreement, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncAgreements:
+ 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:
+ agreement = await async_client.terms_of_service.agreements.retrieve(
+ "550e8400-e29b-41d4-a716-446655440000",
+ )
+ assert_matches_type(AgreementRetrieveResponse, agreement, 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.terms_of_service.agreements.with_raw_response.retrieve(
+ "550e8400-e29b-41d4-a716-446655440000",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ agreement = await response.parse()
+ assert_matches_type(AgreementRetrieveResponse, agreement, 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.terms_of_service.agreements.with_streaming_response.retrieve(
+ "550e8400-e29b-41d4-a716-446655440000",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ agreement = await response.parse()
+ assert_matches_type(AgreementRetrieveResponse, agreement, 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 `agreement_id` but received ''"):
+ await async_client.terms_of_service.agreements.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncTelnyx) -> None:
+ agreement = await async_client.terms_of_service.agreements.list()
+ assert_matches_type(AsyncDefaultFlatPagination[AgreementListResponse], agreement, 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:
+ agreement = await async_client.terms_of_service.agreements.list(
+ page_number=1,
+ page_size=20,
+ product_type="branded_calling",
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[AgreementListResponse], agreement, 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.terms_of_service.agreements.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ agreement = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[AgreementListResponse], agreement, 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.terms_of_service.agreements.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ agreement = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[AgreementListResponse], agreement, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/terms_of_service/test_branded_calling.py b/tests/api_resources/terms_of_service/test_branded_calling.py
new file mode 100644
index 00000000..932fd585
--- /dev/null
+++ b/tests/api_resources/terms_of_service/test_branded_calling.py
@@ -0,0 +1,80 @@
+# 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.types.terms_of_service import BrandedCallingAgreeResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestBrandedCalling:
+ 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_agree(self, client: Telnyx) -> None:
+ branded_calling = client.terms_of_service.branded_calling.agree()
+ assert_matches_type(BrandedCallingAgreeResponse, branded_calling, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_agree(self, client: Telnyx) -> None:
+ response = client.terms_of_service.branded_calling.with_raw_response.agree()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ branded_calling = response.parse()
+ assert_matches_type(BrandedCallingAgreeResponse, branded_calling, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_agree(self, client: Telnyx) -> None:
+ with client.terms_of_service.branded_calling.with_streaming_response.agree() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ branded_calling = response.parse()
+ assert_matches_type(BrandedCallingAgreeResponse, branded_calling, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncBrandedCalling:
+ 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_agree(self, async_client: AsyncTelnyx) -> None:
+ branded_calling = await async_client.terms_of_service.branded_calling.agree()
+ assert_matches_type(BrandedCallingAgreeResponse, branded_calling, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_agree(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.terms_of_service.branded_calling.with_raw_response.agree()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ branded_calling = await response.parse()
+ assert_matches_type(BrandedCallingAgreeResponse, branded_calling, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_agree(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.terms_of_service.branded_calling.with_streaming_response.agree() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ branded_calling = await response.parse()
+ assert_matches_type(BrandedCallingAgreeResponse, branded_calling, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/terms_of_service/test_number_reputation.py b/tests/api_resources/terms_of_service/test_number_reputation.py
index 79b859d7..08542453 100644
--- a/tests/api_resources/terms_of_service/test_number_reputation.py
+++ b/tests/api_resources/terms_of_service/test_number_reputation.py
@@ -8,6 +8,8 @@
import pytest
from telnyx import Telnyx, AsyncTelnyx
+from tests.utils import assert_matches_type
+from telnyx.types.terms_of_service import NumberReputationAgreeResponse
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -19,7 +21,7 @@ class TestNumberReputation:
@parametrize
def test_method_agree(self, client: Telnyx) -> None:
number_reputation = client.terms_of_service.number_reputation.agree()
- assert number_reputation is None
+ assert_matches_type(NumberReputationAgreeResponse, number_reputation, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -29,7 +31,7 @@ def test_raw_response_agree(self, client: Telnyx) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number_reputation = response.parse()
- assert number_reputation is None
+ assert_matches_type(NumberReputationAgreeResponse, number_reputation, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -39,7 +41,7 @@ def test_streaming_response_agree(self, client: Telnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number_reputation = response.parse()
- assert number_reputation is None
+ assert_matches_type(NumberReputationAgreeResponse, number_reputation, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -53,7 +55,7 @@ class TestAsyncNumberReputation:
@parametrize
async def test_method_agree(self, async_client: AsyncTelnyx) -> None:
number_reputation = await async_client.terms_of_service.number_reputation.agree()
- assert number_reputation is None
+ assert_matches_type(NumberReputationAgreeResponse, number_reputation, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -63,7 +65,7 @@ async def test_raw_response_agree(self, async_client: AsyncTelnyx) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number_reputation = await response.parse()
- assert number_reputation is None
+ assert_matches_type(NumberReputationAgreeResponse, number_reputation, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -73,6 +75,6 @@ async def test_streaming_response_agree(self, async_client: AsyncTelnyx) -> None
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
number_reputation = await response.parse()
- assert number_reputation is None
+ assert_matches_type(NumberReputationAgreeResponse, number_reputation, path=["response"])
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_call_reasons.py b/tests/api_resources/test_call_reasons.py
new file mode 100644
index 00000000..09c9fa78
--- /dev/null
+++ b/tests/api_resources/test_call_reasons.py
@@ -0,0 +1,170 @@
+# 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.types import (
+ CallReasonListResponse,
+ CallReasonValidateResponse,
+)
+from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestCallReasons:
+ 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_list(self, client: Telnyx) -> None:
+ call_reason = client.call_reasons.list()
+ assert_matches_type(SyncDefaultFlatPagination[CallReasonListResponse], call_reason, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Telnyx) -> None:
+ call_reason = client.call_reasons.list(
+ page_number=1,
+ page_size=100,
+ )
+ assert_matches_type(SyncDefaultFlatPagination[CallReasonListResponse], call_reason, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Telnyx) -> None:
+ response = client.call_reasons.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ call_reason = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[CallReasonListResponse], call_reason, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Telnyx) -> None:
+ with client.call_reasons.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ call_reason = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[CallReasonListResponse], call_reason, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_validate(self, client: Telnyx) -> None:
+ call_reason = client.call_reasons.validate(
+ body=["Appointment reminders", "Billing inquiries"],
+ )
+ assert_matches_type(CallReasonValidateResponse, call_reason, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_validate(self, client: Telnyx) -> None:
+ response = client.call_reasons.with_raw_response.validate(
+ body=["Appointment reminders", "Billing inquiries"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ call_reason = response.parse()
+ assert_matches_type(CallReasonValidateResponse, call_reason, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_validate(self, client: Telnyx) -> None:
+ with client.call_reasons.with_streaming_response.validate(
+ body=["Appointment reminders", "Billing inquiries"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ call_reason = response.parse()
+ assert_matches_type(CallReasonValidateResponse, call_reason, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncCallReasons:
+ 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_list(self, async_client: AsyncTelnyx) -> None:
+ call_reason = await async_client.call_reasons.list()
+ assert_matches_type(AsyncDefaultFlatPagination[CallReasonListResponse], call_reason, 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:
+ call_reason = await async_client.call_reasons.list(
+ page_number=1,
+ page_size=100,
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[CallReasonListResponse], call_reason, 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.call_reasons.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ call_reason = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[CallReasonListResponse], call_reason, 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.call_reasons.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ call_reason = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[CallReasonListResponse], call_reason, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_validate(self, async_client: AsyncTelnyx) -> None:
+ call_reason = await async_client.call_reasons.validate(
+ body=["Appointment reminders", "Billing inquiries"],
+ )
+ assert_matches_type(CallReasonValidateResponse, call_reason, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_validate(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.call_reasons.with_raw_response.validate(
+ body=["Appointment reminders", "Billing inquiries"],
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ call_reason = await response.parse()
+ assert_matches_type(CallReasonValidateResponse, call_reason, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_validate(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.call_reasons.with_streaming_response.validate(
+ body=["Appointment reminders", "Billing inquiries"],
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ call_reason = await response.parse()
+ assert_matches_type(CallReasonValidateResponse, call_reason, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_dir.py b/tests/api_resources/test_dir.py
new file mode 100644
index 00000000..93a88091
--- /dev/null
+++ b/tests/api_resources/test_dir.py
@@ -0,0 +1,814 @@
+# 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.types import (
+ DirListResponse,
+ DirSubmitResponse,
+ DirUpdateResponse,
+ DirRetrieveResponse,
+ DirListDocumentTypesResponse,
+ DirUpdateInfringementResponse,
+ DirListInfringementClaimsResponse,
+)
+from telnyx._utils import parse_datetime
+from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestDir:
+ 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:
+ dir = client.dir.retrieve(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(DirRetrieveResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: Telnyx) -> None:
+ response = client.dir.with_raw_response.retrieve(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(DirRetrieveResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Telnyx) -> None:
+ with client.dir.with_streaming_response.retrieve(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(DirRetrieveResponse, dir, 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 `dir_id` but received ''"):
+ client.dir.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update(self, client: Telnyx) -> None:
+ dir = client.dir.update(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(DirUpdateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update_with_all_params(self, client: Telnyx) -> None:
+ dir = client.dir.update(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ authorizer_email="dev@stainless.com",
+ authorizer_name="authorizer_name",
+ call_reasons=["Appointment reminders", "Billing inquiries", "Lab results"],
+ display_name="Acme Plumbing & Wellness",
+ logo_url="https://acmeplumbing.example.com/logo-v2-256.bmp",
+ reselling=True,
+ )
+ assert_matches_type(DirUpdateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_update(self, client: Telnyx) -> None:
+ response = client.dir.with_raw_response.update(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(DirUpdateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_update(self, client: Telnyx) -> None:
+ with client.dir.with_streaming_response.update(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(DirUpdateResponse, dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_update(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.with_raw_response.update(
+ dir_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list(self, client: Telnyx) -> None:
+ dir = client.dir.list()
+ assert_matches_type(SyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_with_all_params(self, client: Telnyx) -> None:
+ dir = client.dir.list(
+ enterprise_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ filter_expiring_at_gte=parse_datetime("2019-12-27T18:11:19.117Z"),
+ filter_expiring_at_lte=parse_datetime("2019-12-27T18:11:19.117Z"),
+ page_number=1,
+ page_size=20,
+ search="search",
+ sort="created_at",
+ status="draft",
+ )
+ assert_matches_type(SyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list(self, client: Telnyx) -> None:
+ response = client.dir.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list(self, client: Telnyx) -> None:
+ with client.dir.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_delete(self, client: Telnyx) -> None:
+ dir = client.dir.delete(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert dir is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_delete(self, client: Telnyx) -> None:
+ response = client.dir.with_raw_response.delete(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert dir is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_delete(self, client: Telnyx) -> None:
+ with client.dir.with_streaming_response.delete(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert dir is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_delete(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.with_raw_response.delete(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_document_types(self, client: Telnyx) -> None:
+ dir = client.dir.list_document_types()
+ assert_matches_type(DirListDocumentTypesResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list_document_types(self, client: Telnyx) -> None:
+ response = client.dir.with_raw_response.list_document_types()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(DirListDocumentTypesResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list_document_types(self, client: Telnyx) -> None:
+ with client.dir.with_streaming_response.list_document_types() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(DirListDocumentTypesResponse, dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_infringement_claims(self, client: Telnyx) -> None:
+ dir = client.dir.list_infringement_claims(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(SyncDefaultFlatPagination[DirListInfringementClaimsResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_list_infringement_claims_with_all_params(self, client: Telnyx) -> None:
+ dir = client.dir.list_infringement_claims(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ page_number=1,
+ page_size=20,
+ )
+ assert_matches_type(SyncDefaultFlatPagination[DirListInfringementClaimsResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_list_infringement_claims(self, client: Telnyx) -> None:
+ response = client.dir.with_raw_response.list_infringement_claims(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[DirListInfringementClaimsResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_list_infringement_claims(self, client: Telnyx) -> None:
+ with client.dir.with_streaming_response.list_infringement_claims(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(SyncDefaultFlatPagination[DirListInfringementClaimsResponse], dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_list_infringement_claims(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.with_raw_response.list_infringement_claims(
+ dir_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_submit(self, client: Telnyx) -> None:
+ dir = client.dir.submit(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(DirSubmitResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_submit(self, client: Telnyx) -> None:
+ response = client.dir.with_raw_response.submit(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(DirSubmitResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_submit(self, client: Telnyx) -> None:
+ with client.dir.with_streaming_response.submit(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(DirSubmitResponse, dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_submit(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.with_raw_response.submit(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update_infringement(self, client: Telnyx) -> None:
+ dir = client.dir.update_infringement(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ )
+ assert_matches_type(DirUpdateInfringementResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update_infringement_with_all_params(self, client: Telnyx) -> None:
+ dir = client.dir.update_infringement(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ call_reasons=["string"],
+ display_name="x",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "business_registration",
+ "description": "Certificate of incorporation.",
+ }
+ ],
+ logo_url="logo_url",
+ )
+ assert_matches_type(DirUpdateInfringementResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_update_infringement(self, client: Telnyx) -> None:
+ response = client.dir.with_raw_response.update_infringement(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = response.parse()
+ assert_matches_type(DirUpdateInfringementResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_update_infringement(self, client: Telnyx) -> None:
+ with client.dir.with_streaming_response.update_infringement(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = response.parse()
+ assert_matches_type(DirUpdateInfringementResponse, dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_update_infringement(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ client.dir.with_raw_response.update_infringement(
+ dir_id="",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ )
+
+
+class TestAsyncDir:
+ 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:
+ dir = await async_client.dir.retrieve(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(DirRetrieveResponse, dir, 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.dir.with_raw_response.retrieve(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(DirRetrieveResponse, dir, 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.dir.with_streaming_response.retrieve(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(DirRetrieveResponse, dir, 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 `dir_id` but received ''"):
+ await async_client.dir.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.update(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(DirUpdateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.update(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ authorizer_email="dev@stainless.com",
+ authorizer_name="authorizer_name",
+ call_reasons=["Appointment reminders", "Billing inquiries", "Lab results"],
+ display_name="Acme Plumbing & Wellness",
+ logo_url="https://acmeplumbing.example.com/logo-v2-256.bmp",
+ reselling=True,
+ )
+ assert_matches_type(DirUpdateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.with_raw_response.update(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(DirUpdateResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.with_streaming_response.update(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(DirUpdateResponse, dir, 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_update(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.with_raw_response.update(
+ dir_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.list()
+ assert_matches_type(AsyncDefaultFlatPagination[DirListResponse], dir, 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:
+ dir = await async_client.dir.list(
+ enterprise_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ filter_expiring_at_gte=parse_datetime("2019-12-27T18:11:19.117Z"),
+ filter_expiring_at_lte=parse_datetime("2019-12-27T18:11:19.117Z"),
+ page_number=1,
+ page_size=20,
+ search="search",
+ sort="created_at",
+ status="draft",
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[DirListResponse], dir, 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.dir.with_raw_response.list()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[DirListResponse], dir, 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.dir.with_streaming_response.list() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[DirListResponse], dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_delete(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.delete(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert dir is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_delete(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.with_raw_response.delete(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert dir is None
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_delete(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.with_streaming_response.delete(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert dir is None
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_delete(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.with_raw_response.delete(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_document_types(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.list_document_types()
+ assert_matches_type(DirListDocumentTypesResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list_document_types(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.with_raw_response.list_document_types()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(DirListDocumentTypesResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list_document_types(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.with_streaming_response.list_document_types() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(DirListDocumentTypesResponse, dir, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_infringement_claims(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.list_infringement_claims(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[DirListInfringementClaimsResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_list_infringement_claims_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.list_infringement_claims(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ page_number=1,
+ page_size=20,
+ )
+ assert_matches_type(AsyncDefaultFlatPagination[DirListInfringementClaimsResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_list_infringement_claims(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.with_raw_response.list_infringement_claims(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[DirListInfringementClaimsResponse], dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_list_infringement_claims(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.with_streaming_response.list_infringement_claims(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(AsyncDefaultFlatPagination[DirListInfringementClaimsResponse], dir, 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_list_infringement_claims(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.with_raw_response.list_infringement_claims(
+ dir_id="",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_submit(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.submit(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+ assert_matches_type(DirSubmitResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_submit(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.with_raw_response.submit(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(DirSubmitResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_submit(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.with_streaming_response.submit(
+ "16635d38-75a6-4481-82e8-69af60e05011",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(DirSubmitResponse, dir, 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_submit(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.with_raw_response.submit(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update_infringement(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.update_infringement(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ )
+ assert_matches_type(DirUpdateInfringementResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update_infringement_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ dir = await async_client.dir.update_infringement(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ call_reasons=["string"],
+ display_name="x",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "business_registration",
+ "description": "Certificate of incorporation.",
+ }
+ ],
+ logo_url="logo_url",
+ )
+ assert_matches_type(DirUpdateInfringementResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_update_infringement(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.dir.with_raw_response.update_infringement(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ dir = await response.parse()
+ assert_matches_type(DirUpdateInfringementResponse, dir, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_update_infringement(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.dir.with_streaming_response.update_infringement(
+ dir_id="16635d38-75a6-4481-82e8-69af60e05011",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ dir = await response.parse()
+ assert_matches_type(DirUpdateInfringementResponse, dir, 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_update_infringement(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `dir_id` but received ''"):
+ await async_client.dir.with_raw_response.update_infringement(
+ dir_id="",
+ certify_brand_is_accurate=True,
+ certify_ip_ownership=True,
+ certify_no_infringement=True,
+ certify_no_shaft_content=True,
+ infringement_resolution_notes="Updated the display name to remove the disputed mark and re-uploaded the authorization.",
+ )
diff --git a/tests/api_resources/test_enterprises.py b/tests/api_resources/test_enterprises.py
index 63971370..bf7c4e54 100644
--- a/tests/api_resources/test_enterprises.py
+++ b/tests/api_resources/test_enterprises.py
@@ -14,6 +14,7 @@
EnterpriseCreateResponse,
EnterpriseUpdateResponse,
EnterpriseRetrieveResponse,
+ EnterpriseActivateBrandedCallingResponse,
)
from telnyx.pagination import SyncDefaultFlatPagination, AsyncDefaultFlatPagination
@@ -28,41 +29,42 @@ class TestEnterprises:
def test_method_create(self, client: Telnyx) -> None:
enterprise = client.enterprises.create(
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@run065.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
country_code="US",
- doing_business_as="Acme",
+ doing_business_as="Run 065 Debug",
fein="12-3456789",
industry="technology",
- legal_name="Acme Corp Inc.",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Run 065 Debug Co",
number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "org@run065.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Org",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
organization_type="commercial",
- website="https://acme.com",
+ website="https://run065.example.com",
)
assert_matches_type(EnterpriseCreateResponse, enterprise, path=["response"])
@@ -71,47 +73,48 @@ def test_method_create(self, client: Telnyx) -> None:
def test_method_create_with_all_params(self, client: Telnyx) -> None:
enterprise = client.enterprises.create(
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
- "extended_address": "Suite 400",
+ "street_address": "100 Main St",
+ "extended_address": "Suite 504",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@run065.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
country_code="US",
- doing_business_as="Acme",
+ doing_business_as="Run 065 Debug",
fein="12-3456789",
industry="technology",
- legal_name="Acme Corp Inc.",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Run 065 Debug Co",
number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "org@run065.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Org",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
- "extended_address": "Suite 400",
+ "street_address": "100 Main St",
+ "extended_address": "Suite 504",
},
organization_type="commercial",
- website="https://acme.com",
+ website="https://run065.example.com",
corporate_registration_number="corporate_registration_number",
- customer_reference="customer_reference",
+ customer_reference="internal-id-12345",
dun_bradstreet_number="dun_bradstreet_number",
- primary_business_domain_sic_code="7372",
+ primary_business_domain_sic_code="primary_business_domain_sic_code",
professional_license_number="professional_license_number",
role_type="enterprise",
)
@@ -122,41 +125,42 @@ def test_method_create_with_all_params(self, client: Telnyx) -> None:
def test_raw_response_create(self, client: Telnyx) -> None:
response = client.enterprises.with_raw_response.create(
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@run065.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
country_code="US",
- doing_business_as="Acme",
+ doing_business_as="Run 065 Debug",
fein="12-3456789",
industry="technology",
- legal_name="Acme Corp Inc.",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Run 065 Debug Co",
number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "org@run065.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Org",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
organization_type="commercial",
- website="https://acme.com",
+ website="https://run065.example.com",
)
assert response.is_closed is True
@@ -169,41 +173,42 @@ def test_raw_response_create(self, client: Telnyx) -> None:
def test_streaming_response_create(self, client: Telnyx) -> None:
with client.enterprises.with_streaming_response.create(
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@run065.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
country_code="US",
- doing_business_as="Acme",
+ doing_business_as="Run 065 Debug",
fein="12-3456789",
industry="technology",
- legal_name="Acme Corp Inc.",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Run 065 Debug Co",
number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "org@run065.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Org",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
organization_type="commercial",
- website="https://acme.com",
+ website="https://run065.example.com",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -217,7 +222,7 @@ def test_streaming_response_create(self, client: Telnyx) -> None:
@parametrize
def test_method_retrieve(self, client: Telnyx) -> None:
enterprise = client.enterprises.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert_matches_type(EnterpriseRetrieveResponse, enterprise, path=["response"])
@@ -225,7 +230,7 @@ def test_method_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_retrieve(self, client: Telnyx) -> None:
response = client.enterprises.with_raw_response.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -237,7 +242,7 @@ def test_raw_response_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_retrieve(self, client: Telnyx) -> None:
with client.enterprises.with_streaming_response.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -259,7 +264,7 @@ def test_path_params_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_method_update(self, client: Telnyx) -> None:
enterprise = client.enterprises.update(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert_matches_type(EnterpriseUpdateResponse, enterprise, path=["response"])
@@ -267,48 +272,49 @@ def test_method_update(self, client: Telnyx) -> None:
@parametrize
def test_method_update_with_all_params(self, client: Telnyx) -> None:
enterprise = client.enterprises.update(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
- "extended_address": "Suite 400",
+ "street_address": "100 Main St",
+ "extended_address": "Suite 504",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@acmeplumbing.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
corporate_registration_number="corporate_registration_number",
- customer_reference="customer_reference",
- doing_business_as="doing_business_as",
+ customer_reference="internal-ref-2026Q2",
+ doing_business_as="Acme Plumbing",
dun_bradstreet_number="dun_bradstreet_number",
- fein="fein",
- industry="industry",
- legal_name="xxx",
- number_of_employees="1-10",
+ fein="12-3456789",
+ industry="business",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Acme Plumbing LLC",
+ number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "sam@acmeplumbing.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Owner",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
- "extended_address": "Suite 400",
+ "street_address": "100 Main St",
+ "extended_address": "Suite 504",
},
primary_business_domain_sic_code="primary_business_domain_sic_code",
professional_license_number="professional_license_number",
- website="website",
+ website="https://acmeplumbing.example.com",
)
assert_matches_type(EnterpriseUpdateResponse, enterprise, path=["response"])
@@ -316,7 +322,7 @@ def test_method_update_with_all_params(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_update(self, client: Telnyx) -> None:
response = client.enterprises.with_raw_response.update(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -328,7 +334,7 @@ def test_raw_response_update(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_update(self, client: Telnyx) -> None:
with client.enterprises.with_streaming_response.update(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -358,7 +364,7 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None:
enterprise = client.enterprises.list(
legal_name="Acme",
page_number=1,
- page_size=1,
+ page_size=10,
)
assert_matches_type(SyncDefaultFlatPagination[EnterprisePublic], enterprise, path=["response"])
@@ -388,7 +394,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None:
@parametrize
def test_method_delete(self, client: Telnyx) -> None:
enterprise = client.enterprises.delete(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert enterprise is None
@@ -396,7 +402,7 @@ def test_method_delete(self, client: Telnyx) -> None:
@parametrize
def test_raw_response_delete(self, client: Telnyx) -> None:
response = client.enterprises.with_raw_response.delete(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -408,7 +414,7 @@ def test_raw_response_delete(self, client: Telnyx) -> None:
@parametrize
def test_streaming_response_delete(self, client: Telnyx) -> None:
with client.enterprises.with_streaming_response.delete(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -426,6 +432,48 @@ def test_path_params_delete(self, client: Telnyx) -> None:
"",
)
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_activate_branded_calling(self, client: Telnyx) -> None:
+ enterprise = client.enterprises.activate_branded_calling(
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+ assert_matches_type(EnterpriseActivateBrandedCallingResponse, enterprise, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_activate_branded_calling(self, client: Telnyx) -> None:
+ response = client.enterprises.with_raw_response.activate_branded_calling(
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ enterprise = response.parse()
+ assert_matches_type(EnterpriseActivateBrandedCallingResponse, enterprise, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_activate_branded_calling(self, client: Telnyx) -> None:
+ with client.enterprises.with_streaming_response.activate_branded_calling(
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ enterprise = response.parse()
+ assert_matches_type(EnterpriseActivateBrandedCallingResponse, enterprise, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_activate_branded_calling(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ client.enterprises.with_raw_response.activate_branded_calling(
+ "",
+ )
+
class TestAsyncEnterprises:
parametrize = pytest.mark.parametrize(
@@ -437,41 +485,42 @@ class TestAsyncEnterprises:
async def test_method_create(self, async_client: AsyncTelnyx) -> None:
enterprise = await async_client.enterprises.create(
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@run065.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
country_code="US",
- doing_business_as="Acme",
+ doing_business_as="Run 065 Debug",
fein="12-3456789",
industry="technology",
- legal_name="Acme Corp Inc.",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Run 065 Debug Co",
number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "org@run065.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Org",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
organization_type="commercial",
- website="https://acme.com",
+ website="https://run065.example.com",
)
assert_matches_type(EnterpriseCreateResponse, enterprise, path=["response"])
@@ -480,47 +529,48 @@ async def test_method_create(self, async_client: AsyncTelnyx) -> None:
async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) -> None:
enterprise = await async_client.enterprises.create(
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
- "extended_address": "Suite 400",
+ "street_address": "100 Main St",
+ "extended_address": "Suite 504",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@run065.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
country_code="US",
- doing_business_as="Acme",
+ doing_business_as="Run 065 Debug",
fein="12-3456789",
industry="technology",
- legal_name="Acme Corp Inc.",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Run 065 Debug Co",
number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "org@run065.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Org",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
- "extended_address": "Suite 400",
+ "street_address": "100 Main St",
+ "extended_address": "Suite 504",
},
organization_type="commercial",
- website="https://acme.com",
+ website="https://run065.example.com",
corporate_registration_number="corporate_registration_number",
- customer_reference="customer_reference",
+ customer_reference="internal-id-12345",
dun_bradstreet_number="dun_bradstreet_number",
- primary_business_domain_sic_code="7372",
+ primary_business_domain_sic_code="primary_business_domain_sic_code",
professional_license_number="professional_license_number",
role_type="enterprise",
)
@@ -531,41 +581,42 @@ async def test_method_create_with_all_params(self, async_client: AsyncTelnyx) ->
async def test_raw_response_create(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.with_raw_response.create(
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@run065.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
country_code="US",
- doing_business_as="Acme",
+ doing_business_as="Run 065 Debug",
fein="12-3456789",
industry="technology",
- legal_name="Acme Corp Inc.",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Run 065 Debug Co",
number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "org@run065.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Org",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
organization_type="commercial",
- website="https://acme.com",
+ website="https://run065.example.com",
)
assert response.is_closed is True
@@ -578,41 +629,42 @@ async def test_raw_response_create(self, async_client: AsyncTelnyx) -> None:
async def test_streaming_response_create(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.with_streaming_response.create(
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@run065.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
country_code="US",
- doing_business_as="Acme",
+ doing_business_as="Run 065 Debug",
fein="12-3456789",
industry="technology",
- legal_name="Acme Corp Inc.",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Run 065 Debug Co",
number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "org@run065.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Org",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
+ "street_address": "100 Main St",
},
organization_type="commercial",
- website="https://acme.com",
+ website="https://run065.example.com",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -626,7 +678,7 @@ async def test_streaming_response_create(self, async_client: AsyncTelnyx) -> Non
@parametrize
async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
enterprise = await async_client.enterprises.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert_matches_type(EnterpriseRetrieveResponse, enterprise, path=["response"])
@@ -634,7 +686,7 @@ async def test_method_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.with_raw_response.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -646,7 +698,7 @@ async def test_raw_response_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_retrieve(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.with_streaming_response.retrieve(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -668,7 +720,7 @@ async def test_path_params_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_update(self, async_client: AsyncTelnyx) -> None:
enterprise = await async_client.enterprises.update(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert_matches_type(EnterpriseUpdateResponse, enterprise, path=["response"])
@@ -676,48 +728,49 @@ async def test_method_update(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) -> None:
enterprise = await async_client.enterprises.update(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
billing_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
- "extended_address": "Suite 400",
+ "street_address": "100 Main St",
+ "extended_address": "Suite 504",
},
billing_contact={
- "email": "billing@acme.com",
- "first_name": "John",
- "last_name": "Doe",
- "phone_number": "15551234568",
+ "email": "billing@acmeplumbing.example.com",
+ "first_name": "Alex",
+ "last_name": "Bill",
+ "phone_number": "+13125550001",
},
corporate_registration_number="corporate_registration_number",
- customer_reference="customer_reference",
- doing_business_as="doing_business_as",
+ customer_reference="internal-ref-2026Q2",
+ doing_business_as="Acme Plumbing",
dun_bradstreet_number="dun_bradstreet_number",
- fein="fein",
- industry="industry",
- legal_name="xxx",
- number_of_employees="1-10",
+ fein="12-3456789",
+ industry="business",
+ jurisdiction_of_incorporation="Delaware",
+ legal_name="Acme Plumbing LLC",
+ number_of_employees="51-200",
organization_contact={
- "email": "jane.smith@acme.com",
- "first_name": "Jane",
- "job_title": "VP of Engineering",
- "last_name": "Smith",
- "phone": "+16035551234",
+ "email": "sam@acmeplumbing.example.com",
+ "first_name": "Sam",
+ "job_title": "Compliance Lead",
+ "last_name": "Owner",
+ "phone_number": "+13125550000",
},
- organization_legal_type="corporation",
+ organization_legal_type="llc",
organization_physical_address={
- "administrative_area": "Illinois",
+ "administrative_area": "IL",
"city": "Chicago",
- "country": "United States",
+ "country": "US",
"postal_code": "60601",
- "street_address": "123 Main St",
- "extended_address": "Suite 400",
+ "street_address": "100 Main St",
+ "extended_address": "Suite 504",
},
primary_business_domain_sic_code="primary_business_domain_sic_code",
professional_license_number="professional_license_number",
- website="website",
+ website="https://acmeplumbing.example.com",
)
assert_matches_type(EnterpriseUpdateResponse, enterprise, path=["response"])
@@ -725,7 +778,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncTelnyx) ->
@parametrize
async def test_raw_response_update(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.with_raw_response.update(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -737,7 +790,7 @@ async def test_raw_response_update(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_update(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.with_streaming_response.update(
- enterprise_id="6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ enterprise_id="4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -767,7 +820,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N
enterprise = await async_client.enterprises.list(
legal_name="Acme",
page_number=1,
- page_size=1,
+ page_size=10,
)
assert_matches_type(AsyncDefaultFlatPagination[EnterprisePublic], enterprise, path=["response"])
@@ -797,7 +850,7 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_delete(self, async_client: AsyncTelnyx) -> None:
enterprise = await async_client.enterprises.delete(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert enterprise is None
@@ -805,7 +858,7 @@ async def test_method_delete(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_raw_response_delete(self, async_client: AsyncTelnyx) -> None:
response = await async_client.enterprises.with_raw_response.delete(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
)
assert response.is_closed is True
@@ -817,7 +870,7 @@ async def test_raw_response_delete(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_streaming_response_delete(self, async_client: AsyncTelnyx) -> None:
async with async_client.enterprises.with_streaming_response.delete(
- "6a09cdc3-8948-47f0-aa62-74ac943d6c58",
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -834,3 +887,45 @@ async def test_path_params_delete(self, async_client: AsyncTelnyx) -> None:
await async_client.enterprises.with_raw_response.delete(
"",
)
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_activate_branded_calling(self, async_client: AsyncTelnyx) -> None:
+ enterprise = await async_client.enterprises.activate_branded_calling(
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+ assert_matches_type(EnterpriseActivateBrandedCallingResponse, enterprise, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_activate_branded_calling(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.enterprises.with_raw_response.activate_branded_calling(
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ enterprise = await response.parse()
+ assert_matches_type(EnterpriseActivateBrandedCallingResponse, enterprise, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_activate_branded_calling(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.enterprises.with_streaming_response.activate_branded_calling(
+ "4a6192a4-573d-446d-b3ce-aff9117272a6",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ enterprise = await response.parse()
+ assert_matches_type(EnterpriseActivateBrandedCallingResponse, enterprise, 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_activate_branded_calling(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `enterprise_id` but received ''"):
+ await async_client.enterprises.with_raw_response.activate_branded_calling(
+ "",
+ )
diff --git a/tests/api_resources/test_infringement_claims.py b/tests/api_resources/test_infringement_claims.py
new file mode 100644
index 00000000..376f2f06
--- /dev/null
+++ b/tests/api_resources/test_infringement_claims.py
@@ -0,0 +1,235 @@
+# 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.types import (
+ InfringementClaimContestResponse,
+ InfringementClaimRetrieveResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestInfringementClaims:
+ 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:
+ infringement_claim = client.infringement_claims.retrieve(
+ "e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ )
+ assert_matches_type(InfringementClaimRetrieveResponse, infringement_claim, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: Telnyx) -> None:
+ response = client.infringement_claims.with_raw_response.retrieve(
+ "e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ infringement_claim = response.parse()
+ assert_matches_type(InfringementClaimRetrieveResponse, infringement_claim, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Telnyx) -> None:
+ with client.infringement_claims.with_streaming_response.retrieve(
+ "e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ infringement_claim = response.parse()
+ assert_matches_type(InfringementClaimRetrieveResponse, infringement_claim, 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 `claim_id` but received ''"):
+ client.infringement_claims.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_contest(self, client: Telnyx) -> None:
+ infringement_claim = client.infringement_claims.contest(
+ claim_id="e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ )
+ assert_matches_type(InfringementClaimContestResponse, infringement_claim, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_contest_with_all_params(self, client: Telnyx) -> None:
+ infringement_claim = client.infringement_claims.contest(
+ claim_id="e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "trademark_registration",
+ "description": "USPTO trademark certificate.",
+ }
+ ],
+ )
+ assert_matches_type(InfringementClaimContestResponse, infringement_claim, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_contest(self, client: Telnyx) -> None:
+ response = client.infringement_claims.with_raw_response.contest(
+ claim_id="e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ infringement_claim = response.parse()
+ assert_matches_type(InfringementClaimContestResponse, infringement_claim, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_contest(self, client: Telnyx) -> None:
+ with client.infringement_claims.with_streaming_response.contest(
+ claim_id="e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ infringement_claim = response.parse()
+ assert_matches_type(InfringementClaimContestResponse, infringement_claim, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_contest(self, client: Telnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `claim_id` but received ''"):
+ client.infringement_claims.with_raw_response.contest(
+ claim_id="",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ )
+
+
+class TestAsyncInfringementClaims:
+ 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:
+ infringement_claim = await async_client.infringement_claims.retrieve(
+ "e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ )
+ assert_matches_type(InfringementClaimRetrieveResponse, infringement_claim, 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.infringement_claims.with_raw_response.retrieve(
+ "e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ infringement_claim = await response.parse()
+ assert_matches_type(InfringementClaimRetrieveResponse, infringement_claim, 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.infringement_claims.with_streaming_response.retrieve(
+ "e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ infringement_claim = await response.parse()
+ assert_matches_type(InfringementClaimRetrieveResponse, infringement_claim, 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 `claim_id` but received ''"):
+ await async_client.infringement_claims.with_raw_response.retrieve(
+ "",
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_contest(self, async_client: AsyncTelnyx) -> None:
+ infringement_claim = await async_client.infringement_claims.contest(
+ claim_id="e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ )
+ assert_matches_type(InfringementClaimContestResponse, infringement_claim, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_contest_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ infringement_claim = await async_client.infringement_claims.contest(
+ claim_id="e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ documents=[
+ {
+ "document_id": "2a7e8337-e803-4057-a4ae-26c40eb0bc6c",
+ "document_type": "trademark_registration",
+ "description": "USPTO trademark certificate.",
+ }
+ ],
+ )
+ assert_matches_type(InfringementClaimContestResponse, infringement_claim, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_contest(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.infringement_claims.with_raw_response.contest(
+ claim_id="e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ infringement_claim = await response.parse()
+ assert_matches_type(InfringementClaimContestResponse, infringement_claim, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_contest(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.infringement_claims.with_streaming_response.contest(
+ claim_id="e379fbc8-cd83-4bef-a280-a0ac9d00dcf8",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ infringement_claim = await response.parse()
+ assert_matches_type(InfringementClaimContestResponse, infringement_claim, 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_contest(self, async_client: AsyncTelnyx) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `claim_id` but received ''"):
+ await async_client.infringement_claims.with_raw_response.contest(
+ claim_id="",
+ contest_notes="We own the trademark outright; our registration precedes the claimant by three years. See attached certificate.",
+ )
diff --git a/tests/api_resources/test_public_internet_gateways.py b/tests/api_resources/test_public_internet_gateways.py
index 821b3803..14e4cf46 100644
--- a/tests/api_resources/test_public_internet_gateways.py
+++ b/tests/api_resources/test_public_internet_gateways.py
@@ -10,7 +10,7 @@
from telnyx import Telnyx, AsyncTelnyx
from tests.utils import assert_matches_type
from telnyx.types import (
- PublicInternetGatewayRead,
+ PublicInternetGatewayListResponse,
PublicInternetGatewayCreateResponse,
PublicInternetGatewayDeleteResponse,
PublicInternetGatewayRetrieveResponse,
@@ -108,7 +108,7 @@ def test_path_params_retrieve(self, client: Telnyx) -> None:
def test_method_list(self, client: Telnyx) -> None:
public_internet_gateway = client.public_internet_gateways.list()
assert_matches_type(
- SyncDefaultFlatPagination[PublicInternetGatewayRead], public_internet_gateway, path=["response"]
+ SyncDefaultFlatPagination[PublicInternetGatewayListResponse], public_internet_gateway, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -120,7 +120,7 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None:
page_size=0,
)
assert_matches_type(
- SyncDefaultFlatPagination[PublicInternetGatewayRead], public_internet_gateway, path=["response"]
+ SyncDefaultFlatPagination[PublicInternetGatewayListResponse], public_internet_gateway, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -132,7 +132,7 @@ def test_raw_response_list(self, client: Telnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
public_internet_gateway = response.parse()
assert_matches_type(
- SyncDefaultFlatPagination[PublicInternetGatewayRead], public_internet_gateway, path=["response"]
+ SyncDefaultFlatPagination[PublicInternetGatewayListResponse], public_internet_gateway, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -144,7 +144,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None:
public_internet_gateway = response.parse()
assert_matches_type(
- SyncDefaultFlatPagination[PublicInternetGatewayRead], public_internet_gateway, path=["response"]
+ SyncDefaultFlatPagination[PublicInternetGatewayListResponse], public_internet_gateway, path=["response"]
)
assert cast(Any, response.is_closed) is True
@@ -282,7 +282,7 @@ async def test_path_params_retrieve(self, async_client: AsyncTelnyx) -> None:
async def test_method_list(self, async_client: AsyncTelnyx) -> None:
public_internet_gateway = await async_client.public_internet_gateways.list()
assert_matches_type(
- AsyncDefaultFlatPagination[PublicInternetGatewayRead], public_internet_gateway, path=["response"]
+ AsyncDefaultFlatPagination[PublicInternetGatewayListResponse], public_internet_gateway, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -294,7 +294,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N
page_size=0,
)
assert_matches_type(
- AsyncDefaultFlatPagination[PublicInternetGatewayRead], public_internet_gateway, path=["response"]
+ AsyncDefaultFlatPagination[PublicInternetGatewayListResponse], public_internet_gateway, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -306,7 +306,7 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
public_internet_gateway = await response.parse()
assert_matches_type(
- AsyncDefaultFlatPagination[PublicInternetGatewayRead], public_internet_gateway, path=["response"]
+ AsyncDefaultFlatPagination[PublicInternetGatewayListResponse], public_internet_gateway, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -318,7 +318,9 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None:
public_internet_gateway = await response.parse()
assert_matches_type(
- AsyncDefaultFlatPagination[PublicInternetGatewayRead], public_internet_gateway, path=["response"]
+ AsyncDefaultFlatPagination[PublicInternetGatewayListResponse],
+ public_internet_gateway,
+ path=["response"],
)
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_terms_of_service.py b/tests/api_resources/test_terms_of_service.py
new file mode 100644
index 00000000..3fe0941c
--- /dev/null
+++ b/tests/api_resources/test_terms_of_service.py
@@ -0,0 +1,96 @@
+# 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.types import TermsOfServiceStatusResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestTermsOfService:
+ 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_status(self, client: Telnyx) -> None:
+ terms_of_service = client.terms_of_service.status()
+ assert_matches_type(TermsOfServiceStatusResponse, terms_of_service, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_status_with_all_params(self, client: Telnyx) -> None:
+ terms_of_service = client.terms_of_service.status(
+ product_type="branded_calling",
+ )
+ assert_matches_type(TermsOfServiceStatusResponse, terms_of_service, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_status(self, client: Telnyx) -> None:
+ response = client.terms_of_service.with_raw_response.status()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ terms_of_service = response.parse()
+ assert_matches_type(TermsOfServiceStatusResponse, terms_of_service, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_status(self, client: Telnyx) -> None:
+ with client.terms_of_service.with_streaming_response.status() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ terms_of_service = response.parse()
+ assert_matches_type(TermsOfServiceStatusResponse, terms_of_service, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncTermsOfService:
+ 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_status(self, async_client: AsyncTelnyx) -> None:
+ terms_of_service = await async_client.terms_of_service.status()
+ assert_matches_type(TermsOfServiceStatusResponse, terms_of_service, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_status_with_all_params(self, async_client: AsyncTelnyx) -> None:
+ terms_of_service = await async_client.terms_of_service.status(
+ product_type="branded_calling",
+ )
+ assert_matches_type(TermsOfServiceStatusResponse, terms_of_service, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_status(self, async_client: AsyncTelnyx) -> None:
+ response = await async_client.terms_of_service.with_raw_response.status()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ terms_of_service = await response.parse()
+ assert_matches_type(TermsOfServiceStatusResponse, terms_of_service, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_status(self, async_client: AsyncTelnyx) -> None:
+ async with async_client.terms_of_service.with_streaming_response.status() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ terms_of_service = await response.parse()
+ assert_matches_type(TermsOfServiceStatusResponse, terms_of_service, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_uac_connections.py b/tests/api_resources/test_uac_connections.py
index 6fe9f2df..b50af293 100644
--- a/tests/api_resources/test_uac_connections.py
+++ b/tests/api_resources/test_uac_connections.py
@@ -10,7 +10,7 @@
from telnyx import Telnyx, AsyncTelnyx
from tests.utils import assert_matches_type
from telnyx.types import (
- UacConnection,
+ UacConnectionListResponse,
UacConnectionCreateResponse,
UacConnectionDeleteResponse,
UacConnectionUpdateResponse,
@@ -303,7 +303,7 @@ def test_path_params_update(self, client: Telnyx) -> None:
@parametrize
def test_method_list(self, client: Telnyx) -> None:
uac_connection = client.uac_connections.list()
- assert_matches_type(SyncDefaultFlatPagination[UacConnection], uac_connection, path=["response"])
+ assert_matches_type(SyncDefaultFlatPagination[UacConnectionListResponse], uac_connection, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -318,7 +318,7 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None:
page_size=0,
sort="connection_name",
)
- assert_matches_type(SyncDefaultFlatPagination[UacConnection], uac_connection, path=["response"])
+ assert_matches_type(SyncDefaultFlatPagination[UacConnectionListResponse], uac_connection, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -328,7 +328,7 @@ def test_raw_response_list(self, client: Telnyx) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
uac_connection = response.parse()
- assert_matches_type(SyncDefaultFlatPagination[UacConnection], uac_connection, path=["response"])
+ assert_matches_type(SyncDefaultFlatPagination[UacConnectionListResponse], uac_connection, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -338,7 +338,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
uac_connection = response.parse()
- assert_matches_type(SyncDefaultFlatPagination[UacConnection], uac_connection, path=["response"])
+ assert_matches_type(SyncDefaultFlatPagination[UacConnectionListResponse], uac_connection, path=["response"])
assert cast(Any, response.is_closed) is True
@@ -669,7 +669,7 @@ async def test_path_params_update(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_list(self, async_client: AsyncTelnyx) -> None:
uac_connection = await async_client.uac_connections.list()
- assert_matches_type(AsyncDefaultFlatPagination[UacConnection], uac_connection, path=["response"])
+ assert_matches_type(AsyncDefaultFlatPagination[UacConnectionListResponse], uac_connection, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -684,7 +684,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N
page_size=0,
sort="connection_name",
)
- assert_matches_type(AsyncDefaultFlatPagination[UacConnection], uac_connection, path=["response"])
+ assert_matches_type(AsyncDefaultFlatPagination[UacConnectionListResponse], uac_connection, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -694,7 +694,7 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
uac_connection = await response.parse()
- assert_matches_type(AsyncDefaultFlatPagination[UacConnection], uac_connection, path=["response"])
+ assert_matches_type(AsyncDefaultFlatPagination[UacConnectionListResponse], uac_connection, path=["response"])
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -704,7 +704,9 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
uac_connection = await response.parse()
- assert_matches_type(AsyncDefaultFlatPagination[UacConnection], uac_connection, path=["response"])
+ assert_matches_type(
+ AsyncDefaultFlatPagination[UacConnectionListResponse], uac_connection, path=["response"]
+ )
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_virtual_cross_connects.py b/tests/api_resources/test_virtual_cross_connects.py
index 7b7e2cb1..e44f183c 100644
--- a/tests/api_resources/test_virtual_cross_connects.py
+++ b/tests/api_resources/test_virtual_cross_connects.py
@@ -10,7 +10,7 @@
from telnyx import Telnyx, AsyncTelnyx
from tests.utils import assert_matches_type
from telnyx.types import (
- VirtualCrossConnectCombined,
+ VirtualCrossConnectListResponse,
VirtualCrossConnectCreateResponse,
VirtualCrossConnectDeleteResponse,
VirtualCrossConnectUpdateResponse,
@@ -183,7 +183,7 @@ def test_path_params_update(self, client: Telnyx) -> None:
def test_method_list(self, client: Telnyx) -> None:
virtual_cross_connect = client.virtual_cross_connects.list()
assert_matches_type(
- SyncDefaultFlatPagination[VirtualCrossConnectCombined], virtual_cross_connect, path=["response"]
+ SyncDefaultFlatPagination[VirtualCrossConnectListResponse], virtual_cross_connect, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -195,7 +195,7 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None:
page_size=0,
)
assert_matches_type(
- SyncDefaultFlatPagination[VirtualCrossConnectCombined], virtual_cross_connect, path=["response"]
+ SyncDefaultFlatPagination[VirtualCrossConnectListResponse], virtual_cross_connect, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -207,7 +207,7 @@ def test_raw_response_list(self, client: Telnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
virtual_cross_connect = response.parse()
assert_matches_type(
- SyncDefaultFlatPagination[VirtualCrossConnectCombined], virtual_cross_connect, path=["response"]
+ SyncDefaultFlatPagination[VirtualCrossConnectListResponse], virtual_cross_connect, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -219,7 +219,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None:
virtual_cross_connect = response.parse()
assert_matches_type(
- SyncDefaultFlatPagination[VirtualCrossConnectCombined], virtual_cross_connect, path=["response"]
+ SyncDefaultFlatPagination[VirtualCrossConnectListResponse], virtual_cross_connect, path=["response"]
)
assert cast(Any, response.is_closed) is True
@@ -431,7 +431,7 @@ async def test_path_params_update(self, async_client: AsyncTelnyx) -> None:
async def test_method_list(self, async_client: AsyncTelnyx) -> None:
virtual_cross_connect = await async_client.virtual_cross_connects.list()
assert_matches_type(
- AsyncDefaultFlatPagination[VirtualCrossConnectCombined], virtual_cross_connect, path=["response"]
+ AsyncDefaultFlatPagination[VirtualCrossConnectListResponse], virtual_cross_connect, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -443,7 +443,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N
page_size=0,
)
assert_matches_type(
- AsyncDefaultFlatPagination[VirtualCrossConnectCombined], virtual_cross_connect, path=["response"]
+ AsyncDefaultFlatPagination[VirtualCrossConnectListResponse], virtual_cross_connect, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -455,7 +455,7 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None:
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
virtual_cross_connect = await response.parse()
assert_matches_type(
- AsyncDefaultFlatPagination[VirtualCrossConnectCombined], virtual_cross_connect, path=["response"]
+ AsyncDefaultFlatPagination[VirtualCrossConnectListResponse], virtual_cross_connect, path=["response"]
)
@pytest.mark.skip(reason="Mock server tests are disabled")
@@ -467,7 +467,7 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None:
virtual_cross_connect = await response.parse()
assert_matches_type(
- AsyncDefaultFlatPagination[VirtualCrossConnectCombined], virtual_cross_connect, path=["response"]
+ AsyncDefaultFlatPagination[VirtualCrossConnectListResponse], virtual_cross_connect, path=["response"]
)
assert cast(Any, response.is_closed) is True
diff --git a/tests/api_resources/test_wireguard_interfaces.py b/tests/api_resources/test_wireguard_interfaces.py
index 88924f8c..8627060c 100644
--- a/tests/api_resources/test_wireguard_interfaces.py
+++ b/tests/api_resources/test_wireguard_interfaces.py
@@ -10,7 +10,7 @@
from telnyx import Telnyx, AsyncTelnyx
from tests.utils import assert_matches_type
from telnyx.types import (
- WireguardInterfaceRead,
+ WireguardInterfaceListResponse,
WireguardInterfaceCreateResponse,
WireguardInterfaceDeleteResponse,
WireguardInterfaceRetrieveResponse,
@@ -114,7 +114,9 @@ def test_path_params_retrieve(self, client: Telnyx) -> None:
@parametrize
def test_method_list(self, client: Telnyx) -> None:
wireguard_interface = client.wireguard_interfaces.list()
- assert_matches_type(SyncDefaultFlatPagination[WireguardInterfaceRead], wireguard_interface, path=["response"])
+ assert_matches_type(
+ SyncDefaultFlatPagination[WireguardInterfaceListResponse], wireguard_interface, path=["response"]
+ )
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -124,7 +126,9 @@ def test_method_list_with_all_params(self, client: Telnyx) -> None:
page_number=0,
page_size=0,
)
- assert_matches_type(SyncDefaultFlatPagination[WireguardInterfaceRead], wireguard_interface, path=["response"])
+ assert_matches_type(
+ SyncDefaultFlatPagination[WireguardInterfaceListResponse], wireguard_interface, path=["response"]
+ )
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -134,7 +138,9 @@ def test_raw_response_list(self, client: Telnyx) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
wireguard_interface = response.parse()
- assert_matches_type(SyncDefaultFlatPagination[WireguardInterfaceRead], wireguard_interface, path=["response"])
+ assert_matches_type(
+ SyncDefaultFlatPagination[WireguardInterfaceListResponse], wireguard_interface, path=["response"]
+ )
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -145,7 +151,7 @@ def test_streaming_response_list(self, client: Telnyx) -> None:
wireguard_interface = response.parse()
assert_matches_type(
- SyncDefaultFlatPagination[WireguardInterfaceRead], wireguard_interface, path=["response"]
+ SyncDefaultFlatPagination[WireguardInterfaceListResponse], wireguard_interface, path=["response"]
)
assert cast(Any, response.is_closed) is True
@@ -289,7 +295,9 @@ async def test_path_params_retrieve(self, async_client: AsyncTelnyx) -> None:
@parametrize
async def test_method_list(self, async_client: AsyncTelnyx) -> None:
wireguard_interface = await async_client.wireguard_interfaces.list()
- assert_matches_type(AsyncDefaultFlatPagination[WireguardInterfaceRead], wireguard_interface, path=["response"])
+ assert_matches_type(
+ AsyncDefaultFlatPagination[WireguardInterfaceListResponse], wireguard_interface, path=["response"]
+ )
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -299,7 +307,9 @@ async def test_method_list_with_all_params(self, async_client: AsyncTelnyx) -> N
page_number=0,
page_size=0,
)
- assert_matches_type(AsyncDefaultFlatPagination[WireguardInterfaceRead], wireguard_interface, path=["response"])
+ assert_matches_type(
+ AsyncDefaultFlatPagination[WireguardInterfaceListResponse], wireguard_interface, path=["response"]
+ )
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -309,7 +319,9 @@ async def test_raw_response_list(self, async_client: AsyncTelnyx) -> None:
assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
wireguard_interface = await response.parse()
- assert_matches_type(AsyncDefaultFlatPagination[WireguardInterfaceRead], wireguard_interface, path=["response"])
+ assert_matches_type(
+ AsyncDefaultFlatPagination[WireguardInterfaceListResponse], wireguard_interface, path=["response"]
+ )
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
@@ -320,7 +332,7 @@ async def test_streaming_response_list(self, async_client: AsyncTelnyx) -> None:
wireguard_interface = await response.parse()
assert_matches_type(
- AsyncDefaultFlatPagination[WireguardInterfaceRead], wireguard_interface, path=["response"]
+ AsyncDefaultFlatPagination[WireguardInterfaceListResponse], wireguard_interface, path=["response"]
)
assert cast(Any, response.is_closed) is True