---
title: "List assistants"
method: GET
path: "/ai/assistants"
tags: ["Assistants"]
---

# List assistants

`GET /ai/assistants`

Retrieve a list of all AI Assistants configured by the user.

## Response `200`

Successful Response

- AssistantsListData
  - `data` InferenceEmbeddingAssistant[], required
    - `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. On update, a sent `tools` array fully replaces the assistant's inline tools; omit the field to leave them unchanged. Each tool type except `function`, `webhook`, and `client_side_tool` allows at most one instance per assistant, counted across inline `tools` and shared `tool_ids` combined.
      - union
        - FunctionTool
          - `type` 'function', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `function` FunctionDefinition, required
            - `name` string, required
            - `description` string
            - `parameters` object
        - InferenceEmbeddingWebhookTool
          - `type` 'webhook', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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.
              - …
            - `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
              - …
            - `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
              - …
            - `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
              - …
            - `preset_body_fields` object — Body fields supplied by the assistant configuration rather than by the model. They are never advertised in the tool definition, so the LLM can neither see nor set them, and they take precedence over a `body_parameters` value of the same name. Values support mustache templating, so they can hold dynamic variables (`{{customer_id}}`) and integration secrets (`{{#integration_secret}}my-secret{{/integration_secret}}`). Not sent on `GET` requests, which carry no body.
            - `preset_query_params` object — Query string parameters supplied by the assistant configuration rather than by the model. They are never advertised in the tool definition, so the LLM can neither see nor set them, and they take precedence over a `query_parameters` value of the same name. Values support mustache templating, so they can hold dynamic variables (`{{telnyx_end_user_target}}`) and integration secrets (`{{#integration_secret}}my-secret{{/integration_secret}}`). Unlike values templated directly into the `url`, these are percent-encoded, so a value such as `+15551234567` survives the round trip.
            - `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.
              - …
            - `messages` union[] — Filler messages spoken while a synchronous webhook request is in progress. `request_start` messages are spoken immediately when the request begins. `request_response_delayed` messages are spoken after `timing_ms` has elapsed only if the webhook response is still pending. Filler messages are not used for asynchronous webhooks.
              - …
        - ClientSideTool
          - `type` 'client_side_tool', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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
              - …
        - RetrievalTool
          - `type` 'retrieval', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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.
              - …
        - InferenceEmbeddingHangupTool
          - `type` 'hangup', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `hangup` HangupToolParams, required
            - `description` string — The description of the function that will be passed to the assistant.
        - InferenceEmbeddingTransferTool
          - `type` 'transfer', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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.
              - …
            - `from` string, required — Number or SIP URI placing the call.
            - `diversion` string — The number the inbound call was received on, forwarded so an unverified non-Telnyx `from` can be used as the caller id -- typically to transfer out as the original caller by pairing `from: "{{telnyx_end_user_target}}"` with `diversion: "{{telnyx_agent_target}}"`. The caller id is only accepted while that number is still on an active inbound call to this `diversion` number, and the `diversion` number must be one you own or have verified.
            - `warm_transfer_instructions` string — Natural language instructions for your agent for how to provide context for the transfer recipient.
            - `warm_transfer_acceptance` object — Requires the transfer destination to accept the call before the caller is bridged. When enabled, the assistant speaks privately with the destination after they answer — delivering the warm transfer message and asking whether they take the call — while the caller keeps hearing ringback. The assistant then finalizes the transfer with the built-in `complete_transfer` tool: an accept bridges the calls, a decline hangs up the destination and returns the assistant to the caller with the reason the destination gave. Requires either `warm_transfer_instructions` or a `message` on every target, otherwise the assistant fails to save. Only available for calls started with `ai_assistant_start`; single-caller conversations only (a conference or additional invited participants fall back to a regular warm transfer).
              - …
            - `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.
              - …
            - `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.
              - …
        - InviteTool
          - `type` 'invite', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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.
              - …
            - `custom_headers` object[] — Custom headers to be added to the SIP INVITE for the invite command.
              - …
            - `voicemail_detection` object — Configuration for voicemail detection (AMD - Answering Machine Detection) on the invited call.
              - …
        - SIPReferTool
          - `type` 'refer', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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.
              - …
            - `sip_headers` object[] — SIP headers to be added to the SIP REFER. Currently only User-to-User and Diversion headers are supported.
              - …
            - `custom_headers` object[] — Custom headers to be added to the SIP REFER.
              - …
        - DTMFTool
          - `type` 'send_dtmf', required
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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
          - `shared` boolean — Whether this tool comes from the shared Tools Library. Responses merge shared tools into `tools` with `shared: true`; inline tools carry `shared: false`. Read-only: set by the server, not accepted in requests. When updating an assistant, omit `shared: true` tools from the request `tools` array and manage them through `tool_ids` instead — re-sending their definitions creates an inline duplicate (rejected with error code 10015 when the type allows only one instance per assistant).
          - `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.
              - …
    - `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`.
    - `a2a_agents` AssistantA2AAgent[] — A2A agents this assistant can delegate to. Tools are not stored here: at the start of every conversation each agent's card is fetched and one tool is derived per skill the card advertises, named `a2a_<name>_<skill_id>`. The following limits are not enforced when the assistant is saved, and anything past them is dropped when the conversation starts: 64 agents per assistant, 64 skills per card, 128 derived tools per assistant, and a 6 second budget for all card fetches combined. An agent whose card cannot be fetched costs the assistant that capability for the conversation; it does not fail the call.
      - `name` string, required — Identifies the agent and seeds the names of the tools derived from its card (`a2a_<name>_<skill_id>`). Characters outside `[A-Za-z0-9_]` are replaced with `_` before the tool name is built, so two agents whose names differ only in punctuation collide and are rejected.
      - `url` string, required — The agent's base URL, or the URL of its agent card. At most 2,048 bytes once UTF-8 encoded. `/.well-known/agent-card.json` is appended to the path unless it already ends in `.json`. Must be an `http://` or `https://` URL for an externally reachable host: internal destinations (`localhost`, private and reserved IP ranges, `.local` domains) are rejected, and the hostname may not contain a `{{...}}` placeholder. Placeholders in the path are allowed.
      - `headers` A2AAgentHeader[] — Headers sent when fetching this agent's card and on every call made to it. Use them to authenticate to the agent.
        - `name` string, required — HTTP header name. May only contain alphanumeric characters, hyphens, and underscores, or a `{{dynamic_variable}}` placeholder surrounded by those characters.
        - `value` string, required — Header value, stored exactly as written. It may be a literal, a `{{dynamic_variable}}`, or an `{{#integration_secret}}identifier{{/integration_secret}}` section that resolves to a stored integration secret when the conversation starts. Control characters are not allowed. The encrypted `{{variable | encryption_secret_ref}}` form used for per-caller credentials is not resolved here and is rejected when the assistant is saved.
      - `async` boolean — When `true`, the assistant hands the turn straight back to the model and the agent's answer is delivered into the conversation once it arrives, instead of the caller waiting for it in silence.
      - `timeout_ms` integer — Total budget, in milliseconds, for one call to this agent, including any time spent polling a task that is still running. Omit to inherit the assistant's tool timeout.
      - `poll_interval_ms` integer — How often, in milliseconds, to poll an agent task that has not finished yet. Defaults to 500.
      - `messages` union[] — Filler messages spoken while a call to this agent is in progress. `request_start` messages are spoken immediately when the call begins. `request_response_delayed` messages are spoken after `timing_ms` has elapsed only if the agent has not answered yet. Filler messages are not used when `async` is `true`.
        - union
          - object
            - `type` 'request_start', required — Speak the filler message immediately when the call to the agent begins.
            - `content` string, required — The text the assistant speaks.
            - `timing_ms` integer — An optional delay value. This value is ignored for `request_start` messages.
          - object
            - `type` 'request_response_delayed', required — Speak the filler message only if the agent has not answered yet after `timing_ms`.
            - `content` string, required — The text the assistant speaks.
            - `timing_ms` integer, required — How long to wait, in milliseconds, before speaking this message.
    - `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-3-5-pro' | 'assemblyai/universal-streaming' | 'xai/grok-stt' | 'soniox/stt-rt-v4' | 'soniox/stt-rt-v5' | 'nvidia/parakeet-v3' | 'omi-health/omi-med-stt-v1' | 'humain/realtime' | 'reson8/turns' | 'cohere/ar-stt' | '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-3-5-pro` is a multilingual streaming model with configurable turn detection. The legacy alias `assemblyai/universal-streaming` is still accepted and resolves to the same model. - `xai/grok-stt` is a multilingual Grok STT model. - `soniox/stt-rt-v4` and `soniox/stt-rt-v5` are multilingual streaming models with automatic language detection, configurable endpointing, term biasing (`context`), and `language_hints`. - `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection. - `omi-health/omi-med-stt-v1` is an English-only medical transcription model (Parakeet-based). - `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. - `cohere/ar-stt` is a non-streaming Arabic and English transcription model.
      - `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` and `soniox/stt-rt-v5`, `auto` omits the language hint and lets Soniox auto-detect; ISO 639-1 codes (e.g. `en`, `es`) bias detection toward that language; `settings.language_hints` can pin multiple languages at once instead. 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. For `cohere/ar-stt`, supported values are `ar` and `en`; unlike other models, this model does not auto-detect and defaults to `ar` when `language` is omitted.
      - `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-3-5-pro (and its legacy alias 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-3-5-pro (and its legacy alias 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-3-5-pro (and its legacy alias 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 and soniox/stt-rt-v5. When true, Soniox streams interim (non-final) results in addition to finalized transcripts.
        - `enable_endpoint_detection` boolean — Available only for soniox/stt-rt-v4 and soniox/stt-rt-v5. 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 and soniox/stt-rt-v5. Maximum silence (in milliseconds) before Soniox emits an end-of-utterance event. Only honored when `enable_endpoint_detection` is true.
        - `context` string — Available only for soniox/stt-rt-v4 and soniox/stt-rt-v5. A comma-separated list of terms to boost for recognition during transcription, for staff names, building names, or other domain-specific vocabulary. 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 Soniox.
        - `language_hints` string[] — Available only for soniox/stt-rt-v4 and soniox/stt-rt-v5. A list of ISO 639-1 language codes (e.g. `["nl", "fr"]`) to pin recognition to multiple languages at once, overriding the single hint derived from `language`.
    - `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` 'aicoustics' | 'krisp' | 'deepfilternet' | 'disabled' — The noise suppression engine to use. 'aicoustics' is STT-optimized and recommended for AI assistants (configure through noise_suppression_config). Use 'disabled' to turn off noise suppression.
      - `noise_suppression_config` object — Configuration for noise suppression. Applicable fields depend on the engine: 'attenuation_limit' and 'mode' only when noise_suppression is 'deepfilternet'; 'family', 'size' and 'enhancement_level' only when noise_suppression is 'aicoustics'.
        - `attenuation_limit` integer — Attenuation limit for noise suppression. Range: 0-100. Only applicable when noise_suppression is 'deepfilternet'.
        - `mode` 'advanced' — Mode for noise suppression configuration. Only applicable when noise_suppression is 'deepfilternet'.
        - `family` 'quail' — AiCoustics model family optimized for Voice AI and STT. Only applicable when noise_suppression is 'aicoustics'.
        - `size` 'vf' | 'vf_2_0_l' — AiCoustics model size. 'vf' tracks the latest model release; 'vf_2_0_l' is pinned to version 2.0 for consistent, predictable behavior. Only applicable when noise_suppression is 'aicoustics'.
        - `enhancement_level` number — AiCoustics enhancement intensity. Range: 0-1. Only applicable when noise_suppression is 'aicoustics'.
      - `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.
      - `fallback_destination` string — Destination number or SIP URI to transfer the caller to when the AI conversation ends abnormally, for example because of an assistant-side error, so the caller is not left in dead air. This only fires for abnormal ends: it does not fire when the conversation ends on purpose (the caller hung up, the assistant completed normally, the caller hung up after a relay handoff, or voicemail was detected), and it does not fire when the assistant already transferred or bridged the call.
      - `send_message_history_updates` boolean — Whether the assistant sends a `call.ai_gather.message_history_updated` webhook with the full message history every time the conversation history changes. Leave unset to inherit the `send_message_history_updates` value from the `ai_assistant_start` or `gather_using_ai` command that started the conversation. Setting it here is authoritative: `true` turns the webhooks on even when the start command did not request them, and `false` turns them off even when it did. Messages exchanged during a private warm transfer acceptance phase are never included.
      - `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'.
      - `disable_dtmf` boolean — Disable inbound DTMF for the entire call. Must be set to true if a 'pay' tool is configured anywhere on the assistant — on the main tool array or on any workflow node — enforced at write time.
      - `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.
      - `in_transit_data_locality` boolean — Requires every model call made for a web chat turn to be received and served inside your organization's data-locality region, rather than only stored there. Applies to web chat only — voice and messaging assistants are unaffected. Enabling it requires a data-locality region with in-region inference (USA, EU, AUS, UAE; see [Inference regions](https://developers.telnyx.com/docs/inference/models/regions)) and Telnyx-hosted models for the assistant, its fallback, and any conversation-flow node that overrides the model; the request is rejected otherwise. Once enabled, send chat requests to your region's API hostname: a request entering the platform in another region is rejected rather than forwarded, because forwarding it would already have moved the content across the border. Defaults to false.
    - `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.
      - `interrupt_prediction_threshold` number, nullable — Interrupt-prediction sensitivity, from 0.0 to 1.0. Set to null or 0.0 to disable interrupt prediction.
    - `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 final tool calls such as sending a summary or updating a record via webhook or function tools. Integration and MCP server tools are not available post-conversation; call-control tools (e.g. hangup, transfer) are also unavailable. 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).
              - …
            - `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.
              - …
            - `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
              - …
            - `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.
              - …
            - `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.
              - …
            - `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
              - …
            - `type` 'prompt' — Node kind discriminator. `prompt` is an LLM-driven step.
            - `voice_settings` VoiceSettings
              - …
          - 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.
              - …
            - `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. On update, a sent `tools` array fully replaces the assistant's inline tools; omit the field to leave them unchanged. Each tool type except `function`, `webhook`, and `client_side_tool` allows at most one instance per assistant, counted across inline `tools` and shared `tool_ids` combined.
              - …
            - `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.
              - …
      - `start_node_id` string, required — ID of the node where the conversation begins.

## Other responses

- `422` — Validation Error

## Changes

> 81 revisions in range; 1 not diffed.

- **2026-09-21** `1581f4d44566` — 2 warning
  - added the new `omi-health/omi-med-stt-v1` enum value to the `data/items/conversation_flow/nodes/items/oneOf[subschema #1: FlowNode]/transcription/model` response property for the response status `200`
  - added the new `omi-health/omi-med-stt-v1` enum value to the `data/items/transcription/model` response property for the response status `200`
- **2026-09-21** `d18924181c6e` — 1 info
  - added the optional property `data/items/interruption_settings/interrupt_prediction_threshold` to the response with the `200` status
- **2026-09-17** `4596ec306e59` — 2 warning
  - added the new `assemblyai/universal-3-5-pro` enum value to the `data/items/conversation_flow/nodes/items/oneOf[subschema #1: FlowNode]/transcription/model` response property for the response status `200`
  - added the new `assemblyai/universal-3-5-pro` enum value to the `data/items/transcription/model` response property for the response status `200`
- …earlier changes not shown

[Full history](https://skmtc.dev/team-telnyx/apis/telnyx-api-2/changes/ai/assistants/get.md)

---

[API](https://skmtc.dev/team-telnyx/apis/telnyx-api-2.md) · [All operations](https://skmtc.dev/team-telnyx/apis/telnyx-api-2/llms.txt) · [OpenAPI document](https://skmtc.dev/team-telnyx/apis/telnyx-api-2/revisions/f6e9ed754d05?raw)
