---
title: "Create an assistant"
method: POST
path: "/ai/assistants"
tags: ["Assistants"]
---

# Create an assistant

`POST /ai/assistants`

Create a new AI Assistant.

## Request body

- CreateAssistantRequest
  - `name` string, required
  - `model` string — ID of the model to use when `external_llm` is not set. You can use the [Get models API](https://developers.telnyx.com/api-reference/openai-chat/get-available-models-openai-compatible) to see available models. If `external_llm` is provided, the assistant uses `external_llm` instead of this field. If neither `model` nor `external_llm` is provided, Telnyx applies the default model.
  - `instructions` string, required — System instructions for the assistant. These may be templated with [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables)
  - `tools` union[] — Deprecated for new integrations. Inline tool definitions available to the assistant. Prefer `tool_ids` to attach shared tools created with the AI Tools endpoints.
    - union
      - InferenceEmbeddingWebhookTool
        - `type` 'webhook', required
        - `webhook` WebhookToolParams, required
          - `name` string, required — The name of the tool.
          - `description` string, required — The description of the tool.
          - `url` string, required — The URL of the external tool to be called. This URL is going to be used by the assistant. The URL can be templated like: `https://example.com/api/v1/{id}`, where `{id}` is a placeholder for a value that will be provided by the assistant if `path_parameters` are provided with the `id` attribute.
          - `method` 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' — The HTTP method to be used when calling the external tool.
          - `headers` object[] — The headers to be sent to the external tool.
            - `name` string
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `Bearer {{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret as the bearer token. [Telnyx signature headers](https://developers.telnyx.com/docs/voice/programmable-voice/voice-api-webhooks) will be automatically added to the request.
          - `body_parameters` object — The body parameters the webhook tool accepts, described as a JSON Schema object. These parameters will be passed to the webhook as the body of the request. See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format
            - `properties` object — The properties of the body parameters.
            - `required` string[] — The required properties of the body parameters.
            - `type` 'object'
          - `path_parameters` object — The path parameters the webhook tool accepts, described as a JSON Schema object. These parameters will be passed to the webhook as the path of the request if the URL contains a placeholder for a value. See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format
            - `properties` object — The properties of the path parameters.
            - `required` string[] — The required properties of the path parameters.
            - `type` 'object'
          - `query_parameters` object — The query parameters the webhook tool accepts, described as a JSON Schema object. These parameters will be passed to the webhook as the query of the request. See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format
            - `properties` object — The properties of the query parameters.
            - `required` string[] — The required properties of the query parameters.
            - `type` 'object'
          - `async` boolean — If async, the assistant will move forward without waiting for your server to respond.
          - `async_timeout_ms` integer — Maximum time in milliseconds that the conversation worker waits for an async webhook response before returning "Submitted" to the LLM. If unset, the platform default (currently 300ms) is used.
          - `timeout_ms` integer — The maximum number of milliseconds to wait for the webhook to respond. Only applicable when async is false.
          - `store_fields_as_variables` object[] — A list of mappings that extract values from the webhook response and store them as dynamic variables. Each mapping specifies a dynamic variable name and a dot-notation path to the value in the response body.
            - `name` string, required — The name of the dynamic variable to store the extracted value in.
            - `value_path` string, required — A dot-notation path to the value in the webhook response body (e.g. 'customer.name' or 'id').
      - ClientSideTool
        - `type` 'client_side_tool', required
        - `client_side_tool` ClientSideToolParams, required
          - `name` string, required — The name of the tool.
          - `description` string, required — The description of the tool.
          - `parameters` object, required — The parameters the tool accepts, described as a JSON Schema object. See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format
            - `properties` object — The properties of the parameters.
            - `required` string[] — The required properties of the parameters.
            - `type` 'object'
      - RetrievalTool
        - `type` 'retrieval', required
        - `retrieval` BucketIds, required
          - `bucket_ids` string[], required — List of [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) to use for retrieval-augmented generation.
          - `max_num_results` integer — The maximum number of results to retrieve as context for the language model.
      - HandoffTool — The handoff tool allows the assistant to hand off control of the conversation to another AI assistant. By default, this will happen transparently to the end user.
        - `type` 'handoff', required
        - `handoff` HandoffToolParams, required
          - `voice_mode` 'unified' | 'distinct' — With the unified voice mode all assistants share the same voice, making the handoff transparent to the user. With the distinct voice mode all assistants retain their voice configuration, providing the experience of a conference call with a team of assistants.
          - `ai_assistants` object[], required — List of possible assistants that can receive a handoff.
            - `name` string, required — Helpful name for giving context on when to handoff to the assistant.
            - `id` string, required — The ID of the assistant to hand off to.
      - HangupTool
        - `type` 'hangup', required
        - `hangup` HangupToolParams, required
          - `description` string — The description of the function that will be passed to the assistant.
      - InferenceEmbeddingTransferTool
        - `type` 'transfer', required
        - `transfer` InferenceEmbeddingTransferToolParams, required
          - `targets` union, required — The different possible targets of the transfer. The assistant will be able to choose one of the targets to transfer the call to. This can also be a dynamic variable string like `{{ targets }}` where `targets` is returned by the dynamic variables webhook and resolves to an array of target objects at runtime.
            - object[]
              - …
            - string — A dynamic variable string like `{{ targets }}` where `targets` is returned by the dynamic variables webhook and resolves to an array of target objects at runtime.
          - `from` string, required — Number or SIP URI placing the call.
          - `warm_transfer_instructions` string — Natural language instructions for your agent for how to provide context for the transfer recipient.
          - `description` string — A description of the transfer tool. By default, Telnyx generates this automatically based on the configured targets. Typically only set when importing an assistant from another provider that allowed a custom description; in that case the provided value is preserved. Most users should leave this empty and let Telnyx manage it.
          - `warm_message_delay_ms` integer, nullable — Optional delay in milliseconds before playing the warm message audio when the transferred call is answered. When set, the audio_url is not included in the dial command; instead, playback starts after the specified delay. When not set, existing behavior (audio_url in dial) is preserved.
          - `custom_headers` object[] — Custom headers to be added to the SIP INVITE for the transfer command.
            - `name` string
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `{{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret.
          - `voicemail_detection` object — Configuration for voicemail detection (AMD - Answering Machine Detection) on the transferred call. Allows the assistant to detect when a voicemail system answers the transferred call and take appropriate action.
            - `detection_mode` 'disabled' | 'premium' — The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.
            - `on_voicemail_detected` object — Action to take when voicemail is detected on the transferred call.
              - …
            - `detection_config` object — Advanced AMD detection configuration parameters. All values are optional - Telnyx will use defaults if not specified.
              - …
      - InviteTool
        - `type` 'invite', required
        - `invite` InviteToolConfig, required
          - `from` string, required — Number or SIP URI placing the call.
          - `targets` union — The different possible targets of the invite. The assistant will be able to choose one of the targets to invite to the call. This can also be a dynamic variable string like `{{ targets }}` where `targets` is returned by the dynamic variables webhook and resolves to an array of target objects at runtime. If omitted or null, the invite tool can still be configured and targets may be supplied dynamically at runtime.
            - object[]
              - …
            - string — A dynamic variable string like `{{ targets }}` where `targets` is returned by the dynamic variables webhook and resolves to an array of target objects at runtime.
          - `custom_headers` object[] — Custom headers to be added to the SIP INVITE for the invite command.
            - `name` string
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `{{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret.
          - `voicemail_detection` object — Configuration for voicemail detection (AMD - Answering Machine Detection) on the invited call.
            - `detection_mode` 'disabled' | 'premium' — The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.
            - `on_voicemail_detected` object — Action to take when voicemail is detected on the invited call.
              - …
      - SIPReferTool
        - `type` 'refer', required
        - `refer` SIPReferToolParams, required
          - `targets` object[], required — The different possible targets of the SIP refer. The assistant will be able to choose one of the targets to refer the call to.
            - `name` string, required — The name of the target.
            - `sip_address` string, required — The SIP URI to which the call will be referred.
            - `sip_auth_username` string — SIP Authentication username used for SIP challenges.
            - `sip_auth_password` string — SIP Authentication password used for SIP challenges.
          - `sip_headers` object[] — SIP headers to be added to the SIP REFER. Currently only User-to-User and Diversion headers are supported.
            - `name` 'User-to-User' | 'Diversion'
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `{{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret.
          - `custom_headers` object[] — Custom headers to be added to the SIP REFER.
            - `name` string
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `{{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret.
      - DTMFTool
        - `type` 'send_dtmf', required
        - `send_dtmf` object, required
      - SendMessageTool — The send_message tool allows the assistant to send SMS or MMS messages to the end user. The 'to' and 'from' addresses are automatically determined from the conversation context, and the message text is generated by the assistant unless a message_template is provided for runtime variable substitution.
        - `type` 'send_message', required
        - `send_message` object, required
          - `message_template` string, nullable — Optional message template with dynamic variable support using mustache syntax (e.g., {{variable_name}}). When set, the assistant will use this template for the SMS body instead of generating one. Dynamic variables like {{telnyx_end_user_target}}, {{telnyx_agent_target}}, and custom webhook-provided variables will be resolved at runtime.
      - SkipTurnTool
        - `type` 'skip_turn', required
        - `skip_turn` SkipTurnToolParams, required
          - `description` string — The description of the function that will be passed to the assistant.
      - PayTool — (BETA) The pay tool allows the assistant to collect card payments from the caller via DTMF during the conversation. Recording is automatically paused while the pay tool is active and resumes when the payment flow completes. The connector_name must reference a pay connector configured in the Telnyx API.
        - `type` 'pay', required
        - `pay` PayToolParams, required
          - `connector_name` string, required — The name of the pay connector configured in the Telnyx API. Must reference an existing pay connector for this organization.
          - `currency` string — Default currency for payments processed by this tool.
          - `payment_method` string — Default payment method for payments processed by this tool.
          - `description` string, nullable — Optional description of the pay tool that will be passed to the assistant.
      - UpdateDynamicVariablesTool — The update_dynamic_variables tool lets the assistant write values into the conversation's dynamic-variables context during the call. Updated variables are available to later `{{variable}}` interpolation (prompts, speak nodes, message templates) and to flow edge conditions. Declare each variable the assistant is allowed to set under `updatable_variables`.
        - `type` 'update_dynamic_variables', required
        - `update_dynamic_variables` UpdateDynamicVariablesToolParams, required — Configuration for an update_dynamic_variables tool.
          - `name` string, required — The function name surfaced to the LLM. Must match the OpenAI function-name pattern `^[a-zA-Z0-9_-]+$` and be unique across the assistant's function, webhook, and client_side tools.
          - `description` string, required — Description of the tool passed to the assistant, guiding when to call it and which variables to update.
          - `updatable_variables` object[], required — The dynamic variables the assistant is allowed to write. At least one is required.
            - `name` string, required — The dynamic-variable key to update. Must match `^[a-zA-Z0-9._-]+$` and may not start with the reserved `telnyx_` prefix (reserved for system variables). The `pattern` encodes both rules via a negative lookahead.
            - `type` string — Optional hint for the variable's value type (e.g. `string`).
            - `description` string — Optional description of the variable, guiding the assistant on what value to capture.
  - `mcp_servers` AssistantMCPServer[] — MCP servers attached to the assistant. Create MCP servers with `/ai/mcp_servers`, then reference them by `id` here.
    - `id` string, required — 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` string[] — Optional per-assistant allowlist of MCP tool names. When omitted, the assistant uses the MCP server's configured `allowed_tools`.
  - `tool_ids` string[] — IDs of shared tools to attach to the assistant. New integrations should prefer `tool_ids` over inline `tools`.
  - `description` string
  - `greeting` string — Text that the assistant will use to start the conversation. This may be templated with [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables). Use an empty string to have the assistant wait for the user to speak first. Use the special value `<assistant-speaks-first-with-model-generated-message>` to have the assistant generate the greeting based on the system instructions.
  - `llm_api_key_ref` string — This is only needed when using third-party inference providers selected by `model`. The `identifier` for an integration secret [/v2/integration_secrets](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) that refers to your LLM provider's API key. For bring-your-own endpoint authentication, use `external_llm.llm_api_key_ref` instead. Warning: Free plans are unlikely to work with this integration.
  - `external_llm` ExternalLLMReq
    - `model` string, required — Model identifier to use with the external LLM endpoint.
    - `base_url` string, required — Base URL for the external LLM endpoint.
    - `llm_api_key_ref` string — Integration secret identifier for the external LLM API key.
    - `authentication_method` 'token' | 'certificate' — Authentication method used when connecting to the external LLM endpoint.
    - `certificate_ref` string — Integration secret identifier for the client certificate used with certificate authentication.
    - `token_retrieval_url` string — URL used to retrieve an access token when certificate authentication is enabled.
    - `forward_metadata` boolean — 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.
  - `fallback_config` FallbackConfigReq
    - `model` string — Fallback Telnyx-hosted model to use when the primary LLM provider is unavailable.
    - `llm_api_key_ref` string — Integration secret identifier for the fallback model API key.
    - `external_llm` ExternalLLMReq
      - `model` string, required — Model identifier to use with the external LLM endpoint.
      - `base_url` string, required — Base URL for the external LLM endpoint.
      - `llm_api_key_ref` string — Integration secret identifier for the external LLM API key.
      - `authentication_method` 'token' | 'certificate' — Authentication method used when connecting to the external LLM endpoint.
      - `certificate_ref` string — Integration secret identifier for the client certificate used with certificate authentication.
      - `token_retrieval_url` string — URL used to retrieve an access token when certificate authentication is enabled.
      - `forward_metadata` boolean — 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.
  - `voice_settings` VoiceSettings
    - `voice` string, required — The voice to be used by the voice assistant. Check the full list of [available voices](https://developers.telnyx.com/docs/tts-stt/tts-available-voices) via our voices API. To use ElevenLabs, you must reference your ElevenLabs API key as an integration secret under the `api_key_ref` field. See [integration secrets documentation](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) for details. For Telnyx voices, use `Telnyx.<model_id>.<voice_id>` (e.g. Telnyx.KokoroTTS.af_heart). The voice portion of the identifier supports [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables) using mustache syntax (e.g. `Telnyx.Ultra.{{voice_id}}`). The variable is resolved at call time from your dynamic variables webhook, allowing you to select the voice dynamically per call.
    - `voice_speed` number — The speed of the voice in the range [0.25, 2.0]. 1.0 is deafult speed. Larger numbers make the voice faster, smaller numbers make it slower. This is only applicable for Telnyx Natural voices.
    - `api_key_ref` string — The `identifier` for an integration secret [/v2/integration_secrets](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) that refers to your ElevenLabs API key. Warning: Free plans are unlikely to work with this integration.
    - `temperature` number — Determines how stable the voice is and the randomness between each generation. Lower values create a broader emotional range; higher values produce more consistent, monotonous output. Only applicable when using ElevenLabs.
    - `similarity_boost` number — Determines how closely the AI should adhere to the original voice when attempting to replicate it. Only applicable when using ElevenLabs.
    - `use_speaker_boost` boolean — Amplifies similarity to the original speaker voice. Increases computational load and latency slightly. Only applicable when using ElevenLabs.
    - `style` number — Determines the style exaggeration of the voice. Amplifies speaker style but consumes additional resources when set above 0. Only applicable when using ElevenLabs.
    - `speed` number — Adjusts speech velocity. 1.0 is default speed; values less than 1.0 slow speech; values greater than 1.0 accelerate it. Only applicable when using ElevenLabs.
    - `language_boost` 'null' | 'auto' | 'Chinese' | 'Chinese,Yue' | 'English' | 'Arabic' | 'Russian' | 'Spanish' | 'French' | 'Portuguese' | 'German' | 'Turkish' | 'Dutch' | 'Ukrainian' | 'Vietnamese' | 'Indonesian' | 'Japanese' | 'Italian' | 'Korean' | 'Thai' | 'Polish' | 'Romanian' | 'Greek' | 'Czech' | 'Finnish' | 'Hindi' | 'Bulgarian' | 'Danish' | 'Hebrew' | 'Malay' | 'Persian' | 'Slovak' | 'Swedish' | 'Croatian' | 'Filipino' | 'Hungarian' | 'Norwegian' | 'Slovenian' | 'Catalan' | 'Nynorsk' | 'Tamil' | 'Afrikaans', nullable — Enhances recognition for specific languages and dialects during MiniMax TTS synthesis. Default is null (no boost). Set to 'auto' for automatic language detection. Only applicable when using MiniMax voices.
    - `expressive_mode` boolean — Enables emotionally expressive speech using SSML emotion tags. When enabled, the assistant uses audio tags like angry, excited, content, and sad to add emotional nuance. Only supported for Telnyx Ultra voices.
    - `background_audio` union — Optional background audio to play on the call. Use a predefined media bed, or supply a looped MP3 URL. If a media URL is chosen in the portal, customers can preview it before saving.
      - object
        - `type` 'predefined_media', required — Select from predefined media options.
        - `value` 'silence' | 'office', required — The predefined media to use. `silence` disables background audio.
        - `volume` number — Volume level for the predefined background audio. Supports values from 0.1 to 1.0 in 0.1 increments.
      - object
        - `type` 'media_url', required — Provide a direct URL to an MP3 file. The audio will loop during the call.
        - `value` string, uri, required — HTTPS URL to an MP3 file.
      - object
        - `type` 'media_name', required — Reference a previously uploaded media by its name from Telnyx Media Storage.
        - `value` string, required — The `name` of a media asset created via [Media Storage API](https://developers.telnyx.com/api/media-storage/create-media-storage). The audio will loop during the call.
  - `transcription` TranscriptionSettings
    - `model` 'deepgram/flux' | 'deepgram/nova-3' | 'deepgram/nova-2' | 'azure/fast' | 'assemblyai/universal-streaming' | 'xai/grok-stt' | 'soniox/stt-rt-v4' | 'nvidia/parakeet-v3' | 'humain/realtime' | 'reson8/turns' | 'distil-whisper/distil-large-v2' | 'openai/whisper-large-v3-turbo' — The speech to text model to be used by the voice assistant. All Deepgram models are run on-premise. - `deepgram/flux` is optimized for turn-taking with multilingual language hints. - `deepgram/nova-3` is multilingual with automatic language detection. - `deepgram/nova-2` is Deepgram's previous-generation multilingual model. - `azure/fast` is a multilingual Azure transcription model. - `assemblyai/universal-streaming` is a multilingual streaming model with configurable turn detection. - `xai/grok-stt` is a multilingual Grok STT model. - `soniox/stt-rt-v4` is a multilingual streaming model with automatic language detection and configurable endpointing. - `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection. - `humain/realtime` is a streaming model with native Arabic and Arabic/English code-switching support. - `reson8/turns` is a turn-based streaming model covering 10 European languages with automatic language detection.
    - `language` string — The language of the audio to be transcribed. If not set, or if set to `auto`, supported models will automatically detect the language. For `deepgram/flux`, supported values are: `auto` (Telnyx language detection controls the language hint), `multi` (no language hint), and language-specific hints `en`, `es`, `fr`, `de`, `hi`, `ru`, `pt`, `ja`, `it`, and `nl`. For `soniox/stt-rt-v4`, `auto` omits the language hint and lets Soniox auto-detect; ISO 639-1 codes (e.g. `en`, `es`) bias detection toward that language. For `humain/realtime`, supported values are `ar`, `en`, `codeswitch` (Arabic/English code-switching), and `auto` (resolves server-side to code-switching). Unlike other models, `humain/realtime` does not fall back to `auto` when `language` is omitted — omitting it applies `en` instead. For `reson8/turns`, supported values are `auto` (or unset) for automatic language detection, and the language codes `nl`, `en`, `fr`, `fy`, `de`, `it`, `pl`, `pt`, `es`, and `sv` to fix the transcription language.
    - `api_key_ref` string — Integration secret identifier for the transcription provider API key. Currently used for Azure transcription regions that require a customer-provided API key.
    - `region` string — Region on third party cloud providers (currently Azure) if using one of their models. Some regions require `api_key_ref`.
    - `settings` TranscriptionSettingsConfig
      - `smart_format` boolean
      - `numerals` boolean
      - `eot_threshold` number — Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.
      - `eot_timeout_ms` integer — Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.
      - `eager_eot_threshold` number — Available only for deepgram/flux. Confidence threshold for eager end of turn detection. Must be lower than or equal to eot_threshold. Setting this equal to eot_threshold effectively disables eager end of turn.
      - `keyterm` string — Available only for deepgram/nova-3 and deepgram/flux. A comma-separated list of key terms to boost for recognition during transcription. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. This field may be templated with [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables) using mustache syntax (e.g. `Telnyx,{{customer_name}},VoIP`). Variables are resolved at call time before the value is sent to the speech-to-text engine.
      - `end_of_turn_confidence_threshold` number — Available only for assemblyai/universal-streaming. Confidence level required to trigger an end of turn. Higher values require more certainty before ending a turn.
      - `min_turn_silence` integer — Available only for assemblyai/universal-streaming. Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.
      - `max_turn_silence` integer — Available only for assemblyai/universal-streaming. Maximum duration of silence in milliseconds before forcing an end of turn.
      - `interim_results` boolean — Available only for soniox/stt-rt-v4. When true, Soniox streams interim (non-final) results in addition to finalized transcripts.
      - `enable_endpoint_detection` boolean — Available only for soniox/stt-rt-v4. When true, Soniox emits end-of-utterance events at the cadence configured by `max_endpoint_delay_ms`.
      - `max_endpoint_delay_ms` integer — Available only for soniox/stt-rt-v4. Maximum silence (in milliseconds) before Soniox emits an end-of-utterance event. Only honored when `enable_endpoint_detection` is true.
  - `telephony_settings` TelephonySettings
    - `default_texml_app_id` string — Default Texml App used for voice calls with your assistant. This will be created automatically on assistant creation.
    - `supports_unauthenticated_web_calls` boolean — When enabled, allows users to interact with your AI assistant directly from your website without requiring authentication. This is required for FE widgets that work with assistants that have telephony enabled.
    - `noise_suppression` 'krisp' | 'deepfilternet' | 'disabled' — The noise suppression engine to use. Use 'disabled' to turn off noise suppression.
    - `noise_suppression_config` object — Configuration for noise suppression. Only applicable when noise_suppression is 'deepfilternet'.
      - `attenuation_limit` integer — Attenuation limit for noise suppression. Range: 0-100.
      - `mode` 'advanced' — Mode for noise suppression configuration.
    - `time_limit_secs` integer — Maximum duration in seconds for the AI assistant to participate on the call. When this limit is reached the assistant will be stopped. This limit does not apply to portions of a call without an active assistant (for instance, a call transferred to a human representative).
    - `user_idle_timeout_secs` integer — Maximum duration in seconds of end user silence on the call. When this limit is reached the assistant will be stopped. This limit does not apply to portions of a call without an active assistant (for instance, a call transferred to a human representative).
    - `user_idle_reply_secs` integer — Duration in seconds of end user silence before the assistant checks in on the user. When this limit is reached the assistant will prompt the user to respond. This is distinct from user_idle_timeout_secs which stops the assistant entirely.
    - `voicemail_detection` object — Configuration for voicemail detection (AMD - Answering Machine Detection) on outgoing calls. These settings only apply if AMD is enabled on the Dial command. See [TeXML Dial documentation](https://developers.telnyx.com/api-reference/texml-rest-commands/initiate-an-outbound-call) for enabling AMD. Recommended settings: MachineDetection=Enable, AsyncAmd=true, DetectionMode=Premium.
      - `on_voicemail_detected` object — Action to take when voicemail is detected.
        - `action` 'stop_assistant' | 'leave_message_and_stop_assistant' | 'continue_assistant' — The action to take when voicemail is detected.
        - `voicemail_message` object — Configuration for the voicemail message to leave. Only applicable when action is 'leave_message_and_stop_assistant'.
          - `type` 'prompt' | 'message' — The type of voicemail message. Use 'prompt' to have the assistant generate a message based on a prompt, or 'message' to leave a specific message.
          - `prompt` string — The prompt to use for generating the voicemail message. Only applicable when type is 'prompt'.
          - `message` string — The specific message to leave as voicemail. Only applicable when type is 'message'.
    - `recording_settings` object — Configuration for call recording format and channel settings.
      - `enabled` boolean — Whether call recording is enabled. When set to false, calls will not be recorded regardless of other recording configuration.
      - `channels` 'single' | 'dual' — The number of channels for the recording. 'single' for mono, 'dual' for stereo.
      - `format` 'wav' | 'mp3' — The format of the recording file.
      - `stop_on_conversation_end` boolean — When enabled, the call recording will stop when the conversation ends (for example, when the assistant hangs up or the call is transferred). When disabled, recording continues until the call itself ends.
  - `messaging_settings` MessagingSettings
    - `default_messaging_profile_id` string — Default Messaging Profile used for messaging exchanges with your assistant. This will be created automatically on assistant creation.
    - `delivery_status_webhook_url` string — The URL where webhooks related to delivery statused for assistant messages will be sent.
    - `conversation_inactivity_minutes` integer — If more than this many minutes have passed since the last message, the assistant will start a new conversation instead of continuing the existing one.
  - `enabled_features` EnabledFeatures[]
  - `insight_settings` InsightSettings
    - `insight_group_id` string — Reference to an Insight Group. Insights in this group will be run automatically for all the assistant's conversations.
  - `privacy_settings` PrivacySettings
    - `data_retention` boolean — If true, conversation history and insights will be stored. If false, they will not be stored. This in‑tool toggle governs solely the retention of conversation history and insights via the AI assistant. It has no effect on any separate recording, transcription, or storage configuration that you have set at the account, number, or application level. All such external settings remain in force regardless of your selection here.
  - `dynamic_variables_webhook_url` string — If `dynamic_variables_webhook_url` is set, Telnyx sends a POST request to this URL at the start of the conversation to resolve dynamic variables. **Gotcha:** the webhook response must wrap variables under a top-level `dynamic_variables` object, e.g. `{"dynamic_variables": {"customer_name": "Jane"}}`. Returning a flat object will be ignored and variables will fall back to their defaults. See the [dynamic variables guide](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables) for the full request/response format and timeout behavior.
  - `dynamic_variables_webhook_timeout_ms` integer — Timeout in milliseconds for the dynamic variables webhook. Must be between 1 and 10000 ms. If the webhook does not respond within this timeout, the call proceeds with default values. See the [dynamic variables guide](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables).
  - `dynamic_variables` object — Map of dynamic variables and their default values
  - `widget_settings` WidgetSettings — Configuration settings for the assistant's web widget.
    - `theme` 'light' | 'dark' — The visual theme for the widget.
    - `audio_visualizer_config` AudioVisualizerConfig
      - `color` 'verdant' | 'twilight' | 'bloom' | 'mystic' | 'flare' | 'glacier' — The color theme for the audio visualizer.
      - `preset` string — The preset style for the audio visualizer.
    - `start_call_text` string — Custom text displayed on the start call button.
    - `default_state` 'expanded' | 'collapsed' — The default state of the widget.
    - `position` 'fixed' | 'static' — The positioning style for the widget.
    - `view_history_url` string, nullable — URL to view conversation history.
    - `report_issue_url` string, nullable — URL for users to report issues.
    - `give_feedback_url` string, nullable — URL for users to give feedback.
    - `agent_thinking_text` string — Text displayed while the agent is processing.
    - `speak_to_interrupt_text` string — Text prompting users to speak to interrupt.
    - `logo_icon_url` string, nullable — URL to a custom logo icon for the widget.
  - `interruption_settings` InferenceEmbeddingInterruptionSettings — 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`).
    - `enable` boolean — Whether users can interrupt the assistant while it is speaking.
    - `disable_greeting_interruption` boolean — When true, disables user interruptions while the assistant greeting is playing.
    - `start_speaking_plan` StartSpeakingPlan — 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.
      - `wait_seconds` number, float — Minimum seconds to wait before the assistant starts speaking.
      - `transcription_endpointing_plan` TranscriptionEndpointingPlan — 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_punctuation_seconds` number, float — Seconds to wait after the transcript ends with punctuation.
        - `on_no_punctuation_seconds` number, float — Seconds to wait after the transcript ends without punctuation.
        - `on_number_seconds` number, float — Seconds to wait after the transcript ends with a number.
  - `integrations` AssistantIntegration[] — Connected integrations attached to the assistant. The catalog of available integrations is at `/ai/integrations`; the user's connected integrations are at `/ai/integrations/connections`. Each item references a catalog integration by `integration_id`.
    - `integration_id` string, required — 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` string[] — Optional per-assistant allowlist of integration tool names. When omitted or empty, all tools allowed by the connected integration are available to the assistant.
  - `observability_settings` ObservabilityReq
    - `status` 'enabled' | 'disabled'
    - `secret_key_ref` string
    - `public_key_ref` string
    - `host` string
    - `prompt_name` string
    - `prompt_version` integer
    - `prompt_label` string
    - `prompt_sync` 'enabled' | 'disabled' — Whether to auto-publish the assistant's instructions as a Langfuse prompt. When ENABLED + prompt_name set, every assistant create/update pushes `instructions` to Langfuse via create_prompt and stores the returned version in prompt_version.
  - `tags` string[] — Tags associated with the assistant. Tags can also be managed with the assistant tag endpoints.
  - `post_conversation_settings` PostConversationSettingsReq — 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` boolean — 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.
  - `conversation_flow` ConversationFlowReq — Conversation flow as supplied by API clients (create / update). A directed graph of `FlowNodeReq` connected by `FlowEdge`s. Validation enforces unique node/edge IDs, that `start_node_id` references a real node, and that every edge's endpoints reference real nodes.
    - `edges` FlowEdge[] — Directed transitions between nodes. May be empty for a single-node flow.
      - `condition` union, required — Condition that gates the transition. Discriminated by `type`: `llm`, `expression`.
        - LLMCondition — Edge condition evaluated by the LLM from a natural-language prompt. The model is asked to judge the prompt against conversation context and returns true/false. Use this for fuzzy intents that aren't expressible as a deterministic expression (e.g. 'user wants to escalate to a human').
          - `prompt` string, required — Natural-language criterion the LLM judges as true/false.
          - `type` 'llm', required
        - ExpressionCondition — Edge condition evaluated as a deterministic expression AST. The expression is computed against runtime dynamic variables and must evaluate to a boolean. Prefer this over `LLMCondition` when the rule is a clean function of known variables — it's cheaper and predictable.
          - `expression` union, required — A node in a deterministic expression AST. Exactly one variant is selected by the `type` discriminator. Terminal variants (`number_literal`, `string_literal`, `bool_literal`, `variable`) bottom out the recursion; `arithmetic`, `bool_op`, and `comparison` nest further sub-expressions. Extracted into a single named schema so the recursive union is defined once (was previously inlined at every operand site).
            - ComparisonExpression — Compare two sub-expressions with a relational or membership operator. Evaluates to a boolean. Used in edge conditions to gate transitions on runtime values, e.g. `user_age >= 18` or `tier == "gold"`.
              - …
            - BooleanOpExpression — Combine sub-expressions with a logical operator (`and` / `or` / `not`). `and` and `or` accept two or more operands; `not` accepts exactly one.
              - …
            - ArithmeticExpression — Numeric expression: applies an arithmetic operator to two sub-expressions. Useful for derived numeric checks, e.g. `cart_total + shipping > 50`. Both operands should resolve to numbers at runtime.
              - …
            - DynamicVariableExpression — Reference a dynamic variable by name. Resolved at runtime from the assistant's dynamic-variables context (see `Assistant.dynamic_variables` and the dynamic-variables webhook).
              - …
            - StringLiteralExpression — Constant string value.
              - …
            - NumberLiteralExpression — Constant numeric value (float; integers are accepted and stored as float).
              - …
            - BooleanLiteralExpression — Constant boolean value. Useful for unconditional ('always') edges.
              - …
          - `type` 'expression', required
        - DefaultCondition — Fallback edge condition: fires only when no other edge's condition is true. Evaluated after every conditioned (`llm` / `expression`) edge regardless of declaration order, so it routes the flow whenever none of the node's other outgoing edges match. Valid **only** on edges leaving a `tool` or `speak` node, where the deterministic step auto-advances and must always have somewhere to go. A tool/speak node with any outgoing edge is required to carry exactly one `default` edge so it never dead-ends; a tool/speak node with no outgoing edges is a valid terminal step. Carries no parameters.
          - `type` 'default', required
      - `id` string, required — Caller-supplied unique identifier for this edge within the flow.
      - `start_node_id` string, required — ID of the node this edge transitions away from.
      - `target` union, required — Destination of the transition. Discriminated by `type`: `node` (jump to another node in this flow) or `assistant` (hand off to a different assistant).
        - NodeTarget — Edge target referencing another node within the same flow. The runtime transitions the active node to `node_id` and continues processing within the current assistant's flow.
          - `node_id` string, required — ID of the node this edge transitions into.
          - `type` 'node', required
        - AssistantTarget — Edge target referencing a different assistant. When the edge fires, the conversation hands off to `assistant_id`: the active assistant on the conversation row is rewritten and the new assistant's flow starts at its own `start_node_id`. The current turn's LLM response is delivered to the user as-is; subsequent turns route to the new assistant.
          - `assistant_id` string, required — ID of the assistant the conversation transitions to.
          - `position` NodePosition — 2D coordinates for a node, used by authoring UIs to lay out the graph. Purely a presentation aid. The runtime ignores `position`; it round-trips through the API so frontends can persist the graph layout customers arrange in the editor.
            - `x` number, required — Horizontal coordinate in the authoring canvas.
            - `y` number, required — Vertical coordinate in the authoring canvas.
          - `type` 'assistant', required
          - `voice_mode` 'unified' | 'distinct' — Voice behavior when handing off to the target assistant, mirroring the handoff tool's `voice_mode`. `unified` (default) keeps the current voice across the handoff; `distinct` lets the target assistant speak with its own configured voice. Only applies to assistant targets — node targets override voice via the node's own `voice_settings`.
    - `nodes` union[], required — All nodes in the flow. Must contain `start_node_id`. Each node is a prompt node (`type: prompt`) or a tool node (`type: tool`).
      - union
        - FlowNodeReq — One step in a conversation flow, as supplied by API clients. Each node carries the prompt, tool scope, and optional overrides for model/voice/transcription. Unset overrides cascade from the assistant.
          - `external_llm` ExternalLLMReq
            - `model` string, required — Model identifier to use with the external LLM endpoint.
            - `base_url` string, required — Base URL for the external LLM endpoint.
            - `llm_api_key_ref` string — Integration secret identifier for the external LLM API key.
            - `authentication_method` 'token' | 'certificate' — Authentication method used when connecting to the external LLM endpoint.
            - `certificate_ref` string — Integration secret identifier for the client certificate used with certificate authentication.
            - `token_retrieval_url` string — URL used to retrieve an access token when certificate authentication is enabled.
            - `forward_metadata` boolean — 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.
          - `id` string, required — Caller-supplied unique identifier for this node within the flow.
          - `instructions` string, required — Prompt that drives the LLM while this node is active. Required.
          - `instructions_mode` 'replace' | 'append' — How `instructions` combine with the assistant-level instructions. `replace` (default): the node's instructions are used alone. `append`: the node's instructions are concatenated after the assistant's instructions.
          - `llm_api_key_ref` string — Override for `Assistant.llm_api_key_ref` while this node is active. Part of the LLM bundle — see `model` for cascade semantics.
          - `model` string — Override for `Assistant.model` while this node is active. Part of the LLM bundle (`model` + `llm_api_key_ref` + `external_llm`): when any of the three is set on the node, all three are taken from the node and the assistant-level LLM identity is not consulted. When none of the three is set, the assistant's bundle cascades unchanged.
          - `name` string — Optional human-readable label, displayed in authoring UIs.
          - `position` NodePosition — 2D coordinates for a node, used by authoring UIs to lay out the graph. Purely a presentation aid. The runtime ignores `position`; it round-trips through the API so frontends can persist the graph layout customers arrange in the editor.
            - `x` number, required — Horizontal coordinate in the authoring canvas.
            - `y` number, required — Vertical coordinate in the authoring canvas.
          - `shared_tool_ids` string[] — IDs of shared (org-level) tools available at this node. Knowledge bases are attached the same way — via a shared retrieval tool. Tools not listed here are not callable while this node is active.
          - `tools_mode` 'replace' | 'append' — How `shared_tool_ids` combine with the assistant-level tool set. `replace` (default): only the node's tools are callable. `append`: the node's tools are added to the assistant's tools. Ignored when `shared_tool_ids` is null.
          - `transcription` TranscriptionSettings
            - `model` 'deepgram/flux' | 'deepgram/nova-3' | 'deepgram/nova-2' | 'azure/fast' | 'assemblyai/universal-streaming' | 'xai/grok-stt' | 'soniox/stt-rt-v4' | 'nvidia/parakeet-v3' | 'humain/realtime' | 'reson8/turns' | 'distil-whisper/distil-large-v2' | 'openai/whisper-large-v3-turbo' — The speech to text model to be used by the voice assistant. All Deepgram models are run on-premise. - `deepgram/flux` is optimized for turn-taking with multilingual language hints. - `deepgram/nova-3` is multilingual with automatic language detection. - `deepgram/nova-2` is Deepgram's previous-generation multilingual model. - `azure/fast` is a multilingual Azure transcription model. - `assemblyai/universal-streaming` is a multilingual streaming model with configurable turn detection. - `xai/grok-stt` is a multilingual Grok STT model. - `soniox/stt-rt-v4` is a multilingual streaming model with automatic language detection and configurable endpointing. - `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection. - `humain/realtime` is a streaming model with native Arabic and Arabic/English code-switching support. - `reson8/turns` is a turn-based streaming model covering 10 European languages with automatic language detection.
            - `language` string — The language of the audio to be transcribed. If not set, or if set to `auto`, supported models will automatically detect the language. For `deepgram/flux`, supported values are: `auto` (Telnyx language detection controls the language hint), `multi` (no language hint), and language-specific hints `en`, `es`, `fr`, `de`, `hi`, `ru`, `pt`, `ja`, `it`, and `nl`. For `soniox/stt-rt-v4`, `auto` omits the language hint and lets Soniox auto-detect; ISO 639-1 codes (e.g. `en`, `es`) bias detection toward that language. For `humain/realtime`, supported values are `ar`, `en`, `codeswitch` (Arabic/English code-switching), and `auto` (resolves server-side to code-switching). Unlike other models, `humain/realtime` does not fall back to `auto` when `language` is omitted — omitting it applies `en` instead. For `reson8/turns`, supported values are `auto` (or unset) for automatic language detection, and the language codes `nl`, `en`, `fr`, `fy`, `de`, `it`, `pl`, `pt`, `es`, and `sv` to fix the transcription language.
            - `api_key_ref` string — Integration secret identifier for the transcription provider API key. Currently used for Azure transcription regions that require a customer-provided API key.
            - `region` string — Region on third party cloud providers (currently Azure) if using one of their models. Some regions require `api_key_ref`.
            - `settings` TranscriptionSettingsConfig
              - …
          - `type` 'prompt' — Node kind discriminator. `prompt` (default) is an LLM-driven step; `tool` is a standalone tool execution (see `ToolNodeReq`).
          - `voice_settings` VoiceSettings
            - `voice` string, required — The voice to be used by the voice assistant. Check the full list of [available voices](https://developers.telnyx.com/docs/tts-stt/tts-available-voices) via our voices API. To use ElevenLabs, you must reference your ElevenLabs API key as an integration secret under the `api_key_ref` field. See [integration secrets documentation](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) for details. For Telnyx voices, use `Telnyx.<model_id>.<voice_id>` (e.g. Telnyx.KokoroTTS.af_heart). The voice portion of the identifier supports [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables) using mustache syntax (e.g. `Telnyx.Ultra.{{voice_id}}`). The variable is resolved at call time from your dynamic variables webhook, allowing you to select the voice dynamically per call.
            - `voice_speed` number — The speed of the voice in the range [0.25, 2.0]. 1.0 is deafult speed. Larger numbers make the voice faster, smaller numbers make it slower. This is only applicable for Telnyx Natural voices.
            - `api_key_ref` string — The `identifier` for an integration secret [/v2/integration_secrets](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) that refers to your ElevenLabs API key. Warning: Free plans are unlikely to work with this integration.
            - `temperature` number — Determines how stable the voice is and the randomness between each generation. Lower values create a broader emotional range; higher values produce more consistent, monotonous output. Only applicable when using ElevenLabs.
            - `similarity_boost` number — Determines how closely the AI should adhere to the original voice when attempting to replicate it. Only applicable when using ElevenLabs.
            - `use_speaker_boost` boolean — Amplifies similarity to the original speaker voice. Increases computational load and latency slightly. Only applicable when using ElevenLabs.
            - `style` number — Determines the style exaggeration of the voice. Amplifies speaker style but consumes additional resources when set above 0. Only applicable when using ElevenLabs.
            - `speed` number — Adjusts speech velocity. 1.0 is default speed; values less than 1.0 slow speech; values greater than 1.0 accelerate it. Only applicable when using ElevenLabs.
            - `language_boost` 'null' | 'auto' | 'Chinese' | 'Chinese,Yue' | 'English' | 'Arabic' | 'Russian' | 'Spanish' | 'French' | 'Portuguese' | 'German' | 'Turkish' | 'Dutch' | 'Ukrainian' | 'Vietnamese' | 'Indonesian' | 'Japanese' | 'Italian' | 'Korean' | 'Thai' | 'Polish' | 'Romanian' | 'Greek' | 'Czech' | 'Finnish' | 'Hindi' | 'Bulgarian' | 'Danish' | 'Hebrew' | 'Malay' | 'Persian' | 'Slovak' | 'Swedish' | 'Croatian' | 'Filipino' | 'Hungarian' | 'Norwegian' | 'Slovenian' | 'Catalan' | 'Nynorsk' | 'Tamil' | 'Afrikaans', nullable — Enhances recognition for specific languages and dialects during MiniMax TTS synthesis. Default is null (no boost). Set to 'auto' for automatic language detection. Only applicable when using MiniMax voices.
            - `expressive_mode` boolean — Enables emotionally expressive speech using SSML emotion tags. When enabled, the assistant uses audio tags like angry, excited, content, and sad to add emotional nuance. Only supported for Telnyx Ultra voices.
            - `background_audio` union — Optional background audio to play on the call. Use a predefined media bed, or supply a looped MP3 URL. If a media URL is chosen in the portal, customers can preview it before saving.
              - …
        - ToolNodeReq — A standalone tool step in a conversation flow, as supplied by clients. Unlike a prompt node, a tool node has no instructions or model — it isn't an LLM turn. Reaching it deterministically runs one shared tool (arguments filled from matching dynamic variables by name), then routes on the result via outgoing `tool_result` edges.
          - `id` string, required — Caller-supplied unique identifier for this node within the flow.
          - `name` string — Optional human-readable label, displayed in authoring UIs.
          - `position` NodePosition — 2D coordinates for a node, used by authoring UIs to lay out the graph. Purely a presentation aid. The runtime ignores `position`; it round-trips through the API so frontends can persist the graph layout customers arrange in the editor.
            - `x` number, required — Horizontal coordinate in the authoring canvas.
            - `y` number, required — Vertical coordinate in the authoring canvas.
          - `shared_tool_id` string, required — ID of the single shared (org-level) tool this node executes. When the flow reaches this node the tool runs as a deliberate step (no LLM turn); its outgoing `tool_result` edges then route on the outcome. Arguments are filled from the conversation's dynamic variables by name — a dynamic variable whose name matches one of the tool's parameters supplies that argument. Cross-validated against the org's shared tools on write.
          - `type` 'tool' — Node kind discriminator. Always `tool` for a tool node.
        - SpeakNodeReq — A standalone scripted-message step in a flow, as supplied by clients. Unlike a prompt node, a speak node has no instructions or model — it isn't an LLM turn. Reaching it delivers `message` to the user verbatim (with `{{variable}}` interpolation), then routes via outgoing `llm` / `expression` edges.
          - `type` 'speak' — Node kind discriminator. Always `speak` for a speak node.
          - `id` string, required — Caller-supplied unique identifier for this node within the flow.
          - `name` string — Optional human-readable label, displayed in authoring UIs.
          - `message` string, required — Message delivered to the user verbatim when the flow reaches this node. No LLM turn — the text is spoken/sent exactly as written. `{{variable}}` placeholders are interpolated from the conversation's dynamic variables; an unresolved placeholder renders as an empty string. After delivering, the flow routes via the node's outgoing `llm` / `expression` edges (commonly a single unconditional edge).
          - `position` NodePosition — 2D coordinates for a node, used by authoring UIs to lay out the graph. Purely a presentation aid. The runtime ignores `position`; it round-trips through the API so frontends can persist the graph layout customers arrange in the editor.
            - `x` number, required — Horizontal coordinate in the authoring canvas.
            - `y` number, required — Vertical coordinate in the authoring canvas.
    - `start_node_id` string, required — ID of the node where the conversation begins.

## Response `200`

Successful Response

- InferenceEmbeddingAssistant
  - `id` string, required
  - `name` string, required
  - `created_at` string, date-time, required
  - `version_id` string — Identifier for the assistant version returned by version-aware assistant endpoints.
  - `version_created_at` string, date-time — Timestamp when this assistant version was created.
  - `description` string
  - `model` string, required — ID of the model to use when `external_llm` is not set. You can use the [Get models API](https://developers.telnyx.com/api-reference/openai-chat/get-available-models-openai-compatible) to see available models. If `external_llm` is provided, the assistant uses `external_llm` instead of this field. If neither `model` nor `external_llm` is provided, Telnyx applies the default model.
  - `instructions` string, required — System instructions for the assistant. These may be templated with [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables)
  - `tools` union[] — Deprecated for new integrations. Inline tool definitions available to the assistant. Prefer `tool_ids` to attach shared tools created with the AI Tools endpoints.
    - union
      - InferenceEmbeddingWebhookTool
        - `type` 'webhook', required
        - `webhook` WebhookToolParams, required
          - `name` string, required — The name of the tool.
          - `description` string, required — The description of the tool.
          - `url` string, required — The URL of the external tool to be called. This URL is going to be used by the assistant. The URL can be templated like: `https://example.com/api/v1/{id}`, where `{id}` is a placeholder for a value that will be provided by the assistant if `path_parameters` are provided with the `id` attribute.
          - `method` 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' — The HTTP method to be used when calling the external tool.
          - `headers` object[] — The headers to be sent to the external tool.
            - `name` string
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `Bearer {{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret as the bearer token. [Telnyx signature headers](https://developers.telnyx.com/docs/voice/programmable-voice/voice-api-webhooks) will be automatically added to the request.
          - `body_parameters` object — The body parameters the webhook tool accepts, described as a JSON Schema object. These parameters will be passed to the webhook as the body of the request. See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format
            - `properties` object — The properties of the body parameters.
            - `required` string[] — The required properties of the body parameters.
            - `type` 'object'
          - `path_parameters` object — The path parameters the webhook tool accepts, described as a JSON Schema object. These parameters will be passed to the webhook as the path of the request if the URL contains a placeholder for a value. See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format
            - `properties` object — The properties of the path parameters.
            - `required` string[] — The required properties of the path parameters.
            - `type` 'object'
          - `query_parameters` object — The query parameters the webhook tool accepts, described as a JSON Schema object. These parameters will be passed to the webhook as the query of the request. See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format
            - `properties` object — The properties of the query parameters.
            - `required` string[] — The required properties of the query parameters.
            - `type` 'object'
          - `async` boolean — If async, the assistant will move forward without waiting for your server to respond.
          - `async_timeout_ms` integer — Maximum time in milliseconds that the conversation worker waits for an async webhook response before returning "Submitted" to the LLM. If unset, the platform default (currently 300ms) is used.
          - `timeout_ms` integer — The maximum number of milliseconds to wait for the webhook to respond. Only applicable when async is false.
          - `store_fields_as_variables` object[] — A list of mappings that extract values from the webhook response and store them as dynamic variables. Each mapping specifies a dynamic variable name and a dot-notation path to the value in the response body.
            - `name` string, required — The name of the dynamic variable to store the extracted value in.
            - `value_path` string, required — A dot-notation path to the value in the webhook response body (e.g. 'customer.name' or 'id').
      - ClientSideTool
        - `type` 'client_side_tool', required
        - `client_side_tool` ClientSideToolParams, required
          - `name` string, required — The name of the tool.
          - `description` string, required — The description of the tool.
          - `parameters` object, required — The parameters the tool accepts, described as a JSON Schema object. See the [JSON Schema reference](https://json-schema.org/understanding-json-schema) for documentation about the format
            - `properties` object — The properties of the parameters.
            - `required` string[] — The required properties of the parameters.
            - `type` 'object'
      - RetrievalTool
        - `type` 'retrieval', required
        - `retrieval` BucketIds, required
          - `bucket_ids` string[], required — List of [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) to use for retrieval-augmented generation.
          - `max_num_results` integer — The maximum number of results to retrieve as context for the language model.
      - HandoffTool — The handoff tool allows the assistant to hand off control of the conversation to another AI assistant. By default, this will happen transparently to the end user.
        - `type` 'handoff', required
        - `handoff` HandoffToolParams, required
          - `voice_mode` 'unified' | 'distinct' — With the unified voice mode all assistants share the same voice, making the handoff transparent to the user. With the distinct voice mode all assistants retain their voice configuration, providing the experience of a conference call with a team of assistants.
          - `ai_assistants` object[], required — List of possible assistants that can receive a handoff.
            - `name` string, required — Helpful name for giving context on when to handoff to the assistant.
            - `id` string, required — The ID of the assistant to hand off to.
      - HangupTool
        - `type` 'hangup', required
        - `hangup` HangupToolParams, required
          - `description` string — The description of the function that will be passed to the assistant.
      - InferenceEmbeddingTransferTool
        - `type` 'transfer', required
        - `transfer` InferenceEmbeddingTransferToolParams, required
          - `targets` union, required — The different possible targets of the transfer. The assistant will be able to choose one of the targets to transfer the call to. This can also be a dynamic variable string like `{{ targets }}` where `targets` is returned by the dynamic variables webhook and resolves to an array of target objects at runtime.
            - object[]
              - …
            - string — A dynamic variable string like `{{ targets }}` where `targets` is returned by the dynamic variables webhook and resolves to an array of target objects at runtime.
          - `from` string, required — Number or SIP URI placing the call.
          - `warm_transfer_instructions` string — Natural language instructions for your agent for how to provide context for the transfer recipient.
          - `description` string — A description of the transfer tool. By default, Telnyx generates this automatically based on the configured targets. Typically only set when importing an assistant from another provider that allowed a custom description; in that case the provided value is preserved. Most users should leave this empty and let Telnyx manage it.
          - `warm_message_delay_ms` integer, nullable — Optional delay in milliseconds before playing the warm message audio when the transferred call is answered. When set, the audio_url is not included in the dial command; instead, playback starts after the specified delay. When not set, existing behavior (audio_url in dial) is preserved.
          - `custom_headers` object[] — Custom headers to be added to the SIP INVITE for the transfer command.
            - `name` string
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `{{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret.
          - `voicemail_detection` object — Configuration for voicemail detection (AMD - Answering Machine Detection) on the transferred call. Allows the assistant to detect when a voicemail system answers the transferred call and take appropriate action.
            - `detection_mode` 'disabled' | 'premium' — The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.
            - `on_voicemail_detected` object — Action to take when voicemail is detected on the transferred call.
              - …
            - `detection_config` object — Advanced AMD detection configuration parameters. All values are optional - Telnyx will use defaults if not specified.
              - …
      - InviteTool
        - `type` 'invite', required
        - `invite` InviteToolConfig, required
          - `from` string, required — Number or SIP URI placing the call.
          - `targets` union — The different possible targets of the invite. The assistant will be able to choose one of the targets to invite to the call. This can also be a dynamic variable string like `{{ targets }}` where `targets` is returned by the dynamic variables webhook and resolves to an array of target objects at runtime. If omitted or null, the invite tool can still be configured and targets may be supplied dynamically at runtime.
            - object[]
              - …
            - string — A dynamic variable string like `{{ targets }}` where `targets` is returned by the dynamic variables webhook and resolves to an array of target objects at runtime.
          - `custom_headers` object[] — Custom headers to be added to the SIP INVITE for the invite command.
            - `name` string
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `{{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret.
          - `voicemail_detection` object — Configuration for voicemail detection (AMD - Answering Machine Detection) on the invited call.
            - `detection_mode` 'disabled' | 'premium' — The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.
            - `on_voicemail_detected` object — Action to take when voicemail is detected on the invited call.
              - …
      - SIPReferTool
        - `type` 'refer', required
        - `refer` SIPReferToolParams, required
          - `targets` object[], required — The different possible targets of the SIP refer. The assistant will be able to choose one of the targets to refer the call to.
            - `name` string, required — The name of the target.
            - `sip_address` string, required — The SIP URI to which the call will be referred.
            - `sip_auth_username` string — SIP Authentication username used for SIP challenges.
            - `sip_auth_password` string — SIP Authentication password used for SIP challenges.
          - `sip_headers` object[] — SIP headers to be added to the SIP REFER. Currently only User-to-User and Diversion headers are supported.
            - `name` 'User-to-User' | 'Diversion'
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `{{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret.
          - `custom_headers` object[] — Custom headers to be added to the SIP REFER.
            - `name` string
            - `value` string — The value of the header. Note that we support mustache templating for the value. For example you can use `{{#integration_secret}}test-secret{{/integration_secret}}` to pass the value of the integration secret.
      - DTMFTool
        - `type` 'send_dtmf', required
        - `send_dtmf` object, required
      - SendMessageTool — The send_message tool allows the assistant to send SMS or MMS messages to the end user. The 'to' and 'from' addresses are automatically determined from the conversation context, and the message text is generated by the assistant unless a message_template is provided for runtime variable substitution.
        - `type` 'send_message', required
        - `send_message` object, required
          - `message_template` string, nullable — Optional message template with dynamic variable support using mustache syntax (e.g., {{variable_name}}). When set, the assistant will use this template for the SMS body instead of generating one. Dynamic variables like {{telnyx_end_user_target}}, {{telnyx_agent_target}}, and custom webhook-provided variables will be resolved at runtime.
      - SkipTurnTool
        - `type` 'skip_turn', required
        - `skip_turn` SkipTurnToolParams, required
          - `description` string — The description of the function that will be passed to the assistant.
      - PayTool — (BETA) The pay tool allows the assistant to collect card payments from the caller via DTMF during the conversation. Recording is automatically paused while the pay tool is active and resumes when the payment flow completes. The connector_name must reference a pay connector configured in the Telnyx API.
        - `type` 'pay', required
        - `pay` PayToolParams, required
          - `connector_name` string, required — The name of the pay connector configured in the Telnyx API. Must reference an existing pay connector for this organization.
          - `currency` string — Default currency for payments processed by this tool.
          - `payment_method` string — Default payment method for payments processed by this tool.
          - `description` string, nullable — Optional description of the pay tool that will be passed to the assistant.
      - UpdateDynamicVariablesTool — The update_dynamic_variables tool lets the assistant write values into the conversation's dynamic-variables context during the call. Updated variables are available to later `{{variable}}` interpolation (prompts, speak nodes, message templates) and to flow edge conditions. Declare each variable the assistant is allowed to set under `updatable_variables`.
        - `type` 'update_dynamic_variables', required
        - `update_dynamic_variables` UpdateDynamicVariablesToolParams, required — Configuration for an update_dynamic_variables tool.
          - `name` string, required — The function name surfaced to the LLM. Must match the OpenAI function-name pattern `^[a-zA-Z0-9_-]+$` and be unique across the assistant's function, webhook, and client_side tools.
          - `description` string, required — Description of the tool passed to the assistant, guiding when to call it and which variables to update.
          - `updatable_variables` object[], required — The dynamic variables the assistant is allowed to write. At least one is required.
            - `name` string, required — The dynamic-variable key to update. Must match `^[a-zA-Z0-9._-]+$` and may not start with the reserved `telnyx_` prefix (reserved for system variables). The `pattern` encodes both rules via a negative lookahead.
            - `type` string — Optional hint for the variable's value type (e.g. `string`).
            - `description` string — Optional description of the variable, guiding the assistant on what value to capture.
  - `mcp_servers` AssistantMCPServer[] — MCP servers attached to the assistant. Create MCP servers with `/ai/mcp_servers`, then reference them by `id` here.
    - `id` string, required — 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` string[] — Optional per-assistant allowlist of MCP tool names. When omitted, the assistant uses the MCP server's configured `allowed_tools`.
  - `greeting` string — Text that the assistant will use to start the conversation. This may be templated with [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables). Use an empty string to have the assistant wait for the user to speak first. Use the special value `<assistant-speaks-first-with-model-generated-message>` to have the assistant generate the greeting based on the system instructions.
  - `llm_api_key_ref` string — This is only needed when using third-party inference providers selected by `model`. The `identifier` for an integration secret [/v2/integration_secrets](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) that refers to your LLM provider's API key. For bring-your-own endpoint authentication, use `external_llm.llm_api_key_ref` instead. Warning: Free plans are unlikely to work with this integration.
  - `external_llm` ExternalLLM
    - `model` string, required — Model identifier to use with the external LLM endpoint.
    - `base_url` string, required — Base URL for the external LLM endpoint.
    - `llm_api_key_ref` string — Integration secret identifier for the external LLM API key.
    - `authentication_method` 'token' | 'certificate' — Authentication method used when connecting to the external LLM endpoint.
    - `certificate_ref` string — Integration secret identifier for the client certificate used with certificate authentication.
    - `token_retrieval_url` string — URL used to retrieve an access token when certificate authentication is enabled.
    - `forward_metadata` boolean — 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.
  - `fallback_config` FallbackConfig
    - `model` string — Fallback Telnyx-hosted model to use when the primary LLM provider is unavailable.
    - `llm_api_key_ref` string — Integration secret identifier for the fallback model API key.
    - `external_llm` ExternalLLM
      - `model` string, required — Model identifier to use with the external LLM endpoint.
      - `base_url` string, required — Base URL for the external LLM endpoint.
      - `llm_api_key_ref` string — Integration secret identifier for the external LLM API key.
      - `authentication_method` 'token' | 'certificate' — Authentication method used when connecting to the external LLM endpoint.
      - `certificate_ref` string — Integration secret identifier for the client certificate used with certificate authentication.
      - `token_retrieval_url` string — URL used to retrieve an access token when certificate authentication is enabled.
      - `forward_metadata` boolean — 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.
  - `voice_settings` VoiceSettings
    - `voice` string, required — The voice to be used by the voice assistant. Check the full list of [available voices](https://developers.telnyx.com/docs/tts-stt/tts-available-voices) via our voices API. To use ElevenLabs, you must reference your ElevenLabs API key as an integration secret under the `api_key_ref` field. See [integration secrets documentation](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) for details. For Telnyx voices, use `Telnyx.<model_id>.<voice_id>` (e.g. Telnyx.KokoroTTS.af_heart). The voice portion of the identifier supports [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables) using mustache syntax (e.g. `Telnyx.Ultra.{{voice_id}}`). The variable is resolved at call time from your dynamic variables webhook, allowing you to select the voice dynamically per call.
    - `voice_speed` number — The speed of the voice in the range [0.25, 2.0]. 1.0 is deafult speed. Larger numbers make the voice faster, smaller numbers make it slower. This is only applicable for Telnyx Natural voices.
    - `api_key_ref` string — The `identifier` for an integration secret [/v2/integration_secrets](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) that refers to your ElevenLabs API key. Warning: Free plans are unlikely to work with this integration.
    - `temperature` number — Determines how stable the voice is and the randomness between each generation. Lower values create a broader emotional range; higher values produce more consistent, monotonous output. Only applicable when using ElevenLabs.
    - `similarity_boost` number — Determines how closely the AI should adhere to the original voice when attempting to replicate it. Only applicable when using ElevenLabs.
    - `use_speaker_boost` boolean — Amplifies similarity to the original speaker voice. Increases computational load and latency slightly. Only applicable when using ElevenLabs.
    - `style` number — Determines the style exaggeration of the voice. Amplifies speaker style but consumes additional resources when set above 0. Only applicable when using ElevenLabs.
    - `speed` number — Adjusts speech velocity. 1.0 is default speed; values less than 1.0 slow speech; values greater than 1.0 accelerate it. Only applicable when using ElevenLabs.
    - `language_boost` 'null' | 'auto' | 'Chinese' | 'Chinese,Yue' | 'English' | 'Arabic' | 'Russian' | 'Spanish' | 'French' | 'Portuguese' | 'German' | 'Turkish' | 'Dutch' | 'Ukrainian' | 'Vietnamese' | 'Indonesian' | 'Japanese' | 'Italian' | 'Korean' | 'Thai' | 'Polish' | 'Romanian' | 'Greek' | 'Czech' | 'Finnish' | 'Hindi' | 'Bulgarian' | 'Danish' | 'Hebrew' | 'Malay' | 'Persian' | 'Slovak' | 'Swedish' | 'Croatian' | 'Filipino' | 'Hungarian' | 'Norwegian' | 'Slovenian' | 'Catalan' | 'Nynorsk' | 'Tamil' | 'Afrikaans', nullable — Enhances recognition for specific languages and dialects during MiniMax TTS synthesis. Default is null (no boost). Set to 'auto' for automatic language detection. Only applicable when using MiniMax voices.
    - `expressive_mode` boolean — Enables emotionally expressive speech using SSML emotion tags. When enabled, the assistant uses audio tags like angry, excited, content, and sad to add emotional nuance. Only supported for Telnyx Ultra voices.
    - `background_audio` union — Optional background audio to play on the call. Use a predefined media bed, or supply a looped MP3 URL. If a media URL is chosen in the portal, customers can preview it before saving.
      - object
        - `type` 'predefined_media', required — Select from predefined media options.
        - `value` 'silence' | 'office', required — The predefined media to use. `silence` disables background audio.
        - `volume` number — Volume level for the predefined background audio. Supports values from 0.1 to 1.0 in 0.1 increments.
      - object
        - `type` 'media_url', required — Provide a direct URL to an MP3 file. The audio will loop during the call.
        - `value` string, uri, required — HTTPS URL to an MP3 file.
      - object
        - `type` 'media_name', required — Reference a previously uploaded media by its name from Telnyx Media Storage.
        - `value` string, required — The `name` of a media asset created via [Media Storage API](https://developers.telnyx.com/api/media-storage/create-media-storage). The audio will loop during the call.
  - `transcription` TranscriptionSettings
    - `model` 'deepgram/flux' | 'deepgram/nova-3' | 'deepgram/nova-2' | 'azure/fast' | 'assemblyai/universal-streaming' | 'xai/grok-stt' | 'soniox/stt-rt-v4' | 'nvidia/parakeet-v3' | 'humain/realtime' | 'reson8/turns' | 'distil-whisper/distil-large-v2' | 'openai/whisper-large-v3-turbo' — The speech to text model to be used by the voice assistant. All Deepgram models are run on-premise. - `deepgram/flux` is optimized for turn-taking with multilingual language hints. - `deepgram/nova-3` is multilingual with automatic language detection. - `deepgram/nova-2` is Deepgram's previous-generation multilingual model. - `azure/fast` is a multilingual Azure transcription model. - `assemblyai/universal-streaming` is a multilingual streaming model with configurable turn detection. - `xai/grok-stt` is a multilingual Grok STT model. - `soniox/stt-rt-v4` is a multilingual streaming model with automatic language detection and configurable endpointing. - `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection. - `humain/realtime` is a streaming model with native Arabic and Arabic/English code-switching support. - `reson8/turns` is a turn-based streaming model covering 10 European languages with automatic language detection.
    - `language` string — The language of the audio to be transcribed. If not set, or if set to `auto`, supported models will automatically detect the language. For `deepgram/flux`, supported values are: `auto` (Telnyx language detection controls the language hint), `multi` (no language hint), and language-specific hints `en`, `es`, `fr`, `de`, `hi`, `ru`, `pt`, `ja`, `it`, and `nl`. For `soniox/stt-rt-v4`, `auto` omits the language hint and lets Soniox auto-detect; ISO 639-1 codes (e.g. `en`, `es`) bias detection toward that language. For `humain/realtime`, supported values are `ar`, `en`, `codeswitch` (Arabic/English code-switching), and `auto` (resolves server-side to code-switching). Unlike other models, `humain/realtime` does not fall back to `auto` when `language` is omitted — omitting it applies `en` instead. For `reson8/turns`, supported values are `auto` (or unset) for automatic language detection, and the language codes `nl`, `en`, `fr`, `fy`, `de`, `it`, `pl`, `pt`, `es`, and `sv` to fix the transcription language.
    - `api_key_ref` string — Integration secret identifier for the transcription provider API key. Currently used for Azure transcription regions that require a customer-provided API key.
    - `region` string — Region on third party cloud providers (currently Azure) if using one of their models. Some regions require `api_key_ref`.
    - `settings` TranscriptionSettingsConfig
      - `smart_format` boolean
      - `numerals` boolean
      - `eot_threshold` number — Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.
      - `eot_timeout_ms` integer — Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.
      - `eager_eot_threshold` number — Available only for deepgram/flux. Confidence threshold for eager end of turn detection. Must be lower than or equal to eot_threshold. Setting this equal to eot_threshold effectively disables eager end of turn.
      - `keyterm` string — Available only for deepgram/nova-3 and deepgram/flux. A comma-separated list of key terms to boost for recognition during transcription. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. This field may be templated with [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables) using mustache syntax (e.g. `Telnyx,{{customer_name}},VoIP`). Variables are resolved at call time before the value is sent to the speech-to-text engine.
      - `end_of_turn_confidence_threshold` number — Available only for assemblyai/universal-streaming. Confidence level required to trigger an end of turn. Higher values require more certainty before ending a turn.
      - `min_turn_silence` integer — Available only for assemblyai/universal-streaming. Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.
      - `max_turn_silence` integer — Available only for assemblyai/universal-streaming. Maximum duration of silence in milliseconds before forcing an end of turn.
      - `interim_results` boolean — Available only for soniox/stt-rt-v4. When true, Soniox streams interim (non-final) results in addition to finalized transcripts.
      - `enable_endpoint_detection` boolean — Available only for soniox/stt-rt-v4. When true, Soniox emits end-of-utterance events at the cadence configured by `max_endpoint_delay_ms`.
      - `max_endpoint_delay_ms` integer — Available only for soniox/stt-rt-v4. Maximum silence (in milliseconds) before Soniox emits an end-of-utterance event. Only honored when `enable_endpoint_detection` is true.
  - `telephony_settings` TelephonySettings
    - `default_texml_app_id` string — Default Texml App used for voice calls with your assistant. This will be created automatically on assistant creation.
    - `supports_unauthenticated_web_calls` boolean — When enabled, allows users to interact with your AI assistant directly from your website without requiring authentication. This is required for FE widgets that work with assistants that have telephony enabled.
    - `noise_suppression` 'krisp' | 'deepfilternet' | 'disabled' — The noise suppression engine to use. Use 'disabled' to turn off noise suppression.
    - `noise_suppression_config` object — Configuration for noise suppression. Only applicable when noise_suppression is 'deepfilternet'.
      - `attenuation_limit` integer — Attenuation limit for noise suppression. Range: 0-100.
      - `mode` 'advanced' — Mode for noise suppression configuration.
    - `time_limit_secs` integer — Maximum duration in seconds for the AI assistant to participate on the call. When this limit is reached the assistant will be stopped. This limit does not apply to portions of a call without an active assistant (for instance, a call transferred to a human representative).
    - `user_idle_timeout_secs` integer — Maximum duration in seconds of end user silence on the call. When this limit is reached the assistant will be stopped. This limit does not apply to portions of a call without an active assistant (for instance, a call transferred to a human representative).
    - `user_idle_reply_secs` integer — Duration in seconds of end user silence before the assistant checks in on the user. When this limit is reached the assistant will prompt the user to respond. This is distinct from user_idle_timeout_secs which stops the assistant entirely.
    - `voicemail_detection` object — Configuration for voicemail detection (AMD - Answering Machine Detection) on outgoing calls. These settings only apply if AMD is enabled on the Dial command. See [TeXML Dial documentation](https://developers.telnyx.com/api-reference/texml-rest-commands/initiate-an-outbound-call) for enabling AMD. Recommended settings: MachineDetection=Enable, AsyncAmd=true, DetectionMode=Premium.
      - `on_voicemail_detected` object — Action to take when voicemail is detected.
        - `action` 'stop_assistant' | 'leave_message_and_stop_assistant' | 'continue_assistant' — The action to take when voicemail is detected.
        - `voicemail_message` object — Configuration for the voicemail message to leave. Only applicable when action is 'leave_message_and_stop_assistant'.
          - `type` 'prompt' | 'message' — The type of voicemail message. Use 'prompt' to have the assistant generate a message based on a prompt, or 'message' to leave a specific message.
          - `prompt` string — The prompt to use for generating the voicemail message. Only applicable when type is 'prompt'.
          - `message` string — The specific message to leave as voicemail. Only applicable when type is 'message'.
    - `recording_settings` object — Configuration for call recording format and channel settings.
      - `enabled` boolean — Whether call recording is enabled. When set to false, calls will not be recorded regardless of other recording configuration.
      - `channels` 'single' | 'dual' — The number of channels for the recording. 'single' for mono, 'dual' for stereo.
      - `format` 'wav' | 'mp3' — The format of the recording file.
      - `stop_on_conversation_end` boolean — When enabled, the call recording will stop when the conversation ends (for example, when the assistant hangs up or the call is transferred). When disabled, recording continues until the call itself ends.
  - `messaging_settings` MessagingSettings
    - `default_messaging_profile_id` string — Default Messaging Profile used for messaging exchanges with your assistant. This will be created automatically on assistant creation.
    - `delivery_status_webhook_url` string — The URL where webhooks related to delivery statused for assistant messages will be sent.
    - `conversation_inactivity_minutes` integer — If more than this many minutes have passed since the last message, the assistant will start a new conversation instead of continuing the existing one.
  - `enabled_features` EnabledFeatures[]
  - `insight_settings` InsightSettings
    - `insight_group_id` string — Reference to an Insight Group. Insights in this group will be run automatically for all the assistant's conversations.
  - `privacy_settings` PrivacySettings
    - `data_retention` boolean — If true, conversation history and insights will be stored. If false, they will not be stored. This in‑tool toggle governs solely the retention of conversation history and insights via the AI assistant. It has no effect on any separate recording, transcription, or storage configuration that you have set at the account, number, or application level. All such external settings remain in force regardless of your selection here.
  - `dynamic_variables_webhook_url` string — If `dynamic_variables_webhook_url` is set, Telnyx sends a POST request to this URL at the start of the conversation to resolve dynamic variables. **Gotcha:** the webhook response must wrap variables under a top-level `dynamic_variables` object, e.g. `{"dynamic_variables": {"customer_name": "Jane"}}`. Returning a flat object will be ignored and variables will fall back to their defaults. See the [dynamic variables guide](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables) for the full request/response format and timeout behavior.
  - `dynamic_variables_webhook_timeout_ms` integer — Timeout in milliseconds for the dynamic variables webhook. Must be between 1 and 10000 ms. If the webhook does not respond within this timeout, the call proceeds with default values. See the [dynamic variables guide](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables).
  - `dynamic_variables` object — Map of dynamic variables and their values
  - `import_metadata` ImportMetadata
    - `import_provider` 'elevenlabs' | 'vapi' | 'retell' — Provider the assistant was imported from.
    - `import_id` string — ID of the assistant in the provider's system.
  - `widget_settings` WidgetSettings — Configuration settings for the assistant's web widget.
    - `theme` 'light' | 'dark' — The visual theme for the widget.
    - `audio_visualizer_config` AudioVisualizerConfig
      - `color` 'verdant' | 'twilight' | 'bloom' | 'mystic' | 'flare' | 'glacier' — The color theme for the audio visualizer.
      - `preset` string — The preset style for the audio visualizer.
    - `start_call_text` string — Custom text displayed on the start call button.
    - `default_state` 'expanded' | 'collapsed' — The default state of the widget.
    - `position` 'fixed' | 'static' — The positioning style for the widget.
    - `view_history_url` string, nullable — URL to view conversation history.
    - `report_issue_url` string, nullable — URL for users to report issues.
    - `give_feedback_url` string, nullable — URL for users to give feedback.
    - `agent_thinking_text` string — Text displayed while the agent is processing.
    - `speak_to_interrupt_text` string — Text prompting users to speak to interrupt.
    - `logo_icon_url` string, nullable — URL to a custom logo icon for the widget.
  - `interruption_settings` InferenceEmbeddingInterruptionSettings — 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`).
    - `enable` boolean — Whether users can interrupt the assistant while it is speaking.
    - `disable_greeting_interruption` boolean — When true, disables user interruptions while the assistant greeting is playing.
    - `start_speaking_plan` StartSpeakingPlan — 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.
      - `wait_seconds` number, float — Minimum seconds to wait before the assistant starts speaking.
      - `transcription_endpointing_plan` TranscriptionEndpointingPlan — 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_punctuation_seconds` number, float — Seconds to wait after the transcript ends with punctuation.
        - `on_no_punctuation_seconds` number, float — Seconds to wait after the transcript ends without punctuation.
        - `on_number_seconds` number, float — Seconds to wait after the transcript ends with a number.
  - `integrations` AssistantIntegration[] — Connected integrations attached to the assistant. The catalog of available integrations is at `/ai/integrations`; the user's connected integrations are at `/ai/integrations/connections`. Each item references a catalog integration by `integration_id`.
    - `integration_id` string, required — 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` string[] — Optional per-assistant allowlist of integration tool names. When omitted or empty, all tools allowed by the connected integration are available to the assistant.
  - `observability_settings` Observability
    - `status` 'enabled' | 'disabled'
    - `secret_key_ref` string
    - `public_key_ref` string
    - `host` string
    - `prompt_name` string
    - `prompt_version` integer
    - `prompt_label` string
    - `prompt_sync` 'enabled' | 'disabled' — Whether to auto-publish the assistant's instructions as a Langfuse prompt. When ENABLED + prompt_name set, every assistant create/update pushes `instructions` to Langfuse via create_prompt and stores the returned version in prompt_version.
  - `version_name` string — Human-readable name for the assistant version.
  - `related_mission_ids` string[] — IDs of missions related to this assistant.
  - `tags` string[] — Tags associated with the assistant. Tags can also be managed with the assistant tag endpoints.
  - `post_conversation_settings` PostConversationSettings — 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` boolean — 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.
  - `conversation_flow` ConversationFlow — Conversation flow as returned by the API.
    - `edges` FlowEdge[] — Directed transitions between nodes.
      - `condition` union, required — Condition that gates the transition. Discriminated by `type`: `llm`, `expression`.
        - LLMCondition — Edge condition evaluated by the LLM from a natural-language prompt. The model is asked to judge the prompt against conversation context and returns true/false. Use this for fuzzy intents that aren't expressible as a deterministic expression (e.g. 'user wants to escalate to a human').
          - `prompt` string, required — Natural-language criterion the LLM judges as true/false.
          - `type` 'llm', required
        - ExpressionCondition — Edge condition evaluated as a deterministic expression AST. The expression is computed against runtime dynamic variables and must evaluate to a boolean. Prefer this over `LLMCondition` when the rule is a clean function of known variables — it's cheaper and predictable.
          - `expression` union, required — A node in a deterministic expression AST. Exactly one variant is selected by the `type` discriminator. Terminal variants (`number_literal`, `string_literal`, `bool_literal`, `variable`) bottom out the recursion; `arithmetic`, `bool_op`, and `comparison` nest further sub-expressions. Extracted into a single named schema so the recursive union is defined once (was previously inlined at every operand site).
            - ComparisonExpression — Compare two sub-expressions with a relational or membership operator. Evaluates to a boolean. Used in edge conditions to gate transitions on runtime values, e.g. `user_age >= 18` or `tier == "gold"`.
              - …
            - BooleanOpExpression — Combine sub-expressions with a logical operator (`and` / `or` / `not`). `and` and `or` accept two or more operands; `not` accepts exactly one.
              - …
            - ArithmeticExpression — Numeric expression: applies an arithmetic operator to two sub-expressions. Useful for derived numeric checks, e.g. `cart_total + shipping > 50`. Both operands should resolve to numbers at runtime.
              - …
            - DynamicVariableExpression — Reference a dynamic variable by name. Resolved at runtime from the assistant's dynamic-variables context (see `Assistant.dynamic_variables` and the dynamic-variables webhook).
              - …
            - StringLiteralExpression — Constant string value.
              - …
            - NumberLiteralExpression — Constant numeric value (float; integers are accepted and stored as float).
              - …
            - BooleanLiteralExpression — Constant boolean value. Useful for unconditional ('always') edges.
              - …
          - `type` 'expression', required
        - DefaultCondition — Fallback edge condition: fires only when no other edge's condition is true. Evaluated after every conditioned (`llm` / `expression`) edge regardless of declaration order, so it routes the flow whenever none of the node's other outgoing edges match. Valid **only** on edges leaving a `tool` or `speak` node, where the deterministic step auto-advances and must always have somewhere to go. A tool/speak node with any outgoing edge is required to carry exactly one `default` edge so it never dead-ends; a tool/speak node with no outgoing edges is a valid terminal step. Carries no parameters.
          - `type` 'default', required
      - `id` string, required — Caller-supplied unique identifier for this edge within the flow.
      - `start_node_id` string, required — ID of the node this edge transitions away from.
      - `target` union, required — Destination of the transition. Discriminated by `type`: `node` (jump to another node in this flow) or `assistant` (hand off to a different assistant).
        - NodeTarget — Edge target referencing another node within the same flow. The runtime transitions the active node to `node_id` and continues processing within the current assistant's flow.
          - `node_id` string, required — ID of the node this edge transitions into.
          - `type` 'node', required
        - AssistantTarget — Edge target referencing a different assistant. When the edge fires, the conversation hands off to `assistant_id`: the active assistant on the conversation row is rewritten and the new assistant's flow starts at its own `start_node_id`. The current turn's LLM response is delivered to the user as-is; subsequent turns route to the new assistant.
          - `assistant_id` string, required — ID of the assistant the conversation transitions to.
          - `position` NodePosition — 2D coordinates for a node, used by authoring UIs to lay out the graph. Purely a presentation aid. The runtime ignores `position`; it round-trips through the API so frontends can persist the graph layout customers arrange in the editor.
            - `x` number, required — Horizontal coordinate in the authoring canvas.
            - `y` number, required — Vertical coordinate in the authoring canvas.
          - `type` 'assistant', required
          - `voice_mode` 'unified' | 'distinct' — Voice behavior when handing off to the target assistant, mirroring the handoff tool's `voice_mode`. `unified` (default) keeps the current voice across the handoff; `distinct` lets the target assistant speak with its own configured voice. Only applies to assistant targets — node targets override voice via the node's own `voice_settings`.
    - `nodes` union[], required — All nodes in the flow.
      - union
        - FlowNode — One step in a conversation flow, as returned by the API.
          - `external_llm` ExternalLLM
            - `model` string, required — Model identifier to use with the external LLM endpoint.
            - `base_url` string, required — Base URL for the external LLM endpoint.
            - `llm_api_key_ref` string — Integration secret identifier for the external LLM API key.
            - `authentication_method` 'token' | 'certificate' — Authentication method used when connecting to the external LLM endpoint.
            - `certificate_ref` string — Integration secret identifier for the client certificate used with certificate authentication.
            - `token_retrieval_url` string — URL used to retrieve an access token when certificate authentication is enabled.
            - `forward_metadata` boolean — 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.
          - `id` string, required — Caller-supplied unique identifier for this node within the flow.
          - `instructions` string, required — Prompt that drives the LLM while this node is active. Required.
          - `instructions_mode` 'replace' | 'append' — How `instructions` combine with the assistant-level instructions. `replace` (default): the node's instructions are used alone. `append`: the node's instructions are concatenated after the assistant's instructions.
          - `llm_api_key_ref` string — Override for `Assistant.llm_api_key_ref` while this node is active. Part of the LLM bundle — see `model` for cascade semantics.
          - `model` string — Override for `Assistant.model` while this node is active. Part of the LLM bundle (`model` + `llm_api_key_ref` + `external_llm`): when any of the three is set on the node, all three are taken from the node and the assistant-level LLM identity is not consulted. When none of the three is set, the assistant's bundle cascades unchanged.
          - `name` string — Optional human-readable label, displayed in authoring UIs.
          - `position` NodePosition — 2D coordinates for a node, used by authoring UIs to lay out the graph. Purely a presentation aid. The runtime ignores `position`; it round-trips through the API so frontends can persist the graph layout customers arrange in the editor.
            - `x` number, required — Horizontal coordinate in the authoring canvas.
            - `y` number, required — Vertical coordinate in the authoring canvas.
          - `shared_tool_ids` string[] — IDs of shared (org-level) tools available at this node. Knowledge bases are attached the same way — via a shared retrieval tool. Tools not listed here are not callable while this node is active.
          - `tools` AssistantTools[] — Full tool definitions for this node, resolved from `shared_tool_ids` server-side. Populated on responses so clients can render the flow without a follow-up fetch per shared tool. Ignored on input — set `shared_tool_ids` to configure a node's tools.
            - union[] — Deprecated for new integrations. Inline tool definitions available to the assistant. Prefer `tool_ids` to attach shared tools created with the AI Tools endpoints.
              - …
          - `tools_mode` 'replace' | 'append' — How `shared_tool_ids` combine with the assistant-level tool set. `replace` (default): only the node's tools are callable. `append`: the node's tools are added to the assistant's tools. Ignored when `shared_tool_ids` is null.
          - `transcription` TranscriptionSettings
            - `model` 'deepgram/flux' | 'deepgram/nova-3' | 'deepgram/nova-2' | 'azure/fast' | 'assemblyai/universal-streaming' | 'xai/grok-stt' | 'soniox/stt-rt-v4' | 'nvidia/parakeet-v3' | 'humain/realtime' | 'reson8/turns' | 'distil-whisper/distil-large-v2' | 'openai/whisper-large-v3-turbo' — The speech to text model to be used by the voice assistant. All Deepgram models are run on-premise. - `deepgram/flux` is optimized for turn-taking with multilingual language hints. - `deepgram/nova-3` is multilingual with automatic language detection. - `deepgram/nova-2` is Deepgram's previous-generation multilingual model. - `azure/fast` is a multilingual Azure transcription model. - `assemblyai/universal-streaming` is a multilingual streaming model with configurable turn detection. - `xai/grok-stt` is a multilingual Grok STT model. - `soniox/stt-rt-v4` is a multilingual streaming model with automatic language detection and configurable endpointing. - `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection. - `humain/realtime` is a streaming model with native Arabic and Arabic/English code-switching support. - `reson8/turns` is a turn-based streaming model covering 10 European languages with automatic language detection.
            - `language` string — The language of the audio to be transcribed. If not set, or if set to `auto`, supported models will automatically detect the language. For `deepgram/flux`, supported values are: `auto` (Telnyx language detection controls the language hint), `multi` (no language hint), and language-specific hints `en`, `es`, `fr`, `de`, `hi`, `ru`, `pt`, `ja`, `it`, and `nl`. For `soniox/stt-rt-v4`, `auto` omits the language hint and lets Soniox auto-detect; ISO 639-1 codes (e.g. `en`, `es`) bias detection toward that language. For `humain/realtime`, supported values are `ar`, `en`, `codeswitch` (Arabic/English code-switching), and `auto` (resolves server-side to code-switching). Unlike other models, `humain/realtime` does not fall back to `auto` when `language` is omitted — omitting it applies `en` instead. For `reson8/turns`, supported values are `auto` (or unset) for automatic language detection, and the language codes `nl`, `en`, `fr`, `fy`, `de`, `it`, `pl`, `pt`, `es`, and `sv` to fix the transcription language.
            - `api_key_ref` string — Integration secret identifier for the transcription provider API key. Currently used for Azure transcription regions that require a customer-provided API key.
            - `region` string — Region on third party cloud providers (currently Azure) if using one of their models. Some regions require `api_key_ref`.
            - `settings` TranscriptionSettingsConfig
              - …
          - `type` 'prompt' — Node kind discriminator. `prompt` is an LLM-driven step.
          - `voice_settings` VoiceSettings
            - `voice` string, required — The voice to be used by the voice assistant. Check the full list of [available voices](https://developers.telnyx.com/docs/tts-stt/tts-available-voices) via our voices API. To use ElevenLabs, you must reference your ElevenLabs API key as an integration secret under the `api_key_ref` field. See [integration secrets documentation](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) for details. For Telnyx voices, use `Telnyx.<model_id>.<voice_id>` (e.g. Telnyx.KokoroTTS.af_heart). The voice portion of the identifier supports [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables) using mustache syntax (e.g. `Telnyx.Ultra.{{voice_id}}`). The variable is resolved at call time from your dynamic variables webhook, allowing you to select the voice dynamically per call.
            - `voice_speed` number — The speed of the voice in the range [0.25, 2.0]. 1.0 is deafult speed. Larger numbers make the voice faster, smaller numbers make it slower. This is only applicable for Telnyx Natural voices.
            - `api_key_ref` string — The `identifier` for an integration secret [/v2/integration_secrets](https://developers.telnyx.com/api-reference/integration-secrets/create-a-secret) that refers to your ElevenLabs API key. Warning: Free plans are unlikely to work with this integration.
            - `temperature` number — Determines how stable the voice is and the randomness between each generation. Lower values create a broader emotional range; higher values produce more consistent, monotonous output. Only applicable when using ElevenLabs.
            - `similarity_boost` number — Determines how closely the AI should adhere to the original voice when attempting to replicate it. Only applicable when using ElevenLabs.
            - `use_speaker_boost` boolean — Amplifies similarity to the original speaker voice. Increases computational load and latency slightly. Only applicable when using ElevenLabs.
            - `style` number — Determines the style exaggeration of the voice. Amplifies speaker style but consumes additional resources when set above 0. Only applicable when using ElevenLabs.
            - `speed` number — Adjusts speech velocity. 1.0 is default speed; values less than 1.0 slow speech; values greater than 1.0 accelerate it. Only applicable when using ElevenLabs.
            - `language_boost` 'null' | 'auto' | 'Chinese' | 'Chinese,Yue' | 'English' | 'Arabic' | 'Russian' | 'Spanish' | 'French' | 'Portuguese' | 'German' | 'Turkish' | 'Dutch' | 'Ukrainian' | 'Vietnamese' | 'Indonesian' | 'Japanese' | 'Italian' | 'Korean' | 'Thai' | 'Polish' | 'Romanian' | 'Greek' | 'Czech' | 'Finnish' | 'Hindi' | 'Bulgarian' | 'Danish' | 'Hebrew' | 'Malay' | 'Persian' | 'Slovak' | 'Swedish' | 'Croatian' | 'Filipino' | 'Hungarian' | 'Norwegian' | 'Slovenian' | 'Catalan' | 'Nynorsk' | 'Tamil' | 'Afrikaans', nullable — Enhances recognition for specific languages and dialects during MiniMax TTS synthesis. Default is null (no boost). Set to 'auto' for automatic language detection. Only applicable when using MiniMax voices.
            - `expressive_mode` boolean — Enables emotionally expressive speech using SSML emotion tags. When enabled, the assistant uses audio tags like angry, excited, content, and sad to add emotional nuance. Only supported for Telnyx Ultra voices.
            - `background_audio` union — Optional background audio to play on the call. Use a predefined media bed, or supply a looped MP3 URL. If a media URL is chosen in the portal, customers can preview it before saving.
              - …
        - ToolNode — A standalone tool step in a conversation flow, as returned by the API.
          - `id` string, required — Caller-supplied unique identifier for this node within the flow.
          - `name` string — Optional human-readable label, displayed in authoring UIs.
          - `position` NodePosition — 2D coordinates for a node, used by authoring UIs to lay out the graph. Purely a presentation aid. The runtime ignores `position`; it round-trips through the API so frontends can persist the graph layout customers arrange in the editor.
            - `x` number, required — Horizontal coordinate in the authoring canvas.
            - `y` number, required — Vertical coordinate in the authoring canvas.
          - `shared_tool_id` string, required — ID of the single shared (org-level) tool this node executes. When the flow reaches this node the tool runs as a deliberate step (no LLM turn); its outgoing `tool_result` edges then route on the outcome. Arguments are filled from the conversation's dynamic variables by name — a dynamic variable whose name matches one of the tool's parameters supplies that argument. Cross-validated against the org's shared tools on write.
          - `tool` union[] — Deprecated for new integrations. Inline tool definitions available to the assistant. Prefer `tool_ids` to attach shared tools created with the AI Tools endpoints.
            - union
              - …
          - `type` 'tool' — Node kind discriminator. Always `tool` for a tool node.
        - SpeakNode — A standalone scripted-message step in a flow, as returned by the API.
          - `type` 'speak' — Node kind discriminator. Always `speak` for a speak node.
          - `id` string, required — Caller-supplied unique identifier for this node within the flow.
          - `name` string — Optional human-readable label, displayed in authoring UIs.
          - `message` string, required — Message delivered to the user verbatim when the flow reaches this node. No LLM turn — the text is spoken/sent exactly as written. `{{variable}}` placeholders are interpolated from the conversation's dynamic variables; an unresolved placeholder renders as an empty string. After delivering, the flow routes via the node's outgoing `llm` / `expression` edges (commonly a single unconditional edge).
          - `position` NodePosition — 2D coordinates for a node, used by authoring UIs to lay out the graph. Purely a presentation aid. The runtime ignores `position`; it round-trips through the API so frontends can persist the graph layout customers arrange in the editor.
            - `x` number, required — Horizontal coordinate in the authoring canvas.
            - `y` number, required — Vertical coordinate in the authoring canvas.
    - `start_node_id` string, required — ID of the node where the conversation begins.

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/team-telnyx/apis/telnyx-api-2.md) · [All operations](https://skmtc.net/team-telnyx/apis/telnyx-api-2/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/team-telnyx/telnyx-api-2/versions/8f5f4e537994/schema)
