Creates a new AI assistant from the provided configuration, including its model, instructions, and attached tools, and returns the created assistant.
POST
/
ai
/
assistants
JavaScript
import Telnyx from 'telnyx';const client = new Telnyx({ apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted});const inferenceEmbedding = await client.ai.assistants.create({ instructions: 'instructions', name: 'name',});console.log(inferenceEmbedding.id);
import os
from telnyx import Telnyx
client = Telnyx(
api_key=os.environ.get("TELNYX_API_KEY"), # This is the default and can be omitted
)
inference_embedding = client.ai.assistants.create(
instructions="instructions",
name="name",
)
print(inference_embedding.id)
{
"errors": [
{
"code": "10036",
"title": "Resource is being processed",
"detail": "A request with this Idempotency-Key is already being processed.",
"source": {
"pointer": "/header/Idempotency-Key"
}
}
]
}
Optional opaque, unquoted key for safely retrying the same logical request. Keys must contain 1 to 255 letters, numbers, hyphens, or underscores. Generate a unique UUID v4 for each operation and reuse it only when retrying that operation with the same request. Invalid headers—including duplicate, empty, malformed, or overlong values—return 400 with error code 10015. A request already in progress with the same key returns 409; reusing the key with a different request returns 422. Only successful responses are replayed, for up to 24 hours. Do not include sensitive data in the key.
ID of the model to use when external_llm is not set. You can use the Get models API 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.
Deprecated for new integrations. Inline tool definitions available to the assistant. Prefer tool_ids to attach shared tools created with the AI Tools endpoints.
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.
Text that the assistant will use to start the conversation. This may be templated with 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.
This is only needed when using third-party inference providers selected by model. The identifier for an integration secret /v2/integration_secrets 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.
If telephony is enabled, the assistant will be able to make and receive calls. If messaging is enabled, the assistant will be able to send and receive messages.
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 for the full request/response format and timeout behavior.
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.
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).
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.
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.
Splits the conversation between a frontend model that talks to the caller and a backend model that does the work. On the GPT-Live route the frontend model cannot call tools at all — when it needs something done it raises a delegation and waits. On the chat completion route the frontend keeps a single delegate tool that returns immediately, so the conversation carries on while the backend works. Either way the backend's answer is spoken as commentary or kept as silent context, depending on speak_results. Beta feature.
Streams conversation and telephony events to a WebSocket server you host, and accepts messages injected back into the conversation. Telnyx opens the connection as a client, once per conversation. Delivery is best effort throughout: while the connection is down events are dropped rather than queued, and no socket failure is ever allowed to affect the call. Beta feature.
Conversation flow as supplied by API clients (create / update).
A directed graph of FlowNodeReq connected by FlowEdges. Validation
enforces unique node/edge IDs, that start_node_id references a real
node, and that every edge's endpoints reference real nodes.
Show child attributes
Example:
{ "edges": [ { "condition": { "prompt": "The caller is asking about a bill or charge.", "type": "llm" }, "id": "e_intake_to_billing", "start_node_id": "n_intake", "target": { "node_id": "n_billing", "type": "node" } }, { "condition": { "prompt": "The caller has explicitly asked for a human.", "type": "llm" }, "id": "e_intake_to_escalation_assistant", "start_node_id": "n_intake", "target": { "assistant_id": "assistant-human-handoff", "position": { "x": 600, "y": 80 }, "type": "assistant", "voice_mode": "distinct" } } ], "nodes": [ { "type": "prompt", "id": "n_intake", "instructions": "Greet the caller and ask what they're calling about.", "name": "Intake", "position": { "x": 120, "y": 80 }, "shared_tool_ids": ["tool-faq-kb"] }, { "type": "prompt", "id": "n_billing", "instructions": "Focus on billing questions. Look up the caller's latest invoice with the billing tool before answering.", "instructions_mode": "append", "model": "moonshotai/Kimi-K2.6", "name": "Billing", "position": { "x": 420, "y": 80 }, "shared_tool_ids": ["tool-billing-lookup"], "tools_mode": "append" } ], "start_node_id": "n_intake" }
ID of the model to use when external_llm is not set. You can use the Get models API 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.
The assistant's tools. Responses merge the assistant's shared Tools Library tools into this array alongside inline tools, each flagged shared: true; inline tools carry shared: false. On update, a sent tools array fully replaces the inline tools only — shared tools stay attached unless tool_ids changes. Each tool type except function, webhook, and client_side_tool allows at most one instance per assistant across both sources.
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.
Text that the assistant will use to start the conversation. This may be templated with 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.
This is only needed when using third-party inference providers selected by model. The identifier for an integration secret /v2/integration_secrets 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.
If telephony is enabled, the assistant will be able to make and receive calls. If messaging is enabled, the assistant will be able to send and receive messages.
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 for the full request/response format and timeout behavior.
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.
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).
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.
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.
Splits the conversation between a frontend model that talks to the caller and a backend model that does the work. On the GPT-Live route the frontend model cannot call tools at all — when it needs something done it raises a delegation and waits. On the chat completion route the frontend keeps a single delegate tool that returns immediately, so the conversation carries on while the backend works. Either way the backend's answer is spoken as commentary or kept as silent context, depending on speak_results. Beta feature.
Streams conversation and telephony events to a WebSocket server you host, and accepts messages injected back into the conversation. Telnyx opens the connection as a client, once per conversation. Delivery is best effort throughout: while the connection is down events are dropped rather than queued, and no socket failure is ever allowed to affect the call. Beta feature.
{ "edges": [ { "condition": { "prompt": "The caller is asking about a bill or charge.", "type": "llm" }, "id": "e_intake_to_billing", "start_node_id": "n_intake", "target": { "node_id": "n_billing", "type": "node" } }, { "condition": { "prompt": "The caller has explicitly asked for a human.", "type": "llm" }, "id": "e_intake_to_escalation_assistant", "start_node_id": "n_intake", "target": { "assistant_id": "assistant-human-handoff", "position": { "x": 600, "y": 80 }, "type": "assistant", "voice_mode": "distinct" } } ], "nodes": [ { "type": "prompt", "id": "n_intake", "instructions": "Greet the caller and ask what they're calling about.", "name": "Intake", "position": { "x": 120, "y": 80 }, "shared_tool_ids": ["tool-faq-kb"] }, { "type": "prompt", "id": "n_billing", "instructions": "Focus on billing questions. Look up the caller's latest invoice with the billing tool before answering.", "instructions_mode": "append", "model": "moonshotai/Kimi-K2.6", "name": "Billing", "position": { "x": 420, "y": 80 }, "shared_tool_ids": ["tool-billing-lookup"], "tools_mode": "append" } ], "start_node_id": "n_intake" }
Was this page helpful?
JavaScript
import Telnyx from 'telnyx';const client = new Telnyx({ apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted});const inferenceEmbedding = await client.ai.assistants.create({ instructions: 'instructions', name: 'name',});console.log(inferenceEmbedding.id);
import os
from telnyx import Telnyx
client = Telnyx(
api_key=os.environ.get("TELNYX_API_KEY"), # This is the default and can be omitted
)
inference_embedding = client.ai.assistants.create(
instructions="instructions",
name="name",
)
print(inference_embedding.id)
{
"errors": [
{
"code": "10036",
"title": "Resource is being processed",
"detail": "A request with this Idempotency-Key is already being processed.",
"source": {
"pointer": "/header/Idempotency-Key"
}
}
]
}
{"docsConfig":{"theme":"sequoia","$schema":"https://mintlify.com/docs.json","name":"Telnyx","description":"Infrastructure for real-time agents. Voice, AI, Edge Compute","colors":{"primary":"#00B688","light":"#00B688","dark":"#00B688"},"logo":{"light":"https://mintcdn.com/telnyx/v2FpkbJg6PQ53qHU/assets/images/site/logo.svg?fit=max\u0026auto=format\u0026n=v2FpkbJg6PQ53qHU\u0026q=85\u0026s=5ee3f61d11ba90a197dd9a1e3499fab6","dark":"https://mintcdn.com/telnyx/v2FpkbJg6PQ53qHU/assets/images/site/logo-dark.svg?fit=max\u0026auto=format\u0026n=v2FpkbJg6PQ53qHU\u0026q=85\u0026s=d65aaa12ec708c79e5833cbdea958055"},"favicon":"https://mintcdn.com/telnyx/t-qaBUa_gCxdRz_m/favicon.ico?fit=max\u0026auto=format\u0026n=t-qaBUa_gCxdRz_m\u0026q=85\u0026s=8291283238ab8c0e2a7a985e69f38c2f","background":{"decoration":"gradient"},"navbar":{"links":[{"icon":"triangle-exclamation","href":"/docs/development/api-fundamentals/api-errors","label":"Error codes"},{"icon":"headset","href":"https://telnyx.com/contact-us","label":"Contact us"},{"icon":"user","href":"https://portal.telnyx.com/#/login/sign-in","label":"Login"}],"primary":{"type":"button","label":"Sign Up","href":"https://telnyx.com/sign-up"}},"footer":{"socials":{"github":"https://github.com/team-telnyx","linkedin":"https://www.linkedin.com/company/telnyx","slack":"https://joinslack.telnyx.com","x":"https://x.com/telnyx"},"links":[{"header":"Resources","items":[{"label":"Pricing","href":"https://developers.telnyx.com/internal/pages/pricing"},{"label":"Compare Telnyx","href":"https://developers.telnyx.com/internal/pages/compare"},{"label":"Support center","href":"https://support.telnyx.com/en"},{"label":"SETI","href":"https://seti.telnyx.com"},{"label":"Agent platform configs","href":"https://github.com/team-telnyx/ai"},{"label":"About Telnyx","href":"https://developers.telnyx.com/internal/pages/about"},{"label":"Service status","href":"https://status.telnyx.com"}]},{"header":"Updates","items":[{"label":"Release notes","href":"https://telnyx.com/release-notes"}]},{"header":"Community","items":[{"label":"Low Latency Club","href":"https://lowlatencyclub.ai/"}]},{"header":"Legal","items":[{"label":"Privacy policy","href":"https://telnyx.com/privacy-policy"},{"label":"Terms and conditions","href":"https://telnyx.com/terms-and-conditions"}]}]},"seo":{"metatags":{"og:description":"Infrastructure for real-time agents. Voice, AI, Edge Compute","description":"Infrastructure for real-time agents. Voice, AI, Edge Compute"},"organization":{"name":"Telnyx","url":"https://telnyx.com","logo":"https://telnyx.com/favicon.ico","sameAs":["https://x.com/telnyx","https://www.linkedin.com/company/telnyx/","https://github.com/team-telnyx"]}},"fonts":{"heading":{"family":"PP Formula","weight":800,"source":"assets/fonts/PPFormula-Extrabold.woff2","format":"woff2"},"body":{"family":"Inter","weight":400,"source":"assets/fonts/Inter-Regular.woff2","format":"woff2"}},"styling":{"eyebrows":"breadcrumbs","latex":true},"integrations":{"gtm":{"tagId":"GTM-NRRX236"}},"banner":{"content":"Check out our upcoming events and meetups! [View events →](https://lowlatencyclub.ai/)","dismissible":true},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"navigation":{"global":{"anchors":[{"anchor":"Home","icon":"house","href":"/docs/overview"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"telnyx","hasAudioNarration":false,"actualSubdomain":"telnyx","customDomains":["developers.telnyx.com"],"gitSource":{"type":"github","owner":"team-telnyx","repo":"developer-docs-mintlify","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6aecc1177e2a3b454e46ab4a","collectionId":"e89de448-4ed6-4586-a5dc-1bb465c580ba","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6aecc1177e2a3b454e46ab4a"},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"ENABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6aecdffdcf361b99cc057bd9","clientVersion":"0.0.4074","searchFilterCounts":[{"language":"default","tag":"API Reference","count":601},{"language":"default","tag":"Calling","count":592},{"language":"default","tag":"Other APIs","count":406},{"language":"default","tag":"AI","count":395},{"language":"default","tag":"Messaging","count":353},{"language":"default","tag":"Numbers","count":287},{"language":"default","tag":"Agent Platform","count":282},{"language":"default","tag":"Assistants","count":202},{"language":"default","tag":"Voice API","count":178},{"language":"default","tag":"SMS \u0026 MMS","count":149}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"custom.css","content":"[class*=\"sidebar\"] [class*=\"tag\"],[class*=\"sidebar\"] [class*=\"badge\"],nav [class*=\"tag\"],nav [class*=\"badge\"]{font-size:0.8rem!important}#ot-sdk-btn-floating{left:auto!important;right:10px!important}body:has([aria-label=\"Preview Widget\"]) #ot-sdk-btn-floating{bottom:88px!important}#navbar .nav-tabs-item:has(>div>svg[style*=\"/book-open.svg\"]){display:none}.nav-tabs a.nav-tabs-item:not([aria-current=\"location\"]){display:none}#navbar div:has(>div>.nav-tabs>a.nav-tabs-item:first-child:last-child){display:none}@media (width >= 64rem){.txd-side{display:block}button[data-component-part=\"products-selector-trigger\"],button.tx-product-switcher{display:none!important}}#mobile-nav [data-component-part=\"products-selector-trigger\"],#mobile-nav #navigation-items>div:has(>div>button[aria-haspopup=\"menu\"]),#mobile-nav.tx-has-directory #navigation-items{display:none!important}#mobile-nav .tx-mobile-directory{padding:0;margin-bottom:1.5rem}#mobile-nav .tx-mobile-directory a,#mobile-nav .tx-mobile-directory .tx-dir-suite-head{min-height:2.75rem}#mobile-nav .tx-mobile-directory :is(a,.tx-dir-suite-head):focus-visible{outline:2px solid currentColor;outline-offset:-2px}.txd-shell{display:flex;gap:0;max-width:none;margin:0;padding:3rem 2rem 6rem 0}.txd-side{width:18rem;flex-shrink:0}.txd-main{flex:1;min-width:0;max-width:56rem;margin-left:11.75rem}@media (max-width: 80rem){.txd-main{margin-left:4rem}}@media (width \u003c 64rem){.txd-shell{display:block;padding:2rem 1.5rem 5rem}.txd-side{display:none}.txd-main{margin-left:0}}:is(#tx-directory,.tx-mobile-directory){margin:0 0 0.5rem;padding:0 0.5rem 0 1rem}:is(#tx-directory,.tx-mobile-directory) .tx-dir-label{font-size:0.72rem;font-weight:600;letter-spacing:0.06em;text-transform:uppercase;opacity:0.55;margin:0 0 0.4rem}:is(#tx-directory,.tx-mobile-directory) .tx-dir-label-gap{margin-top:1.5rem}:is(#tx-directory,.tx-mobile-directory) .tx-dir-link,:is(#tx-directory,.tx-mobile-directory) summary{display:flex;align-items:center;cursor:pointer;font-size:0.875rem;line-height:1.25rem;padding:0.35rem 0.5rem;border-radius:0.375rem;color:rgb(55 65 81);text-decoration:none}html.dark :is(#tx-directory,.tx-mobile-directory) .tx-dir-link,html.dark :is(#tx-directory,.tx-mobile-directory) summary{color:rgb(156 163 175)}:is(#tx-directory,.tx-mobile-directory) .tx-dir-link:hover,:is(#tx-directory,.tx-mobile-directory) summary:hover{color:rgb(17 24 39);background:rgb(0 0 0 / 0.04)}:is(#tx-directory,.tx-mobile-directory) .tx-dir-link[aria-current=\"page\"]{color:#00b688;background:transparent;box-shadow:none;font-weight:400;text-shadow:-0.2px 0 0 currentColor, 0.2px 0 0 currentColor}html.dark :is(#tx-directory,.tx-mobile-directory) .tx-dir-link:hover,html.dark :is(#tx-directory,.tx-mobile-directory) summary:hover{color:rgb(229 231 235);background:rgb(255 255 255 / 0.06)}html.dark :is(#tx-directory,.tx-mobile-directory) .tx-dir-link[aria-current=\"page\"]{color:#5eead4;background:transparent;box-shadow:none}:is(#tx-directory,.tx-mobile-directory) .tx-dir-soon,:is(#tx-directory,.tx-mobile-directory) .tx-dir-soon:hover,html.dark :is(#tx-directory,.tx-mobile-directory) .tx-dir-soon,html.dark :is(#tx-directory,.tx-mobile-directory) .tx-dir-soon:hover{cursor:default;opacity:0.45;background:transparent;color:inherit}:is(#tx-directory,.tx-mobile-directory) .tx-dir-soon sup{font-size:0.6rem;line-height:1;letter-spacing:0.05em;text-transform:uppercase;margin-left:0.4rem;vertical-align:super}:is(#tx-directory,.tx-mobile-directory) .tx-dir-suite{margin-bottom:0.15rem}:is(#tx-directory,.tx-mobile-directory) .tx-dir-suite-head{display:flex;align-items:center;cursor:pointer;user-select:none;font-size:0.875rem;line-height:1.25rem;font-weight:500;padding:0.35rem 0.5rem;border-radius:0.375rem;color:rgb(55 65 81)}html.dark :is(#tx-directory,.tx-mobile-directory) .tx-dir-suite-head{color:rgb(156 163 175)}:is(#tx-directory,.tx-mobile-directory) .tx-dir-suite-head:hover{color:rgb(17 24 39);background:rgb(0 0 0 / 0.04)}html.dark :is(#tx-directory,.tx-mobile-directory) .tx-dir-suite-head:hover{color:rgb(229 231 235);background:rgb(255 255 255 / 0.06)}:is(#tx-directory,.tx-mobile-directory) .tx-dir-suite-head::after{content:'';width:0.42rem;height:0.42rem;margin-left:auto;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(-45deg);transition:transform 0.15s;flex-shrink:0;opacity:0.7}:is(#tx-directory,.tx-mobile-directory) .tx-dir-suite.open>.tx-dir-suite-head::after{transform:rotate(45deg)}:is(#tx-directory,.tx-mobile-directory) .tx-dir-suite.open>.tx-dir-suite-head{color:rgb(17 24 39);background:rgb(0 0 0 / 0.04);font-weight:600}html.dark :is(#tx-directory,.tx-mobile-directory) .tx-dir-suite.open>.tx-dir-suite-head{color:rgb(229 231 235);background:rgb(255 255 255 / 0.06)}:is(#tx-directory,.tx-mobile-directory) .tx-dir-suite>ul{display:none}:is(#tx-directory,.tx-mobile-directory) .tx-dir-suite.open>ul{display:block}:is(#tx-directory,.tx-mobile-directory) ul{margin:0.15rem 0 0.5rem;padding:0}:is(#tx-directory,.tx-mobile-directory) li{list-style:none}:is(#tx-directory,.tx-mobile-directory) li a{display:flex;align-items:center;font-size:0.875rem;line-height:1.25rem;padding:0.3rem 0.5rem 0.3rem 1.6rem;border-radius:0.375rem;color:rgb(107 114 128);text-decoration:none}:is(#tx-directory,.tx-mobile-directory) .tx-dir-section-item{font-weight:500}html.dark :is(#tx-directory,.tx-mobile-directory) li a{color:rgb(156 163 175)}:is(#tx-directory,.tx-mobile-directory) li a:hover{color:rgb(17 24 39);background:rgb(0 0 0 / 0.04)}html.dark :is(#tx-directory,.tx-mobile-directory) li a:hover{color:rgb(229 231 235);background:rgb(255 255 255 / 0.06)}:is(#tx-directory,.tx-mobile-directory) .tx-dir-icon{display:inline-block;width:1rem;height:1rem;flex-shrink:0;margin-right:0.5rem;background-color:currentColor;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:contain;mask-size:contain}.txi-arrows-left-right-to-line{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/arrows-left-right-to-line.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/arrows-left-right-to-line.svg\")}.txi-bolt{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/bolt.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/bolt.svg\")}.txi-brain{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/brain.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/brain.svg\")}.txi-brain-circuit{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/brain-circuit.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/brain-circuit.svg\")}.txi-brands-whatsapp{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/brands/whatsapp.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/brands/whatsapp.svg\")}.txi-broadcast-tower{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/broadcast-tower.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/broadcast-tower.svg\")}.txi-browser{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/browser.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/browser.svg\")}.txi-circle-nodes{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/circle-nodes.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/circle-nodes.svg\")}.txi-clone{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/clone.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/clone.svg\")}.txi-cloud{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/cloud.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/cloud.svg\")}.txi-code{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/code.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/code.svg\")}.txi-comment-sms{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/comment-sms.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/comment-sms.svg\")}.txi-cubes{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/cubes.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/cubes.svg\")}.txi-database{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/database.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/database.svg\")}.txi-door-open{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/door-open.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/door-open.svg\")}.txi-envelope{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/envelope.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/envelope.svg\")}.txi-eye{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/eye.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/eye.svg\")}.txi-file-certificate{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/file-certificate.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/file-certificate.svg\")}.txi-fingerprint{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/fingerprint.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/fingerprint.svg\")}.txi-folder-tree{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/folder-tree.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/folder-tree.svg\")}.txi-globe{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/globe.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/globe.svg\")}.txi-hard-drive{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/hard-drive.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/hard-drive.svg\")}.txi-hashtag{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/hashtag.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/hashtag.svg\")}.txi-headset{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/headset.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/headset.svg\")}.txi-key{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/key.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/key.svg\")}.txi-layer-group{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/layer-group.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/layer-group.svg\")}.txi-magnifying-glass{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/magnifying-glass.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/magnifying-glass.svg\")}.txi-message{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/message.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/message.svg\")}.txi-message-dots{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/message-dots.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/message-dots.svg\")}.txi-microchip-ai{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/microchip-ai.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/microchip-ai.svg\")}.txi-microphone{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/microphone.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/microphone.svg\")}.txi-network-wired{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/network-wired.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/network-wired.svg\")}.txi-phone{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/phone.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/phone.svg\")}.txi-phone-volume{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/phone-volume.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/phone-volume.svg\")}.txi-plug{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/plug.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/plug.svg\")}.txi-right-left{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/right-left.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/right-left.svg\")}.txi-robot{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/robot.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/robot.svg\")}.txi-server{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/server.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/server.svg\")}.txi-share-nodes{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/share-nodes.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/share-nodes.svg\")}.txi-shield{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/shield.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/shield.svg\")}.txi-shield-check{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/shield-check.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/shield-check.svg\")}.txi-signal{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/signal.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/signal.svg\")}.txi-sim-card{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/sim-card.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/sim-card.svg\")}.txi-split{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/split.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/split.svg\")}.txi-table{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/table.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/table.svg\")}.txi-tower-control{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/tower-control.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/tower-control.svg\")}.txi-train-tunnel{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/train-tunnel.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/train-tunnel.svg\")}.txi-video{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/video.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/video.svg\")}.txi-wand-magic-sparkles{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/wand-magic-sparkles.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/wand-magic-sparkles.svg\")}.txi-waveform{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/waveform.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/waveform.svg\")}.txi-waveform-lines{-webkit-mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/waveform-lines.svg\");mask-image:url(\"https://d3gk2c5xim1je2.cloudfront.net/fontawesome/v7.2.0/regular/waveform-lines.svg\")}.txd-main .txd-h1{font-family:var(--font-family-headings-custom, \"PP Formula\"), -apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif;font-size:2.1rem;font-weight:500;letter-spacing:-0.01em;margin:1.2rem 0 0.4rem;color:rgb(22 28 26)}html.dark .txd-main .txd-h1{color:rgb(229 231 235)}.txd-main .txd-lead{font-size:1.3rem;line-height:1.55;font-weight:500;margin:0.9rem 0 1.3rem;color:rgb(31 41 55)}html.dark .txd-main .txd-lead{color:rgb(209 213 219)}.txd-main .txd-h2{font-family:var(--font-family-headings-custom, \"PP Formula\"), -apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif;font-size:1.45rem;font-weight:500;margin:2.4rem 0 0.4rem;color:rgb(22 28 26)}html.dark .txd-main .txd-h2{color:rgb(229 231 235)}.txd-main .txd-section-h{font-size:1.05rem;font-weight:600;margin:1.8rem 0 0.2rem;opacity:0.85}.txd-main .txd-p{margin:0.7rem 0 1rem;line-height:1.65;color:rgb(75 85 99)}html.dark .txd-main .txd-p{color:rgb(156 163 175)}.txd-main .txd-p a{text-decoration:underline}.txd-main .txd-h1{max-width:46rem;line-height:1.12}.txd-main .txd-hero-copy{max-width:45rem}.txd-main .txd-follow-up{margin-top:1rem}.txd-main .txd-follow-up a{color:#00b688;font-weight:600;text-decoration:none}.txd-main .txd-follow-up a:hover{text-decoration:underline}.txd-main a:focus-visible{outline:2px solid #00b688;outline-offset:3px}@media (max-width: 48rem){.txd-main .txd-h1{font-size:1.9rem}}@media (min-width: 64.01rem) and (max-width: 90rem){.txd-main{margin-right:4rem}}.rm-explorer{--rm-border: rgb(15 23 42 / 14%);--rm-muted: #5f6b68;--rm-soft: #f6f8f7}.dark .rm-explorer{--rm-border: rgb(255 255 255 / 14%);--rm-muted: #a2aaa8;--rm-soft: #151a19}#resource-map-toolbar{position:sticky;top:5rem;z-index:20;margin:1.25rem 0 1.75rem;padding:.75rem 0;background:var(--rm-surface, #fff);border-bottom:1px solid var(--rm-border)}.dark #resource-map-toolbar{background:#0b0e0d}.rm-controls{display:grid;grid-template-columns:minmax(15rem, 1fr) minmax(10rem, auto) auto;gap:.625rem;align-items:center}.rm-search{position:relative;min-width:0}.rm-search svg{position:absolute;top:50%;left:.75rem;width:1rem;height:1rem;color:var(--rm-muted);fill:none;stroke:currentColor;stroke-width:1.8;transform:translateY(-50%);pointer-events:none}.rm-search input,.rm-area-select,.rm-collapse,.rm-clear,.rm-empty button{min-height:2.5rem;color:inherit;background:transparent;border:1px solid var(--rm-border);border-radius:.5rem;font:inherit;font-size:.875rem}.rm-search input{width:100%;padding:.58rem 2.6rem .58rem 2.35rem}.rm-search input::placeholder{color:var(--rm-muted);opacity:1}.rm-shortcut{position:absolute;top:50%;right:.65rem;display:grid;width:1.5rem;height:1.5rem;place-items:center;color:var(--rm-muted);background:var(--rm-soft);border:1px solid var(--rm-border);border-radius:.35rem;font:inherit;font-size:.72rem;transform:translateY(-50%);pointer-events:none}.rm-area-wrap{position:relative;max-width:13rem}.rm-area-select{width:100%;max-width:13rem;padding:.55rem 2.25rem .55rem .75rem;appearance:none;cursor:pointer}.rm-area-caret{position:absolute;top:50%;right:.85rem;width:.45rem;height:.45rem;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:translateY(-70%) rotate(45deg);pointer-events:none}.rm-collapse,.rm-clear,.rm-empty button{padding:.5rem .75rem;font-weight:650;cursor:pointer}.rm-search input:focus-visible,.rm-area-select:focus-visible,.rm-collapse:focus-visible,.rm-clear:focus-visible,.rm-empty button:focus-visible{outline:2px solid #00b688;outline-offset:2px;border-color:#00b688;box-shadow:none!important}.rm-collapse:hover,.rm-clear:hover,.rm-empty button:hover{color:#08785d;background:var(--rm-soft)}.dark .rm-collapse:hover,.dark .rm-clear:hover,.dark .rm-empty button:hover{color:#5eead4}.rm-meta{display:flex;min-height:1.65rem;align-items:center;justify-content:space-between;gap:.75rem;padding:.45rem .15rem 0}.rm-status{color:var(--rm-muted);font-size:.78rem;line-height:1.35}.rm-clear{min-height:1.8rem;padding:.2rem .55rem;border-color:transparent;font-size:.78rem}.rm-empty{display:grid;justify-items:start;gap:.35rem;margin:-.5rem 0 1.75rem;padding:1.1rem 1.2rem;color:var(--rm-muted);background:var(--rm-soft);border:1px solid var(--rm-border);border-radius:.75rem;font-size:.875rem}.rm-empty strong{color:inherit;font-size:.95rem}.rm-empty button{min-height:2.2rem;margin-top:.35rem}.rm-resource-list{display:block!important;margin:0 0 .75rem!important;border-color:var(--rm-border)!important;border-top:0!important;border-radius:0 0 .75rem .75rem!important}.rm-resource-list>details.accordion{margin:0!important;border:0!important;border-radius:0!important}.rm-resource-list>details.accordion+details.accordion{border-top:1px solid var(--rm-border)!important}.rm-resource-list>details.accordion>summary{min-height:3rem;padding:.7rem .9rem!important;border-radius:0!important}.rm-resource-list>details.accordion:first-child>summary{border-radius:0!important}.rm-resource-list>details.accordion:last-child:not([open])>summary{border-radius:0 0 .75rem .75rem!important}.rm-resource-list [data-component-part=\"accordion-title\"]{display:flex;min-width:0;align-items:baseline;justify-content:space-between;gap:1rem}.rm-resource-name{min-width:0;overflow-wrap:anywhere;font-weight:650}.rm-method-count{flex:0 0 auto;color:var(--rm-muted);font-size:.75rem;font-weight:500;white-space:nowrap}.rm-resource-list details[open]>summary{background:var(--rm-soft)}.rm-resource-list details[open] [data-component-part=\"accordion-content\"]{margin-right:1rem;margin-left:1rem}.rm-resource-list tbody tr.rm-row-match{background:rgb(0 182 136 / 8%)}.rm-resource-list td:first-child code{white-space:nowrap}.rm-resource-list tbody tr[hidden],.rm-explorer h2[hidden],.rm-resource-list[hidden],.rm-empty[hidden],.rm-collapse[hidden],.rm-clear[hidden]{display:none!important}.rm-explorer h2{position:relative;min-height:3rem;margin:.45rem 0 0!important;scroll-margin-top:10rem;border:1px solid var(--rm-border);border-radius:.75rem}.rm-explorer h2.rm-section-open{border-radius:.75rem .75rem 0 0}.rm-section-toggle{display:grid;width:100%;min-height:3rem;grid-template-columns:minmax(0, 1fr) auto auto;align-items:center;gap:.75rem;padding:.6rem .9rem;color:inherit;text-align:left;background:transparent;border:0;cursor:pointer}.rm-section-toggle:hover,.rm-section-toggle:focus-visible{background:var(--rm-soft)}.rm-section-toggle:focus-visible{outline:2px solid #00b688;outline-offset:2px;border-radius:.7rem}.rm-section-name{font-size:1rem;font-weight:700}.rm-section-count{display:grid;min-width:1.65rem;min-height:1.4rem;place-items:center;padding:3px 6px;color:#08785d;background:rgb(0 182 136 / 10%);border-radius:.35rem;font-size:12px;font-weight:700;line-height:16px;white-space:nowrap}.dark .rm-section-count{color:#5eead4;background:#12302b}.rm-section-caret{width:.5rem;height:.5rem;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg) translateY(-.15rem)}.rm-section-toggle[aria-expanded=\"true\"] .rm-section-caret{transform:rotate(225deg) translate(-.1rem, -.05rem)}@media (max-width: 767px){#resource-map-toolbar{position:static;top:auto;z-index:auto;margin-top:1rem;padding-top:.6rem}.rm-controls{grid-template-columns:minmax(0, 1fr) auto}.rm-search{grid-column:1 / -1}.rm-search input{padding-right:.75rem}.rm-shortcut{display:none}.rm-area-wrap,.rm-area-select{width:100%;max-width:none}.rm-resource-list [data-component-part=\"accordion-title\"]{gap:.65rem}.rm-method-count{font-size:.7rem}.rm-resource-list table,.rm-resource-list tbody{display:block;width:100%;min-width:0!important}.rm-resource-list thead{display:none}.rm-resource-list tbody tr{display:grid;width:100%;grid-template-columns:minmax(0, 1fr);gap:.45rem;padding:.75rem 0}.rm-resource-list tbody tr+tr{border-top:1px solid var(--rm-border)}.rm-resource-list tbody td{display:grid;width:100%;min-width:0!important;grid-template-columns:4.5rem minmax(0, 1fr);align-items:start;gap:.5rem;padding:0!important;border:0!important}.rm-resource-list tbody td::before{color:var(--rm-muted);font-size:.68rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}.rm-resource-list tbody td:first-child::before{content:\"Method\"}.rm-resource-list tbody td:last-child::before{content:\"Endpoint\"}.rm-resource-list tbody td code,.rm-resource-list tbody td a{min-width:0;white-space:normal!important;overflow-wrap:anywhere}}@media (prefers-reduced-motion: reduce){.rm-explorer *,.rm-explorer *::before,.rm-explorer *::after{scroll-behavior:auto!important;transition-duration:.01ms!important}}.sdk-launchpad{--sdk-border: #d8e1de;--sdk-panel: #ffffff;margin:1rem 0 1.5rem;padding:1rem;overflow:hidden;color:inherit;background:var(--sdk-panel);border:1px solid var(--sdk-border);border-radius:12px}.dark .sdk-launchpad{--sdk-border: #293431;--sdk-panel: #101513}.sdk-launchpad-kicker{margin:0 0 .25rem!important;color:#08785d;font-size:.68rem;font-weight:800;letter-spacing:.1em}.dark .sdk-launchpad-kicker{color:#5eead4}.sdk-launchpad>h2{margin-top:.25rem}.sdk-launchpad [role=\"tablist\"]{display:flex;flex-wrap:wrap;gap:.25rem}.sdk-launchpad [role=\"tab\"]{min-width:56px;min-height:44px}.sdk-launchpad [role=\"tab\"][aria-selected=\"true\"]{color:#08785d!important}.dark .sdk-launchpad [role=\"tab\"][aria-selected=\"true\"]{color:#5eead4!important}.sdk-launchpad [role=\"tab\"]:focus-visible,.sdk-launchpad a:focus-visible,.sdk-launchpad-code:focus-visible{outline:2px solid #08785d;outline-offset:2px}.dark .sdk-launchpad [role=\"tab\"]:focus-visible,.dark .sdk-launchpad a:focus-visible,.dark .sdk-launchpad-code:focus-visible{outline-color:#5eead4}.sdk-launchpad-code{max-width:100%;overflow-x:auto;border-radius:.5rem}.sdk-launchpad-code pre{max-width:none;overflow-x:visible!important}.sdk-launchpad-code button{min-width:44px;min-height:44px}#content-area:has(#sdk-launchpad) .chat-assistant-floating-input{display:none}@media (max-width: 640px){.sdk-launchpad{margin-top:.75rem;padding:.75rem}.sdk-launchpad-kicker{display:none}.sdk-launchpad [role=\"tablist\"]{display:grid;grid-template-columns:repeat(6, minmax(0, 1fr));gap:.2rem;overflow:visible}.sdk-launchpad [role=\"tab\"]{min-width:0;min-height:44px;padding-inline:.2rem;font-size:.75rem;line-height:1.15;white-space:nowrap}}.sdk-directory li{margin-block:.5rem}.mdx-content table td{min-width:0!important}.mdx-content table td :is(code,a){overflow-wrap:anywhere}.mdx-content table :is(th,td):first-child code{white-space:nowrap;word-break:normal;overflow-wrap:normal}@media (min-width: 768px){.tx-table-grid table{table-layout:fixed}.tx-table-grid table :is(th,td):first-child{width:40%}}@media (min-width: 768px){.tx-table-grid-3 table{table-layout:fixed}.tx-table-grid-3 table :is(th,td):first-child{width:22%}.tx-table-grid-3 table :is(th,td):last-child{width:18%}}.tx-retirement-banner{margin-bottom:1.5rem}.tx-retirement-banner>div{margin:0}@media (min-width: 1024px){.tx-retirement-banner{position:sticky;top:calc(6rem + var(--banner-height, 0px));z-index:20;padding-top:.5rem;background:rgb(var(--background-light, 255 255 255))}.dark .tx-retirement-banner{background:rgb(var(--background-dark, 9 12 14))}}#content>.callout:first-child{margin-top:0}#content strong{font-weight:600}"}],"page":{"pagePath":"api-reference/assistants/create-an-assistant","slug":"/api-reference/assistants/create-an-assistant","pageMetadata":{"title":"Create an assistant","description":"Creates a new AI assistant from the provided configuration, including its model, instructions, and attached tools, and returns the created assistant.","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants","href":"/api-reference/assistants/create-an-assistant","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Creates a new AI assistant from the provided configuration, including its model, instructions, and attached tools, and returns the created assistant.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Create an assistant","description":"Creates a new AI assistant from the provided configuration, including its model, instructions, and attached tools, and returns the created assistant.","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants","href":"/api-reference/assistants/create-an-assistant","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":["/_mintlify/custom/telnyx/a2dd5aaa2ff5831a/reading-progress.js","/_mintlify/custom/telnyx/7b77ce9cedb163fd/webmcp-init.js","/_mintlify/custom/telnyx/7fbfee588ac7ad38/structured-data.js","/_mintlify/custom/telnyx/41d9633b1a2dd405/scripts/tests/generate-llms-txt.test.js","/_mintlify/custom/telnyx/8851ad5fd6e9b5c7/scripts/tests/direct-source-workflows.test.js","/_mintlify/custom/telnyx/7ad13bb6588be22f/scripts/tests/redirects.test.js","/_mintlify/custom/telnyx/f981035eb45fcbdb/scripts/tests/generate-error-catalog.test.js","/_mintlify/custom/telnyx/132bc205f55282a5/scripts/tests/sync-llms-automerge.test.js","/_mintlify/custom/telnyx/05e787f15f45952b/scripts/tests/webhook-catalog-lifecycle.test.js","/_mintlify/custom/telnyx/01b840b27496e6c8/scripts/tests/repository-structure.test.js","/_mintlify/custom/telnyx/5ebc7d6e18012563/scripts/tests/legacy-content-usage.test.js","/_mintlify/custom/telnyx/ac1f21e68bf4050a/scripts/docs/check-llms-links.js","/_mintlify/custom/telnyx/5f7d2f1ae375b9ad/scripts/docs/check-llms-native-routes.js","/_mintlify/custom/telnyx/b8d13287c2dcc5b9/scripts/docs/fetch-coverage.js","/_mintlify/custom/telnyx/e0a29f76f2645359/scripts/docs/generate-error-catalog.js","/_mintlify/custom/telnyx/9ffa8f6166445a46/scripts/docs/generate-llms-txt.js","/_mintlify/custom/telnyx/f1f111fe784c3ede/scripts/docs/update-tts-voices.js","/_mintlify/custom/telnyx/c48ad0189f7f1c57/scripts/docs/build-sdk-doc-pages.js","/_mintlify/custom/telnyx/f840117777d76f9e/scripts/tests/sdk-doc-pages.test.js","/_mintlify/custom/telnyx/414c53c50b0e1968/resource-map-filter.js","/_mintlify/custom/telnyx/80af622b3010a712/scripts/tests/sdk-language-switcher.test.js","/_mintlify/custom/telnyx/52fa0fbcb966f8b6/sdk-language-switcher.js","/_mintlify/custom/telnyx/660ec334a362cf1c/home-directory.js","/_mintlify/custom/telnyx/33d3f1dbdec08735/scripts/generate-home-directory.js","/_mintlify/custom/telnyx/137e3eb8e1d1d85a/scripts/tests/api-fundamentals.test.js","/_mintlify/custom/telnyx/24a8eed3a5010d4c/scripts/tests/agent-sdk-workflow.test.js","/_mintlify/custom/telnyx/abc2169efcd5115c/scripts/tests/homepage-overview.test.js","/_mintlify/custom/telnyx/8edf49ac62deef02/scripts/tests/batch-detail-records-navigation.test.js","/_mintlify/custom/telnyx/e005178572336f01/scripts/tests/api-discoverability.test.js","/_mintlify/custom/telnyx/78cb83896fbea5cf/scripts/tests/home-directory.test.js","/_mintlify/custom/telnyx/11ae45253e6b7be6/scripts/tests/agent-readiness.test.js","/_mintlify/custom/telnyx/82396d5a75077c2a/scripts/tests/sample-workflow-regressions.test.js","/_mintlify/custom/telnyx/5f6625c0420c9328/scripts/tests/openapi-mintlify-parsing.test.js","/_mintlify/custom/telnyx/c7dca602ca9641ec/scripts/tests/llms-markdown-assets.test.js","/_mintlify/custom/telnyx/02d6acd7c86b79f9/scripts/tests/agent-browser-quickstart.test.js"],"openApiReferenceData":{"operation":{"tags":["Assistants"],"summary":"Create an assistant","description":"Creates a new AI assistant from the provided configuration, including its model, instructions, and attached tools, and returns the created assistant.","operationId":"create_new_assistant_public_assistants_post","parameters":["7c5f76da-e2e2-4e11-b5c6-459ea4c68564"],"requestBody":"cf59bd16-f682-4d58-84fc-78b303178d90","responses":{"200":"1b39a950-572c-4c61-b34a-a8010c2ae9c4","400":"830c28a4-8fe9-4cac-b8e0-7a5cf026f2d5","409":"3ff5470f-dc53-4d2f-ab01-914012e2821c","413":"a16cb406-84d3-4f55-afff-74a3e8272ca8","422":"8d19f324-3cf8-432e-aa73-2e872c001bdd","503":"6e4d4866-e0bf-4fd5-8bc6-e09c78b28d77"},"x-codeSamples":[{"lang":"JavaScript","source":"import Telnyx from 'telnyx';\n\nconst client = new Telnyx({\n apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted\n});\n\nconst inferenceEmbedding = await client.ai.assistants.create({\n instructions: 'instructions',\n name: 'name',\n});\n\nconsole.log(inferenceEmbedding.id);"},{"lang":"Python","source":"import os\nfrom telnyx import Telnyx\n\nclient = Telnyx(\n api_key=os.environ.get(\"TELNYX_API_KEY\"), # This is the default and can be omitted\n)\ninference_embedding = client.ai.assistants.create(\n instructions=\"instructions\",\n name=\"name\",\n)\nprint(inference_embedding.id)\n"},{"lang":"Go","source":"package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/team-telnyx/telnyx-go\"\n\t\"github.com/team-telnyx/telnyx-go/option\"\n)\n\nfunc main() {\n\tclient := telnyx.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tinferenceEmbedding, err := client.AI.Assistants.New(context.TODO(), telnyx.AIAssistantNewParams{\n\t\tInstructions: \"instructions\",\n\t\tName: \"name\",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", inferenceEmbedding.ID)\n}\n"},{"lang":"Java","source":"package com.telnyx.sdk.example;\n\nimport com.telnyx.sdk.client.TelnyxClient;\nimport com.telnyx.sdk.client.okhttp.TelnyxOkHttpClient;\nimport com.telnyx.sdk.models.ai.assistants.AssistantCreateParams;\nimport com.telnyx.sdk.models.ai.assistants.InferenceEmbedding;\n\npublic final class Main {\n private Main() {}\n\n public static void main(String[] args) {\n TelnyxClient client = TelnyxOkHttpClient.fromEnv();\n\n AssistantCreateParams params = AssistantCreateParams.builder()\n .instructions(\"instructions\")\n .name(\"name\")\n .build();\n InferenceEmbedding inferenceEmbedding = client.ai().assistants().create(params);\n }\n}"},{"lang":"Ruby","source":"require \"telnyx\"\n\ntelnyx = Telnyx::Client.new(api_key: \"My API Key\")\n\ninference_embedding = telnyx.ai.assistants.create(instructions: \"instructions\", name: \"name\")\n\nputs(inference_embedding)"},{"lang":"PHP","source":"\u003c?php\n\nrequire_once dirname(__DIR__) . '/vendor/autoload.php';\n\nuse Telnyx\\Client;\nuse Telnyx\\AI\\Assistants\\EnabledFeatures;\nuse Telnyx\\Core\\Exceptions\\APIException;\n\n$client = new Client(apiKey: getenv('TELNYX_API_KEY') ?: 'My API Key');\n\ntry {\n $inferenceEmbedding = $client->ai->assistants->create(\n instructions: 'instructions',\n name: 'name',\n conversationFlow: [\n 'nodes' => [\n [\n 'id' => 'n_intake',\n 'instructions' => 'Greet the caller and ask what they\\'re calling about.',\n 'externalLlm' => [\n 'baseURL' => 'base_url',\n 'model' => 'model',\n 'authenticationMethod' => 'token',\n 'certificateRef' => 'certificate_ref',\n 'forwardMetadata' => true,\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'tokenRetrievalURL' => 'token_retrieval_url',\n ],\n 'instructionsMode' => 'replace',\n 'llmAPIKeyRef' => 'my-key-ref',\n 'model' => 'moonshotai/Kimi-K2.6',\n 'name' => 'Intake',\n 'position' => ['x' => 120, 'y' => 80],\n 'sharedToolIDs' => ['tool-faq-kb'],\n 'toolsMode' => 'replace',\n 'transcription' => [\n 'apiKeyRef' => 'api_key_ref',\n 'language' => 'language',\n 'model' => 'deepgram/flux',\n 'region' => 'region',\n 'settings' => [\n 'eagerEotThreshold' => 0.3,\n 'enableEndpointDetection' => true,\n 'endOfTurnConfidenceThreshold' => 0,\n 'eotThreshold' => 0.5,\n 'eotTimeoutMs' => 500,\n 'interimResults' => true,\n 'keyterm' => 'keyterm',\n 'maxEndpointDelayMs' => 500,\n 'maxTurnSilence' => 100,\n 'minTurnSilence' => 100,\n 'numerals' => true,\n 'smartFormat' => true,\n ],\n ],\n 'type' => 'prompt',\n 'voiceSettings' => [\n 'voice' => 'voice',\n 'apiKeyRef' => 'api_key_ref',\n 'backgroundAudio' => [\n 'type' => 'predefined_media',\n 'value' => 'silence',\n 'volume' => 0.1,\n ],\n 'expressiveMode' => true,\n 'languageBoost' => 'auto',\n 'similarityBoost' => 0,\n 'speed' => 0,\n 'style' => 0,\n 'temperature' => 0,\n 'useSpeakerBoost' => true,\n 'voiceSpeed' => 0,\n ],\n ],\n [\n 'id' => 'n_billing',\n 'instructions' => 'Focus on billing questions. Look up the caller\\'s latest invoice with the billing tool before answering.',\n 'externalLlm' => [\n 'baseURL' => 'base_url',\n 'model' => 'model',\n 'authenticationMethod' => 'token',\n 'certificateRef' => 'certificate_ref',\n 'forwardMetadata' => true,\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'tokenRetrievalURL' => 'token_retrieval_url',\n ],\n 'instructionsMode' => 'append',\n 'llmAPIKeyRef' => 'my-key-ref',\n 'model' => 'moonshotai/Kimi-K2.6',\n 'name' => 'Billing',\n 'position' => ['x' => 420, 'y' => 80],\n 'sharedToolIDs' => ['tool-billing-lookup'],\n 'toolsMode' => 'append',\n 'transcription' => [\n 'apiKeyRef' => 'api_key_ref',\n 'language' => 'language',\n 'model' => 'deepgram/flux',\n 'region' => 'region',\n 'settings' => [\n 'eagerEotThreshold' => 0.3,\n 'enableEndpointDetection' => true,\n 'endOfTurnConfidenceThreshold' => 0,\n 'eotThreshold' => 0.5,\n 'eotTimeoutMs' => 500,\n 'interimResults' => true,\n 'keyterm' => 'keyterm',\n 'maxEndpointDelayMs' => 500,\n 'maxTurnSilence' => 100,\n 'minTurnSilence' => 100,\n 'numerals' => true,\n 'smartFormat' => true,\n ],\n ],\n 'type' => 'prompt',\n 'voiceSettings' => [\n 'voice' => 'voice',\n 'apiKeyRef' => 'api_key_ref',\n 'backgroundAudio' => [\n 'type' => 'predefined_media',\n 'value' => 'silence',\n 'volume' => 0.1,\n ],\n 'expressiveMode' => true,\n 'languageBoost' => 'auto',\n 'similarityBoost' => 0,\n 'speed' => 0,\n 'style' => 0,\n 'temperature' => 0,\n 'useSpeakerBoost' => true,\n 'voiceSpeed' => 0,\n ],\n ],\n ],\n 'startNodeID' => 'n_intake',\n 'edges' => [\n [\n 'id' => 'e_intake_to_billing',\n 'condition' => [\n 'prompt' => 'The caller is asking about a bill or charge.',\n 'type' => 'llm',\n ],\n 'startNodeID' => 'n_intake',\n 'target' => ['nodeID' => 'n_billing', 'type' => 'node'],\n ],\n [\n 'id' => 'e_intake_to_escalation_assistant',\n 'condition' => [\n 'prompt' => 'The caller has explicitly asked for a human.',\n 'type' => 'llm',\n ],\n 'startNodeID' => 'n_intake',\n 'target' => [\n 'assistantID' => 'assistant-human-handoff',\n 'type' => 'assistant',\n 'position' => ['x' => 600, 'y' => 80],\n 'voiceMode' => 'distinct',\n ],\n ],\n ],\n ],\n description: 'description',\n dynamicVariables: ['foo' => 'bar'],\n dynamicVariablesWebhookTimeoutMs: 1,\n dynamicVariablesWebhookURL: 'dynamic_variables_webhook_url',\n enabledFeatures: [EnabledFeatures::TELEPHONY],\n externalLlm: [\n 'baseURL' => 'base_url',\n 'model' => 'model',\n 'authenticationMethod' => 'token',\n 'certificateRef' => 'certificate_ref',\n 'forwardMetadata' => true,\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'tokenRetrievalURL' => 'token_retrieval_url',\n ],\n fallbackConfig: [\n 'externalLlm' => [\n 'baseURL' => 'base_url',\n 'model' => 'model',\n 'authenticationMethod' => 'token',\n 'certificateRef' => 'certificate_ref',\n 'forwardMetadata' => true,\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'tokenRetrievalURL' => 'token_retrieval_url',\n ],\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'model' => 'model',\n ],\n greeting: 'greeting',\n insightSettings: ['insightGroupID' => 'insight_group_id'],\n integrations: [\n ['integrationID' => 'integration_id', 'allowedList' => ['string']]\n ],\n interruptionSettings: [\n 'disableGreetingInterruption' => true,\n 'enable' => true,\n 'startSpeakingPlan' => [\n 'transcriptionEndpointingPlan' => [\n 'onNoPunctuationSeconds' => 0,\n 'onNumberSeconds' => 0,\n 'onPunctuationSeconds' => 0,\n ],\n 'waitSeconds' => 0,\n ],\n ],\n llmAPIKeyRef: 'llm_api_key_ref',\n mcpServers: [['id' => 'id', 'allowedTools' => ['string']]],\n messagingSettings: [\n 'conversationInactivityMinutes' => 1,\n 'defaultMessagingProfileID' => 'default_messaging_profile_id',\n 'deliveryStatusWebhookURL' => 'delivery_status_webhook_url',\n ],\n model: 'model',\n observabilitySettings: [\n 'host' => 'host',\n 'promptLabel' => 'prompt_label',\n 'promptName' => 'prompt_name',\n 'promptSync' => 'enabled',\n 'promptVersion' => 1,\n 'publicKeyRef' => 'public_key_ref',\n 'secretKeyRef' => 'secret_key_ref',\n 'status' => 'enabled',\n ],\n postConversationSettings: ['enabled' => true],\n privacySettings: ['dataRetention' => true],\n tags: ['string'],\n telephonySettings: [\n 'defaultTexmlAppID' => 'default_texml_app_id',\n 'noiseSuppression' => 'krisp',\n 'noiseSuppressionConfig' => [\n 'attenuationLimit' => 0, 'mode' => 'advanced'\n ],\n 'recordingSettings' => [\n 'channels' => 'single',\n 'enabled' => true,\n 'format' => 'wav',\n 'stopOnConversationEnd' => true,\n ],\n 'supportsUnauthenticatedWebCalls' => true,\n 'timeLimitSecs' => 30,\n 'userIdleReplySecs' => 0,\n 'userIdleTimeoutSecs' => 10,\n 'voicemailDetection' => [\n 'onVoicemailDetected' => [\n 'action' => 'stop_assistant',\n 'voicemailMessage' => [\n 'message' => 'message', 'prompt' => 'prompt', 'type' => 'prompt'\n ],\n ],\n ],\n ],\n toolIDs: ['string'],\n tools: [\n [\n 'type' => 'webhook',\n 'webhook' => [\n 'description' => 'description',\n 'name' => 'name',\n 'url' => 'https://example.com/api/v1/function',\n 'async' => true,\n 'asyncTimeoutMs' => 1,\n 'bodyParameters' => [\n 'properties' => ['age' => 'bar', 'location' => 'bar'],\n 'required' => ['age', 'location'],\n 'type' => 'object',\n ],\n 'headers' => [['name' => 'name', 'value' => 'value']],\n 'method' => 'GET',\n 'pathParameters' => [\n 'properties' => ['id' => 'bar'],\n 'required' => ['id'],\n 'type' => 'object',\n ],\n 'queryParameters' => [\n 'properties' => ['page' => 'bar'],\n 'required' => ['page'],\n 'type' => 'object',\n ],\n 'storeFieldsAsVariables' => [['name' => 'x', 'valuePath' => 'x']],\n 'timeoutMs' => 500,\n ],\n ],\n ],\n transcription: [\n 'apiKeyRef' => 'api_key_ref',\n 'language' => 'language',\n 'model' => 'deepgram/flux',\n 'region' => 'region',\n 'settings' => [\n 'eagerEotThreshold' => 0.3,\n 'enableEndpointDetection' => true,\n 'endOfTurnConfidenceThreshold' => 0,\n 'eotThreshold' => 0.5,\n 'eotTimeoutMs' => 500,\n 'interimResults' => true,\n 'keyterm' => 'keyterm',\n 'maxEndpointDelayMs' => 500,\n 'maxTurnSilence' => 100,\n 'minTurnSilence' => 100,\n 'numerals' => true,\n 'smartFormat' => true,\n ],\n ],\n voiceSettings: [\n 'voice' => 'voice',\n 'apiKeyRef' => 'api_key_ref',\n 'backgroundAudio' => [\n 'type' => 'predefined_media', 'value' => 'silence', 'volume' => 0.1\n ],\n 'expressiveMode' => true,\n 'languageBoost' => 'auto',\n 'similarityBoost' => 0,\n 'speed' => 0,\n 'style' => 0,\n 'temperature' => 0,\n 'useSpeakerBoost' => true,\n 'voiceSpeed' => 0,\n ],\n widgetSettings: [\n 'agentThinkingText' => 'agent_thinking_text',\n 'audioVisualizerConfig' => ['color' => 'verdant', 'preset' => 'preset'],\n 'defaultState' => 'expanded',\n 'giveFeedbackURL' => 'give_feedback_url',\n 'logoIconURL' => 'logo_icon_url',\n 'position' => 'fixed',\n 'reportIssueURL' => 'report_issue_url',\n 'speakToInterruptText' => 'speak_to_interrupt_text',\n 'startCallText' => 'start_call_text',\n 'theme' => 'light',\n 'viewHistoryURL' => 'view_history_url',\n ],\n );\n\n var_dump($inferenceEmbedding);\n} catch (APIException $e) {\n echo $e->getMessage();\n}"},{"lang":"CLI","source":"telnyx ai:assistants create \\\n --api-key 'My API Key' \\\n --instructions instructions \\\n --name name"}],"method":"post","type":"path","servers":["e1077638-f2c5-4868-8a50-25633dbe3f9b"],"security":["56a3d1db-c9c9-42dd-99ba-415f5aad88ec"],"path":"/ai/assistants","baseUrlOptions":["https://api.telnyx.com/v2"],"title":"Create an assistant","codeSamples":[{"lang":"JavaScript","source":"import Telnyx from 'telnyx';\n\nconst client = new Telnyx({\n apiKey: process.env['TELNYX_API_KEY'], // This is the default and can be omitted\n});\n\nconst inferenceEmbedding = await client.ai.assistants.create({\n instructions: 'instructions',\n name: 'name',\n});\n\nconsole.log(inferenceEmbedding.id);"},{"lang":"Python","source":"import os\nfrom telnyx import Telnyx\n\nclient = Telnyx(\n api_key=os.environ.get(\"TELNYX_API_KEY\"), # This is the default and can be omitted\n)\ninference_embedding = client.ai.assistants.create(\n instructions=\"instructions\",\n name=\"name\",\n)\nprint(inference_embedding.id)\n"},{"lang":"Go","source":"package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/team-telnyx/telnyx-go\"\n\t\"github.com/team-telnyx/telnyx-go/option\"\n)\n\nfunc main() {\n\tclient := telnyx.NewClient(\n\t\toption.WithAPIKey(\"My API Key\"),\n\t)\n\tinferenceEmbedding, err := client.AI.Assistants.New(context.TODO(), telnyx.AIAssistantNewParams{\n\t\tInstructions: \"instructions\",\n\t\tName: \"name\",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf(\"%+v\\n\", inferenceEmbedding.ID)\n}\n"},{"lang":"Java","source":"package com.telnyx.sdk.example;\n\nimport com.telnyx.sdk.client.TelnyxClient;\nimport com.telnyx.sdk.client.okhttp.TelnyxOkHttpClient;\nimport com.telnyx.sdk.models.ai.assistants.AssistantCreateParams;\nimport com.telnyx.sdk.models.ai.assistants.InferenceEmbedding;\n\npublic final class Main {\n private Main() {}\n\n public static void main(String[] args) {\n TelnyxClient client = TelnyxOkHttpClient.fromEnv();\n\n AssistantCreateParams params = AssistantCreateParams.builder()\n .instructions(\"instructions\")\n .name(\"name\")\n .build();\n InferenceEmbedding inferenceEmbedding = client.ai().assistants().create(params);\n }\n}"},{"lang":"Ruby","source":"require \"telnyx\"\n\ntelnyx = Telnyx::Client.new(api_key: \"My API Key\")\n\ninference_embedding = telnyx.ai.assistants.create(instructions: \"instructions\", name: \"name\")\n\nputs(inference_embedding)"},{"lang":"PHP","source":"\u003c?php\n\nrequire_once dirname(__DIR__) . '/vendor/autoload.php';\n\nuse Telnyx\\Client;\nuse Telnyx\\AI\\Assistants\\EnabledFeatures;\nuse Telnyx\\Core\\Exceptions\\APIException;\n\n$client = new Client(apiKey: getenv('TELNYX_API_KEY') ?: 'My API Key');\n\ntry {\n $inferenceEmbedding = $client->ai->assistants->create(\n instructions: 'instructions',\n name: 'name',\n conversationFlow: [\n 'nodes' => [\n [\n 'id' => 'n_intake',\n 'instructions' => 'Greet the caller and ask what they\\'re calling about.',\n 'externalLlm' => [\n 'baseURL' => 'base_url',\n 'model' => 'model',\n 'authenticationMethod' => 'token',\n 'certificateRef' => 'certificate_ref',\n 'forwardMetadata' => true,\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'tokenRetrievalURL' => 'token_retrieval_url',\n ],\n 'instructionsMode' => 'replace',\n 'llmAPIKeyRef' => 'my-key-ref',\n 'model' => 'moonshotai/Kimi-K2.6',\n 'name' => 'Intake',\n 'position' => ['x' => 120, 'y' => 80],\n 'sharedToolIDs' => ['tool-faq-kb'],\n 'toolsMode' => 'replace',\n 'transcription' => [\n 'apiKeyRef' => 'api_key_ref',\n 'language' => 'language',\n 'model' => 'deepgram/flux',\n 'region' => 'region',\n 'settings' => [\n 'eagerEotThreshold' => 0.3,\n 'enableEndpointDetection' => true,\n 'endOfTurnConfidenceThreshold' => 0,\n 'eotThreshold' => 0.5,\n 'eotTimeoutMs' => 500,\n 'interimResults' => true,\n 'keyterm' => 'keyterm',\n 'maxEndpointDelayMs' => 500,\n 'maxTurnSilence' => 100,\n 'minTurnSilence' => 100,\n 'numerals' => true,\n 'smartFormat' => true,\n ],\n ],\n 'type' => 'prompt',\n 'voiceSettings' => [\n 'voice' => 'voice',\n 'apiKeyRef' => 'api_key_ref',\n 'backgroundAudio' => [\n 'type' => 'predefined_media',\n 'value' => 'silence',\n 'volume' => 0.1,\n ],\n 'expressiveMode' => true,\n 'languageBoost' => 'auto',\n 'similarityBoost' => 0,\n 'speed' => 0,\n 'style' => 0,\n 'temperature' => 0,\n 'useSpeakerBoost' => true,\n 'voiceSpeed' => 0,\n ],\n ],\n [\n 'id' => 'n_billing',\n 'instructions' => 'Focus on billing questions. Look up the caller\\'s latest invoice with the billing tool before answering.',\n 'externalLlm' => [\n 'baseURL' => 'base_url',\n 'model' => 'model',\n 'authenticationMethod' => 'token',\n 'certificateRef' => 'certificate_ref',\n 'forwardMetadata' => true,\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'tokenRetrievalURL' => 'token_retrieval_url',\n ],\n 'instructionsMode' => 'append',\n 'llmAPIKeyRef' => 'my-key-ref',\n 'model' => 'moonshotai/Kimi-K2.6',\n 'name' => 'Billing',\n 'position' => ['x' => 420, 'y' => 80],\n 'sharedToolIDs' => ['tool-billing-lookup'],\n 'toolsMode' => 'append',\n 'transcription' => [\n 'apiKeyRef' => 'api_key_ref',\n 'language' => 'language',\n 'model' => 'deepgram/flux',\n 'region' => 'region',\n 'settings' => [\n 'eagerEotThreshold' => 0.3,\n 'enableEndpointDetection' => true,\n 'endOfTurnConfidenceThreshold' => 0,\n 'eotThreshold' => 0.5,\n 'eotTimeoutMs' => 500,\n 'interimResults' => true,\n 'keyterm' => 'keyterm',\n 'maxEndpointDelayMs' => 500,\n 'maxTurnSilence' => 100,\n 'minTurnSilence' => 100,\n 'numerals' => true,\n 'smartFormat' => true,\n ],\n ],\n 'type' => 'prompt',\n 'voiceSettings' => [\n 'voice' => 'voice',\n 'apiKeyRef' => 'api_key_ref',\n 'backgroundAudio' => [\n 'type' => 'predefined_media',\n 'value' => 'silence',\n 'volume' => 0.1,\n ],\n 'expressiveMode' => true,\n 'languageBoost' => 'auto',\n 'similarityBoost' => 0,\n 'speed' => 0,\n 'style' => 0,\n 'temperature' => 0,\n 'useSpeakerBoost' => true,\n 'voiceSpeed' => 0,\n ],\n ],\n ],\n 'startNodeID' => 'n_intake',\n 'edges' => [\n [\n 'id' => 'e_intake_to_billing',\n 'condition' => [\n 'prompt' => 'The caller is asking about a bill or charge.',\n 'type' => 'llm',\n ],\n 'startNodeID' => 'n_intake',\n 'target' => ['nodeID' => 'n_billing', 'type' => 'node'],\n ],\n [\n 'id' => 'e_intake_to_escalation_assistant',\n 'condition' => [\n 'prompt' => 'The caller has explicitly asked for a human.',\n 'type' => 'llm',\n ],\n 'startNodeID' => 'n_intake',\n 'target' => [\n 'assistantID' => 'assistant-human-handoff',\n 'type' => 'assistant',\n 'position' => ['x' => 600, 'y' => 80],\n 'voiceMode' => 'distinct',\n ],\n ],\n ],\n ],\n description: 'description',\n dynamicVariables: ['foo' => 'bar'],\n dynamicVariablesWebhookTimeoutMs: 1,\n dynamicVariablesWebhookURL: 'dynamic_variables_webhook_url',\n enabledFeatures: [EnabledFeatures::TELEPHONY],\n externalLlm: [\n 'baseURL' => 'base_url',\n 'model' => 'model',\n 'authenticationMethod' => 'token',\n 'certificateRef' => 'certificate_ref',\n 'forwardMetadata' => true,\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'tokenRetrievalURL' => 'token_retrieval_url',\n ],\n fallbackConfig: [\n 'externalLlm' => [\n 'baseURL' => 'base_url',\n 'model' => 'model',\n 'authenticationMethod' => 'token',\n 'certificateRef' => 'certificate_ref',\n 'forwardMetadata' => true,\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'tokenRetrievalURL' => 'token_retrieval_url',\n ],\n 'llmAPIKeyRef' => 'llm_api_key_ref',\n 'model' => 'model',\n ],\n greeting: 'greeting',\n insightSettings: ['insightGroupID' => 'insight_group_id'],\n integrations: [\n ['integrationID' => 'integration_id', 'allowedList' => ['string']]\n ],\n interruptionSettings: [\n 'disableGreetingInterruption' => true,\n 'enable' => true,\n 'startSpeakingPlan' => [\n 'transcriptionEndpointingPlan' => [\n 'onNoPunctuationSeconds' => 0,\n 'onNumberSeconds' => 0,\n 'onPunctuationSeconds' => 0,\n ],\n 'waitSeconds' => 0,\n ],\n ],\n llmAPIKeyRef: 'llm_api_key_ref',\n mcpServers: [['id' => 'id', 'allowedTools' => ['string']]],\n messagingSettings: [\n 'conversationInactivityMinutes' => 1,\n 'defaultMessagingProfileID' => 'default_messaging_profile_id',\n 'deliveryStatusWebhookURL' => 'delivery_status_webhook_url',\n ],\n model: 'model',\n observabilitySettings: [\n 'host' => 'host',\n 'promptLabel' => 'prompt_label',\n 'promptName' => 'prompt_name',\n 'promptSync' => 'enabled',\n 'promptVersion' => 1,\n 'publicKeyRef' => 'public_key_ref',\n 'secretKeyRef' => 'secret_key_ref',\n 'status' => 'enabled',\n ],\n postConversationSettings: ['enabled' => true],\n privacySettings: ['dataRetention' => true],\n tags: ['string'],\n telephonySettings: [\n 'defaultTexmlAppID' => 'default_texml_app_id',\n 'noiseSuppression' => 'krisp',\n 'noiseSuppressionConfig' => [\n 'attenuationLimit' => 0, 'mode' => 'advanced'\n ],\n 'recordingSettings' => [\n 'channels' => 'single',\n 'enabled' => true,\n 'format' => 'wav',\n 'stopOnConversationEnd' => true,\n ],\n 'supportsUnauthenticatedWebCalls' => true,\n 'timeLimitSecs' => 30,\n 'userIdleReplySecs' => 0,\n 'userIdleTimeoutSecs' => 10,\n 'voicemailDetection' => [\n 'onVoicemailDetected' => [\n 'action' => 'stop_assistant',\n 'voicemailMessage' => [\n 'message' => 'message', 'prompt' => 'prompt', 'type' => 'prompt'\n ],\n ],\n ],\n ],\n toolIDs: ['string'],\n tools: [\n [\n 'type' => 'webhook',\n 'webhook' => [\n 'description' => 'description',\n 'name' => 'name',\n 'url' => 'https://example.com/api/v1/function',\n 'async' => true,\n 'asyncTimeoutMs' => 1,\n 'bodyParameters' => [\n 'properties' => ['age' => 'bar', 'location' => 'bar'],\n 'required' => ['age', 'location'],\n 'type' => 'object',\n ],\n 'headers' => [['name' => 'name', 'value' => 'value']],\n 'method' => 'GET',\n 'pathParameters' => [\n 'properties' => ['id' => 'bar'],\n 'required' => ['id'],\n 'type' => 'object',\n ],\n 'queryParameters' => [\n 'properties' => ['page' => 'bar'],\n 'required' => ['page'],\n 'type' => 'object',\n ],\n 'storeFieldsAsVariables' => [['name' => 'x', 'valuePath' => 'x']],\n 'timeoutMs' => 500,\n ],\n ],\n ],\n transcription: [\n 'apiKeyRef' => 'api_key_ref',\n 'language' => 'language',\n 'model' => 'deepgram/flux',\n 'region' => 'region',\n 'settings' => [\n 'eagerEotThreshold' => 0.3,\n 'enableEndpointDetection' => true,\n 'endOfTurnConfidenceThreshold' => 0,\n 'eotThreshold' => 0.5,\n 'eotTimeoutMs' => 500,\n 'interimResults' => true,\n 'keyterm' => 'keyterm',\n 'maxEndpointDelayMs' => 500,\n 'maxTurnSilence' => 100,\n 'minTurnSilence' => 100,\n 'numerals' => true,\n 'smartFormat' => true,\n ],\n ],\n voiceSettings: [\n 'voice' => 'voice',\n 'apiKeyRef' => 'api_key_ref',\n 'backgroundAudio' => [\n 'type' => 'predefined_media', 'value' => 'silence', 'volume' => 0.1\n ],\n 'expressiveMode' => true,\n 'languageBoost' => 'auto',\n 'similarityBoost' => 0,\n 'speed' => 0,\n 'style' => 0,\n 'temperature' => 0,\n 'useSpeakerBoost' => true,\n 'voiceSpeed' => 0,\n ],\n widgetSettings: [\n 'agentThinkingText' => 'agent_thinking_text',\n 'audioVisualizerConfig' => ['color' => 'verdant', 'preset' => 'preset'],\n 'defaultState' => 'expanded',\n 'giveFeedbackURL' => 'give_feedback_url',\n 'logoIconURL' => 'logo_icon_url',\n 'position' => 'fixed',\n 'reportIssueURL' => 'report_issue_url',\n 'speakToInterruptText' => 'speak_to_interrupt_text',\n 'startCallText' => 'start_call_text',\n 'theme' => 'light',\n 'viewHistoryURL' => 'view_history_url',\n ],\n );\n\n var_dump($inferenceEmbedding);\n} catch (APIException $e) {\n echo $e->getMessage();\n}"},{"lang":"CLI","source":"telnyx ai:assistants create \\\n --api-key 'My API Key' \\\n --instructions instructions \\\n --name name"}],"requiredOnlyExamples":false,"requestExampleType":"codeSamples","responseExampleType":"generated"},"dependencies":{"parameters":{"7c5f76da-e2e2-4e11-b5c6-459ea4c68564":{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional opaque, unquoted key for safely retrying the same logical request. Keys must contain 1 to 255 letters, numbers, hyphens, or underscores. Generate a unique UUID v4 for each operation and reuse it only when retrying that operation with the same request. Invalid headers—including duplicate, empty, malformed, or overlong values—return 400 with error code 10015. A request already in progress with the same key returns 409; reusing the key with a different request returns 422. Only successful responses are replayed, for up to 24 hours. Do not include sensitive data in the key.","schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[A-Za-z0-9_-]{1,255}$","isRequired":false,"description":"Optional opaque, unquoted key for safely retrying the same logical request. Keys must contain 1 to 255 letters, numbers, hyphens, or underscores. Generate a unique UUID v4 for each operation and reuse it only when retrying that operation with the same request. Invalid headers—including duplicate, empty, malformed, or overlong values—return 400 with error code 10015. A request already in progress with the same key returns 409; reusing the key with a different request returns 422. Only successful responses are replayed, for up to 24 hours. Do not include sensitive data in the key.","uniqueKey":"","typeLabel":"string"},"example":"8e03978e-40d5-43e8-bc93-6894a57f9326"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"name":{"type":"string","isRequired":true,"uniqueKey":"name","typeLabel":"string"},"instructions":{"type":"string","description":"System instructions for the assistant. These may be templated with [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables)","isRequired":true,"uniqueKey":"instructions","typeLabel":"string"},"model":{"type":"string","description":"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.","uniqueKey":"model","typeLabel":"string"},"tools":{"description":"Deprecated for new integrations. Inline tool definitions available to the assistant. Prefer `tool_ids` to attach shared tools created with the AI Tools endpoints.","type":"array","items":{"oneOf":[{"type":"object","title":"FunctionTool","required":["type","function"],"properties":{"type":{"type":"string","enum":["function"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"},"function":{"properties":{"name":{"type":"string","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.function.name","typeLabel":"string"},"description":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.0.function.description","typeLabel":"string"},"parameters":{"type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.function.parameters","typeLabel":"object"}},"type":"object","required":["name"],"title":"FunctionDefinition","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.function","typeLabel":"FunctionDefinition · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.0","typeLabel":"FunctionTool · object"},{"type":"object","title":"WebhookTool","required":["type","webhook"],"properties":{"type":{"type":"string","enum":["webhook"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"},"webhook":{"properties":{"name":{"type":"string","description":"The name of the tool.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.name","typeLabel":"string"},"description":{"type":"string","description":"The description of the tool.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.description","typeLabel":"string"},"url":{"description":"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.","type":"string","example":"https://example.com/api/v1/function","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.url","typeLabel":"string"},"method":{"description":"The HTTP method to be used when calling the external tool.","type":"string","enum":["GET","POST","PUT","DELETE","PATCH"],"default":"POST","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.method","typeLabel":"enum\u003cstring>"},"headers":{"description":"The headers to be sent to the external tool.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.headers","typeLabel":"object[]"},"body_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the body parameters.","type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the body parameters.","type":"array","items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"age":{"description":"The age of the customer.","type":"integer"},"location":{"description":"The location of the customer.","type":"string"}},"required":["age","location"],"type":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters","typeLabel":"object"},"path_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the path parameters.","type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the path parameters.","type":"array","items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"id":{"description":"The id of the customer.","type":"string"}},"required":["id"],"type":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters","typeLabel":"object"},"query_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the query parameters.","type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the query parameters.","type":"array","items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"page":{"description":"The page number.","type":"integer"}},"required":["page"],"type":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters","typeLabel":"object"},"preset_body_fields":{"type":"object","additionalProperties":true,"description":"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.","example":{"account_id":"{{customer_id}}","source":"telnyx-assistant"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.preset_body_fields","typeLabel":"object"},"preset_query_params":{"type":"object","additionalProperties":true,"description":"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.","example":{"caller":"{{telnyx_end_user_target}}","channel":"voice"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.preset_query_params","typeLabel":"object"},"async":{"type":"boolean","default":false,"description":"If async, the assistant will move forward without waiting for your server to respond.","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.async","typeLabel":"boolean"},"async_timeout_ms":{"type":"integer","minimum":1,"maximum":15000,"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.async_timeout_ms","typeLabel":"integer"},"store_fields_as_variables":{"type":"array","description":"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.","items":{"type":"object","required":["name","value_path"],"properties":{"name":{"type":"string","minLength":1,"description":"The name of the dynamic variable to store the extracted value in.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX].name","typeLabel":"string"},"value_path":{"type":"string","minLength":1,"description":"A dot-notation path to the value in the webhook response body (e.g. 'customer.name' or 'id').","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX].value_path","typeLabel":"string"}},"additionalProperties":false,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.store_fields_as_variables","typeLabel":"object[]"},"messages":{"type":"array","description":"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.","items":{"oneOf":[{"type":"object","title":"WebhookToolRequestStartMessage","required":["type","content"],"properties":{"type":{"type":"string","const":"request_start","description":"Speak the filler message immediately when the webhook request begins.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"An optional delay value. This value is ignored for `request_start` messages.","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0","typeLabel":"WebhookToolRequestStartMessage · object"},{"type":"object","title":"WebhookToolRequestResponseDelayedMessage","required":["type","content","timing_ms"],"properties":{"type":{"type":"string","const":"request_response_delayed","description":"Speak the filler message after the configured delay if the webhook response is still pending.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"The delay in milliseconds from the start of the webhook request.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1","typeLabel":"WebhookToolRequestResponseDelayedMessage · object"}],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX]","typeLabel":"WebhookToolRequestStartMessage · object | WebhookToolRequestResponseDelayedMessage · object"},"example":[{"type":"request_start","content":"Let me look that up for you."},{"type":"request_response_delayed","content":"Still working on that.","timing_ms":5000}],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages","typeLabel":"(WebhookToolRequestStartMessage · object | WebhookToolRequestResponseDelayedMessage · object)[]"}},"type":"object","required":["url","name","description"],"title":"WebhookToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook","typeLabel":"WebhookToolParams · object"},"timeout_ms":{"type":"integer","default":5000,"maximum":60000,"description":"The maximum number of milliseconds to wait for the webhook to respond before the tool call is aborted. Set this at the tool level, as a sibling of `type` — a `timeout_ms` nested inside the `webhook` object is stored but not applied, and the tool runs at this default instead. Applies when `webhook.async` is false.","uniqueKey":"tools.items.[INDEX].oneOf.1.timeout_ms","typeLabel":"integer"}},"uniqueKey":"tools.items.[INDEX].oneOf.1","typeLabel":"WebhookTool · object"},{"type":"object","title":"ClientSideTool","required":["type","client_side_tool"],"properties":{"type":{"type":"string","enum":["client_side_tool"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.type","typeLabel":"enum\u003cstring>"},"client_side_tool":{"title":"ClientSideToolParams","type":"object","properties":{"name":{"type":"string","description":"The name of the tool.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.name","typeLabel":"string"},"description":{"type":"string","description":"The description of the tool.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.description","typeLabel":"string"},"parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the parameters.","type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the parameters.","type":"array","items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"age":{"description":"The age of the customer.","type":"integer"},"location":{"description":"The location of the customer.","type":"string"}},"required":["age","location"],"type":"object"},"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters","typeLabel":"object"}},"required":["name","description","parameters"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool","typeLabel":"ClientSideToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.2","typeLabel":"ClientSideTool · object"},{"type":"object","title":"RetrievalTool","required":["type","retrieval"],"properties":{"type":{"type":"string","enum":["retrieval"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.3.type","typeLabel":"enum\u003cstring>"},"retrieval":{"properties":{"bucket_ids":{"items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.3.retrieval.bucket_ids.items.[INDEX]","typeLabel":"string"},"type":"array","description":"List of [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) to use for retrieval-augmented generation.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.3.retrieval.bucket_ids","typeLabel":"string[]"},"max_num_results":{"description":"The maximum number of results to retrieve as context for the language model.","type":"integer","uniqueKey":"tools.items.[INDEX].oneOf.3.retrieval.max_num_results","typeLabel":"integer"}},"type":"object","required":["bucket_ids"],"title":"BucketIds","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.3.retrieval","typeLabel":"BucketIds · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.3","typeLabel":"RetrievalTool · object"},{"type":"object","title":"HandoffTool","description":"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.","required":["type","handoff"],"properties":{"type":{"type":"string","enum":["handoff"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.type","typeLabel":"enum\u003cstring>"},"handoff":{"properties":{"ai_assistants":{"type":"array","description":"List of possible assistants that can receive a handoff.","items":{"type":"object","properties":{"name":{"type":"string","description":"Helpful name for giving context on when to handoff to the assistant.","example":"Scheduling Specialist","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX].name","typeLabel":"string"},"id":{"type":"string","description":"The ID of the assistant to hand off to.","example":"assistant-1234567890abcdef","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX].id","typeLabel":"string"}},"required":["name","id"],"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.ai_assistants","typeLabel":"object[]"},"voice_mode":{"type":"string","enum":["unified","distinct"],"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.voice_mode","typeLabel":"enum\u003cstring>"}},"required":["ai_assistants"],"type":"object","title":"HandoffToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff","typeLabel":"HandoffToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.4","typeLabel":"HandoffTool · object"},{"type":"object","title":"HangupTool","required":["type","hangup"],"properties":{"type":{"type":"string","enum":["hangup"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.5.type","typeLabel":"enum\u003cstring>"},"hangup":{"properties":{"description":{"type":"string","default":"This tool is used to hang up the call.","description":"The description of the function that will be passed to the assistant.","uniqueKey":"tools.items.[INDEX].oneOf.5.hangup.description","typeLabel":"string"}},"type":"object","title":"HangupToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.5.hangup","typeLabel":"HangupToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.5","typeLabel":"HangupTool · object"},{"type":"object","title":"TransferTool","required":["type","transfer"],"properties":{"type":{"type":"string","enum":["transfer"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.type","typeLabel":"enum\u003cstring>"},"transfer":{"properties":{"targets":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"to":{"type":"string","description":"The destination number or SIP URI of the call.","example":"+13129457420","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].to","typeLabel":"string"},"name":{"type":"string","description":"The name of the target.","example":"Support","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].name","typeLabel":"string"},"message":{"type":"string","description":"The warm transfer message to deliver to this specific target. When set, it takes precedence over the message the assistant composes from `warm_transfer_instructions`.","example":"I have a caller asking about a billing issue on invoice 4471.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].message","typeLabel":"string"},"extension":{"type":"string","description":"DTMF digits to send automatically after the transfer destination answers. Useful for reaching an extension behind an IVR (e.g. `\"200\"` to dial extension 200 once the called party picks up). Allowed characters: `0-9`, `A-D`, `w` (0.5s pause), `W` (1s pause), `*`, `#`. Maximum 64 characters. When omitted, no automatic DTMF is sent.","example":"wwww200","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].extension","typeLabel":"string"},"sip_auth_username":{"type":"string","description":"SIP Authentication username used for SIP challenges. Applies when `to` is a SIP URI.","example":"sipuser","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].sip_auth_username","typeLabel":"string"},"sip_auth_password":{"type":"string","description":"SIP Authentication password used for SIP challenges. Applies when `to` is a SIP URI.","example":"sippass","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].sip_auth_password","typeLabel":"string"}},"required":["to"],"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"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.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0","typeLabel":"object[]"},{"type":"string","description":"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.","example":"{{ targets }}","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.1","typeLabel":"string"}],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets","typeLabel":"object[] | string"},"from":{"type":"string","example":"+35319605860","description":"Number or SIP URI placing the call.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.from","typeLabel":"string"},"diversion":{"type":"string","example":"{{telnyx_agent_target}}","description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.diversion","typeLabel":"string"},"warm_transfer_instructions":{"type":"string","example":"Briefly greet the transfer recipient and provide any relevant information from the call. Let them know you will bridge the call right after.","description":"Natural language instructions for your agent for how to provide context for the transfer recipient.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_instructions","typeLabel":"string"},"warm_transfer_acceptance":{"type":"object","description":"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).","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether the destination must accept the transfer before the calls are bridged.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.enabled","typeLabel":"boolean"},"end_user_target_context_mode":{"type":"string","enum":["private","shared"],"default":"private","description":"Controls whether the private exchange between the assistant and the transfer destination is kept out of the conversation. With `private` (default) the exchange never reaches the conversation history, AI conversations, webhooks or insights, and the transfer tool result is rewritten with the outcome only. With `shared` the exchange stays in the conversation like any other messages.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.end_user_target_context_mode","typeLabel":"enum\u003cstring>"},"require_acceptance":{"type":"boolean","default":false,"description":"Fail closed when the acceptance consult cannot run. Off by default: if the consult cannot be set up for any reason — including where acceptance is unavailable at all (`gather_using_ai`, Conversation Relay or web calls, a conference, or additional invited participants) — the transfer degrades to a plain warm transfer (the warm transfer message is played to the destination as audio and the calls are bridged anyway). Set to true to treat those paths as a decline instead: the destination is disconnected without being asked, the assistant returns to the caller, and no bridge happens without an acceptance. Only consult-setup failures are affected; the destination must still explicitly accept on every consult that does run.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.require_acceptance","typeLabel":"boolean"},"timeout_secs":{"type":"integer","minimum":10,"maximum":600,"default":60,"description":"How long, in seconds, the destination has to accept the transfer, counted from when the private consult starts (right after the destination answers, or after `warm_message_delay_ms`). The caller keeps hearing ringback the whole time. If no acceptance arrives in time, the destination is hung up and the assistant returns to the caller (the transfer fails as a timeout). Raise it for destinations that answer before a human is on the line, such as a call-center queue/ACD or an IVR playing hold audio; keep it as short as practical, since the caller waits on ringback until it expires.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.timeout_secs","typeLabel":"integer"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance","typeLabel":"object"},"description":{"type":"string","description":"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.","example":"Transfer the call to a human agent.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.description","typeLabel":"string"},"bridge_beep":{"type":"object","description":"Plays a short beep once the transfer completes and the calls are bridged, so the transfer destination knows the caller is now on the line. The warm transfer message plays before the bridge; this marks the moment the caller actually joins. Works with and without `warm_transfer_acceptance`.","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether to play the beep when the calls are bridged.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.bridge_beep.enabled","typeLabel":"boolean"},"target_legs":{"type":"string","enum":["self","both"],"default":"self","description":"Who hears the beep. `self` plays it to the transfer destination only; `both` plays it to the destination and the original caller.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.bridge_beep.target_legs","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.bridge_beep","typeLabel":"object"},"warm_message_delay_ms":{"oneOf":[{"type":"integer","example":2000,"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms.oneOf.0","typeLabel":"integer"},{"type":"null","example":2000,"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms.oneOf.1","typeLabel":"null"}],"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms","typeLabel":"integer | null"},"custom_headers":{"description":"Custom headers to be added to the SIP INVITE for the transfer command.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.custom_headers","typeLabel":"object[]"},"voicemail_detection":{"type":"object","description":"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.","properties":{"detection_mode":{"type":"string","enum":["disabled","premium"],"description":"The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_mode","typeLabel":"enum\u003cstring>"},"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected on the transferred call.","properties":{"action":{"type":"string","enum":["stop_transfer","leave_message_and_stop_transfer"],"description":"The action to take when voicemail is detected. 'stop_transfer' hangs up immediately. 'leave_message_and_stop_transfer' leaves a message then hangs up.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"},"voicemail_message":{"type":"object","description":"Configuration for the voicemail message to leave. Only applicable when action is 'leave_message_and_stop_transfer'.","properties":{"type":{"type":"string","enum":["message","warm_transfer_instructions"],"description":"The type of voicemail message. Use 'message' to leave a specific TTS message, or 'warm_transfer_instructions' to play the warm transfer audio.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"The specific message to leave as voicemail (converted to speech). Only applicable when type is 'message'.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message.message","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message","typeLabel":"object"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected","typeLabel":"object"},"detection_config":{"type":"object","description":"Advanced AMD detection configuration parameters. All values are optional - Telnyx will use defaults if not specified.","properties":{"greeting_silence_duration_millis":{"type":"integer","minimum":500,"maximum":50000,"description":"Duration of silence after the greeting to wait before considering the greeting complete.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_silence_duration_millis","typeLabel":"integer"},"greeting_total_analysis_time_millis":{"type":"integer","minimum":500,"maximum":300000,"description":"Maximum time to spend analyzing the greeting.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_total_analysis_time_millis","typeLabel":"integer"},"after_greeting_silence_millis":{"type":"integer","minimum":100,"maximum":5000,"description":"Duration of silence after greeting detection before finalizing the result.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.after_greeting_silence_millis","typeLabel":"integer"},"between_words_silence_millis":{"type":"integer","minimum":10,"maximum":5000,"description":"Maximum silence duration between words during greeting.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.between_words_silence_millis","typeLabel":"integer"},"greeting_duration_millis":{"type":"integer","minimum":100,"maximum":10000,"description":"Expected duration of greeting speech.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_duration_millis","typeLabel":"integer"},"initial_silence_millis":{"type":"integer","minimum":100,"maximum":500000,"description":"Maximum silence duration at the start of the call before speech.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.initial_silence_millis","typeLabel":"integer"},"maximum_number_of_words":{"type":"integer","minimum":1,"maximum":50,"description":"Maximum number of words expected in a human greeting.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.maximum_number_of_words","typeLabel":"integer"},"maximum_word_length_millis":{"type":"integer","minimum":50,"maximum":5000,"description":"Maximum duration of a single word.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.maximum_word_length_millis","typeLabel":"integer"},"silence_threshold":{"type":"integer","minimum":1,"maximum":1000,"description":"Audio level threshold for silence detection.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.silence_threshold","typeLabel":"integer"},"total_analysis_time_millis":{"type":"integer","minimum":500,"maximum":60000,"description":"Total time allowed for AMD analysis.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.total_analysis_time_millis","typeLabel":"integer"},"min_word_length_millis":{"type":"integer","minimum":1,"maximum":1000,"description":"Minimum duration for audio to be considered a word.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.min_word_length_millis","typeLabel":"integer"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config","typeLabel":"object"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection","typeLabel":"object"}},"type":"object","required":["targets","from"],"title":"TransferToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer","typeLabel":"TransferToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.6","typeLabel":"TransferTool · object"},{"type":"object","title":"InviteTool","required":["type","invite"],"properties":{"type":{"type":"string","enum":["invite"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.type","typeLabel":"enum\u003cstring>"},"invite":{"properties":{"from":{"type":"string","example":"+35319605860","description":"Number or SIP URI placing the call.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.from","typeLabel":"string"},"targets":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"to":{"type":"string","description":"The destination number or SIP URI of the call.","example":"+13129457420","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX].to","typeLabel":"string"},"name":{"type":"string","description":"The name of the target.","example":"Support","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX].name","typeLabel":"string"}},"required":["to"],"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.0","typeLabel":"object[]"},{"type":"string","description":"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.","example":"{{ targets }}","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.1","typeLabel":"string"},{"type":"null","description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.2","typeLabel":"null"}],"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets","typeLabel":"object[] | string | null"},"custom_headers":{"description":"Custom headers to be added to the SIP INVITE for the invite command.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.custom_headers","typeLabel":"object[]"},"voicemail_detection":{"type":"object","description":"Configuration for voicemail detection (AMD - Answering Machine Detection) on the invited call.","properties":{"detection_mode":{"type":"string","enum":["disabled","premium"],"description":"The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.voicemail_detection.detection_mode","typeLabel":"enum\u003cstring>"},"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected on the invited call.","properties":{"action":{"type":"string","enum":["stop_invite"],"description":"The action to take when voicemail is detected.","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.voicemail_detection.on_voicemail_detected","typeLabel":"object"}},"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.voicemail_detection","typeLabel":"object"}},"type":"object","required":["from"],"title":"InviteToolConfig","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.invite","typeLabel":"InviteToolConfig · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.7","typeLabel":"InviteTool · object"},{"type":"object","title":"SIPReferTool","required":["type","refer"],"properties":{"type":{"type":"string","enum":["refer"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.type","typeLabel":"enum\u003cstring>"},"refer":{"properties":{"targets":{"type":"array","description":"The different possible targets of the SIP refer. The assistant will be able to choose one of the targets to refer the call to.","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the target.","example":"Support","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].name","typeLabel":"string"},"sip_address":{"type":"string","description":"The SIP URI to which the call will be referred.","example":"sip:[email protected]","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_address","typeLabel":"string"},"sip_auth_username":{"type":"string","description":"SIP Authentication username used for SIP challenges.","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_auth_username","typeLabel":"string"},"sip_auth_password":{"type":"string","description":"SIP Authentication password used for SIP challenges.","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_auth_password","typeLabel":"string"}},"required":["name","sip_address"],"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets","typeLabel":"object[]"},"sip_headers":{"description":"SIP headers to be added to the SIP REFER. Currently only User-to-User and Diversion headers are supported.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","enum":["User-to-User","Diversion"],"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX].name","typeLabel":"enum\u003cstring>"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.sip_headers","typeLabel":"object[]"},"custom_headers":{"description":"Custom headers to be added to the SIP REFER.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.custom_headers","typeLabel":"object[]"}},"type":"object","required":["targets"],"title":"SIPReferToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.refer","typeLabel":"SIPReferToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.8","typeLabel":"SIPReferTool · object"},{"type":"object","title":"DTMFTool","required":["type","send_dtmf"],"properties":{"type":{"type":"string","enum":["send_dtmf"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.9.type","typeLabel":"enum\u003cstring>"},"send_dtmf":{"type":"object","additionalProperties":true,"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.9.send_dtmf","typeLabel":"object"}},"uniqueKey":"tools.items.[INDEX].oneOf.9","typeLabel":"DTMFTool · object"},{"type":"object","title":"SendMessageTool","description":"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.","required":["type","send_message"],"properties":{"type":{"type":"string","enum":["send_message"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.10.type","typeLabel":"enum\u003cstring>"},"send_message":{"type":"object","properties":{"message_template":{"oneOf":[{"type":"string","description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.10.send_message.message_template.oneOf.0","typeLabel":"string"},{"type":"null","description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.10.send_message.message_template.oneOf.1","typeLabel":"null"}],"uniqueKey":"tools.items.[INDEX].oneOf.10.send_message.message_template","typeLabel":"string | null"}},"additionalProperties":true,"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.10.send_message","typeLabel":"object"}},"uniqueKey":"tools.items.[INDEX].oneOf.10","typeLabel":"SendMessageTool · object"},{"type":"object","title":"SkipTurnTool","required":["type","skip_turn"],"properties":{"type":{"type":"string","enum":["skip_turn"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.11.type","typeLabel":"enum\u003cstring>"},"skip_turn":{"properties":{"description":{"type":"string","default":"This tool is used to skip the assistant turn without producing a response.","description":"The description of the function that will be passed to the assistant.","uniqueKey":"tools.items.[INDEX].oneOf.11.skip_turn.description","typeLabel":"string"}},"type":"object","title":"SkipTurnToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.11.skip_turn","typeLabel":"SkipTurnToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.11","typeLabel":"SkipTurnTool · object"},{"type":"object","title":"VisionTool","description":"(BETA) Lets the assistant look at recent image frames the client sent into the conversation (for example webcam or screen-share frames). Frames are sent with `conversation.item.create` and `item.buffer: true`; they never trigger a response on their own. The assistant decides when to look and which frames it needs. Requires a model that supports image input.","required":["type"],"properties":{"type":{"type":"string","enum":["vision"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.12.type","typeLabel":"enum\u003cstring>"},"vision":{"properties":{"max_frame_age_secs":{"type":"integer","minimum":1,"default":10,"description":"Frames received longer ago than this many seconds are not shown to the assistant, so it never describes a frozen or disconnected camera as live.","uniqueKey":"tools.items.[INDEX].oneOf.12.vision.max_frame_age_secs","typeLabel":"integer"}},"type":"object","title":"VisionToolParams","uniqueKey":"tools.items.[INDEX].oneOf.12.vision","typeLabel":"VisionToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.12","typeLabel":"VisionTool · object"},{"type":"object","title":"PayTool","description":"(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.","required":["type","pay"],"properties":{"type":{"type":"string","enum":["pay"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.type","typeLabel":"enum\u003cstring>"},"pay":{"properties":{"connector_name":{"type":"string","description":"The name of the pay connector configured in the Telnyx API. Must reference an existing pay connector for this organization.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.connector_name","typeLabel":"string"},"currency":{"type":"string","default":"USD","description":"Default currency for payments processed by this tool.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.currency","typeLabel":"string"},"payment_method":{"type":"string","default":"credit-card","description":"Default payment method for payments processed by this tool.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.payment_method","typeLabel":"string"},"description":{"oneOf":[{"type":"string","default":null,"description":"Description of the pay tool shown to the assistant so it knows when to call the tool. Not sent to the payment connector — the per-call `description` argument the assistant passes is what reaches the processor.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.description.oneOf.0","typeLabel":"string"},{"type":"null","default":null,"description":"Description of the pay tool shown to the assistant so it knows when to call the tool. Not sent to the payment connector — the per-call `description` argument the assistant passes is what reaches the processor.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.description.oneOf.1","typeLabel":"null"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.description","typeLabel":"string | null"},"connector_parameters":{"type":"object","additionalProperties":true,"description":"Custom key/value parameters forwarded to the pay connector as `parameters` in the processor request. String values may use `{{dynamic_variable}}` templating, resolved per call.","example":{"campaignid":"abc","customer_ref":"CUST-67890"},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.connector_parameters","typeLabel":"object"},"valid_card_types":{"type":"array","items":{"type":"string","enum":["visa","mastercard","amex","maestro","discover","optima","jcb","diners-club","enroute"],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.valid_card_types.items.[INDEX]","typeLabel":"enum\u003cstring>"},"minItems":1,"description":"Restricts accepted card numbers to the listed card types. When the caller enters a card number that does not match one of the listed types, Pay treats the input as invalid and re-prompts for the card number.","example":["visa","mastercard"],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.valid_card_types","typeLabel":"enum\u003cstring>[]"},"postal_code":{"oneOf":[{"type":"string","description":"Controls billing postal code collection for credit-card payments. Set to `false` to skip the postal code prompt without supplying a postal code to the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to prompt the caller. Supply a non-empty string, such as `\"90210\"`, to use that postal code without prompting. This option does not affect ACH debit payments or payments using an existing token.","minLength":1,"pattern":"\\S","example":false,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.postal_code.oneOf.0","typeLabel":"string"},{"type":"boolean","description":"Controls billing postal code collection for credit-card payments. Set to `false` to skip the postal code prompt without supplying a postal code to the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to prompt the caller. Supply a non-empty string, such as `\"90210\"`, to use that postal code without prompting. This option does not affect ACH debit payments or payments using an existing token.","example":false,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.postal_code.oneOf.1","typeLabel":"boolean"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.postal_code","typeLabel":"string | boolean"},"min_postal_code_length":{"type":"integer","minimum":1,"maximum":128,"description":"Minimum number of digits the caller must enter when collecting a credit-card billing postal code. Applies only when `postal_code` prompts the caller. Omitted means the platform default (1) applies. The maximum number of digits collected is the greater of 10 and this value. This does not validate the length of a postal code supplied directly in `postal_code`.","example":5,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.min_postal_code_length","typeLabel":"integer"},"max_attempts":{"type":"integer","minimum":1,"maximum":3,"description":"Maximum number of attempts for each payment collection step. Omitted means the platform default (3) applies.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.max_attempts","typeLabel":"integer"},"timeout_millis":{"type":"integer","minimum":1,"maximum":600000,"description":"Time in milliseconds to wait for DTMF input for each collection step. Omitted means the platform default (5000) applies. Increase this for slower entry, e.g. a 16-digit card number.","example":12000,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.timeout_millis","typeLabel":"integer"},"inter_digit_timeout_millis":{"type":"integer","minimum":1,"maximum":600000,"description":"Time in milliseconds to wait between consecutive DTMF digits. Omitted means the platform default (5000) applies.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.inter_digit_timeout_millis","typeLabel":"integer"},"prompts":{"type":"object","title":"Pay Tool Prompts","description":"Custom text-to-speech prompts keyed by payment collection step. The AI assistant merges its own card-number prompt into this map, matching on the same step keys.","additionalProperties":false,"properties":{"payment-card-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number","typeLabel":"string | Pay Tool Prompt · object[]"},"expiration-date":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date","typeLabel":"string | Pay Tool Prompt · object[]"},"postal-code":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code","typeLabel":"string | Pay Tool Prompt · object[]"},"security-code":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code","typeLabel":"string | Pay Tool Prompt · object[]"},"bank-routing-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number","typeLabel":"string | Pay Tool Prompt · object[]"},"bank-account-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number","typeLabel":"string | Pay Tool Prompt · object[]"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts","typeLabel":"Pay Tool Prompts · object"}},"required":["connector_name"],"type":"object","title":"PayToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay","typeLabel":"PayToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.13","typeLabel":"PayTool · object"},{"type":"object","title":"UpdateDynamicVariablesTool","description":"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`.","required":["type","update_dynamic_variables"],"properties":{"type":{"type":"string","enum":["update_dynamic_variables"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.type","typeLabel":"enum\u003cstring>"},"update_dynamic_variables":{"description":"Configuration for an update_dynamic_variables tool.","properties":{"name":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","description":"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.","example":"collect_details","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.name","typeLabel":"string"},"description":{"type":"string","description":"Description of the tool passed to the assistant, guiding when to call it and which variables to update.","example":"Collect caller details into conversation variables.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.description","typeLabel":"string"},"updatable_variables":{"type":"array","description":"The dynamic variables the assistant is allowed to write. At least one is required.","minItems":1,"items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"pattern":"^(?!telnyx_)[a-zA-Z0-9._-]+$","description":"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.","example":"customer_name","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].name","typeLabel":"string"},"type":{"type":"string","description":"Optional hint for the variable's value type (e.g. `string`).","example":"string","uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].type","typeLabel":"string"},"description":{"type":"string","description":"Optional description of the variable, guiding the assistant on what value to capture.","example":"The caller's full name.","uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].description","typeLabel":"string"}},"required":["name"],"additionalProperties":false,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables","typeLabel":"object[]"}},"required":["name","description","updatable_variables"],"type":"object","title":"UpdateDynamicVariablesToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables","typeLabel":"UpdateDynamicVariablesToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.14","typeLabel":"UpdateDynamicVariablesTool · object"}],"uniqueKey":"tools.items.[INDEX]","typeLabel":"FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object"},"uniqueKey":"tools","typeLabel":"(FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object)[]"},"mcp_servers":{"type":"array","items":{"type":"object","title":"AssistantMCPServer","description":"Reference to an MCP server attached to an assistant. Create and manage MCP servers with the `/ai/mcp_servers` endpoints, then attach them to assistants by ID.","properties":{"id":{"type":"string","description":"ID of the MCP server to attach. This must be the `id` of an MCP server returned by the `/ai/mcp_servers` endpoints.","isRequired":true,"uniqueKey":"mcp_servers.items.[INDEX].id","typeLabel":"string"},"allowed_tools":{"type":"array","items":{"type":"string","uniqueKey":"mcp_servers.items.[INDEX].allowed_tools.items.[INDEX]","typeLabel":"string"},"description":"Optional per-assistant allowlist of MCP tool names. When omitted, the assistant uses the MCP server's configured `allowed_tools`.","uniqueKey":"mcp_servers.items.[INDEX].allowed_tools","typeLabel":"string[]"}},"required":["id"],"uniqueKey":"mcp_servers.items.[INDEX]","typeLabel":"AssistantMCPServer · object"},"default":[],"description":"MCP servers attached to the assistant. Create MCP servers with `/ai/mcp_servers`, then reference them by `id` here.","uniqueKey":"mcp_servers","typeLabel":"AssistantMCPServer · object[]"},"a2a_agents":{"type":"array","items":{"type":"object","title":"AssistantA2AAgent","description":"A remote agent, reachable over the A2A (Agent2Agent) protocol, that an assistant can delegate to. Tools are not configured here: at the start of every conversation the agent's card is fetched and one tool is derived per skill the card advertises.","properties":{"name":{"type":"string","maxLength":43,"description":"Identifies the agent and seeds the names of the tools derived from its card (`a2a_\u003cname>_\u003cskill_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.","example":"billing_agent","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].name","typeLabel":"string"},"url":{"type":"string","description":"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.","example":"https://agents.example.com","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].url","typeLabel":"string"},"headers":{"type":"array","items":{"type":"object","title":"A2AAgentHeader","description":"A header sent when fetching an A2A agent's card and on every call made to that agent.","properties":{"name":{"type":"string","description":"HTTP header name. May only contain alphanumeric characters, hyphens, and underscores, or a `{{dynamic_variable}}` placeholder surrounded by those characters.","example":"X-Api-Key","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].headers.items.[INDEX].name","typeLabel":"string"},"value":{"type":"string","description":"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.","example":"{{#integration_secret}}my_agent_api_key{{/integration_secret}}","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].headers.items.[INDEX].value","typeLabel":"string"}},"required":["name","value"],"uniqueKey":"a2a_agents.items.[INDEX].headers.items.[INDEX]","typeLabel":"A2AAgentHeader · object"},"description":"Headers sent when fetching this agent's card and on every call made to it. Use them to authenticate to the agent.","uniqueKey":"a2a_agents.items.[INDEX].headers","typeLabel":"A2AAgentHeader · object[]"},"async":{"type":"boolean","default":false,"description":"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.","uniqueKey":"a2a_agents.items.[INDEX].async","typeLabel":"boolean"},"timeout_ms":{"type":"integer","minimum":1,"maximum":4294967295,"description":"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.","example":30000,"uniqueKey":"a2a_agents.items.[INDEX].timeout_ms","typeLabel":"integer"},"poll_interval_ms":{"type":"integer","minimum":1,"maximum":4294967295,"description":"How often, in milliseconds, to poll an agent task that has not finished yet. Defaults to 500.","example":500,"uniqueKey":"a2a_agents.items.[INDEX].poll_interval_ms","typeLabel":"integer"},"messages":{"type":"array","description":"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`.","items":{"oneOf":[{"type":"object","title":"A2AAgentRequestStartMessage","required":["type","content"],"properties":{"type":{"type":"string","const":"request_start","description":"Speak the filler message immediately when the call to the agent begins.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.0.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.0.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"An optional delay value. This value is ignored for `request_start` messages.","uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.0.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.0","typeLabel":"A2AAgentRequestStartMessage · object"},{"type":"object","title":"A2AAgentRequestResponseDelayedMessage","required":["type","content","timing_ms"],"properties":{"type":{"type":"string","const":"request_response_delayed","description":"Speak the filler message only if the agent has not answered yet after `timing_ms`.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.1.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.1.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"How long to wait, in milliseconds, before speaking this message.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.1.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.1","typeLabel":"A2AAgentRequestResponseDelayedMessage · object"}],"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX]","typeLabel":"A2AAgentRequestStartMessage · object | A2AAgentRequestResponseDelayedMessage · object"},"uniqueKey":"a2a_agents.items.[INDEX].messages","typeLabel":"(A2AAgentRequestStartMessage · object | A2AAgentRequestResponseDelayedMessage · object)[]"}},"required":["name","url"],"uniqueKey":"a2a_agents.items.[INDEX]","typeLabel":"AssistantA2AAgent · object"},"default":[],"description":"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_\u003cname>_\u003cskill_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.","uniqueKey":"a2a_agents","typeLabel":"AssistantA2AAgent · object[]"},"tool_ids":{"title":"Ids of shared tools","items":{"type":"string","uniqueKey":"tool_ids.items.[INDEX]","typeLabel":"string"},"type":"array","description":"IDs of shared tools to attach to the assistant. New integrations should prefer `tool_ids` over inline `tools`.","uniqueKey":"tool_ids","typeLabel":"string[]"},"description":{"type":"string","uniqueKey":"description","typeLabel":"string"},"greeting":{"type":"string","description":"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 `\u003cassistant-speaks-first-with-model-generated-message>` to have the assistant generate the greeting based on the system instructions.","uniqueKey":"greeting","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"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.","uniqueKey":"llm_api_key_ref","typeLabel":"string"},"external_llm":{"properties":{"model":{"type":"string","description":"Model identifier to use with the external LLM endpoint.","isRequired":true,"uniqueKey":"external_llm.model","typeLabel":"string"},"base_url":{"type":"string","description":"Base URL for the external LLM endpoint.","isRequired":true,"uniqueKey":"external_llm.base_url","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the external LLM API key.","uniqueKey":"external_llm.llm_api_key_ref","typeLabel":"string"},"authentication_method":{"type":"string","enum":["token","certificate"],"default":"token","description":"Authentication method used when connecting to the external LLM endpoint.","title":"AuthenticationMethod","uniqueKey":"external_llm.authentication_method","typeLabel":"enum\u003cstring>"},"certificate_ref":{"type":"string","description":"Integration secret identifier for the client certificate used with certificate authentication.","uniqueKey":"external_llm.certificate_ref","typeLabel":"string"},"token_retrieval_url":{"type":"string","description":"URL used to retrieve an access token when certificate authentication is enabled.","uniqueKey":"external_llm.token_retrieval_url","typeLabel":"string"},"forward_metadata":{"type":"boolean","default":false,"description":"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.","uniqueKey":"external_llm.forward_metadata","typeLabel":"boolean"},"extra_headers":{"oneOf":[{"type":"object","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"external_llm.extra_headers.oneOf.0.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"external_llm.extra_headers.oneOf.0","typeLabel":"object"},{"type":"null","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"external_llm.extra_headers.oneOf.1.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"external_llm.extra_headers.oneOf.1","typeLabel":"null"}],"uniqueKey":"external_llm.extra_headers","typeLabel":"object | null"}},"type":"object","required":["model","base_url"],"title":"ExternalLLMReq","uniqueKey":"external_llm","typeLabel":"ExternalLLMReq · object"},"fallback_config":{"properties":{"model":{"type":"string","description":"Fallback Telnyx-hosted model to use when the primary LLM provider is unavailable.","uniqueKey":"fallback_config.model","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the fallback model API key.","uniqueKey":"fallback_config.llm_api_key_ref","typeLabel":"string"},"external_llm":{"properties":{"model":{"type":"string","description":"Model identifier to use with the external LLM endpoint.","isRequired":true,"uniqueKey":"fallback_config.external_llm.model","typeLabel":"string"},"base_url":{"type":"string","description":"Base URL for the external LLM endpoint.","isRequired":true,"uniqueKey":"fallback_config.external_llm.base_url","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the external LLM API key.","uniqueKey":"fallback_config.external_llm.llm_api_key_ref","typeLabel":"string"},"authentication_method":{"type":"string","enum":["token","certificate"],"default":"token","description":"Authentication method used when connecting to the external LLM endpoint.","title":"AuthenticationMethod","uniqueKey":"fallback_config.external_llm.authentication_method","typeLabel":"enum\u003cstring>"},"certificate_ref":{"type":"string","description":"Integration secret identifier for the client certificate used with certificate authentication.","uniqueKey":"fallback_config.external_llm.certificate_ref","typeLabel":"string"},"token_retrieval_url":{"type":"string","description":"URL used to retrieve an access token when certificate authentication is enabled.","uniqueKey":"fallback_config.external_llm.token_retrieval_url","typeLabel":"string"},"forward_metadata":{"type":"boolean","default":false,"description":"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.","uniqueKey":"fallback_config.external_llm.forward_metadata","typeLabel":"boolean"},"extra_headers":{"oneOf":[{"type":"object","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"fallback_config.external_llm.extra_headers.oneOf.0.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"fallback_config.external_llm.extra_headers.oneOf.0","typeLabel":"object"},{"type":"null","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"fallback_config.external_llm.extra_headers.oneOf.1.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"fallback_config.external_llm.extra_headers.oneOf.1","typeLabel":"null"}],"uniqueKey":"fallback_config.external_llm.extra_headers","typeLabel":"object | null"}},"type":"object","required":["model","base_url"],"title":"ExternalLLMReq","uniqueKey":"fallback_config.external_llm","typeLabel":"ExternalLLMReq · object"}},"type":"object","title":"FallbackConfigReq","uniqueKey":"fallback_config","typeLabel":"FallbackConfigReq · object"},"voice_settings":{"properties":{"voice":{"type":"string","description":"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.\nTo 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.\u003cmodel_id>.\u003cvoice_id>` (e.g. Telnyx.KokoroTTS.af_heart). For Soniox voices, use `Soniox.tts-rt-v2.\u003cvoice_id>` (e.g. Soniox.tts-rt-v2.Emma); every Soniox voice speaks all supported languages.\nThe 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.","isRequired":true,"uniqueKey":"voice_settings.voice","typeLabel":"string"},"voice_speed":{"type":"number","default":1,"description":"The speed of the voice in the range [0.6, 1.5]. 1.0 is the default speed. Larger numbers make the voice faster, smaller numbers make it slower. Applies to Telnyx `Ultra` voices; values outside this range are rejected by the synthesis engine. Soniox voices support a speed range of 0.7 to 1.3.","uniqueKey":"voice_settings.voice_speed","typeLabel":"number"},"api_key_ref":{"type":"string","description":"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.","uniqueKey":"voice_settings.api_key_ref","typeLabel":"string"},"temperature":{"type":"number","default":0.5,"description":"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.","uniqueKey":"voice_settings.temperature","typeLabel":"number"},"similarity_boost":{"type":"number","default":0.75,"description":"Determines how closely the AI should adhere to the original voice when attempting to replicate it. Only applicable when using ElevenLabs.","uniqueKey":"voice_settings.similarity_boost","typeLabel":"number"},"use_speaker_boost":{"type":"boolean","default":true,"description":"Amplifies similarity to the original speaker voice. Increases computational load and latency slightly. Only applicable when using ElevenLabs.","uniqueKey":"voice_settings.use_speaker_boost","typeLabel":"boolean"},"style":{"type":"number","default":0,"description":"Determines the style exaggeration of the voice. Amplifies speaker style but consumes additional resources when set above 0. Only applicable when using ElevenLabs.","uniqueKey":"voice_settings.style","typeLabel":"number"},"speed":{"type":"number","default":1,"description":"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.","uniqueKey":"voice_settings.speed","typeLabel":"number"},"language":{"oneOf":[{"type":"string","description":"Two-letter ISO 639-1 code of the language the voice speaks, for example `es`. Only applicable to Soniox and AssemblyAI voices, which speak every language of their model. AssemblyAI accepts `en`, `es`, `de`, `fr`, `it`, and `pt`. When unset, the voice speaks English.","default":null,"uniqueKey":"voice_settings.language.oneOf.0","typeLabel":"string"},{"type":"null","description":"Two-letter ISO 639-1 code of the language the voice speaks, for example `es`. Only applicable to Soniox and AssemblyAI voices, which speak every language of their model. AssemblyAI accepts `en`, `es`, `de`, `fr`, `it`, and `pt`. When unset, the voice speaks English.","default":null,"uniqueKey":"voice_settings.language.oneOf.1","typeLabel":"null"}],"uniqueKey":"voice_settings.language","typeLabel":"string | null"},"language_boost":{"oneOf":[{"type":"string","description":"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.","enum":[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"],"default":null,"uniqueKey":"voice_settings.language_boost.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","description":"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.","enum":[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"],"default":null,"uniqueKey":"voice_settings.language_boost.oneOf.1","typeLabel":"null"}],"uniqueKey":"voice_settings.language_boost","typeLabel":"enum\u003cstring> | null"},"expressive_mode":{"type":"boolean","default":false,"description":"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.","uniqueKey":"voice_settings.expressive_mode","typeLabel":"boolean"},"background_audio":{"oneOf":[{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["predefined_media"],"description":"Select from predefined media options.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.0.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","enum":["silence","office"],"default":"silence","description":"The predefined media to use. `silence` disables background audio.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.0.value","typeLabel":"enum\u003cstring>"},"volume":{"type":"number","minimum":0.1,"maximum":1,"multipleOf":0.1,"default":1,"description":"Volume level for the predefined background audio. Supports values from 0.1 to 1.0 in 0.1 increments.","uniqueKey":"voice_settings.background_audio.oneOf.0.volume","typeLabel":"number"}},"uniqueKey":"voice_settings.background_audio.oneOf.0","typeLabel":"object"},{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["media_url"],"description":"Provide a direct URL to an MP3 file. The audio will loop during the call.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.1.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","format":"uri","description":"HTTPS URL to an MP3 file.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.1.value","typeLabel":"string\u003curi>"}},"uniqueKey":"voice_settings.background_audio.oneOf.1","typeLabel":"object"},{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["media_name"],"description":"Reference a previously uploaded media by its name from Telnyx Media Storage.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.2.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","description":"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.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.2.value","typeLabel":"string"}},"uniqueKey":"voice_settings.background_audio.oneOf.2","typeLabel":"object"}],"uniqueKey":"voice_settings.background_audio","typeLabel":"object"},"tool_call_audio":{"oneOf":[{"type":"object","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","required":["type","value"],"example":{"type":"predefined_media","value":"typing","volume":0.5},"properties":{"type":{"type":"string","enum":["predefined_media"],"description":"Select from predefined media options.","isRequired":true,"uniqueKey":"voice_settings.tool_call_audio.oneOf.0.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","enum":["typing"],"description":"The predefined media to use. `typing` plays a keyboard typing sound.","isRequired":true,"uniqueKey":"voice_settings.tool_call_audio.oneOf.0.value","typeLabel":"enum\u003cstring>"},"volume":{"type":"number","minimum":0,"maximum":1,"multipleOf":0.1,"default":0.5,"description":"Volume level for the predefined media. Supports values from 0.0 to 1.0 in 0.1 increments. `0.0` plays no sound.","uniqueKey":"voice_settings.tool_call_audio.oneOf.0.volume","typeLabel":"number"}},"uniqueKey":"voice_settings.tool_call_audio.oneOf.0","typeLabel":"object"},{"type":"object","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","required":["type","value"],"example":{"type":"predefined_media","value":"typing"},"properties":{"type":{"type":"string","enum":["media_url"],"description":"Provide a direct URL to an MP3 file. The audio loops while the tool runs.","isRequired":true,"uniqueKey":"voice_settings.tool_call_audio.oneOf.1.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","format":"uri","description":"HTTPS URL to an MP3 file.","isRequired":true,"uniqueKey":"voice_settings.tool_call_audio.oneOf.1.value","typeLabel":"string\u003curi>"}},"uniqueKey":"voice_settings.tool_call_audio.oneOf.1","typeLabel":"object"},{"type":"null","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","example":{"type":"predefined_media","value":"typing","volume":0.5},"uniqueKey":"voice_settings.tool_call_audio.oneOf.2","typeLabel":"null"}],"uniqueKey":"voice_settings.tool_call_audio","typeLabel":"object · object · null"}},"type":"object","required":["voice"],"uniqueKey":"voice_settings","typeLabel":"object"},"avatar_settings":{"oneOf":[{"type":"object","title":"AvatarSettingsRequest","description":"**Beta:** Optional avatar configuration for supported realtime browser conversations. Omit or set to `null` to create the assistant without an avatar.","required":["provider","avatar_id","background_id","model"],"example":{"provider":"telnyx","avatar_id":"elena","background_id":"office","model":"foxtrot-1"},"properties":{"provider":{"type":"string","const":"telnyx","description":"Selects the Telnyx open-source avatar provider.","isRequired":true,"uniqueKey":"avatar_settings.oneOf.0.provider","typeLabel":"string"},"avatar_id":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"The Telnyx stock avatar or organization-owned custom avatar to render.","example":"avatar_0123456789abcdef0123456789abcdef","isRequired":true,"uniqueKey":"avatar_settings.oneOf.0.avatar_id","typeLabel":"string"},"background_id":{"type":"string","enum":["office","studio","reception","illustrated_workspace"],"description":"The background to render.","isRequired":true,"uniqueKey":"avatar_settings.oneOf.0.background_id","typeLabel":"enum\u003cstring>"},"model":{"type":"string","enum":["foxtrot-1"],"description":"Required avatar model identifier, separate from `avatar_id`. The supported value is `foxtrot-1`. Omission, null, and unsupported model identifiers are rejected.","isRequired":true,"uniqueKey":"avatar_settings.oneOf.0.model","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"avatar_settings.oneOf.0","typeLabel":"AvatarSettingsRequest · object"},{"type":"null","description":"**Beta:** Optional avatar configuration for supported realtime browser conversations. Omit or set to `null` to create the assistant without an avatar.","uniqueKey":"avatar_settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"avatar_settings","typeLabel":"AvatarSettingsRequest · object | null"},"transcription":{"properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","speechmatics/standard","speechmatics/linden-1","azure/fast","assemblyai/universal-3-6-pro","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","telnyx/basira","distil-whisper/distil-large-v2","openai/whisper-large-v3-turbo"],"description":"The speech to text model to be used by the voice assistant. All Deepgram models are run on-premise.\n\n- `deepgram/flux` is optimized for turn-taking with multilingual language hints.\n- `deepgram/nova-3` is multilingual with automatic language detection.\n- `deepgram/nova-2` is Deepgram's previous-generation multilingual model.\n- `speechmatics/standard` is a Speechmatics model self-hosted by Telnyx; it supports a fixed set of language packs (including bilingual packs such as `ar_en`) and defaults to `en`.\n- `speechmatics/linden-1` (preview) is a vendor-hosted streaming model with no auto-detect; set `language` from Speechmatics' Realtime language list (defaults to `en`).\n- `azure/fast` is a multilingual Azure transcription model.\n- `assemblyai/universal-3-6-pro` (AssemblyAI Universal-3.6 Pro) is a multilingual streaming model with configurable turn detection. The legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming` are still accepted and run the same model.\n- `xai/grok-stt` is a multilingual Grok STT model.\n- `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`.\n- `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection.\n- `omi-health/omi-med-stt-v1` is an English-only medical transcription model (Parakeet-based).\n- `humain/realtime` is a streaming model with native Arabic and Arabic/English code-switching support.\n- `reson8/turns` is a turn-based streaming model covering 10 European languages with automatic language detection.\n- `cohere/ar-stt` is a non-streaming Arabic and English transcription model.\n- `telnyx/basira` is a non-streaming Arabic transcription model.","uniqueKey":"transcription.model","typeLabel":"enum\u003cstring>"},"language":{"type":"string","description":"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. For `speechmatics/linden-1`, there is no auto-detect; set a code from Speechmatics' Realtime language list (67 language codes, including `es-bilingual-en` for Spanish and English bilingual, and the spelling and script variants `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant`; `en` alone uses the default spelling); unset defaults to `en`, while an explicit `auto`, `auto_beta`, or `multi` is rejected with a 400.","uniqueKey":"transcription.language","typeLabel":"string"},"api_key_ref":{"title":"Api Key Ref","type":"string","description":"Integration secret identifier for the transcription provider API key. Currently used for Azure transcription regions that require a customer-provided API key.","uniqueKey":"transcription.api_key_ref","typeLabel":"string"},"region":{"title":"Region","type":"string","description":"Region on third party cloud providers (currently Azure) if using one of their models. Some regions require `api_key_ref`.","uniqueKey":"transcription.region","typeLabel":"string"},"settings":{"properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"transcription.settings.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"transcription.settings.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"transcription.settings.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"transcription.settings.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"transcription.settings.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"transcription.settings.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"transcription.settings.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"transcription.settings.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"transcription.settings.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"transcription.settings.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"transcription.settings.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"transcription.settings.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"transcription.settings.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"transcription.settings.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"transcription.settings.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"transcription.settings.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"transcription.settings.language_hints","typeLabel":"string[]"}},"type":"object","title":"TranscriptionSettingsConfig","uniqueKey":"transcription.settings","typeLabel":"TranscriptionSettingsConfig · object"},"fallback_models":{"oneOf":[{"type":"array","items":{"title":"TranscriptionFallbackModel","description":"A streaming speech-to-text model that takes over transcription when the model in use fails.","type":"object","properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","assemblyai/universal-3-6-pro","assemblyai/universal-3-5-pro","assemblyai/universal-streaming","xai/grok-stt","soniox/stt-rt-v4","soniox/stt-rt-v5","humain/realtime","reson8/turns"],"description":"The fallback model. It must be a streaming model other than `transcription.model` and the other fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` (or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or `reson8/turns`.","isRequired":true,"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].model","typeLabel":"enum\u003cstring>"},"language":{"oneOf":[{"type":"string","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].language.oneOf.0","typeLabel":"string"},{"type":"null","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].language.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].language","typeLabel":"string | null"},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.language_hints","typeLabel":"string[]"}},"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0","typeLabel":"TranscriptionSettingsConfig · object"},{"type":"null","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings","typeLabel":"TranscriptionSettingsConfig · object | null"}},"required":["model"],"example":{"model":"deepgram/nova-3","language":"en","settings":{"keyterm":"Telnyx,VoIP,SIP"}},"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX]","typeLabel":"TranscriptionFallbackModel · object"},"maxItems":3,"description":"Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a streaming model too, and must support `language` alongside other models. On update, a list replaces the stored one: omit the field to keep the stored list, or send `null` or `[]` to remove it. When an update changes `model` or `language`, stored fallbacks that no longer fit are removed without an error. Can't be combined with `challenger`, the language booster; to replace a stored language booster, send `challenger: null` in the same request.","example":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"uniqueKey":"transcription.fallback_models.oneOf.0","typeLabel":"TranscriptionFallbackModel · object[]"},{"type":"null","items":{"title":"TranscriptionFallbackModel","description":"A streaming speech-to-text model that takes over transcription when the model in use fails.","type":"object","properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","assemblyai/universal-3-6-pro","assemblyai/universal-3-5-pro","assemblyai/universal-streaming","xai/grok-stt","soniox/stt-rt-v4","soniox/stt-rt-v5","humain/realtime","reson8/turns"],"description":"The fallback model. It must be a streaming model other than `transcription.model` and the other fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` (or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or `reson8/turns`."},"language":{"oneOf":[{"type":"string","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run."},{"type":"null","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run."}]},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean"},"numerals":{"title":"Numerals","type":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript."},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead."},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters."},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and 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":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn."},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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":{"title":"Context","type":"string","maxLength":10000,"description":"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":{"title":"Language Hints","type":"array","items":{"type":"string"},"description":"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`."}}},{"type":"null","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model."}]}},"required":["model"],"example":{"model":"deepgram/nova-3","language":"en","settings":{"keyterm":"Telnyx,VoIP,SIP"}}},"maxItems":3,"description":"Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a streaming model too, and must support `language` alongside other models. On update, a list replaces the stored one: omit the field to keep the stored list, or send `null` or `[]` to remove it. When an update changes `model` or `language`, stored fallbacks that no longer fit are removed without an error. Can't be combined with `challenger`, the language booster; to replace a stored language booster, send `challenger: null` in the same request.","example":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"uniqueKey":"transcription.fallback_models.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.fallback_models","typeLabel":"TranscriptionFallbackModel · object[] | null"},"challenger":{"oneOf":[{"type":"object","title":"TranscriptionChallenger","description":"The language booster: a second model that transcribes alongside `model`, and the rule that decides which transcript the assistant uses. Both models must be streaming, or both non-streaming, and, except with `merge_words`, `model` must support `language` alongside another model (for example, `cohere/ar-stt` supports only `ar` there). If the language booster can't run, the call runs on `model` alone; if either model fails mid-call, the call continues on the other. On update, omit the field to keep the stored language booster, or send `null` to remove it. When an update changes `model` or `language` and the stored language booster no longer fits, it is removed without an error. Can't be combined with `fallback_models`; to replace stored fallbacks, send `fallback_models: []` in the same request.","required":["model"],"example":{"model":"deepgram/nova-3","language":"en","rule":"best_turn"},"properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","azure/fast","assemblyai/universal-3-6-pro","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","telnyx/basira","distil-whisper/distil-large-v2","openai/whisper-large-v3-turbo"],"description":"The language booster's model. It must be the same kind of model as `transcription.model`: both streaming (`deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`, `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, `reson8/turns`) or both non-streaming (`azure/fast`, `nvidia/parakeet-v3`, `omi-health/omi-med-stt-v1`, `cohere/ar-stt`, `distil-whisper/distil-large-v2`, `openai/whisper-large-v3-turbo`, `telnyx/basira`). It can be the same model as `transcription.model` on a different `language`.","isRequired":true,"uniqueKey":"transcription.challenger.oneOf.0.model","typeLabel":"enum\u003cstring>"},"language":{"oneOf":[{"type":"string","description":"The language this model transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when this model doesn't support the language it would run. It is also rejected when it would run the same model on the same language as `transcription.model`.","uniqueKey":"transcription.challenger.oneOf.0.language.oneOf.0","typeLabel":"string"},{"type":"null","description":"The language this model transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when this model doesn't support the language it would run. It is also rejected when it would run the same model on the same language as `transcription.model`.","uniqueKey":"transcription.challenger.oneOf.0.language.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.challenger.oneOf.0.language","typeLabel":"string | null"},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the language booster, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.language_hints","typeLabel":"string[]"}},"uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0","typeLabel":"TranscriptionSettingsConfig · object"},{"type":"null","description":"Settings for the language booster, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.challenger.oneOf.0.settings","typeLabel":"TranscriptionSettingsConfig · object | null"},"rule":{"type":"string","enum":["best_turn","best_engine","merge_words"],"default":"best_turn","description":"How the assistant picks the transcript it uses. The models are compared on how complete and confident their transcripts are, not on language, so the rules work best when both models understand the callers' language.\n\n- `best_turn` (default): both models transcribe the whole call. Each turn uses the language booster's transcript only when it scores higher than the transcript of `transcription.model` (clearly higher with non-streaming models). With streaming models, `transcription.model` also decides when each turn ends. Available for every pair.\n- `best_engine`: both models transcribe the first turns, then the call continues alone on the model whose transcripts scored higher. If neither clearly leads, `transcription.model` continues. Streaming models only.\n- `merge_words`: both models transcribe each utterance and their words are merged, keeping Arabic and English spoken in the same sentence. Available only for `telnyx/basira` with `cohere/ar-stt`, in either order. The pair runs on the language that applies to `telnyx/basira` (its own, or that of `transcription.model`), which must be Arabic (`ar` or an `ar-` locale), `multi`, or `auto`.","uniqueKey":"transcription.challenger.oneOf.0.rule","typeLabel":"enum\u003cstring>"}},"uniqueKey":"transcription.challenger.oneOf.0","typeLabel":"TranscriptionChallenger · object"},{"type":"null","description":"The language booster: a second model that transcribes alongside `model`, and the rule that decides which transcript the assistant uses. Both models must be streaming, or both non-streaming, and, except with `merge_words`, `model` must support `language` alongside another model (for example, `cohere/ar-stt` supports only `ar` there). If the language booster can't run, the call runs on `model` alone; if either model fails mid-call, the call continues on the other. On update, omit the field to keep the stored language booster, or send `null` to remove it. When an update changes `model` or `language` and the stored language booster no longer fits, it is removed without an error. Can't be combined with `fallback_models`; to replace stored fallbacks, send `fallback_models: []` in the same request.","uniqueKey":"transcription.challenger.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.challenger","typeLabel":"TranscriptionChallenger · object | null"}},"type":"object","uniqueKey":"transcription","typeLabel":"object"},"telephony_settings":{"properties":{"default_texml_app_id":{"type":"string","description":"Default Texml App used for voice calls with your assistant. This will be created automatically on assistant creation.","uniqueKey":"telephony_settings.default_texml_app_id","typeLabel":"string"},"supports_unauthenticated_web_calls":{"type":"boolean","description":"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.","uniqueKey":"telephony_settings.supports_unauthenticated_web_calls","typeLabel":"boolean"},"noise_suppression":{"type":"string","enum":["aicoustics","krisp","deepfilternet","disabled"],"description":"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.","uniqueKey":"telephony_settings.noise_suppression","typeLabel":"enum\u003cstring>"},"noise_suppression_config":{"type":"object","description":"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'.","properties":{"attenuation_limit":{"type":"integer","minimum":0,"maximum":100,"default":100,"description":"Attenuation limit for noise suppression. Range: 0-100. Only applicable when noise_suppression is 'deepfilternet'.","uniqueKey":"telephony_settings.noise_suppression_config.attenuation_limit","typeLabel":"integer"},"mode":{"type":"string","enum":["advanced"],"description":"Mode for noise suppression configuration. Only applicable when noise_suppression is 'deepfilternet'.","uniqueKey":"telephony_settings.noise_suppression_config.mode","typeLabel":"enum\u003cstring>"},"family":{"type":"string","enum":["quail"],"description":"AiCoustics model family optimized for Voice AI and STT. Only applicable when noise_suppression is 'aicoustics'.","uniqueKey":"telephony_settings.noise_suppression_config.family","typeLabel":"enum\u003cstring>"},"size":{"type":"string","enum":["vf","vf_2_0_l"],"description":"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'.","uniqueKey":"telephony_settings.noise_suppression_config.size","typeLabel":"enum\u003cstring>"},"enhancement_level":{"type":"number","minimum":0,"maximum":1,"default":0.8,"description":"AiCoustics enhancement intensity. Range: 0-1. Only applicable when noise_suppression is 'aicoustics'.","uniqueKey":"telephony_settings.noise_suppression_config.enhancement_level","typeLabel":"number"}},"uniqueKey":"telephony_settings.noise_suppression_config","typeLabel":"object"},"time_limit_secs":{"type":"integer","minimum":30,"maximum":14400,"default":1800,"description":"Maximum duration in seconds for the AI assistant to participate on the call. When this limit is reached the assistant will be stopped. Stopping the assistant does not itself hang up the call, and what happens next depends on how the assistant is running. On Call Control (ai_assistant_start) the call leg stays connected and continues to be billed until it is hung up (for example with the Hangup call command) or until the call ends for another reason. On TeXML, the assistant's `\u003cConnect>\u003cAIAssistant>` instruction ends; in the default TeXML setup for assistants no instructions follow it, so the call is hung up. Your application receives a call.conversation.ended webhook when the assistant stops. This limit does not apply to portions of a call without an active assistant (for instance, a call transferred to a human representative).","uniqueKey":"telephony_settings.time_limit_secs","typeLabel":"integer"},"user_idle_timeout_secs":{"type":"integer","minimum":10,"maximum":14400,"description":"Maximum duration in seconds of end user silence on the call. When this limit is reached the assistant will be stopped. Stopping the assistant does not itself hang up the call, and what happens next depends on how the assistant is running. On Call Control (ai_assistant_start) the call leg stays connected and continues to be billed until it is hung up (for example with the Hangup call command) or until the call ends for another reason. On TeXML, the assistant's `\u003cConnect>\u003cAIAssistant>` instruction ends; in the default TeXML setup for assistants no instructions follow it, so the call is hung up. Your application receives a call.conversation.ended webhook when the assistant stops. This limit does not apply to portions of a call without an active assistant (for instance, a call transferred to a human representative).","uniqueKey":"telephony_settings.user_idle_timeout_secs","typeLabel":"integer"},"user_idle_reply_secs":{"type":"integer","minimum":0,"default":10,"description":"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.","uniqueKey":"telephony_settings.user_idle_reply_secs","typeLabel":"integer"},"fallback_destination":{"type":"string","description":"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.","uniqueKey":"telephony_settings.fallback_destination","typeLabel":"string"},"send_message_history_updates":{"type":"boolean","description":"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.","uniqueKey":"telephony_settings.send_message_history_updates","typeLabel":"boolean"},"conversation_ended_full_history":{"type":"boolean","default":false,"description":"When enabled, the `messages` array of the `call.conversation.ended` webhook contains the full conversation history in order: user and assistant turns, assistant tool calls (`tool_calls`), tool results (`role: tool` with `tool_call_id`), and informational `system` and `developer` entries. The assistant's instructions are never included. When disabled, `messages` contains only user and assistant text turns.","uniqueKey":"telephony_settings.conversation_ended_full_history","typeLabel":"boolean"},"greeting_delay_ms":{"oneOf":[{"type":"integer","minimum":0,"maximum":2000,"description":"Milliseconds to wait after an inbound call is answered before the assistant starts and speaks its greeting. Increase it if the beginning of the greeting is cut off on some connections (for example, WebRTC calls). When unset (`null`), the platform default of 250 ms is used. Set to `0` to start without a delay. Maximum 2000.","uniqueKey":"telephony_settings.greeting_delay_ms.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"maximum":2000,"description":"Milliseconds to wait after an inbound call is answered before the assistant starts and speaks its greeting. Increase it if the beginning of the greeting is cut off on some connections (for example, WebRTC calls). When unset (`null`), the platform default of 250 ms is used. Set to `0` to start without a delay. Maximum 2000.","uniqueKey":"telephony_settings.greeting_delay_ms.oneOf.1","typeLabel":"null"}],"uniqueKey":"telephony_settings.greeting_delay_ms","typeLabel":"integer | null"},"voicemail_detection":{"type":"object","description":"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.","properties":{"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected.","properties":{"action":{"type":"string","enum":["stop_assistant","leave_message_and_stop_assistant","continue_assistant"],"description":"The action to take when voicemail is detected.","uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"},"voicemail_message":{"type":"object","description":"Configuration for the voicemail message to leave. Only applicable when action is 'leave_message_and_stop_assistant'.","properties":{"type":{"type":"string","enum":["prompt","message"],"description":"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.","uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.voicemail_message.type","typeLabel":"enum\u003cstring>"},"prompt":{"type":"string","description":"The prompt to use for generating the voicemail message. Only applicable when type is 'prompt'.","uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.voicemail_message.prompt","typeLabel":"string"},"message":{"type":"string","description":"The specific message to leave as voicemail. Only applicable when type is 'message'.","uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.voicemail_message.message","typeLabel":"string"}},"uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.voicemail_message","typeLabel":"object"}},"uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected","typeLabel":"object"}},"uniqueKey":"telephony_settings.voicemail_detection","typeLabel":"object"},"disable_dtmf":{"type":"boolean","default":false,"description":"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.","uniqueKey":"telephony_settings.disable_dtmf","typeLabel":"boolean"},"recording_settings":{"type":"object","description":"Configuration for call recording format and channel settings.","properties":{"enabled":{"type":"boolean","default":true,"description":"Whether call recording is enabled. When set to false, calls will not be recorded regardless of other recording configuration.","uniqueKey":"telephony_settings.recording_settings.enabled","typeLabel":"boolean"},"channels":{"type":"string","enum":["single","dual"],"default":"dual","description":"The number of channels for the recording. 'single' for mono, 'dual' for stereo.","uniqueKey":"telephony_settings.recording_settings.channels","typeLabel":"enum\u003cstring>"},"format":{"type":"string","enum":["wav","mp3"],"default":"mp3","description":"The format of the recording file.","uniqueKey":"telephony_settings.recording_settings.format","typeLabel":"enum\u003cstring>"},"stop_on_conversation_end":{"type":"boolean","default":false,"description":"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.","uniqueKey":"telephony_settings.recording_settings.stop_on_conversation_end","typeLabel":"boolean"}},"uniqueKey":"telephony_settings.recording_settings","typeLabel":"object"}},"type":"object","title":"TelephonySettings","uniqueKey":"telephony_settings","typeLabel":"TelephonySettings · object"},"messaging_settings":{"properties":{"default_messaging_profile_id":{"type":"string","description":"Default Messaging Profile used for messaging exchanges with your assistant. This will be created automatically on assistant creation.","uniqueKey":"messaging_settings.default_messaging_profile_id","typeLabel":"string"},"delivery_status_webhook_url":{"type":"string","description":"The URL where webhooks related to delivery statused for assistant messages will be sent.","uniqueKey":"messaging_settings.delivery_status_webhook_url","typeLabel":"string"},"conversation_inactivity_minutes":{"type":"integer","minimum":1,"maximum":10000000,"description":"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.","uniqueKey":"messaging_settings.conversation_inactivity_minutes","typeLabel":"integer"}},"type":"object","uniqueKey":"messaging_settings","typeLabel":"object"},"enabled_features":{"items":{"type":"string","enum":["telephony","messaging"],"description":"If `telephony` is enabled, the assistant will be able to make and receive calls. If `messaging` is enabled, the assistant will be able to send and receive messages.","uniqueKey":"enabled_features.items.[INDEX]","typeLabel":"enum\u003cstring>"},"type":"array","uniqueKey":"enabled_features","typeLabel":"enum\u003cstring>[]"},"insight_settings":{"properties":{"insight_group_id":{"type":"string","description":"Reference to an Insight Group. Insights in this group will be run automatically for all the assistant's conversations.","uniqueKey":"insight_settings.insight_group_id","typeLabel":"string"},"model":{"oneOf":[{"type":"string","description":"The model that generates the assistant's insights when a conversation ends. It runs every insight in the group, Telnyx-managed insights included. Must be `zai-org/GLM-5.3-Flash` or `meta-llama/Llama-3.3-70B-Instruct`; any other model returns `422`. When omitted on create, it defaults to `zai-org/GLM-5.3-Flash`; when omitted on update, the current model is kept. `null` uses Telnyx's default insight models, which assistants created before this setting have. Insights of messaging conversations, and insights regenerated later, always use Telnyx's default insight models.","example":"zai-org/GLM-5.3-Flash","uniqueKey":"insight_settings.model.oneOf.0","typeLabel":"string"},{"type":"null","description":"The model that generates the assistant's insights when a conversation ends. It runs every insight in the group, Telnyx-managed insights included. Must be `zai-org/GLM-5.3-Flash` or `meta-llama/Llama-3.3-70B-Instruct`; any other model returns `422`. When omitted on create, it defaults to `zai-org/GLM-5.3-Flash`; when omitted on update, the current model is kept. `null` uses Telnyx's default insight models, which assistants created before this setting have. Insights of messaging conversations, and insights regenerated later, always use Telnyx's default insight models.","example":"zai-org/GLM-5.3-Flash","uniqueKey":"insight_settings.model.oneOf.1","typeLabel":"null"}],"uniqueKey":"insight_settings.model","typeLabel":"string | null"}},"type":"object","uniqueKey":"insight_settings","typeLabel":"object"},"privacy_settings":{"properties":{"data_retention":{"type":"boolean","description":"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.","uniqueKey":"privacy_settings.data_retention","typeLabel":"boolean"},"pii_redaction":{"type":"string","enum":["disabled","redact"],"default":"disabled","description":"Controls redaction of personally identifiable information (PII) from the conversation history that is stored for this assistant. `disabled` (default) stores content as-is. `redact` replaces detected PII with `\u003cPII:type/>` placeholders (e.g. `\u003cPII:name/>`, `\u003cPII:phone/>`) as the stored copies are written: message content (user, assistant, and tool-result messages) and tool-call arguments are redacted when written to conversation history, so the stored transcript, its read-back via the history API, and any insights generated from the stored messages contain the placeholders instead of the PII; response bodies returned by webhook tools are redacted too, as stored in the webhook logs — a per-conversation record separate from the transcript. In the Mission Control Portal this field appears as a \"PII Redaction\" on/off toggle, where Enabled corresponds to `redact`. Redaction runs when the stored copy is written, after the LLM has generated its reply: the live conversation is not redacted, the assistant's tools keep receiving the full (unredacted) values during the call, and the LLM still sees full content in its context window. Call recordings (including any recording layout configured under telephony settings) and the payloads of messages/webhooks delivered during the call are never redacted by this setting. The set of detected PII types (names, street addresses, phone numbers, email addresses, government identifiers like SSN and driver's license numbers, credit card and bank account numbers, IP addresses, dates of birth, and other identifiers unique to a person) is fixed by Telnyx and cannot be configured or extended per assistant. Assistants with `redact` cannot be used for SMS/WhatsApp messaging (that combination is rejected with a 400 error); voice and web chat are unaffected.","uniqueKey":"privacy_settings.pii_redaction","typeLabel":"enum\u003cstring>"},"in_transit_data_locality":{"type":"boolean","default":false,"description":"Requires this assistant's conversations to be processed inside your organization's data-locality region, rather than only stored there, on every channel: for web chat, every model call of a turn; for voice, the call's model calls and the Telnyx-hosted speech services it uses; for SMS and WhatsApp, the model calls of each turn (how messages travel through carriers is not covered). Covered processing that cannot be handled in region fails rather than being served elsewhere. 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)), Telnyx-hosted models for the assistant, its fallback, and any conversation-flow node that overrides the model, and, when `insight_settings.model` is set, an insight model available in that region; the request is rejected otherwise. A voice call fails when it starts if its STT model or TTS voice is not self-hosted by Telnyx, if the assistant uses a speech-to-speech model, or if the call's media is anchored outside the region. Once enabled, send web chat requests and WebSocket or WebRTC conversations to your region's API hostname: one entering the platform in another region is refused rather than forwarded, because forwarding it would already have moved the content across the border. See [Data residency](https://developers.telnyx.com/docs/inference/data-residency#in-region-processing-for-ai-assistants). Defaults to false.","uniqueKey":"privacy_settings.in_transit_data_locality","typeLabel":"boolean"}},"type":"object","uniqueKey":"privacy_settings","typeLabel":"object"},"dynamic_variables_webhook_url":{"type":"string","description":"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.","uniqueKey":"dynamic_variables_webhook_url","typeLabel":"string"},"dynamic_variables_webhook_timeout_ms":{"type":"integer","minimum":1,"maximum":10000,"default":1500,"description":"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).","uniqueKey":"dynamic_variables_webhook_timeout_ms","typeLabel":"integer"},"dynamic_variables":{"type":"object","description":"Map of dynamic variables and their default values","additionalProperties":true,"uniqueKey":"dynamic_variables","typeLabel":"object"},"widget_settings":{"type":"object","properties":{"theme":{"type":"string","enum":["light","dark"],"description":"The visual theme for the widget.","uniqueKey":"widget_settings.theme","typeLabel":"enum\u003cstring>"},"audio_visualizer_config":{"type":"object","properties":{"color":{"type":"string","enum":["verdant","twilight","bloom","mystic","flare","glacier"],"description":"The color theme for the audio visualizer.","uniqueKey":"widget_settings.audio_visualizer_config.color","typeLabel":"enum\u003cstring>"},"preset":{"type":"string","description":"The preset style for the audio visualizer.","uniqueKey":"widget_settings.audio_visualizer_config.preset","typeLabel":"string"}},"title":"AudioVisualizerConfig","uniqueKey":"widget_settings.audio_visualizer_config","typeLabel":"AudioVisualizerConfig · object"},"start_call_text":{"type":"string","description":"Custom text displayed on the start call button.","uniqueKey":"widget_settings.start_call_text","typeLabel":"string"},"default_state":{"type":"string","enum":["expanded","collapsed"],"description":"The default state of the widget.","uniqueKey":"widget_settings.default_state","typeLabel":"enum\u003cstring>"},"position":{"type":"string","enum":["fixed","static"],"description":"The positioning style for the widget.","uniqueKey":"widget_settings.position","typeLabel":"enum\u003cstring>"},"view_history_url":{"oneOf":[{"type":"string","description":"URL to view conversation history.","uniqueKey":"widget_settings.view_history_url.oneOf.0","typeLabel":"string"},{"type":"null","description":"URL to view conversation history.","uniqueKey":"widget_settings.view_history_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"widget_settings.view_history_url","typeLabel":"string | null"},"report_issue_url":{"oneOf":[{"type":"string","description":"URL for users to report issues.","uniqueKey":"widget_settings.report_issue_url.oneOf.0","typeLabel":"string"},{"type":"null","description":"URL for users to report issues.","uniqueKey":"widget_settings.report_issue_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"widget_settings.report_issue_url","typeLabel":"string | null"},"give_feedback_url":{"oneOf":[{"type":"string","description":"URL for users to give feedback.","uniqueKey":"widget_settings.give_feedback_url.oneOf.0","typeLabel":"string"},{"type":"null","description":"URL for users to give feedback.","uniqueKey":"widget_settings.give_feedback_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"widget_settings.give_feedback_url","typeLabel":"string | null"},"agent_thinking_text":{"type":"string","description":"Text displayed while the agent is processing.","uniqueKey":"widget_settings.agent_thinking_text","typeLabel":"string"},"speak_to_interrupt_text":{"type":"string","description":"Text prompting users to speak to interrupt.","uniqueKey":"widget_settings.speak_to_interrupt_text","typeLabel":"string"},"logo_icon_url":{"oneOf":[{"type":"string","description":"URL to a custom logo icon for the widget.","uniqueKey":"widget_settings.logo_icon_url.oneOf.0","typeLabel":"string"},{"type":"null","description":"URL to a custom logo icon for the widget.","uniqueKey":"widget_settings.logo_icon_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"widget_settings.logo_icon_url","typeLabel":"string | null"}},"title":"WidgetSettings","description":"Configuration settings for the assistant's web widget.","uniqueKey":"widget_settings","typeLabel":"WidgetSettings · object"},"interruption_settings":{"type":"object","title":"InterruptionSettings","description":"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`).","properties":{"enable":{"type":"boolean","default":true,"description":"Whether users can interrupt the assistant while it is speaking.","uniqueKey":"interruption_settings.enable","typeLabel":"boolean"},"disable_greeting_interruption":{"type":"boolean","description":"When true, disables user interruptions while the assistant greeting is playing.","uniqueKey":"interruption_settings.disable_greeting_interruption","typeLabel":"boolean"},"start_speaking_plan":{"oneOf":[{"type":"object","title":"StartSpeakingPlan","description":"Presence of this object (even `{}`) enables per-turn transcript endpointing while it is set; setting it to `null` clears the plan and disables per-turn matching entirely. Omitting it from an update leaves the existing plan in place (updates are validated against the merged configuration).","properties":{"wait_seconds":{"type":"number","format":"float","default":0.4,"minimum":0,"description":"Wait used when per-turn endpointing does not select a tier. While the plan is present this applies on every turn without a matching tier (including when `transcription_endpointing_plan` is unset); a matching tier replaces it for that turn, and a tier may be shorter or longer than this value.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.wait_seconds","typeLabel":"number\u003cfloat>"},"transcription_endpointing_plan":{"oneOf":[{"type":"object","title":"TranscriptionEndpointingPlan","description":"Omit (stay null) when unset: the per-turn wait stays on `wait_seconds`. Setting `null` on an update clears a previously configured plan.","properties":{"on_punctuation_seconds":{"type":"number","format":"float","default":0.1,"description":"Seconds to wait after the transcript ends with punctuation.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.0.on_punctuation_seconds","typeLabel":"number\u003cfloat>"},"on_no_punctuation_seconds":{"type":"number","format":"float","default":1.5,"description":"Seconds to wait after the transcript ends without punctuation.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.0.on_no_punctuation_seconds","typeLabel":"number\u003cfloat>"},"on_number_seconds":{"type":"number","format":"float","default":0.5,"description":"Seconds to wait after the transcript ends with a number.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.0.on_number_seconds","typeLabel":"number\u003cfloat>"}},"uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.0","typeLabel":"TranscriptionEndpointingPlan · object"},{"type":"null","description":"Omit (stay null) when unset: the per-turn wait stays on `wait_seconds`. Setting `null` on an update clears a previously configured plan.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.1","typeLabel":"null"}],"uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan","typeLabel":"TranscriptionEndpointingPlan · object | null"}},"uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0","typeLabel":"StartSpeakingPlan · object"},{"type":"null","description":"Presence of this object (even `{}`) enables per-turn transcript endpointing while it is set; setting it to `null` clears the plan and disables per-turn matching entirely. Omitting it from an update leaves the existing plan in place (updates are validated against the merged configuration).","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.1","typeLabel":"null"}],"uniqueKey":"interruption_settings.start_speaking_plan","typeLabel":"StartSpeakingPlan · object | null"},"interrupt_prediction_threshold":{"oneOf":[{"type":"number","default":0,"minimum":0,"maximum":1,"description":"Interrupt-prediction sensitivity, from 0.0 to 1.0. Set to null or 0.0 to disable interrupt prediction.","uniqueKey":"interruption_settings.interrupt_prediction_threshold.oneOf.0","typeLabel":"number"},{"type":"null","default":0,"minimum":0,"maximum":1,"description":"Interrupt-prediction sensitivity, from 0.0 to 1.0. Set to null or 0.0 to disable interrupt prediction.","uniqueKey":"interruption_settings.interrupt_prediction_threshold.oneOf.1","typeLabel":"null"}],"uniqueKey":"interruption_settings.interrupt_prediction_threshold","typeLabel":"number | null"}},"uniqueKey":"interruption_settings","typeLabel":"InterruptionSettings · object"},"integrations":{"type":"array","items":{"type":"object","title":"AssistantIntegration","description":"Reference to a connected integration attached to an assistant. Discover available integrations with `/ai/integrations` and connected integrations with `/ai/integrations/connections`.","properties":{"integration_id":{"type":"string","description":"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`.","isRequired":true,"uniqueKey":"integrations.items.[INDEX].integration_id","typeLabel":"string"},"allowed_list":{"type":"array","items":{"type":"string","uniqueKey":"integrations.items.[INDEX].allowed_list.items.[INDEX]","typeLabel":"string"},"description":"Optional per-assistant allowlist of integration tool names. When omitted or empty, all tools allowed by the connected integration are available to the assistant.","uniqueKey":"integrations.items.[INDEX].allowed_list","typeLabel":"string[]"}},"required":["integration_id"],"uniqueKey":"integrations.items.[INDEX]","typeLabel":"AssistantIntegration · object"},"default":[],"description":"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`.","uniqueKey":"integrations","typeLabel":"AssistantIntegration · object[]"},"observability_settings":{"properties":{"status":{"type":"string","enum":["enabled","disabled"],"title":"ObservabilityStatus","default":"disabled","uniqueKey":"observability_settings.status","typeLabel":"enum\u003cstring>"},"secret_key_ref":{"title":"Secret Key Ref","type":"string","uniqueKey":"observability_settings.secret_key_ref","typeLabel":"string"},"public_key_ref":{"title":"Public Key Ref","type":"string","uniqueKey":"observability_settings.public_key_ref","typeLabel":"string"},"host":{"title":"Host","type":"string","uniqueKey":"observability_settings.host","typeLabel":"string"},"prompt_name":{"title":"Prompt Name","type":"string","uniqueKey":"observability_settings.prompt_name","typeLabel":"string"},"prompt_version":{"title":"Prompt Version","type":"integer","minimum":1,"uniqueKey":"observability_settings.prompt_version","typeLabel":"integer"},"prompt_label":{"title":"Prompt Label","type":"string","uniqueKey":"observability_settings.prompt_label","typeLabel":"string"},"prompt_sync":{"type":"string","enum":["enabled","disabled"],"title":"PromptSyncStatus","description":"Whether to auto-publish the assistant's instructions as a Langfuse prompt.\n\nWhen ENABLED + prompt_name set, every assistant create/update pushes\n`instructions` to Langfuse via create_prompt and stores the returned\nversion in prompt_version.","default":"disabled","uniqueKey":"observability_settings.prompt_sync","typeLabel":"enum\u003cstring>"}},"type":"object","title":"ObservabilityReq","uniqueKey":"observability_settings","typeLabel":"ObservabilityReq · object"},"tags":{"type":"array","items":{"type":"string","uniqueKey":"tags.items.[INDEX]","typeLabel":"string"},"default":[],"description":"Tags associated with the assistant. Tags can also be managed with the assistant tag endpoints.","uniqueKey":"tags","typeLabel":"string[]"},"post_conversation_settings":{"type":"object","description":"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.","properties":{"enabled":{"type":"boolean","description":"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.","default":false,"uniqueKey":"post_conversation_settings.enabled","typeLabel":"boolean"}},"uniqueKey":"post_conversation_settings","typeLabel":"object"},"delegation_settings":{"type":"object","title":"DelegationSettings","description":"Splits the conversation between a frontend model that talks to the caller and a backend model that does the work. On the GPT-Live route the frontend model cannot call tools at all — when it needs something done it raises a delegation and waits. On the chat completion route the frontend keeps a single `delegate` tool that returns immediately, so the conversation carries on while the backend works. Either way the backend's answer is spoken as commentary or kept as silent context, depending on `speak_results`. Beta feature.","properties":{"enabled":{"type":"boolean","default":true,"description":"Whether the assistant delegates work to a backend model. Defaults to `true`: a GPT-Live assistant with delegation disabled can hold a conversation but can never look anything up or run a tool.","uniqueKey":"delegation_settings.enabled","typeLabel":"boolean"},"mode":{"type":"string","enum":["telnyx","client"],"default":"telnyx","description":"Who answers a delegation. `telnyx` runs the backend model on Telnyx with the assistant's own tools, MCP servers and observability. `client` relays the delegation to a server you host over the WebSocket configured in `websocket_settings`: Telnyx sends a `session.delegation.created` frame and waits for your `session.delegation.completed` answer. That answer is text only, since the socket offers no tool vocabulary. If no socket is connected the delegation is refused and the assistant tells the caller it cannot look things up right now. Defaults to `telnyx`.","uniqueKey":"delegation_settings.mode","typeLabel":"enum\u003cstring>"},"model":{"type":"string","description":"The backend model that answers delegations. Must be a model available for AI Assistants. When enabling `telnyx` delegation, explicitly set this field or `external_llm.model`; a configuration without either backend model is rejected. Only applies when `mode` is `telnyx`.","uniqueKey":"delegation_settings.model","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the backend model's API key. Required for models from providers other than Telnyx, OpenAI and Anthropic. A raw `api_key` is rejected rather than ignored, so that no plaintext credential is stored on the assistant.","uniqueKey":"delegation_settings.llm_api_key_ref","typeLabel":"string"},"instructions":{"type":"string","description":"Extra instructions for the backend model, in addition to the assistant's own. Use this for the business rules the backend needs and the talking model does not.","uniqueKey":"delegation_settings.instructions","typeLabel":"string"},"speak_results":{"type":"boolean","default":true,"description":"Whether the backend's answer is spoken to the caller. When `true` the result is appended as commentary and paraphrased aloud; when `false` it is kept as silent context that informs later answers without being read out. Defaults to `true`.","uniqueKey":"delegation_settings.speak_results","typeLabel":"boolean"},"external_llm":{"type":"object","title":"ExternalLLM","description":"Run the backend on your own OpenAI-compatible endpoint instead of a Telnyx-hosted model. As above, a raw `api_key` here is rejected — reference an integration secret with `external_llm.llm_api_key_ref` instead.","required":["model","base_url"],"properties":{"model":{"type":"string","description":"Model identifier to use with the external LLM endpoint.","isRequired":true,"uniqueKey":"delegation_settings.external_llm.model","typeLabel":"string"},"base_url":{"type":"string","description":"Base URL for the external LLM endpoint.","isRequired":true,"uniqueKey":"delegation_settings.external_llm.base_url","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the external LLM API key.","uniqueKey":"delegation_settings.external_llm.llm_api_key_ref","typeLabel":"string"},"authentication_method":{"type":"string","enum":["token","certificate"],"default":"token","description":"Authentication method used when connecting to the external LLM endpoint.","title":"AuthenticationMethod","uniqueKey":"delegation_settings.external_llm.authentication_method","typeLabel":"enum\u003cstring>"},"certificate_ref":{"type":"string","description":"Integration secret identifier for the client certificate used with certificate authentication.","uniqueKey":"delegation_settings.external_llm.certificate_ref","typeLabel":"string"},"token_retrieval_url":{"type":"string","description":"URL used to retrieve an access token when certificate authentication is enabled.","uniqueKey":"delegation_settings.external_llm.token_retrieval_url","typeLabel":"string"},"forward_metadata":{"type":"boolean","default":false,"description":"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.","uniqueKey":"delegation_settings.external_llm.forward_metadata","typeLabel":"boolean"},"extra_headers":{"oneOf":[{"type":"object","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"delegation_settings.external_llm.extra_headers.oneOf.0.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"delegation_settings.external_llm.extra_headers.oneOf.0","typeLabel":"object"},{"type":"null","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"delegation_settings.external_llm.extra_headers.oneOf.1.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"delegation_settings.external_llm.extra_headers.oneOf.1","typeLabel":"null"}],"uniqueKey":"delegation_settings.external_llm.extra_headers","typeLabel":"object | null"}},"uniqueKey":"delegation_settings.external_llm","typeLabel":"ExternalLLM · object"}},"uniqueKey":"delegation_settings","typeLabel":"DelegationSettings · object"},"websocket_settings":{"type":"object","title":"WebsocketSettings","description":"Streams conversation and telephony events to a WebSocket server you host, and accepts messages injected back into the conversation. Telnyx opens the connection as a client, once per conversation. Delivery is best effort throughout: while the connection is down events are dropped rather than queued, and no socket failure is ever allowed to affect the call. Beta feature.","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether Telnyx opens a WebSocket to `url` for each of this assistant's conversations. Defaults to `false`.","uniqueKey":"websocket_settings.enabled","typeLabel":"boolean"},"url":{"type":"string","description":"The `ws://` or `wss://` endpoint Telnyx connects to. Required when `enabled` is `true`. Must be externally reachable — localhost, private IP ranges and `.local` domains are rejected.","uniqueKey":"websocket_settings.url","typeLabel":"string"},"auth_ref":{"type":"string","description":"Integration secret identifier whose value Telnyx sends as an `Authorization: Bearer \u003cvalue>` header on the upgrade request. Resolved on every connection attempt, so a rotated secret is picked up by the next reconnect.","uniqueKey":"websocket_settings.auth_ref","typeLabel":"string"}},"uniqueKey":"websocket_settings","typeLabel":"WebsocketSettings · object"},"conversation_flow":{"description":"Conversation flow as supplied by API clients (create / update).\n\nA directed graph of `FlowNodeReq` connected by `FlowEdge`s. Validation\nenforces unique node/edge IDs, that `start_node_id` references a real\nnode, and that every edge's endpoints reference real nodes.","example":{"edges":[{"condition":{"prompt":"The caller is asking about a bill or charge.","type":"llm"},"id":"e_intake_to_billing","start_node_id":"n_intake","target":{"node_id":"n_billing","type":"node"}},{"condition":{"prompt":"The caller has explicitly asked for a human.","type":"llm"},"id":"e_intake_to_escalation_assistant","start_node_id":"n_intake","target":{"assistant_id":"assistant-human-handoff","position":{"x":600,"y":80},"type":"assistant","voice_mode":"distinct"}}],"nodes":[{"type":"prompt","id":"n_intake","instructions":"Greet the caller and ask what they're calling about.","name":"Intake","position":{"x":120,"y":80},"shared_tool_ids":["tool-faq-kb"]},{"type":"prompt","id":"n_billing","instructions":"Focus on billing questions. Look up the caller's latest invoice with the billing tool before answering.","instructions_mode":"append","model":"moonshotai/Kimi-K2.6","name":"Billing","position":{"x":420,"y":80},"shared_tool_ids":["tool-billing-lookup"],"tools_mode":"append"}],"start_node_id":"n_intake"},"properties":{"nodes":{"description":"All nodes in the flow. Must contain `start_node_id`. Each node is a prompt node (`type: prompt`), a tool node (`type: tool`), or a speak node (`type: speak`).","items":{"oneOf":[{"type":"object","title":"FlowNodeReq","description":"One step in a conversation flow, as supplied by API clients.\n\nEach node carries the prompt, tool scope, and optional overrides for\nmodel/voice/transcription. Unset overrides cascade from the assistant.","required":["id","instructions"],"example":{"id":"n_intake","instructions":"Greet the caller and ask what they're calling about.","name":"Intake","position":{"x":120,"y":80},"shared_tool_ids":["tool-faq-kb"],"type":"prompt"},"properties":{"id":{"description":"Caller-supplied unique identifier for this node within the flow.","example":"n_intake","title":"Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.id","typeLabel":"string"},"instructions":{"description":"Prompt that drives the LLM while this node is active. Required.","example":"Greet the caller and ask what they're calling about.","title":"Instructions","type":"string","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.instructions","typeLabel":"string"},"external_llm":{"properties":{"model":{"type":"string","description":"Model identifier to use with the external LLM endpoint.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.model","typeLabel":"string"},"base_url":{"type":"string","description":"Base URL for the external LLM endpoint.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.base_url","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the external LLM API key.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.llm_api_key_ref","typeLabel":"string"},"authentication_method":{"type":"string","enum":["token","certificate"],"default":"token","description":"Authentication method used when connecting to the external LLM endpoint.","title":"AuthenticationMethod","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.authentication_method","typeLabel":"enum\u003cstring>"},"certificate_ref":{"type":"string","description":"Integration secret identifier for the client certificate used with certificate authentication.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.certificate_ref","typeLabel":"string"},"token_retrieval_url":{"type":"string","description":"URL used to retrieve an access token when certificate authentication is enabled.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.token_retrieval_url","typeLabel":"string"},"forward_metadata":{"type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.forward_metadata","typeLabel":"boolean"},"extra_headers":{"oneOf":[{"type":"object","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers.oneOf.0.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers.oneOf.0","typeLabel":"object"},{"type":"null","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers.oneOf.1.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers","typeLabel":"object | null"}},"type":"object","required":["model","base_url"],"title":"ExternalLLMReq","description":"Override for `Assistant.external_llm` while this node is active. Use this to route a node's turns to a different external LLM (different `model`, `base_url`, credentials). Part of the LLM bundle — see `model` for cascade semantics. Mutually exclusive with `model` on the node (a single LLM identity per node).","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm","typeLabel":"ExternalLLMReq · object"},"instructions_mode":{"default":"replace","description":"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.","enum":["replace","append"],"title":"Instructions Mode","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.instructions_mode","typeLabel":"enum\u003cstring>"},"llm_api_key_ref":{"description":"Override for `Assistant.llm_api_key_ref` while this node is active. Part of the LLM bundle — see `model` for cascade semantics.","example":"my-key-ref","title":"Llm Api Key Ref","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.llm_api_key_ref","typeLabel":"string"},"model":{"description":"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.","example":"moonshotai/Kimi-K2.6","title":"Model","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.model","typeLabel":"string"},"name":{"description":"Optional human-readable label, displayed in authoring UIs.","example":"Intake","title":"Name","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.name","typeLabel":"string"},"position":{"description":"Optional canvas coordinates used by authoring UIs to lay out the graph. Ignored by the runtime; round-trips so frontends can persist graph layout across reloads.","properties":{"x":{"description":"Horizontal coordinate in the authoring canvas.","title":"X","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.position.x","typeLabel":"number"},"y":{"description":"Vertical coordinate in the authoring canvas.","title":"Y","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.position.y","typeLabel":"number"}},"required":["x","y"],"title":"NodePosition","type":"object","example":{"x":120,"y":80},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.position","typeLabel":"NodePosition · object"},"shared_tool_ids":{"description":"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.","example":["tool-faq-kb","tool-billing-lookup"],"items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.shared_tool_ids.items.[INDEX]","typeLabel":"string"},"title":"Shared Tool Ids","type":"array","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.shared_tool_ids","typeLabel":"string[]"},"tools_mode":{"default":"replace","description":"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.","enum":["replace","append"],"title":"Tools Mode","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools_mode","typeLabel":"enum\u003cstring>"},"transcription":{"properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","speechmatics/standard","speechmatics/linden-1","azure/fast","assemblyai/universal-3-6-pro","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","telnyx/basira","distil-whisper/distil-large-v2","openai/whisper-large-v3-turbo"],"description":"The speech to text model to be used by the voice assistant. All Deepgram models are run on-premise.\n\n- `deepgram/flux` is optimized for turn-taking with multilingual language hints.\n- `deepgram/nova-3` is multilingual with automatic language detection.\n- `deepgram/nova-2` is Deepgram's previous-generation multilingual model.\n- `speechmatics/standard` is a Speechmatics model self-hosted by Telnyx; it supports a fixed set of language packs (including bilingual packs such as `ar_en`) and defaults to `en`.\n- `speechmatics/linden-1` (preview) is a vendor-hosted streaming model with no auto-detect; set `language` from Speechmatics' Realtime language list (defaults to `en`).\n- `azure/fast` is a multilingual Azure transcription model.\n- `assemblyai/universal-3-6-pro` (AssemblyAI Universal-3.6 Pro) is a multilingual streaming model with configurable turn detection. The legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming` are still accepted and run the same model.\n- `xai/grok-stt` is a multilingual Grok STT model.\n- `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`.\n- `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection.\n- `omi-health/omi-med-stt-v1` is an English-only medical transcription model (Parakeet-based).\n- `humain/realtime` is a streaming model with native Arabic and Arabic/English code-switching support.\n- `reson8/turns` is a turn-based streaming model covering 10 European languages with automatic language detection.\n- `cohere/ar-stt` is a non-streaming Arabic and English transcription model.\n- `telnyx/basira` is a non-streaming Arabic transcription model.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.model","typeLabel":"enum\u003cstring>"},"language":{"type":"string","description":"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. For `speechmatics/linden-1`, there is no auto-detect; set a code from Speechmatics' Realtime language list (67 language codes, including `es-bilingual-en` for Spanish and English bilingual, and the spelling and script variants `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant`; `en` alone uses the default spelling); unset defaults to `en`, while an explicit `auto`, `auto_beta`, or `multi` is rejected with a 400.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.language","typeLabel":"string"},"api_key_ref":{"title":"Api Key Ref","type":"string","description":"Integration secret identifier for the transcription provider API key. Currently used for Azure transcription regions that require a customer-provided API key.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.api_key_ref","typeLabel":"string"},"region":{"title":"Region","type":"string","description":"Region on third party cloud providers (currently Azure) if using one of their models. Some regions require `api_key_ref`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.region","typeLabel":"string"},"settings":{"properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.language_hints","typeLabel":"string[]"}},"type":"object","title":"TranscriptionSettingsConfig","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings","typeLabel":"TranscriptionSettingsConfig · object"},"fallback_models":{"oneOf":[{"type":"array","items":{"title":"TranscriptionFallbackModel","description":"A streaming speech-to-text model that takes over transcription when the model in use fails.","type":"object","properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","assemblyai/universal-3-6-pro","assemblyai/universal-3-5-pro","assemblyai/universal-streaming","xai/grok-stt","soniox/stt-rt-v4","soniox/stt-rt-v5","humain/realtime","reson8/turns"],"description":"The fallback model. It must be a streaming model other than `transcription.model` and the other fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` (or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or `reson8/turns`.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].model","typeLabel":"enum\u003cstring>"},"language":{"oneOf":[{"type":"string","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].language.oneOf.0","typeLabel":"string"},{"type":"null","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].language.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].language","typeLabel":"string | null"},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.language_hints","typeLabel":"string[]"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0","typeLabel":"TranscriptionSettingsConfig · object"},{"type":"null","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings","typeLabel":"TranscriptionSettingsConfig · object | null"}},"required":["model"],"example":{"model":"deepgram/nova-3","language":"en","settings":{"keyterm":"Telnyx,VoIP,SIP"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX]","typeLabel":"TranscriptionFallbackModel · object"},"maxItems":3,"description":"Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a streaming model too, and must support `language` alongside other models. On update, a list replaces the stored one: omit the field to keep the stored list, or send `null` or `[]` to remove it. When an update changes `model` or `language`, stored fallbacks that no longer fit are removed without an error. Can't be combined with `challenger`, the language booster; to replace a stored language booster, send `challenger: null` in the same request.","example":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0","typeLabel":"TranscriptionFallbackModel · object[]"},{"type":"null","items":{"title":"TranscriptionFallbackModel","description":"A streaming speech-to-text model that takes over transcription when the model in use fails.","type":"object","properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","assemblyai/universal-3-6-pro","assemblyai/universal-3-5-pro","assemblyai/universal-streaming","xai/grok-stt","soniox/stt-rt-v4","soniox/stt-rt-v5","humain/realtime","reson8/turns"],"description":"The fallback model. It must be a streaming model other than `transcription.model` and the other fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` (or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or `reson8/turns`."},"language":{"oneOf":[{"type":"string","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run."},{"type":"null","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run."}]},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean"},"numerals":{"title":"Numerals","type":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript."},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead."},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters."},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and 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":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn."},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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":{"title":"Context","type":"string","maxLength":10000,"description":"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":{"title":"Language Hints","type":"array","items":{"type":"string"},"description":"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`."}}},{"type":"null","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model."}]}},"required":["model"],"example":{"model":"deepgram/nova-3","language":"en","settings":{"keyterm":"Telnyx,VoIP,SIP"}}},"maxItems":3,"description":"Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a streaming model too, and must support `language` alongside other models. On update, a list replaces the stored one: omit the field to keep the stored list, or send `null` or `[]` to remove it. When an update changes `model` or `language`, stored fallbacks that no longer fit are removed without an error. Can't be combined with `challenger`, the language booster; to replace a stored language booster, send `challenger: null` in the same request.","example":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models","typeLabel":"TranscriptionFallbackModel · object[] | null"},"challenger":{"oneOf":[{"type":"object","title":"TranscriptionChallenger","description":"The language booster: a second model that transcribes alongside `model`, and the rule that decides which transcript the assistant uses. Both models must be streaming, or both non-streaming, and, except with `merge_words`, `model` must support `language` alongside another model (for example, `cohere/ar-stt` supports only `ar` there). If the language booster can't run, the call runs on `model` alone; if either model fails mid-call, the call continues on the other. On update, omit the field to keep the stored language booster, or send `null` to remove it. When an update changes `model` or `language` and the stored language booster no longer fits, it is removed without an error. Can't be combined with `fallback_models`; to replace stored fallbacks, send `fallback_models: []` in the same request.","required":["model"],"example":{"model":"deepgram/nova-3","language":"en","rule":"best_turn"},"properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","azure/fast","assemblyai/universal-3-6-pro","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","telnyx/basira","distil-whisper/distil-large-v2","openai/whisper-large-v3-turbo"],"description":"The language booster's model. It must be the same kind of model as `transcription.model`: both streaming (`deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`, `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, `reson8/turns`) or both non-streaming (`azure/fast`, `nvidia/parakeet-v3`, `omi-health/omi-med-stt-v1`, `cohere/ar-stt`, `distil-whisper/distil-large-v2`, `openai/whisper-large-v3-turbo`, `telnyx/basira`). It can be the same model as `transcription.model` on a different `language`.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.model","typeLabel":"enum\u003cstring>"},"language":{"oneOf":[{"type":"string","description":"The language this model transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when this model doesn't support the language it would run. It is also rejected when it would run the same model on the same language as `transcription.model`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.language.oneOf.0","typeLabel":"string"},{"type":"null","description":"The language this model transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when this model doesn't support the language it would run. It is also rejected when it would run the same model on the same language as `transcription.model`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.language.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.language","typeLabel":"string | null"},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the language booster, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.language_hints","typeLabel":"string[]"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0","typeLabel":"TranscriptionSettingsConfig · object"},{"type":"null","description":"Settings for the language booster, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings","typeLabel":"TranscriptionSettingsConfig · object | null"},"rule":{"type":"string","enum":["best_turn","best_engine","merge_words"],"default":"best_turn","description":"How the assistant picks the transcript it uses. The models are compared on how complete and confident their transcripts are, not on language, so the rules work best when both models understand the callers' language.\n\n- `best_turn` (default): both models transcribe the whole call. Each turn uses the language booster's transcript only when it scores higher than the transcript of `transcription.model` (clearly higher with non-streaming models). With streaming models, `transcription.model` also decides when each turn ends. Available for every pair.\n- `best_engine`: both models transcribe the first turns, then the call continues alone on the model whose transcripts scored higher. If neither clearly leads, `transcription.model` continues. Streaming models only.\n- `merge_words`: both models transcribe each utterance and their words are merged, keeping Arabic and English spoken in the same sentence. Available only for `telnyx/basira` with `cohere/ar-stt`, in either order. The pair runs on the language that applies to `telnyx/basira` (its own, or that of `transcription.model`), which must be Arabic (`ar` or an `ar-` locale), `multi`, or `auto`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.rule","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0","typeLabel":"TranscriptionChallenger · object"},{"type":"null","description":"The language booster: a second model that transcribes alongside `model`, and the rule that decides which transcript the assistant uses. Both models must be streaming, or both non-streaming, and, except with `merge_words`, `model` must support `language` alongside another model (for example, `cohere/ar-stt` supports only `ar` there). If the language booster can't run, the call runs on `model` alone; if either model fails mid-call, the call continues on the other. On update, omit the field to keep the stored language booster, or send `null` to remove it. When an update changes `model` or `language` and the stored language booster no longer fits, it is removed without an error. Can't be combined with `fallback_models`; to replace stored fallbacks, send `fallback_models: []` in the same request.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger","typeLabel":"TranscriptionChallenger · object | null"}},"type":"object","description":"Per-node transcription override (model/language/region). Unset fields cascade from the assistant-level transcription. A node that sets `model`, `fallback_models`, or `challenger` doesn't inherit the assistant's `fallback_models` or `challenger`; it uses only the ones it sets. Otherwise it inherits them, and they must fit the model and language the node runs; a change they no longer fit is rejected.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription","typeLabel":"object"},"type":{"const":"prompt","default":"prompt","description":"Node kind discriminator. `prompt` (default) is an LLM-driven step; `tool` is a standalone tool execution and `speak` a scripted message (see `ToolNodeReq` / `SpeakNodeReq`).","title":"Type","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.type","typeLabel":"string"},"voice_settings":{"properties":{"voice":{"type":"string","description":"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.\nTo 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.\u003cmodel_id>.\u003cvoice_id>` (e.g. Telnyx.KokoroTTS.af_heart). For Soniox voices, use `Soniox.tts-rt-v2.\u003cvoice_id>` (e.g. Soniox.tts-rt-v2.Emma); every Soniox voice speaks all supported languages.\nThe 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.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.voice","typeLabel":"string"},"voice_speed":{"type":"number","default":1,"description":"The speed of the voice in the range [0.6, 1.5]. 1.0 is the default speed. Larger numbers make the voice faster, smaller numbers make it slower. Applies to Telnyx `Ultra` voices; values outside this range are rejected by the synthesis engine. Soniox voices support a speed range of 0.7 to 1.3.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.voice_speed","typeLabel":"number"},"api_key_ref":{"type":"string","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.api_key_ref","typeLabel":"string"},"temperature":{"type":"number","default":0.5,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.temperature","typeLabel":"number"},"similarity_boost":{"type":"number","default":0.75,"description":"Determines how closely the AI should adhere to the original voice when attempting to replicate it. Only applicable when using ElevenLabs.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.similarity_boost","typeLabel":"number"},"use_speaker_boost":{"type":"boolean","default":true,"description":"Amplifies similarity to the original speaker voice. Increases computational load and latency slightly. Only applicable when using ElevenLabs.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.use_speaker_boost","typeLabel":"boolean"},"style":{"type":"number","default":0,"description":"Determines the style exaggeration of the voice. Amplifies speaker style but consumes additional resources when set above 0. Only applicable when using ElevenLabs.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.style","typeLabel":"number"},"speed":{"type":"number","default":1,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.speed","typeLabel":"number"},"language":{"oneOf":[{"type":"string","description":"Two-letter ISO 639-1 code of the language the voice speaks, for example `es`. Only applicable to Soniox and AssemblyAI voices, which speak every language of their model. AssemblyAI accepts `en`, `es`, `de`, `fr`, `it`, and `pt`. When unset, the voice speaks English.","default":null,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language.oneOf.0","typeLabel":"string"},{"type":"null","description":"Two-letter ISO 639-1 code of the language the voice speaks, for example `es`. Only applicable to Soniox and AssemblyAI voices, which speak every language of their model. AssemblyAI accepts `en`, `es`, `de`, `fr`, `it`, and `pt`. When unset, the voice speaks English.","default":null,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language","typeLabel":"string | null"},"language_boost":{"oneOf":[{"type":"string","description":"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.","enum":[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"],"default":null,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language_boost.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","description":"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.","enum":[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"],"default":null,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language_boost.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language_boost","typeLabel":"enum\u003cstring> | null"},"expressive_mode":{"type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.expressive_mode","typeLabel":"boolean"},"background_audio":{"oneOf":[{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["predefined_media"],"description":"Select from predefined media options.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.0.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","enum":["silence","office"],"default":"silence","description":"The predefined media to use. `silence` disables background audio.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.0.value","typeLabel":"enum\u003cstring>"},"volume":{"type":"number","minimum":0.1,"maximum":1,"multipleOf":0.1,"default":1,"description":"Volume level for the predefined background audio. Supports values from 0.1 to 1.0 in 0.1 increments.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.0.volume","typeLabel":"number"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.0","typeLabel":"object"},{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["media_url"],"description":"Provide a direct URL to an MP3 file. The audio will loop during the call.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.1.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","format":"uri","description":"HTTPS URL to an MP3 file.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.1.value","typeLabel":"string\u003curi>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.1","typeLabel":"object"},{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["media_name"],"description":"Reference a previously uploaded media by its name from Telnyx Media Storage.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.2.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","description":"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.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.2.value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.2","typeLabel":"object"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio","typeLabel":"object"},"tool_call_audio":{"oneOf":[{"type":"object","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","required":["type","value"],"example":{"type":"predefined_media","value":"typing","volume":0.5},"properties":{"type":{"type":"string","enum":["predefined_media"],"description":"Select from predefined media options.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.0.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","enum":["typing"],"description":"The predefined media to use. `typing` plays a keyboard typing sound.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.0.value","typeLabel":"enum\u003cstring>"},"volume":{"type":"number","minimum":0,"maximum":1,"multipleOf":0.1,"default":0.5,"description":"Volume level for the predefined media. Supports values from 0.0 to 1.0 in 0.1 increments. `0.0` plays no sound.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.0.volume","typeLabel":"number"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.0","typeLabel":"object"},{"type":"object","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","required":["type","value"],"example":{"type":"predefined_media","value":"typing"},"properties":{"type":{"type":"string","enum":["media_url"],"description":"Provide a direct URL to an MP3 file. The audio loops while the tool runs.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.1.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","format":"uri","description":"HTTPS URL to an MP3 file.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.1.value","typeLabel":"string\u003curi>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.1","typeLabel":"object"},{"type":"null","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","example":{"type":"predefined_media","value":"typing","volume":0.5},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.2","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio","typeLabel":"object · object · null"}},"type":"object","required":["voice"],"description":"Per-node voice override. Only fields set here override the assistant-level voice settings; unset fields cascade.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings","typeLabel":"object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0","typeLabel":"FlowNodeReq · object"},{"type":"object","title":"ToolNodeReq","description":"A standalone tool step in a conversation flow, as supplied by clients.\n\nUnlike a prompt node, a tool node has no instructions or model — it\nisn't an LLM turn. Reaching it deterministically runs one shared tool\n(arguments filled from matching dynamic variables by name), then routes\nvia outgoing `llm` / `expression` edges, with exactly one `default`\nfallback edge required when the node has any outgoing edges (the\ntool's outcome is readable as `telnyx_last_tool_status_code` in\n`expression` conditions).","required":["id","shared_tool_id"],"example":{"id":"n_charge","message":"One moment while I process your payment.","name":"Charge card","position":{"x":300,"y":200},"shared_tool_id":"tool-charge-card","type":"tool"},"properties":{"id":{"description":"Caller-supplied unique identifier for this node within the flow.","example":"n_charge","title":"Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.id","typeLabel":"string"},"shared_tool_id":{"description":"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 `llm` / `expression` edges route the flow on the tool's 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.","example":"tool-charge-card","title":"Shared Tool Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.shared_tool_id","typeLabel":"string"},"message":{"description":"Optional message delivered to the user verbatim immediately before the tool executes — an announcement such as 'One moment while I look that up.' No LLM turn and no customer turn: the message is spoken/sent, then the tool runs, in the same deterministic step. `{{variable}}` placeholders are interpolated from the conversation's dynamic variables (unresolved → empty string); the tool's own result is not yet available when the message is rendered. Omit for a silent tool step.","example":"One moment while I process your payment.","minLength":1,"pattern":"\\S","title":"Message","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.message","typeLabel":"string"},"name":{"description":"Optional human-readable label, displayed in authoring UIs.","example":"Charge card","title":"Name","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.name","typeLabel":"string"},"position":{"description":"Optional canvas coordinates used by authoring UIs to lay out the graph. Ignored by the runtime; round-trips so frontends can persist graph layout across reloads.","properties":{"x":{"description":"Horizontal coordinate in the authoring canvas.","title":"X","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.position.x","typeLabel":"number"},"y":{"description":"Vertical coordinate in the authoring canvas.","title":"Y","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.position.y","typeLabel":"number"}},"required":["x","y"],"title":"NodePosition","type":"object","example":{"x":300,"y":200},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.position","typeLabel":"NodePosition · object"},"type":{"const":"tool","default":"tool","description":"Node kind discriminator. Always `tool` for a tool node.","title":"Type","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.type","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1","typeLabel":"ToolNodeReq · object"},{"type":"object","title":"SpeakNodeReq","description":"A standalone scripted-message step in a flow, as supplied by clients.\n\nUnlike a prompt node, a speak node has no instructions or model — it isn't\nan LLM turn. Reaching it delivers `message` to the user verbatim (with\n`{{variable}}` interpolation), then routes via outgoing `llm` /\n`expression` edges.","required":["id","message"],"example":{"id":"n_greeting","message":"Thanks for calling, {{caller_name}}. Connecting you now.","name":"Greeting","position":{"x":60,"y":80},"type":"speak"},"properties":{"id":{"type":"string","title":"Id","description":"Caller-supplied unique identifier for this node within the flow.","example":"n_greeting","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.id","typeLabel":"string"},"message":{"type":"string","title":"Message","description":"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).","example":"Thanks for calling, {{caller_name}}. Connecting you now.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.message","typeLabel":"string"},"type":{"type":"string","const":"speak","title":"Type","description":"Node kind discriminator. Always `speak` for a speak node.","default":"speak","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.type","typeLabel":"string"},"name":{"title":"Name","description":"Optional human-readable label, displayed in authoring UIs.","type":"string","example":"Greeting","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.name","typeLabel":"string"},"position":{"description":"Optional canvas coordinates used by authoring UIs to lay out the graph. Ignored by the runtime; round-trips so frontends can persist graph layout across reloads.","properties":{"x":{"description":"Horizontal coordinate in the authoring canvas.","title":"X","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.position.x","typeLabel":"number"},"y":{"description":"Vertical coordinate in the authoring canvas.","title":"Y","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.position.y","typeLabel":"number"}},"required":["x","y"],"title":"NodePosition","type":"object","example":{"x":60,"y":80},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.position","typeLabel":"NodePosition · object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2","typeLabel":"SpeakNodeReq · object"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX]","typeLabel":"FlowNodeReq · object | ToolNodeReq · object | SpeakNodeReq · object"},"title":"Nodes","type":"array","isRequired":true,"uniqueKey":"conversation_flow.nodes","typeLabel":"(FlowNodeReq · object | ToolNodeReq · object | SpeakNodeReq · object)[]"},"start_node_id":{"description":"ID of the node where the conversation begins.","example":"n_intake","title":"Start Node Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.start_node_id","typeLabel":"string"},"edges":{"description":"Directed transitions between nodes. May be empty for a single-node flow.","items":{"description":"Directed transition from one node to a target, gated by a condition.\n\nThe target is either another node in the same flow (`NodeTarget`) or a\ndifferent assistant (`AssistantTarget`). Multiple edges may share a\n`start_node_id`. On calls, `expression` conditions are evaluated before\nthe model turn and take precedence over `llm` conditions regardless of\ndeclaration order, while `llm` conditions are offered to the assistant's\nmodel as transition tools and fire when the model selects one. On chat\nchannels, an `expression` condition that is true when the turn begins\nroutes before the reply is generated; all conditioned edges that remain\nare considered together in declaration order after the reply, and the\nfirst true one wins.","properties":{"condition":{"oneOf":[{"type":"object","title":"LLMCondition","description":"Edge condition routed by the assistant's LLM from a natural-language\nprompt.\n\nHow the edge is decided depends on the channel. On calls, each outgoing\n`llm` condition is offered to the assistant's model as a transition tool\nalongside the assistant's tools, and the edge fires when the model\nselects it; the platform does not evaluate the prompt itself, and\ninstructions that forbid or discourage tool calls can stop these edges\nfrom firing. On chat channels, the edge prompts are evaluated in a\nseparate model call after the reply, which does not use the assistant's\ninstructions. Use this for fuzzy intents that aren't expressible as a\ndeterministic expression (e.g. 'user wants to escalate to a human').","required":["type","prompt"],"example":{"prompt":"The user has confirmed their booking details.","type":"llm"},"properties":{"prompt":{"description":"Natural-language criterion the model routes on. On calls this is offered to the model as the transition tool's description; on chat channels it is judged as a statement in the post-reply evaluation call.","example":"The user has confirmed their booking details.","title":"Prompt","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.0.prompt","typeLabel":"string"},"type":{"const":"llm","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.0.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.0","typeLabel":"LLMCondition · object"},{"type":"object","title":"ExpressionCondition","description":"Edge condition evaluated as a deterministic expression AST.\n\nThe expression is computed against runtime dynamic variables and must\nevaluate to a boolean. Prefer this over `LLMCondition` when the rule is\na clean function of known variables — it's cheaper and predictable.","required":["type","expression"],"example":{"expression":{"left":{"name":"user_age","type":"variable"},"op":">=","right":{"type":"number_literal","value":18},"type":"comparison"},"type":"expression"},"properties":{"expression":{"oneOf":[{"type":"object","title":"ComparisonExpression","description":"Compare two sub-expressions with a relational or membership operator.\n\nEvaluates to a boolean. Used in edge conditions to gate transitions on\nruntime values, e.g. `user_age >= 18` or `tier == \"gold\"`.","required":["type","op","left","right"],"example":{"left":{"name":"user_age","type":"variable"},"op":">=","right":{"type":"number_literal","value":18},"type":"comparison"},"properties":{"left":{"oneOf":[{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7","isRequired":true}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0.left","typeLabel":"any"},"op":{"description":"Relational/membership operator. `contains` / `not_contains` apply to strings (substring) and arrays (membership).","enum":["==","!=","\u003c","\u003c=",">",">=","contains","not_contains"],"title":"Op","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0.op","typeLabel":"enum\u003cstring>"},"right":{"oneOf":[{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7","isRequired":true}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0.right","typeLabel":"any"},"type":{"const":"comparison","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0","typeLabel":"ComparisonExpression · object"},{"type":"object","title":"BooleanOpExpression","description":"Combine sub-expressions with a logical operator (`and` / `or` / `not`).\n\n`and` and `or` accept two or more operands; `not` accepts exactly one.","required":["type","op","operands"],"example":{"op":"and","operands":[{"name":"is_premium","type":"variable"},{"left":{"name":"user_age","type":"variable"},"op":">=","right":{"type":"number_literal","value":18},"type":"comparison"}],"type":"bool_op"},"properties":{"op":{"description":"Logical operator. `not` is unary; `and`/`or` are n-ary (>=2).","enum":["and","or","not"],"title":"Op","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.1.op","typeLabel":"enum\u003cstring>"},"operands":{"description":"Operand sub-expressions. Length must be exactly 1 for `not` and >= 2 for `and`/`or`.","items":{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7"},"title":"Operands","type":"array","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.1.operands","typeLabel":"Operands · array"},"type":{"const":"bool_op","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.1.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.1","typeLabel":"BooleanOpExpression · object"},{"type":"object","title":"ArithmeticExpression","description":"Numeric expression: applies an arithmetic operator to two sub-expressions.\n\nUseful for derived numeric checks, e.g. `cart_total + shipping > 50`.\nBoth operands should resolve to numbers at runtime.","required":["type","op","left","right"],"example":{"left":{"name":"cart_total","type":"variable"},"op":"+","right":{"name":"shipping_cost","type":"variable"},"type":"arithmetic"},"properties":{"left":{"oneOf":[{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7","isRequired":true}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2.left","typeLabel":"any"},"op":{"description":"Arithmetic operator applied to `left` and `right`.","enum":["+","-","*","/","%"],"title":"Op","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2.op","typeLabel":"enum\u003cstring>"},"right":{"oneOf":[{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7","isRequired":true}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2.right","typeLabel":"any"},"type":{"const":"arithmetic","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2","typeLabel":"ArithmeticExpression · object"},{"type":"object","title":"DynamicVariableExpression","description":"Reference a dynamic variable by name.\n\nResolved at runtime from the assistant's dynamic-variables context (see\n`Assistant.dynamic_variables` and the dynamic-variables webhook).","required":["type","name"],"example":{"name":"user_age","type":"variable"},"properties":{"name":{"description":"Variable name to look up in the runtime context.","example":"user_age","title":"Name","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.3.name","typeLabel":"string"},"type":{"const":"variable","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.3.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.3","typeLabel":"DynamicVariableExpression · object"},{"type":"object","title":"StringLiteralExpression","description":"Constant string value.","required":["type","value"],"example":{"type":"string_literal","value":"gold"},"properties":{"type":{"const":"string_literal","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.4.type","typeLabel":"string"},"value":{"description":"Literal string value.","example":"gold","title":"Value","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.4.value","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.4","typeLabel":"StringLiteralExpression · object"},{"type":"object","title":"NumberLiteralExpression","description":"Constant numeric value (float; integers are accepted and stored as float).","required":["type","value"],"example":{"type":"number_literal","value":18},"properties":{"type":{"const":"number_literal","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.5.type","typeLabel":"string"},"value":{"description":"Literal numeric value.","example":18,"title":"Value","type":"number","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.5.value","typeLabel":"number"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.5","typeLabel":"NumberLiteralExpression · object"},{"type":"object","title":"BooleanLiteralExpression","description":"Constant boolean value. Useful for unconditional ('always') edges.","required":["type","value"],"example":{"type":"bool_literal","value":true},"properties":{"type":{"const":"bool_literal","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.6.type","typeLabel":"string"},"value":{"description":"Literal boolean value.","title":"Value","type":"boolean","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.6.value","typeLabel":"boolean"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.6","typeLabel":"BooleanLiteralExpression · object"}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression","typeLabel":"ComparisonExpression · object | BooleanOpExpression · object | ArithmeticExpression · object | DynamicVariableExpression · object | StringLiteralExpression · object | NumberLiteralExpression · object | BooleanLiteralExpression · object"},"type":{"const":"expression","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1","typeLabel":"ExpressionCondition · object"},{"type":"object","title":"DefaultCondition","description":"Fallback edge condition: fires only when no other edge's condition is true.\n\nEvaluated after every conditioned (`llm` / `expression`) edge regardless\nof declaration order, so it routes the flow whenever none of the node's\nother outgoing edges match. Valid **only** on edges leaving a `tool` or\n`speak` node, where the deterministic step auto-advances and must always\nhave somewhere to go. A tool/speak node with any outgoing edge is required\nto carry exactly one `default` edge so it never dead-ends; a tool/speak\nnode with no outgoing edges is a valid terminal step. Carries no parameters.","required":["type"],"example":{"type":"default"},"properties":{"type":{"type":"string","const":"default","title":"Type","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.2.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.2","typeLabel":"DefaultCondition · object"}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition","typeLabel":"LLMCondition · object | ExpressionCondition · object | DefaultCondition · object"},"id":{"description":"Caller-supplied unique identifier for this edge within the flow.","example":"e_age_gate","title":"Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].id","typeLabel":"string"},"start_node_id":{"description":"ID of the node this edge transitions away from.","title":"Start Node Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].start_node_id","typeLabel":"string"},"target":{"oneOf":[{"type":"object","title":"NodeTarget","description":"Edge target referencing another node within the same flow.\n\nThe runtime transitions the active node to `node_id` and continues\nprocessing within the current assistant's flow.","required":["type","node_id"],"properties":{"node_id":{"description":"ID of the node this edge transitions into.","example":"n_billing","title":"Node Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.0.node_id","typeLabel":"string"},"type":{"const":"node","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.0.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.0","typeLabel":"NodeTarget · object"},{"type":"object","title":"AssistantTarget","description":"Edge target referencing a different assistant.\n\nWhen the edge fires, the conversation hands off to `assistant_id`: the\nactive assistant on the conversation row is rewritten and the new\nassistant's flow starts at its own `start_node_id`. The current turn's\nLLM response is delivered to the user as-is; subsequent turns route\nto the new assistant.","required":["type","assistant_id"],"properties":{"assistant_id":{"description":"ID of the assistant the conversation transitions to.","example":"assistant-billing","title":"Assistant Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.assistant_id","typeLabel":"string"},"type":{"const":"assistant","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.type","typeLabel":"string"},"position":{"description":"Optional canvas coordinates for rendering the target assistant as a node in authoring UIs. Pure presentation — the runtime ignores it; round-trips so frontends can persist graph layout across reloads. When multiple edges target the same assistant, each edge's `position` is independent (frontends typically use the first non-null one).","properties":{"x":{"description":"Horizontal coordinate in the authoring canvas.","title":"X","type":"number","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.position.x","typeLabel":"number"},"y":{"description":"Vertical coordinate in the authoring canvas.","title":"Y","type":"number","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.position.y","typeLabel":"number"}},"required":["x","y"],"title":"NodePosition","type":"object","example":{"x":600,"y":80},"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.position","typeLabel":"NodePosition · object"},"voice_mode":{"default":"unified","description":"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`.","enum":["unified","distinct"],"title":"Voice Mode","type":"string","uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.voice_mode","typeLabel":"enum\u003cstring>"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1","typeLabel":"AssistantTarget · object"}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target","typeLabel":"NodeTarget · object | AssistantTarget · object"}},"required":["id","start_node_id","target","condition"],"title":"FlowEdge","type":"object","uniqueKey":"conversation_flow.edges.items.[INDEX]","typeLabel":"FlowEdge · object"},"title":"Edges","type":"array","uniqueKey":"conversation_flow.edges","typeLabel":"FlowEdge · object[]"}},"required":["start_node_id","nodes"],"title":"ConversationFlowReq","type":"object","uniqueKey":"conversation_flow","typeLabel":"ConversationFlowReq · object"}},"type":"object","required":["name","instructions"],"title":"CreateAssistantRequest","uniqueKey":"","typeLabel":"CreateAssistantRequest · object"},"examples":{"Example":{"title":"Example","value":{"name":"\u003cstring>","instructions":"\u003cstring>","model":"\u003cstring>","tools":[{"type":"function","function":{"name":"\u003cstring>","description":"\u003cstring>","parameters":{}}}],"mcp_servers":[],"a2a_agents":[],"tool_ids":["\u003cstring>"],"description":"\u003cstring>","greeting":"\u003cstring>","llm_api_key_ref":"\u003cstring>","fallback_config":{"model":"\u003cstring>","llm_api_key_ref":"\u003cstring>"},"avatar_settings":{"provider":"telnyx","avatar_id":"elena","background_id":"office","model":"foxtrot-1"},"transcription":{"language":"\u003cstring>","api_key_ref":"\u003cstring>","region":"\u003cstring>","settings":{"smart_format":true,"numerals":true,"eot_threshold":0.8,"eot_timeout_ms":5000,"eager_eot_threshold":0.8,"keyterm":"\u003cstring>","remove_disfluencies":false,"end_of_turn_confidence_threshold":0.5,"prompt":"\u003cstring>","min_turn_silence":400,"max_turn_silence":1280,"interim_results":false,"enable_endpoint_detection":false,"max_endpoint_delay_ms":1750,"context":"\u003cstring>","language_hints":["\u003cstring>"]},"fallback_models":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"challenger":{"model":"deepgram/nova-3","language":"en","rule":"best_turn"}},"telephony_settings":{"default_texml_app_id":"\u003cstring>","supports_unauthenticated_web_calls":true,"noise_suppression_config":{"attenuation_limit":100,"mode":"advanced","family":"quail","enhancement_level":0.8},"time_limit_secs":1800,"user_idle_timeout_secs":7205,"user_idle_reply_secs":10,"fallback_destination":"\u003cstring>","send_message_history_updates":true,"conversation_ended_full_history":false,"greeting_delay_ms":1000,"voicemail_detection":{"on_voicemail_detected":{"voicemail_message":{"prompt":"\u003cstring>","message":"\u003cstring>"}}},"disable_dtmf":false,"recording_settings":{"enabled":true,"channels":"dual","format":"mp3","stop_on_conversation_end":false}},"messaging_settings":{"default_messaging_profile_id":"\u003cstring>","delivery_status_webhook_url":"\u003cstring>","conversation_inactivity_minutes":5000000},"enabled_features":[],"insight_settings":{"insight_group_id":"\u003cstring>","model":"zai-org/GLM-5.3-Flash"},"privacy_settings":{"data_retention":true,"pii_redaction":"disabled","in_transit_data_locality":false},"dynamic_variables_webhook_url":"\u003cstring>","dynamic_variables_webhook_timeout_ms":1500,"dynamic_variables":{},"widget_settings":{"audio_visualizer_config":{"preset":"\u003cstring>"},"start_call_text":"\u003cstring>","view_history_url":"\u003cstring>","report_issue_url":"\u003cstring>","give_feedback_url":"\u003cstring>","agent_thinking_text":"\u003cstring>","speak_to_interrupt_text":"\u003cstring>","logo_icon_url":"\u003cstring>"},"interruption_settings":{"enable":true,"disable_greeting_interruption":true,"start_speaking_plan":{"wait_seconds":0.4,"transcription_endpointing_plan":{"on_punctuation_seconds":0.1,"on_no_punctuation_seconds":1.5,"on_number_seconds":0.5}},"interrupt_prediction_threshold":0},"integrations":[],"observability_settings":{"status":"disabled","secret_key_ref":"\u003cstring>","public_key_ref":"\u003cstring>","host":"\u003cstring>","prompt_name":"\u003cstring>","prompt_version":2,"prompt_label":"\u003cstring>","prompt_sync":"disabled"},"tags":[],"post_conversation_settings":{"enabled":false},"delegation_settings":{"enabled":true,"mode":"telnyx","model":"\u003cstring>","llm_api_key_ref":"\u003cstring>","instructions":"\u003cstring>","speak_results":true},"websocket_settings":{"enabled":false,"url":"\u003cstring>","auth_ref":"\u003cstring>"},"conversation_flow":{"edges":[{"condition":{"prompt":"The caller is asking about a bill or charge.","type":"llm"},"id":"e_intake_to_billing","start_node_id":"n_intake","target":{"node_id":"n_billing","type":"node"}},{"condition":{"prompt":"The caller has explicitly asked for a human.","type":"llm"},"id":"e_intake_to_escalation_assistant","start_node_id":"n_intake","target":{"assistant_id":"assistant-human-handoff","position":{"x":600,"y":80},"type":"assistant","voice_mode":"distinct"}}],"nodes":[{"type":"prompt","id":"n_intake","instructions":"Greet the caller and ask what they're calling about.","name":"Intake","position":{"x":120,"y":80},"shared_tool_ids":["tool-faq-kb"]},{"type":"prompt","id":"n_billing","instructions":"Focus on billing questions. Look up the caller's latest invoice with the billing tool before answering.","instructions_mode":"append","model":"moonshotai/Kimi-K2.6","name":"Billing","position":{"x":420,"y":80},"shared_tool_ids":["tool-billing-lookup"],"tools_mode":"append"}],"start_node_id":"n_intake"}}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"1b39a950-572c-4c61-b34a-a8010c2ae9c4":{"description":"Successful Response","content":{"application/json":{"schema":{"properties":{"id":{"type":"string","isRequired":true,"uniqueKey":"id","typeLabel":"string"},"name":{"type":"string","isRequired":true,"uniqueKey":"name","typeLabel":"string"},"created_at":{"type":"string","format":"date-time","isRequired":true,"uniqueKey":"created_at","typeLabel":"string\u003cdate-time>"},"model":{"type":"string","description":"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.","isRequired":true,"uniqueKey":"model","typeLabel":"string"},"instructions":{"type":"string","description":"System instructions for the assistant. These may be templated with [dynamic variables](https://developers.telnyx.com/docs/inference/ai-assistants/dynamic-variables)","isRequired":true,"uniqueKey":"instructions","typeLabel":"string"},"version_id":{"type":"string","description":"Identifier for the assistant version returned by version-aware assistant endpoints.","uniqueKey":"version_id","typeLabel":"string"},"version_created_at":{"type":"string","format":"date-time","description":"Timestamp when this assistant version was created.","uniqueKey":"version_created_at","typeLabel":"string\u003cdate-time>"},"description":{"type":"string","uniqueKey":"description","typeLabel":"string"},"tools":{"description":"The assistant's tools. Responses merge the assistant's shared Tools Library tools into this array alongside inline tools, each flagged `shared: true`; inline tools carry `shared: false`. On update, a sent `tools` array fully replaces the inline tools only — shared tools stay attached unless `tool_ids` changes. Each tool type except `function`, `webhook`, and `client_side_tool` allows at most one instance per assistant across both sources.","type":"array","items":{"oneOf":[{"type":"object","title":"FunctionTool","required":["type","function"],"properties":{"type":{"type":"string","enum":["function"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"},"function":{"properties":{"name":{"type":"string","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.function.name","typeLabel":"string"},"description":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.0.function.description","typeLabel":"string"},"parameters":{"type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.function.parameters","typeLabel":"object"}},"type":"object","required":["name"],"title":"FunctionDefinition","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.function","typeLabel":"FunctionDefinition · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.0.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.0","typeLabel":"FunctionTool · object"},{"type":"object","title":"WebhookTool","required":["type","webhook"],"properties":{"type":{"type":"string","enum":["webhook"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"},"webhook":{"properties":{"name":{"type":"string","description":"The name of the tool.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.name","typeLabel":"string"},"description":{"type":"string","description":"The description of the tool.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.description","typeLabel":"string"},"url":{"description":"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.","type":"string","example":"https://example.com/api/v1/function","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.url","typeLabel":"string"},"method":{"description":"The HTTP method to be used when calling the external tool.","type":"string","enum":["GET","POST","PUT","DELETE","PATCH"],"default":"POST","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.method","typeLabel":"enum\u003cstring>"},"headers":{"description":"The headers to be sent to the external tool.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.headers","typeLabel":"object[]"},"body_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the body parameters.","type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the body parameters.","type":"array","items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"age":{"description":"The age of the customer.","type":"integer"},"location":{"description":"The location of the customer.","type":"string"}},"required":["age","location"],"type":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.body_parameters","typeLabel":"object"},"path_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the path parameters.","type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the path parameters.","type":"array","items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"id":{"description":"The id of the customer.","type":"string"}},"required":["id"],"type":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.path_parameters","typeLabel":"object"},"query_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the query parameters.","type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the query parameters.","type":"array","items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"page":{"description":"The page number.","type":"integer"}},"required":["page"],"type":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.query_parameters","typeLabel":"object"},"preset_body_fields":{"type":"object","additionalProperties":true,"description":"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.","example":{"account_id":"{{customer_id}}","source":"telnyx-assistant"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.preset_body_fields","typeLabel":"object"},"preset_query_params":{"type":"object","additionalProperties":true,"description":"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.","example":{"caller":"{{telnyx_end_user_target}}","channel":"voice"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.preset_query_params","typeLabel":"object"},"async":{"type":"boolean","default":false,"description":"If async, the assistant will move forward without waiting for your server to respond.","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.async","typeLabel":"boolean"},"async_timeout_ms":{"type":"integer","minimum":1,"maximum":15000,"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.async_timeout_ms","typeLabel":"integer"},"store_fields_as_variables":{"type":"array","description":"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.","items":{"type":"object","required":["name","value_path"],"properties":{"name":{"type":"string","minLength":1,"description":"The name of the dynamic variable to store the extracted value in.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX].name","typeLabel":"string"},"value_path":{"type":"string","minLength":1,"description":"A dot-notation path to the value in the webhook response body (e.g. 'customer.name' or 'id').","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX].value_path","typeLabel":"string"}},"additionalProperties":false,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.store_fields_as_variables","typeLabel":"object[]"},"messages":{"type":"array","description":"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.","items":{"oneOf":[{"type":"object","title":"WebhookToolRequestStartMessage","required":["type","content"],"properties":{"type":{"type":"string","const":"request_start","description":"Speak the filler message immediately when the webhook request begins.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"An optional delay value. This value is ignored for `request_start` messages.","uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0","typeLabel":"WebhookToolRequestStartMessage · object"},{"type":"object","title":"WebhookToolRequestResponseDelayedMessage","required":["type","content","timing_ms"],"properties":{"type":{"type":"string","const":"request_response_delayed","description":"Speak the filler message after the configured delay if the webhook response is still pending.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"The delay in milliseconds from the start of the webhook request.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1","typeLabel":"WebhookToolRequestResponseDelayedMessage · object"}],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX]","typeLabel":"WebhookToolRequestStartMessage · object | WebhookToolRequestResponseDelayedMessage · object"},"example":[{"type":"request_start","content":"Let me look that up for you."},{"type":"request_response_delayed","content":"Still working on that.","timing_ms":5000}],"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook.messages","typeLabel":"(WebhookToolRequestStartMessage · object | WebhookToolRequestResponseDelayedMessage · object)[]"}},"type":"object","required":["url","name","description"],"title":"WebhookToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.webhook","typeLabel":"WebhookToolParams · object"},"timeout_ms":{"type":"integer","default":5000,"maximum":60000,"description":"The maximum number of milliseconds to wait for the webhook to respond before the tool call is aborted. Set this at the tool level, as a sibling of `type` — a `timeout_ms` nested inside the `webhook` object is stored but not applied, and the tool runs at this default instead. Applies when `webhook.async` is false.","uniqueKey":"tools.items.[INDEX].oneOf.1.timeout_ms","typeLabel":"integer"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.1.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.1","typeLabel":"WebhookTool · object"},{"type":"object","title":"ClientSideTool","required":["type","client_side_tool"],"properties":{"type":{"type":"string","enum":["client_side_tool"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.type","typeLabel":"enum\u003cstring>"},"client_side_tool":{"title":"ClientSideToolParams","type":"object","properties":{"name":{"type":"string","description":"The name of the tool.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.name","typeLabel":"string"},"description":{"type":"string","description":"The description of the tool.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.description","typeLabel":"string"},"parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the parameters.","type":"object","additionalProperties":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the parameters.","type":"array","items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"age":{"description":"The age of the customer.","type":"integer"},"location":{"description":"The location of the customer.","type":"string"}},"required":["age","location"],"type":"object"},"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool.parameters","typeLabel":"object"}},"required":["name","description","parameters"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.client_side_tool","typeLabel":"ClientSideToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.2.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.2","typeLabel":"ClientSideTool · object"},{"type":"object","title":"RetrievalTool","required":["type","retrieval"],"properties":{"type":{"type":"string","enum":["retrieval"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.3.type","typeLabel":"enum\u003cstring>"},"retrieval":{"properties":{"bucket_ids":{"items":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.3.retrieval.bucket_ids.items.[INDEX]","typeLabel":"string"},"type":"array","description":"List of [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) to use for retrieval-augmented generation.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.3.retrieval.bucket_ids","typeLabel":"string[]"},"max_num_results":{"description":"The maximum number of results to retrieve as context for the language model.","type":"integer","uniqueKey":"tools.items.[INDEX].oneOf.3.retrieval.max_num_results","typeLabel":"integer"}},"type":"object","required":["bucket_ids"],"title":"BucketIds","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.3.retrieval","typeLabel":"BucketIds · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.3.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.3","typeLabel":"RetrievalTool · object"},{"type":"object","title":"HandoffTool","description":"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.","required":["type","handoff"],"properties":{"type":{"type":"string","enum":["handoff"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.type","typeLabel":"enum\u003cstring>"},"handoff":{"properties":{"ai_assistants":{"type":"array","description":"List of possible assistants that can receive a handoff.","items":{"type":"object","properties":{"name":{"type":"string","description":"Helpful name for giving context on when to handoff to the assistant.","example":"Scheduling Specialist","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX].name","typeLabel":"string"},"id":{"type":"string","description":"The ID of the assistant to hand off to.","example":"assistant-1234567890abcdef","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX].id","typeLabel":"string"}},"required":["name","id"],"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.ai_assistants","typeLabel":"object[]"},"voice_mode":{"type":"string","enum":["unified","distinct"],"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.4.handoff.voice_mode","typeLabel":"enum\u003cstring>"}},"required":["ai_assistants"],"type":"object","title":"HandoffToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.handoff","typeLabel":"HandoffToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.4.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.4","typeLabel":"HandoffTool · object"},{"type":"object","title":"HangupTool","required":["type","hangup"],"properties":{"type":{"type":"string","enum":["hangup"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.5.type","typeLabel":"enum\u003cstring>"},"hangup":{"properties":{"description":{"type":"string","default":"This tool is used to hang up the call.","description":"The description of the function that will be passed to the assistant.","uniqueKey":"tools.items.[INDEX].oneOf.5.hangup.description","typeLabel":"string"}},"type":"object","title":"HangupToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.5.hangup","typeLabel":"HangupToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.5.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.5","typeLabel":"HangupTool · object"},{"type":"object","title":"TransferTool","required":["type","transfer"],"properties":{"type":{"type":"string","enum":["transfer"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.type","typeLabel":"enum\u003cstring>"},"transfer":{"properties":{"targets":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"to":{"type":"string","description":"The destination number or SIP URI of the call.","example":"+13129457420","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].to","typeLabel":"string"},"name":{"type":"string","description":"The name of the target.","example":"Support","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].name","typeLabel":"string"},"message":{"type":"string","description":"The warm transfer message to deliver to this specific target. When set, it takes precedence over the message the assistant composes from `warm_transfer_instructions`.","example":"I have a caller asking about a billing issue on invoice 4471.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].message","typeLabel":"string"},"extension":{"type":"string","description":"DTMF digits to send automatically after the transfer destination answers. Useful for reaching an extension behind an IVR (e.g. `\"200\"` to dial extension 200 once the called party picks up). Allowed characters: `0-9`, `A-D`, `w` (0.5s pause), `W` (1s pause), `*`, `#`. Maximum 64 characters. When omitted, no automatic DTMF is sent.","example":"wwww200","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].extension","typeLabel":"string"},"sip_auth_username":{"type":"string","description":"SIP Authentication username used for SIP challenges. Applies when `to` is a SIP URI.","example":"sipuser","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].sip_auth_username","typeLabel":"string"},"sip_auth_password":{"type":"string","description":"SIP Authentication password used for SIP challenges. Applies when `to` is a SIP URI.","example":"sippass","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].sip_auth_password","typeLabel":"string"}},"required":["to"],"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"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.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.0","typeLabel":"object[]"},{"type":"string","description":"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.","example":"{{ targets }}","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets.oneOf.1","typeLabel":"string"}],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.targets","typeLabel":"object[] | string"},"from":{"type":"string","example":"+35319605860","description":"Number or SIP URI placing the call.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.from","typeLabel":"string"},"diversion":{"type":"string","example":"{{telnyx_agent_target}}","description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.diversion","typeLabel":"string"},"warm_transfer_instructions":{"type":"string","example":"Briefly greet the transfer recipient and provide any relevant information from the call. Let them know you will bridge the call right after.","description":"Natural language instructions for your agent for how to provide context for the transfer recipient.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_instructions","typeLabel":"string"},"warm_transfer_acceptance":{"type":"object","description":"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).","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether the destination must accept the transfer before the calls are bridged.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.enabled","typeLabel":"boolean"},"end_user_target_context_mode":{"type":"string","enum":["private","shared"],"default":"private","description":"Controls whether the private exchange between the assistant and the transfer destination is kept out of the conversation. With `private` (default) the exchange never reaches the conversation history, AI conversations, webhooks or insights, and the transfer tool result is rewritten with the outcome only. With `shared` the exchange stays in the conversation like any other messages.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.end_user_target_context_mode","typeLabel":"enum\u003cstring>"},"require_acceptance":{"type":"boolean","default":false,"description":"Fail closed when the acceptance consult cannot run. Off by default: if the consult cannot be set up for any reason — including where acceptance is unavailable at all (`gather_using_ai`, Conversation Relay or web calls, a conference, or additional invited participants) — the transfer degrades to a plain warm transfer (the warm transfer message is played to the destination as audio and the calls are bridged anyway). Set to true to treat those paths as a decline instead: the destination is disconnected without being asked, the assistant returns to the caller, and no bridge happens without an acceptance. Only consult-setup failures are affected; the destination must still explicitly accept on every consult that does run.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.require_acceptance","typeLabel":"boolean"},"timeout_secs":{"type":"integer","minimum":10,"maximum":600,"default":60,"description":"How long, in seconds, the destination has to accept the transfer, counted from when the private consult starts (right after the destination answers, or after `warm_message_delay_ms`). The caller keeps hearing ringback the whole time. If no acceptance arrives in time, the destination is hung up and the assistant returns to the caller (the transfer fails as a timeout). Raise it for destinations that answer before a human is on the line, such as a call-center queue/ACD or an IVR playing hold audio; keep it as short as practical, since the caller waits on ringback until it expires.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.timeout_secs","typeLabel":"integer"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance","typeLabel":"object"},"description":{"type":"string","description":"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.","example":"Transfer the call to a human agent.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.description","typeLabel":"string"},"bridge_beep":{"type":"object","description":"Plays a short beep once the transfer completes and the calls are bridged, so the transfer destination knows the caller is now on the line. The warm transfer message plays before the bridge; this marks the moment the caller actually joins. Works with and without `warm_transfer_acceptance`.","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether to play the beep when the calls are bridged.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.bridge_beep.enabled","typeLabel":"boolean"},"target_legs":{"type":"string","enum":["self","both"],"default":"self","description":"Who hears the beep. `self` plays it to the transfer destination only; `both` plays it to the destination and the original caller.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.bridge_beep.target_legs","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.bridge_beep","typeLabel":"object"},"warm_message_delay_ms":{"oneOf":[{"type":"integer","example":2000,"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms.oneOf.0","typeLabel":"integer"},{"type":"null","example":2000,"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms.oneOf.1","typeLabel":"null"}],"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms","typeLabel":"integer | null"},"custom_headers":{"description":"Custom headers to be added to the SIP INVITE for the transfer command.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.custom_headers","typeLabel":"object[]"},"voicemail_detection":{"type":"object","description":"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.","properties":{"detection_mode":{"type":"string","enum":["disabled","premium"],"description":"The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_mode","typeLabel":"enum\u003cstring>"},"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected on the transferred call.","properties":{"action":{"type":"string","enum":["stop_transfer","leave_message_and_stop_transfer"],"description":"The action to take when voicemail is detected. 'stop_transfer' hangs up immediately. 'leave_message_and_stop_transfer' leaves a message then hangs up.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"},"voicemail_message":{"type":"object","description":"Configuration for the voicemail message to leave. Only applicable when action is 'leave_message_and_stop_transfer'.","properties":{"type":{"type":"string","enum":["message","warm_transfer_instructions"],"description":"The type of voicemail message. Use 'message' to leave a specific TTS message, or 'warm_transfer_instructions' to play the warm transfer audio.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"The specific message to leave as voicemail (converted to speech). Only applicable when type is 'message'.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message.message","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message","typeLabel":"object"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected","typeLabel":"object"},"detection_config":{"type":"object","description":"Advanced AMD detection configuration parameters. All values are optional - Telnyx will use defaults if not specified.","properties":{"greeting_silence_duration_millis":{"type":"integer","minimum":500,"maximum":50000,"description":"Duration of silence after the greeting to wait before considering the greeting complete.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_silence_duration_millis","typeLabel":"integer"},"greeting_total_analysis_time_millis":{"type":"integer","minimum":500,"maximum":300000,"description":"Maximum time to spend analyzing the greeting.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_total_analysis_time_millis","typeLabel":"integer"},"after_greeting_silence_millis":{"type":"integer","minimum":100,"maximum":5000,"description":"Duration of silence after greeting detection before finalizing the result.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.after_greeting_silence_millis","typeLabel":"integer"},"between_words_silence_millis":{"type":"integer","minimum":10,"maximum":5000,"description":"Maximum silence duration between words during greeting.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.between_words_silence_millis","typeLabel":"integer"},"greeting_duration_millis":{"type":"integer","minimum":100,"maximum":10000,"description":"Expected duration of greeting speech.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_duration_millis","typeLabel":"integer"},"initial_silence_millis":{"type":"integer","minimum":100,"maximum":500000,"description":"Maximum silence duration at the start of the call before speech.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.initial_silence_millis","typeLabel":"integer"},"maximum_number_of_words":{"type":"integer","minimum":1,"maximum":50,"description":"Maximum number of words expected in a human greeting.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.maximum_number_of_words","typeLabel":"integer"},"maximum_word_length_millis":{"type":"integer","minimum":50,"maximum":5000,"description":"Maximum duration of a single word.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.maximum_word_length_millis","typeLabel":"integer"},"silence_threshold":{"type":"integer","minimum":1,"maximum":1000,"description":"Audio level threshold for silence detection.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.silence_threshold","typeLabel":"integer"},"total_analysis_time_millis":{"type":"integer","minimum":500,"maximum":60000,"description":"Total time allowed for AMD analysis.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.total_analysis_time_millis","typeLabel":"integer"},"min_word_length_millis":{"type":"integer","minimum":1,"maximum":1000,"description":"Minimum duration for audio to be considered a word.","uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.min_word_length_millis","typeLabel":"integer"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config","typeLabel":"object"}},"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer.voicemail_detection","typeLabel":"object"}},"type":"object","required":["targets","from"],"title":"TransferToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.transfer","typeLabel":"TransferToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.6.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.6","typeLabel":"TransferTool · object"},{"type":"object","title":"InviteTool","required":["type","invite"],"properties":{"type":{"type":"string","enum":["invite"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.type","typeLabel":"enum\u003cstring>"},"invite":{"properties":{"from":{"type":"string","example":"+35319605860","description":"Number or SIP URI placing the call.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.from","typeLabel":"string"},"targets":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"to":{"type":"string","description":"The destination number or SIP URI of the call.","example":"+13129457420","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX].to","typeLabel":"string"},"name":{"type":"string","description":"The name of the target.","example":"Support","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX].name","typeLabel":"string"}},"required":["to"],"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.0","typeLabel":"object[]"},{"type":"string","description":"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.","example":"{{ targets }}","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.1","typeLabel":"string"},{"type":"null","description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets.oneOf.2","typeLabel":"null"}],"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.targets","typeLabel":"object[] | string | null"},"custom_headers":{"description":"Custom headers to be added to the SIP INVITE for the invite command.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.custom_headers","typeLabel":"object[]"},"voicemail_detection":{"type":"object","description":"Configuration for voicemail detection (AMD - Answering Machine Detection) on the invited call.","properties":{"detection_mode":{"type":"string","enum":["disabled","premium"],"description":"The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.voicemail_detection.detection_mode","typeLabel":"enum\u003cstring>"},"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected on the invited call.","properties":{"action":{"type":"string","enum":["stop_invite"],"description":"The action to take when voicemail is detected.","uniqueKey":"tools.items.[INDEX].oneOf.7.invite.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.voicemail_detection.on_voicemail_detected","typeLabel":"object"}},"uniqueKey":"tools.items.[INDEX].oneOf.7.invite.voicemail_detection","typeLabel":"object"}},"type":"object","required":["from"],"title":"InviteToolConfig","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.invite","typeLabel":"InviteToolConfig · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.7.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.7","typeLabel":"InviteTool · object"},{"type":"object","title":"SIPReferTool","required":["type","refer"],"properties":{"type":{"type":"string","enum":["refer"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.type","typeLabel":"enum\u003cstring>"},"refer":{"properties":{"targets":{"type":"array","description":"The different possible targets of the SIP refer. The assistant will be able to choose one of the targets to refer the call to.","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the target.","example":"Support","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].name","typeLabel":"string"},"sip_address":{"type":"string","description":"The SIP URI to which the call will be referred.","example":"sip:[email protected]","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_address","typeLabel":"string"},"sip_auth_username":{"type":"string","description":"SIP Authentication username used for SIP challenges.","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_auth_username","typeLabel":"string"},"sip_auth_password":{"type":"string","description":"SIP Authentication password used for SIP challenges.","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_auth_password","typeLabel":"string"}},"required":["name","sip_address"],"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.targets","typeLabel":"object[]"},"sip_headers":{"description":"SIP headers to be added to the SIP REFER. Currently only User-to-User and Diversion headers are supported.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","enum":["User-to-User","Diversion"],"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX].name","typeLabel":"enum\u003cstring>"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.sip_headers","typeLabel":"object[]"},"custom_headers":{"description":"Custom headers to be added to the SIP REFER.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"tools.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"tools.items.[INDEX].oneOf.8.refer.custom_headers","typeLabel":"object[]"}},"type":"object","required":["targets"],"title":"SIPReferToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.refer","typeLabel":"SIPReferToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.8.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.8","typeLabel":"SIPReferTool · object"},{"type":"object","title":"DTMFTool","required":["type","send_dtmf"],"properties":{"type":{"type":"string","enum":["send_dtmf"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.9.type","typeLabel":"enum\u003cstring>"},"send_dtmf":{"type":"object","additionalProperties":true,"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.9.send_dtmf","typeLabel":"object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.9.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.9","typeLabel":"DTMFTool · object"},{"type":"object","title":"SendMessageTool","description":"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.","required":["type","send_message"],"properties":{"type":{"type":"string","enum":["send_message"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.10.type","typeLabel":"enum\u003cstring>"},"send_message":{"type":"object","properties":{"message_template":{"oneOf":[{"type":"string","description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.10.send_message.message_template.oneOf.0","typeLabel":"string"},{"type":"null","description":"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.","uniqueKey":"tools.items.[INDEX].oneOf.10.send_message.message_template.oneOf.1","typeLabel":"null"}],"uniqueKey":"tools.items.[INDEX].oneOf.10.send_message.message_template","typeLabel":"string | null"}},"additionalProperties":true,"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.10.send_message","typeLabel":"object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.10.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.10","typeLabel":"SendMessageTool · object"},{"type":"object","title":"SkipTurnTool","required":["type","skip_turn"],"properties":{"type":{"type":"string","enum":["skip_turn"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.11.type","typeLabel":"enum\u003cstring>"},"skip_turn":{"properties":{"description":{"type":"string","default":"This tool is used to skip the assistant turn without producing a response.","description":"The description of the function that will be passed to the assistant.","uniqueKey":"tools.items.[INDEX].oneOf.11.skip_turn.description","typeLabel":"string"}},"type":"object","title":"SkipTurnToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.11.skip_turn","typeLabel":"SkipTurnToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.11.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.11","typeLabel":"SkipTurnTool · object"},{"type":"object","title":"VisionTool","description":"(BETA) Lets the assistant look at recent image frames the client sent into the conversation (for example webcam or screen-share frames). Frames are sent with `conversation.item.create` and `item.buffer: true`; they never trigger a response on their own. The assistant decides when to look and which frames it needs. Requires a model that supports image input.","required":["type"],"properties":{"type":{"type":"string","enum":["vision"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.12.type","typeLabel":"enum\u003cstring>"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.12.shared","typeLabel":"boolean"},"vision":{"properties":{"max_frame_age_secs":{"type":"integer","minimum":1,"default":10,"description":"Frames received longer ago than this many seconds are not shown to the assistant, so it never describes a frozen or disconnected camera as live.","uniqueKey":"tools.items.[INDEX].oneOf.12.vision.max_frame_age_secs","typeLabel":"integer"}},"type":"object","title":"VisionToolParams","uniqueKey":"tools.items.[INDEX].oneOf.12.vision","typeLabel":"VisionToolParams · object"}},"uniqueKey":"tools.items.[INDEX].oneOf.12","typeLabel":"VisionTool · object"},{"type":"object","title":"PayTool","description":"(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.","required":["type","pay"],"properties":{"type":{"type":"string","enum":["pay"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.type","typeLabel":"enum\u003cstring>"},"pay":{"properties":{"connector_name":{"type":"string","description":"The name of the pay connector configured in the Telnyx API. Must reference an existing pay connector for this organization.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.connector_name","typeLabel":"string"},"currency":{"type":"string","default":"USD","description":"Default currency for payments processed by this tool.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.currency","typeLabel":"string"},"payment_method":{"type":"string","default":"credit-card","description":"Default payment method for payments processed by this tool.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.payment_method","typeLabel":"string"},"description":{"oneOf":[{"type":"string","default":null,"description":"Description of the pay tool shown to the assistant so it knows when to call the tool. Not sent to the payment connector — the per-call `description` argument the assistant passes is what reaches the processor.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.description.oneOf.0","typeLabel":"string"},{"type":"null","default":null,"description":"Description of the pay tool shown to the assistant so it knows when to call the tool. Not sent to the payment connector — the per-call `description` argument the assistant passes is what reaches the processor.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.description.oneOf.1","typeLabel":"null"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.description","typeLabel":"string | null"},"connector_parameters":{"type":"object","additionalProperties":true,"description":"Custom key/value parameters forwarded to the pay connector as `parameters` in the processor request. String values may use `{{dynamic_variable}}` templating, resolved per call.","example":{"campaignid":"abc","customer_ref":"CUST-67890"},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.connector_parameters","typeLabel":"object"},"valid_card_types":{"type":"array","items":{"type":"string","enum":["visa","mastercard","amex","maestro","discover","optima","jcb","diners-club","enroute"],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.valid_card_types.items.[INDEX]","typeLabel":"enum\u003cstring>"},"minItems":1,"description":"Restricts accepted card numbers to the listed card types. When the caller enters a card number that does not match one of the listed types, Pay treats the input as invalid and re-prompts for the card number.","example":["visa","mastercard"],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.valid_card_types","typeLabel":"enum\u003cstring>[]"},"postal_code":{"oneOf":[{"type":"string","description":"Controls billing postal code collection for credit-card payments. Set to `false` to skip the postal code prompt without supplying a postal code to the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to prompt the caller. Supply a non-empty string, such as `\"90210\"`, to use that postal code without prompting. This option does not affect ACH debit payments or payments using an existing token.","minLength":1,"pattern":"\\S","example":false,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.postal_code.oneOf.0","typeLabel":"string"},{"type":"boolean","description":"Controls billing postal code collection for credit-card payments. Set to `false` to skip the postal code prompt without supplying a postal code to the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to prompt the caller. Supply a non-empty string, such as `\"90210\"`, to use that postal code without prompting. This option does not affect ACH debit payments or payments using an existing token.","example":false,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.postal_code.oneOf.1","typeLabel":"boolean"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.postal_code","typeLabel":"string | boolean"},"min_postal_code_length":{"type":"integer","minimum":1,"maximum":128,"description":"Minimum number of digits the caller must enter when collecting a credit-card billing postal code. Applies only when `postal_code` prompts the caller. Omitted means the platform default (1) applies. The maximum number of digits collected is the greater of 10 and this value. This does not validate the length of a postal code supplied directly in `postal_code`.","example":5,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.min_postal_code_length","typeLabel":"integer"},"max_attempts":{"type":"integer","minimum":1,"maximum":3,"description":"Maximum number of attempts for each payment collection step. Omitted means the platform default (3) applies.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.max_attempts","typeLabel":"integer"},"timeout_millis":{"type":"integer","minimum":1,"maximum":600000,"description":"Time in milliseconds to wait for DTMF input for each collection step. Omitted means the platform default (5000) applies. Increase this for slower entry, e.g. a 16-digit card number.","example":12000,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.timeout_millis","typeLabel":"integer"},"inter_digit_timeout_millis":{"type":"integer","minimum":1,"maximum":600000,"description":"Time in milliseconds to wait between consecutive DTMF digits. Omitted means the platform default (5000) applies.","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.inter_digit_timeout_millis","typeLabel":"integer"},"prompts":{"type":"object","title":"Pay Tool Prompts","description":"Custom text-to-speech prompts keyed by payment collection step. The AI assistant merges its own card-number prompt into this map, matching on the same step keys.","additionalProperties":false,"properties":{"payment-card-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.payment-card-number","typeLabel":"string | Pay Tool Prompt · object[]"},"expiration-date":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.expiration-date","typeLabel":"string | Pay Tool Prompt · object[]"},"postal-code":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.postal-code","typeLabel":"string | Pay Tool Prompt · object[]"},"security-code":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.security-code","typeLabel":"string | Pay Tool Prompt · object[]"},"bank-routing-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number","typeLabel":"string | Pay Tool Prompt · object[]"},"bank-account-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts.bank-account-number","typeLabel":"string | Pay Tool Prompt · object[]"}},"uniqueKey":"tools.items.[INDEX].oneOf.13.pay.prompts","typeLabel":"Pay Tool Prompts · object"}},"required":["connector_name"],"type":"object","title":"PayToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.pay","typeLabel":"PayToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.13.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.13","typeLabel":"PayTool · object"},{"type":"object","title":"UpdateDynamicVariablesTool","description":"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`.","required":["type","update_dynamic_variables"],"properties":{"type":{"type":"string","enum":["update_dynamic_variables"],"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.type","typeLabel":"enum\u003cstring>"},"update_dynamic_variables":{"description":"Configuration for an update_dynamic_variables tool.","properties":{"name":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","description":"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.","example":"collect_details","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.name","typeLabel":"string"},"description":{"type":"string","description":"Description of the tool passed to the assistant, guiding when to call it and which variables to update.","example":"Collect caller details into conversation variables.","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.description","typeLabel":"string"},"updatable_variables":{"type":"array","description":"The dynamic variables the assistant is allowed to write. At least one is required.","minItems":1,"items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"pattern":"^(?!telnyx_)[a-zA-Z0-9._-]+$","description":"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.","example":"customer_name","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].name","typeLabel":"string"},"type":{"type":"string","description":"Optional hint for the variable's value type (e.g. `string`).","example":"string","uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].type","typeLabel":"string"},"description":{"type":"string","description":"Optional description of the variable, guiding the assistant on what value to capture.","example":"The caller's full name.","uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].description","typeLabel":"string"}},"required":["name"],"additionalProperties":false,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables","typeLabel":"object[]"}},"required":["name","description","updatable_variables"],"type":"object","title":"UpdateDynamicVariablesToolParams","isRequired":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.update_dynamic_variables","typeLabel":"UpdateDynamicVariablesToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"tools.items.[INDEX].oneOf.14.shared","typeLabel":"boolean"}},"uniqueKey":"tools.items.[INDEX].oneOf.14","typeLabel":"UpdateDynamicVariablesTool · object"}],"uniqueKey":"tools.items.[INDEX]","typeLabel":"FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object"},"uniqueKey":"tools","typeLabel":"(FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object)[]"},"mcp_servers":{"type":"array","items":{"type":"object","title":"AssistantMCPServer","description":"Reference to an MCP server attached to an assistant. Create and manage MCP servers with the `/ai/mcp_servers` endpoints, then attach them to assistants by ID.","properties":{"id":{"type":"string","description":"ID of the MCP server to attach. This must be the `id` of an MCP server returned by the `/ai/mcp_servers` endpoints.","isRequired":true,"uniqueKey":"mcp_servers.items.[INDEX].id","typeLabel":"string"},"allowed_tools":{"type":"array","items":{"type":"string","uniqueKey":"mcp_servers.items.[INDEX].allowed_tools.items.[INDEX]","typeLabel":"string"},"description":"Optional per-assistant allowlist of MCP tool names. When omitted, the assistant uses the MCP server's configured `allowed_tools`.","uniqueKey":"mcp_servers.items.[INDEX].allowed_tools","typeLabel":"string[]"}},"required":["id"],"uniqueKey":"mcp_servers.items.[INDEX]","typeLabel":"AssistantMCPServer · object"},"default":[],"description":"MCP servers attached to the assistant. Create MCP servers with `/ai/mcp_servers`, then reference them by `id` here.","uniqueKey":"mcp_servers","typeLabel":"AssistantMCPServer · object[]"},"a2a_agents":{"type":"array","items":{"type":"object","title":"AssistantA2AAgent","description":"A remote agent, reachable over the A2A (Agent2Agent) protocol, that an assistant can delegate to. Tools are not configured here: at the start of every conversation the agent's card is fetched and one tool is derived per skill the card advertises.","properties":{"name":{"type":"string","maxLength":43,"description":"Identifies the agent and seeds the names of the tools derived from its card (`a2a_\u003cname>_\u003cskill_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.","example":"billing_agent","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].name","typeLabel":"string"},"url":{"type":"string","description":"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.","example":"https://agents.example.com","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].url","typeLabel":"string"},"headers":{"type":"array","items":{"type":"object","title":"A2AAgentHeader","description":"A header sent when fetching an A2A agent's card and on every call made to that agent.","properties":{"name":{"type":"string","description":"HTTP header name. May only contain alphanumeric characters, hyphens, and underscores, or a `{{dynamic_variable}}` placeholder surrounded by those characters.","example":"X-Api-Key","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].headers.items.[INDEX].name","typeLabel":"string"},"value":{"type":"string","description":"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.","example":"{{#integration_secret}}my_agent_api_key{{/integration_secret}}","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].headers.items.[INDEX].value","typeLabel":"string"}},"required":["name","value"],"uniqueKey":"a2a_agents.items.[INDEX].headers.items.[INDEX]","typeLabel":"A2AAgentHeader · object"},"description":"Headers sent when fetching this agent's card and on every call made to it. Use them to authenticate to the agent.","uniqueKey":"a2a_agents.items.[INDEX].headers","typeLabel":"A2AAgentHeader · object[]"},"async":{"type":"boolean","default":false,"description":"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.","uniqueKey":"a2a_agents.items.[INDEX].async","typeLabel":"boolean"},"timeout_ms":{"type":"integer","minimum":1,"maximum":4294967295,"description":"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.","example":30000,"uniqueKey":"a2a_agents.items.[INDEX].timeout_ms","typeLabel":"integer"},"poll_interval_ms":{"type":"integer","minimum":1,"maximum":4294967295,"description":"How often, in milliseconds, to poll an agent task that has not finished yet. Defaults to 500.","example":500,"uniqueKey":"a2a_agents.items.[INDEX].poll_interval_ms","typeLabel":"integer"},"messages":{"type":"array","description":"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`.","items":{"oneOf":[{"type":"object","title":"A2AAgentRequestStartMessage","required":["type","content"],"properties":{"type":{"type":"string","const":"request_start","description":"Speak the filler message immediately when the call to the agent begins.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.0.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.0.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"An optional delay value. This value is ignored for `request_start` messages.","uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.0.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.0","typeLabel":"A2AAgentRequestStartMessage · object"},{"type":"object","title":"A2AAgentRequestResponseDelayedMessage","required":["type","content","timing_ms"],"properties":{"type":{"type":"string","const":"request_response_delayed","description":"Speak the filler message only if the agent has not answered yet after `timing_ms`.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.1.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.1.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"How long to wait, in milliseconds, before speaking this message.","isRequired":true,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.1.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX].oneOf.1","typeLabel":"A2AAgentRequestResponseDelayedMessage · object"}],"uniqueKey":"a2a_agents.items.[INDEX].messages.items.[INDEX]","typeLabel":"A2AAgentRequestStartMessage · object | A2AAgentRequestResponseDelayedMessage · object"},"uniqueKey":"a2a_agents.items.[INDEX].messages","typeLabel":"(A2AAgentRequestStartMessage · object | A2AAgentRequestResponseDelayedMessage · object)[]"}},"required":["name","url"],"uniqueKey":"a2a_agents.items.[INDEX]","typeLabel":"AssistantA2AAgent · object"},"default":[],"description":"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_\u003cname>_\u003cskill_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.","uniqueKey":"a2a_agents","typeLabel":"AssistantA2AAgent · object[]"},"greeting":{"type":"string","description":"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 `\u003cassistant-speaks-first-with-model-generated-message>` to have the assistant generate the greeting based on the system instructions.","uniqueKey":"greeting","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"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.","uniqueKey":"llm_api_key_ref","typeLabel":"string"},"external_llm":{"properties":{"model":{"type":"string","description":"Model identifier to use with the external LLM endpoint.","isRequired":true,"uniqueKey":"external_llm.model","typeLabel":"string"},"base_url":{"type":"string","description":"Base URL for the external LLM endpoint.","isRequired":true,"uniqueKey":"external_llm.base_url","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the external LLM API key.","uniqueKey":"external_llm.llm_api_key_ref","typeLabel":"string"},"authentication_method":{"type":"string","enum":["token","certificate"],"default":"token","description":"Authentication method used when connecting to the external LLM endpoint.","title":"AuthenticationMethod","uniqueKey":"external_llm.authentication_method","typeLabel":"enum\u003cstring>"},"certificate_ref":{"type":"string","description":"Integration secret identifier for the client certificate used with certificate authentication.","uniqueKey":"external_llm.certificate_ref","typeLabel":"string"},"token_retrieval_url":{"type":"string","description":"URL used to retrieve an access token when certificate authentication is enabled.","uniqueKey":"external_llm.token_retrieval_url","typeLabel":"string"},"forward_metadata":{"type":"boolean","default":false,"description":"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.","uniqueKey":"external_llm.forward_metadata","typeLabel":"boolean"},"extra_headers":{"oneOf":[{"type":"object","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"external_llm.extra_headers.oneOf.0.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"external_llm.extra_headers.oneOf.0","typeLabel":"object"},{"type":"null","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"external_llm.extra_headers.oneOf.1.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"external_llm.extra_headers.oneOf.1","typeLabel":"null"}],"uniqueKey":"external_llm.extra_headers","typeLabel":"object | null"}},"type":"object","required":["model","base_url"],"title":"ExternalLLM","uniqueKey":"external_llm","typeLabel":"ExternalLLM · object"},"fallback_config":{"properties":{"model":{"type":"string","description":"Fallback Telnyx-hosted model to use when the primary LLM provider is unavailable.","uniqueKey":"fallback_config.model","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the fallback model API key.","uniqueKey":"fallback_config.llm_api_key_ref","typeLabel":"string"},"external_llm":{"properties":{"model":{"type":"string","description":"Model identifier to use with the external LLM endpoint.","isRequired":true,"uniqueKey":"fallback_config.external_llm.model","typeLabel":"string"},"base_url":{"type":"string","description":"Base URL for the external LLM endpoint.","isRequired":true,"uniqueKey":"fallback_config.external_llm.base_url","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the external LLM API key.","uniqueKey":"fallback_config.external_llm.llm_api_key_ref","typeLabel":"string"},"authentication_method":{"type":"string","enum":["token","certificate"],"default":"token","description":"Authentication method used when connecting to the external LLM endpoint.","title":"AuthenticationMethod","uniqueKey":"fallback_config.external_llm.authentication_method","typeLabel":"enum\u003cstring>"},"certificate_ref":{"type":"string","description":"Integration secret identifier for the client certificate used with certificate authentication.","uniqueKey":"fallback_config.external_llm.certificate_ref","typeLabel":"string"},"token_retrieval_url":{"type":"string","description":"URL used to retrieve an access token when certificate authentication is enabled.","uniqueKey":"fallback_config.external_llm.token_retrieval_url","typeLabel":"string"},"forward_metadata":{"type":"boolean","default":false,"description":"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.","uniqueKey":"fallback_config.external_llm.forward_metadata","typeLabel":"boolean"},"extra_headers":{"oneOf":[{"type":"object","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"fallback_config.external_llm.extra_headers.oneOf.0.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"fallback_config.external_llm.extra_headers.oneOf.0","typeLabel":"object"},{"type":"null","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"fallback_config.external_llm.extra_headers.oneOf.1.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"fallback_config.external_llm.extra_headers.oneOf.1","typeLabel":"null"}],"uniqueKey":"fallback_config.external_llm.extra_headers","typeLabel":"object | null"}},"type":"object","required":["model","base_url"],"title":"ExternalLLM","uniqueKey":"fallback_config.external_llm","typeLabel":"ExternalLLM · object"}},"type":"object","title":"FallbackConfig","uniqueKey":"fallback_config","typeLabel":"FallbackConfig · object"},"voice_settings":{"properties":{"voice":{"type":"string","description":"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.\nTo 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.\u003cmodel_id>.\u003cvoice_id>` (e.g. Telnyx.KokoroTTS.af_heart). For Soniox voices, use `Soniox.tts-rt-v2.\u003cvoice_id>` (e.g. Soniox.tts-rt-v2.Emma); every Soniox voice speaks all supported languages.\nThe 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.","isRequired":true,"uniqueKey":"voice_settings.voice","typeLabel":"string"},"voice_speed":{"type":"number","default":1,"description":"The speed of the voice in the range [0.6, 1.5]. 1.0 is the default speed. Larger numbers make the voice faster, smaller numbers make it slower. Applies to Telnyx `Ultra` voices; values outside this range are rejected by the synthesis engine. Soniox voices support a speed range of 0.7 to 1.3.","uniqueKey":"voice_settings.voice_speed","typeLabel":"number"},"api_key_ref":{"type":"string","description":"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.","uniqueKey":"voice_settings.api_key_ref","typeLabel":"string"},"temperature":{"type":"number","default":0.5,"description":"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.","uniqueKey":"voice_settings.temperature","typeLabel":"number"},"similarity_boost":{"type":"number","default":0.75,"description":"Determines how closely the AI should adhere to the original voice when attempting to replicate it. Only applicable when using ElevenLabs.","uniqueKey":"voice_settings.similarity_boost","typeLabel":"number"},"use_speaker_boost":{"type":"boolean","default":true,"description":"Amplifies similarity to the original speaker voice. Increases computational load and latency slightly. Only applicable when using ElevenLabs.","uniqueKey":"voice_settings.use_speaker_boost","typeLabel":"boolean"},"style":{"type":"number","default":0,"description":"Determines the style exaggeration of the voice. Amplifies speaker style but consumes additional resources when set above 0. Only applicable when using ElevenLabs.","uniqueKey":"voice_settings.style","typeLabel":"number"},"speed":{"type":"number","default":1,"description":"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.","uniqueKey":"voice_settings.speed","typeLabel":"number"},"language":{"oneOf":[{"type":"string","description":"Two-letter ISO 639-1 code of the language the voice speaks, for example `es`. Only applicable to Soniox and AssemblyAI voices, which speak every language of their model. AssemblyAI accepts `en`, `es`, `de`, `fr`, `it`, and `pt`. When unset, the voice speaks English.","default":null,"uniqueKey":"voice_settings.language.oneOf.0","typeLabel":"string"},{"type":"null","description":"Two-letter ISO 639-1 code of the language the voice speaks, for example `es`. Only applicable to Soniox and AssemblyAI voices, which speak every language of their model. AssemblyAI accepts `en`, `es`, `de`, `fr`, `it`, and `pt`. When unset, the voice speaks English.","default":null,"uniqueKey":"voice_settings.language.oneOf.1","typeLabel":"null"}],"uniqueKey":"voice_settings.language","typeLabel":"string | null"},"language_boost":{"oneOf":[{"type":"string","description":"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.","enum":[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"],"default":null,"uniqueKey":"voice_settings.language_boost.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","description":"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.","enum":[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"],"default":null,"uniqueKey":"voice_settings.language_boost.oneOf.1","typeLabel":"null"}],"uniqueKey":"voice_settings.language_boost","typeLabel":"enum\u003cstring> | null"},"expressive_mode":{"type":"boolean","default":false,"description":"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.","uniqueKey":"voice_settings.expressive_mode","typeLabel":"boolean"},"background_audio":{"oneOf":[{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["predefined_media"],"description":"Select from predefined media options.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.0.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","enum":["silence","office"],"default":"silence","description":"The predefined media to use. `silence` disables background audio.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.0.value","typeLabel":"enum\u003cstring>"},"volume":{"type":"number","minimum":0.1,"maximum":1,"multipleOf":0.1,"default":1,"description":"Volume level for the predefined background audio. Supports values from 0.1 to 1.0 in 0.1 increments.","uniqueKey":"voice_settings.background_audio.oneOf.0.volume","typeLabel":"number"}},"uniqueKey":"voice_settings.background_audio.oneOf.0","typeLabel":"object"},{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["media_url"],"description":"Provide a direct URL to an MP3 file. The audio will loop during the call.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.1.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","format":"uri","description":"HTTPS URL to an MP3 file.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.1.value","typeLabel":"string\u003curi>"}},"uniqueKey":"voice_settings.background_audio.oneOf.1","typeLabel":"object"},{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["media_name"],"description":"Reference a previously uploaded media by its name from Telnyx Media Storage.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.2.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","description":"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.","isRequired":true,"uniqueKey":"voice_settings.background_audio.oneOf.2.value","typeLabel":"string"}},"uniqueKey":"voice_settings.background_audio.oneOf.2","typeLabel":"object"}],"uniqueKey":"voice_settings.background_audio","typeLabel":"object"},"tool_call_audio":{"oneOf":[{"type":"object","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","required":["type","value"],"example":{"type":"predefined_media","value":"typing","volume":0.5},"properties":{"type":{"type":"string","enum":["predefined_media"],"description":"Select from predefined media options.","isRequired":true,"uniqueKey":"voice_settings.tool_call_audio.oneOf.0.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","enum":["typing"],"description":"The predefined media to use. `typing` plays a keyboard typing sound.","isRequired":true,"uniqueKey":"voice_settings.tool_call_audio.oneOf.0.value","typeLabel":"enum\u003cstring>"},"volume":{"type":"number","minimum":0,"maximum":1,"multipleOf":0.1,"default":0.5,"description":"Volume level for the predefined media. Supports values from 0.0 to 1.0 in 0.1 increments. `0.0` plays no sound.","uniqueKey":"voice_settings.tool_call_audio.oneOf.0.volume","typeLabel":"number"}},"uniqueKey":"voice_settings.tool_call_audio.oneOf.0","typeLabel":"object"},{"type":"object","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","required":["type","value"],"example":{"type":"predefined_media","value":"typing"},"properties":{"type":{"type":"string","enum":["media_url"],"description":"Provide a direct URL to an MP3 file. The audio loops while the tool runs.","isRequired":true,"uniqueKey":"voice_settings.tool_call_audio.oneOf.1.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","format":"uri","description":"HTTPS URL to an MP3 file.","isRequired":true,"uniqueKey":"voice_settings.tool_call_audio.oneOf.1.value","typeLabel":"string\u003curi>"}},"uniqueKey":"voice_settings.tool_call_audio.oneOf.1","typeLabel":"object"},{"type":"null","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","example":{"type":"predefined_media","value":"typing","volume":0.5},"uniqueKey":"voice_settings.tool_call_audio.oneOf.2","typeLabel":"null"}],"uniqueKey":"voice_settings.tool_call_audio","typeLabel":"object · object · null"}},"type":"object","required":["voice"],"uniqueKey":"voice_settings","typeLabel":"object"},"avatar_settings":{"oneOf":[{"type":"object","title":"AvatarSettings","description":"**Beta:** Saved avatar configuration for supported realtime browser conversations. `null` means that no avatar is configured.","required":["provider","avatar_id","background_id","model"],"example":{"provider":"telnyx","avatar_id":"elena","background_id":"office","model":"foxtrot-1"},"properties":{"provider":{"type":"string","const":"telnyx","description":"Selects the Telnyx open-source avatar provider.","isRequired":true,"uniqueKey":"avatar_settings.oneOf.0.provider","typeLabel":"string"},"avatar_id":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$","description":"The Telnyx stock avatar or organization-owned custom avatar to render.","example":"avatar_0123456789abcdef0123456789abcdef","isRequired":true,"uniqueKey":"avatar_settings.oneOf.0.avatar_id","typeLabel":"string"},"background_id":{"type":"string","enum":["office","studio","reception","illustrated_workspace"],"description":"The background to render.","isRequired":true,"uniqueKey":"avatar_settings.oneOf.0.background_id","typeLabel":"enum\u003cstring>"},"model":{"type":"string","enum":["foxtrot-1"],"description":"Required avatar model identifier, separate from `avatar_id`. The supported value is `foxtrot-1`. Omission, null, and unsupported model identifiers are rejected.","isRequired":true,"uniqueKey":"avatar_settings.oneOf.0.model","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"avatar_settings.oneOf.0","typeLabel":"AvatarSettings · object"},{"type":"null","description":"**Beta:** Saved avatar configuration for supported realtime browser conversations. `null` means that no avatar is configured.","uniqueKey":"avatar_settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"avatar_settings","typeLabel":"AvatarSettings · object | null"},"transcription":{"properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","speechmatics/standard","speechmatics/linden-1","azure/fast","assemblyai/universal-3-6-pro","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","telnyx/basira","distil-whisper/distil-large-v2","openai/whisper-large-v3-turbo"],"description":"The speech to text model to be used by the voice assistant. All Deepgram models are run on-premise.\n\n- `deepgram/flux` is optimized for turn-taking with multilingual language hints.\n- `deepgram/nova-3` is multilingual with automatic language detection.\n- `deepgram/nova-2` is Deepgram's previous-generation multilingual model.\n- `speechmatics/standard` is a Speechmatics model self-hosted by Telnyx; it supports a fixed set of language packs (including bilingual packs such as `ar_en`) and defaults to `en`.\n- `speechmatics/linden-1` (preview) is a vendor-hosted streaming model with no auto-detect; set `language` from Speechmatics' Realtime language list (defaults to `en`).\n- `azure/fast` is a multilingual Azure transcription model.\n- `assemblyai/universal-3-6-pro` (AssemblyAI Universal-3.6 Pro) is a multilingual streaming model with configurable turn detection. The legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming` are still accepted and run the same model.\n- `xai/grok-stt` is a multilingual Grok STT model.\n- `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`.\n- `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection.\n- `omi-health/omi-med-stt-v1` is an English-only medical transcription model (Parakeet-based).\n- `humain/realtime` is a streaming model with native Arabic and Arabic/English code-switching support.\n- `reson8/turns` is a turn-based streaming model covering 10 European languages with automatic language detection.\n- `cohere/ar-stt` is a non-streaming Arabic and English transcription model.\n- `telnyx/basira` is a non-streaming Arabic transcription model.","uniqueKey":"transcription.model","typeLabel":"enum\u003cstring>"},"language":{"type":"string","description":"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. For `speechmatics/linden-1`, there is no auto-detect; set a code from Speechmatics' Realtime language list (67 language codes, including `es-bilingual-en` for Spanish and English bilingual, and the spelling and script variants `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant`; `en` alone uses the default spelling); unset defaults to `en`, while an explicit `auto`, `auto_beta`, or `multi` is rejected with a 400.","uniqueKey":"transcription.language","typeLabel":"string"},"api_key_ref":{"title":"Api Key Ref","type":"string","description":"Integration secret identifier for the transcription provider API key. Currently used for Azure transcription regions that require a customer-provided API key.","uniqueKey":"transcription.api_key_ref","typeLabel":"string"},"region":{"title":"Region","type":"string","description":"Region on third party cloud providers (currently Azure) if using one of their models. Some regions require `api_key_ref`.","uniqueKey":"transcription.region","typeLabel":"string"},"settings":{"properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"transcription.settings.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"transcription.settings.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"transcription.settings.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"transcription.settings.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"transcription.settings.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"transcription.settings.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"transcription.settings.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"transcription.settings.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"transcription.settings.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"transcription.settings.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"transcription.settings.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"transcription.settings.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"transcription.settings.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"transcription.settings.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"transcription.settings.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"transcription.settings.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"transcription.settings.language_hints","typeLabel":"string[]"}},"type":"object","title":"TranscriptionSettingsConfig","uniqueKey":"transcription.settings","typeLabel":"TranscriptionSettingsConfig · object"},"fallback_models":{"oneOf":[{"type":"array","items":{"title":"TranscriptionFallbackModel","description":"A streaming speech-to-text model that takes over transcription when the model in use fails.","type":"object","properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","assemblyai/universal-3-6-pro","assemblyai/universal-3-5-pro","assemblyai/universal-streaming","xai/grok-stt","soniox/stt-rt-v4","soniox/stt-rt-v5","humain/realtime","reson8/turns"],"description":"The fallback model. It must be a streaming model other than `transcription.model` and the other fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` (or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or `reson8/turns`.","isRequired":true,"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].model","typeLabel":"enum\u003cstring>"},"language":{"oneOf":[{"type":"string","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].language.oneOf.0","typeLabel":"string"},{"type":"null","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].language.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].language","typeLabel":"string | null"},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.language_hints","typeLabel":"string[]"}},"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0","typeLabel":"TranscriptionSettingsConfig · object"},{"type":"null","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX].settings","typeLabel":"TranscriptionSettingsConfig · object | null"}},"required":["model"],"example":{"model":"deepgram/nova-3","language":"en","settings":{"keyterm":"Telnyx,VoIP,SIP"}},"uniqueKey":"transcription.fallback_models.oneOf.0.items.[INDEX]","typeLabel":"TranscriptionFallbackModel · object"},"maxItems":3,"description":"Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a streaming model too, and must support `language` alongside other models. On update, a list replaces the stored one: omit the field to keep the stored list, or send `null` or `[]` to remove it. When an update changes `model` or `language`, stored fallbacks that no longer fit are removed without an error. Can't be combined with `challenger`, the language booster; to replace a stored language booster, send `challenger: null` in the same request.","example":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"uniqueKey":"transcription.fallback_models.oneOf.0","typeLabel":"TranscriptionFallbackModel · object[]"},{"type":"null","items":{"title":"TranscriptionFallbackModel","description":"A streaming speech-to-text model that takes over transcription when the model in use fails.","type":"object","properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","assemblyai/universal-3-6-pro","assemblyai/universal-3-5-pro","assemblyai/universal-streaming","xai/grok-stt","soniox/stt-rt-v4","soniox/stt-rt-v5","humain/realtime","reson8/turns"],"description":"The fallback model. It must be a streaming model other than `transcription.model` and the other fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` (or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or `reson8/turns`."},"language":{"oneOf":[{"type":"string","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run."},{"type":"null","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run."}]},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean"},"numerals":{"title":"Numerals","type":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript."},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead."},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters."},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and 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":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn."},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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":{"title":"Context","type":"string","maxLength":10000,"description":"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":{"title":"Language Hints","type":"array","items":{"type":"string"},"description":"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`."}}},{"type":"null","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model."}]}},"required":["model"],"example":{"model":"deepgram/nova-3","language":"en","settings":{"keyterm":"Telnyx,VoIP,SIP"}}},"maxItems":3,"description":"Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a streaming model too, and must support `language` alongside other models. On update, a list replaces the stored one: omit the field to keep the stored list, or send `null` or `[]` to remove it. When an update changes `model` or `language`, stored fallbacks that no longer fit are removed without an error. Can't be combined with `challenger`, the language booster; to replace a stored language booster, send `challenger: null` in the same request.","example":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"uniqueKey":"transcription.fallback_models.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.fallback_models","typeLabel":"TranscriptionFallbackModel · object[] | null"},"challenger":{"oneOf":[{"type":"object","title":"TranscriptionChallenger","description":"The language booster: a second model that transcribes alongside `model`, and the rule that decides which transcript the assistant uses. Both models must be streaming, or both non-streaming, and, except with `merge_words`, `model` must support `language` alongside another model (for example, `cohere/ar-stt` supports only `ar` there). If the language booster can't run, the call runs on `model` alone; if either model fails mid-call, the call continues on the other. On update, omit the field to keep the stored language booster, or send `null` to remove it. When an update changes `model` or `language` and the stored language booster no longer fits, it is removed without an error. Can't be combined with `fallback_models`; to replace stored fallbacks, send `fallback_models: []` in the same request.","required":["model"],"example":{"model":"deepgram/nova-3","language":"en","rule":"best_turn"},"properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","azure/fast","assemblyai/universal-3-6-pro","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","telnyx/basira","distil-whisper/distil-large-v2","openai/whisper-large-v3-turbo"],"description":"The language booster's model. It must be the same kind of model as `transcription.model`: both streaming (`deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`, `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, `reson8/turns`) or both non-streaming (`azure/fast`, `nvidia/parakeet-v3`, `omi-health/omi-med-stt-v1`, `cohere/ar-stt`, `distil-whisper/distil-large-v2`, `openai/whisper-large-v3-turbo`, `telnyx/basira`). It can be the same model as `transcription.model` on a different `language`.","isRequired":true,"uniqueKey":"transcription.challenger.oneOf.0.model","typeLabel":"enum\u003cstring>"},"language":{"oneOf":[{"type":"string","description":"The language this model transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when this model doesn't support the language it would run. It is also rejected when it would run the same model on the same language as `transcription.model`.","uniqueKey":"transcription.challenger.oneOf.0.language.oneOf.0","typeLabel":"string"},{"type":"null","description":"The language this model transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when this model doesn't support the language it would run. It is also rejected when it would run the same model on the same language as `transcription.model`.","uniqueKey":"transcription.challenger.oneOf.0.language.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.challenger.oneOf.0.language","typeLabel":"string | null"},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the language booster, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0.language_hints","typeLabel":"string[]"}},"uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.0","typeLabel":"TranscriptionSettingsConfig · object"},{"type":"null","description":"Settings for the language booster, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","uniqueKey":"transcription.challenger.oneOf.0.settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.challenger.oneOf.0.settings","typeLabel":"TranscriptionSettingsConfig · object | null"},"rule":{"type":"string","enum":["best_turn","best_engine","merge_words"],"default":"best_turn","description":"How the assistant picks the transcript it uses. The models are compared on how complete and confident their transcripts are, not on language, so the rules work best when both models understand the callers' language.\n\n- `best_turn` (default): both models transcribe the whole call. Each turn uses the language booster's transcript only when it scores higher than the transcript of `transcription.model` (clearly higher with non-streaming models). With streaming models, `transcription.model` also decides when each turn ends. Available for every pair.\n- `best_engine`: both models transcribe the first turns, then the call continues alone on the model whose transcripts scored higher. If neither clearly leads, `transcription.model` continues. Streaming models only.\n- `merge_words`: both models transcribe each utterance and their words are merged, keeping Arabic and English spoken in the same sentence. Available only for `telnyx/basira` with `cohere/ar-stt`, in either order. The pair runs on the language that applies to `telnyx/basira` (its own, or that of `transcription.model`), which must be Arabic (`ar` or an `ar-` locale), `multi`, or `auto`.","uniqueKey":"transcription.challenger.oneOf.0.rule","typeLabel":"enum\u003cstring>"}},"uniqueKey":"transcription.challenger.oneOf.0","typeLabel":"TranscriptionChallenger · object"},{"type":"null","description":"The language booster: a second model that transcribes alongside `model`, and the rule that decides which transcript the assistant uses. Both models must be streaming, or both non-streaming, and, except with `merge_words`, `model` must support `language` alongside another model (for example, `cohere/ar-stt` supports only `ar` there). If the language booster can't run, the call runs on `model` alone; if either model fails mid-call, the call continues on the other. On update, omit the field to keep the stored language booster, or send `null` to remove it. When an update changes `model` or `language` and the stored language booster no longer fits, it is removed without an error. Can't be combined with `fallback_models`; to replace stored fallbacks, send `fallback_models: []` in the same request.","uniqueKey":"transcription.challenger.oneOf.1","typeLabel":"null"}],"uniqueKey":"transcription.challenger","typeLabel":"TranscriptionChallenger · object | null"}},"type":"object","uniqueKey":"transcription","typeLabel":"object"},"telephony_settings":{"properties":{"default_texml_app_id":{"type":"string","description":"Default Texml App used for voice calls with your assistant. This will be created automatically on assistant creation.","uniqueKey":"telephony_settings.default_texml_app_id","typeLabel":"string"},"supports_unauthenticated_web_calls":{"type":"boolean","description":"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.","uniqueKey":"telephony_settings.supports_unauthenticated_web_calls","typeLabel":"boolean"},"noise_suppression":{"type":"string","enum":["aicoustics","krisp","deepfilternet","disabled"],"description":"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.","uniqueKey":"telephony_settings.noise_suppression","typeLabel":"enum\u003cstring>"},"noise_suppression_config":{"type":"object","description":"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'.","properties":{"attenuation_limit":{"type":"integer","minimum":0,"maximum":100,"default":100,"description":"Attenuation limit for noise suppression. Range: 0-100. Only applicable when noise_suppression is 'deepfilternet'.","uniqueKey":"telephony_settings.noise_suppression_config.attenuation_limit","typeLabel":"integer"},"mode":{"type":"string","enum":["advanced"],"description":"Mode for noise suppression configuration. Only applicable when noise_suppression is 'deepfilternet'.","uniqueKey":"telephony_settings.noise_suppression_config.mode","typeLabel":"enum\u003cstring>"},"family":{"type":"string","enum":["quail"],"description":"AiCoustics model family optimized for Voice AI and STT. Only applicable when noise_suppression is 'aicoustics'.","uniqueKey":"telephony_settings.noise_suppression_config.family","typeLabel":"enum\u003cstring>"},"size":{"type":"string","enum":["vf","vf_2_0_l"],"description":"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'.","uniqueKey":"telephony_settings.noise_suppression_config.size","typeLabel":"enum\u003cstring>"},"enhancement_level":{"type":"number","minimum":0,"maximum":1,"default":0.8,"description":"AiCoustics enhancement intensity. Range: 0-1. Only applicable when noise_suppression is 'aicoustics'.","uniqueKey":"telephony_settings.noise_suppression_config.enhancement_level","typeLabel":"number"}},"uniqueKey":"telephony_settings.noise_suppression_config","typeLabel":"object"},"time_limit_secs":{"type":"integer","minimum":30,"maximum":14400,"default":1800,"description":"Maximum duration in seconds for the AI assistant to participate on the call. When this limit is reached the assistant will be stopped. Stopping the assistant does not itself hang up the call, and what happens next depends on how the assistant is running. On Call Control (ai_assistant_start) the call leg stays connected and continues to be billed until it is hung up (for example with the Hangup call command) or until the call ends for another reason. On TeXML, the assistant's `\u003cConnect>\u003cAIAssistant>` instruction ends; in the default TeXML setup for assistants no instructions follow it, so the call is hung up. Your application receives a call.conversation.ended webhook when the assistant stops. This limit does not apply to portions of a call without an active assistant (for instance, a call transferred to a human representative).","uniqueKey":"telephony_settings.time_limit_secs","typeLabel":"integer"},"user_idle_timeout_secs":{"type":"integer","minimum":10,"maximum":14400,"description":"Maximum duration in seconds of end user silence on the call. When this limit is reached the assistant will be stopped. Stopping the assistant does not itself hang up the call, and what happens next depends on how the assistant is running. On Call Control (ai_assistant_start) the call leg stays connected and continues to be billed until it is hung up (for example with the Hangup call command) or until the call ends for another reason. On TeXML, the assistant's `\u003cConnect>\u003cAIAssistant>` instruction ends; in the default TeXML setup for assistants no instructions follow it, so the call is hung up. Your application receives a call.conversation.ended webhook when the assistant stops. This limit does not apply to portions of a call without an active assistant (for instance, a call transferred to a human representative).","uniqueKey":"telephony_settings.user_idle_timeout_secs","typeLabel":"integer"},"user_idle_reply_secs":{"type":"integer","minimum":0,"default":10,"description":"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.","uniqueKey":"telephony_settings.user_idle_reply_secs","typeLabel":"integer"},"fallback_destination":{"type":"string","description":"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.","uniqueKey":"telephony_settings.fallback_destination","typeLabel":"string"},"send_message_history_updates":{"type":"boolean","description":"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.","uniqueKey":"telephony_settings.send_message_history_updates","typeLabel":"boolean"},"conversation_ended_full_history":{"type":"boolean","default":false,"description":"When enabled, the `messages` array of the `call.conversation.ended` webhook contains the full conversation history in order: user and assistant turns, assistant tool calls (`tool_calls`), tool results (`role: tool` with `tool_call_id`), and informational `system` and `developer` entries. The assistant's instructions are never included. When disabled, `messages` contains only user and assistant text turns.","uniqueKey":"telephony_settings.conversation_ended_full_history","typeLabel":"boolean"},"greeting_delay_ms":{"oneOf":[{"type":"integer","minimum":0,"maximum":2000,"description":"Milliseconds to wait after an inbound call is answered before the assistant starts and speaks its greeting. Increase it if the beginning of the greeting is cut off on some connections (for example, WebRTC calls). When unset (`null`), the platform default of 250 ms is used. Set to `0` to start without a delay. Maximum 2000.","uniqueKey":"telephony_settings.greeting_delay_ms.oneOf.0","typeLabel":"integer"},{"type":"null","minimum":0,"maximum":2000,"description":"Milliseconds to wait after an inbound call is answered before the assistant starts and speaks its greeting. Increase it if the beginning of the greeting is cut off on some connections (for example, WebRTC calls). When unset (`null`), the platform default of 250 ms is used. Set to `0` to start without a delay. Maximum 2000.","uniqueKey":"telephony_settings.greeting_delay_ms.oneOf.1","typeLabel":"null"}],"uniqueKey":"telephony_settings.greeting_delay_ms","typeLabel":"integer | null"},"voicemail_detection":{"type":"object","description":"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.","properties":{"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected.","properties":{"action":{"type":"string","enum":["stop_assistant","leave_message_and_stop_assistant","continue_assistant"],"description":"The action to take when voicemail is detected.","uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"},"voicemail_message":{"type":"object","description":"Configuration for the voicemail message to leave. Only applicable when action is 'leave_message_and_stop_assistant'.","properties":{"type":{"type":"string","enum":["prompt","message"],"description":"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.","uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.voicemail_message.type","typeLabel":"enum\u003cstring>"},"prompt":{"type":"string","description":"The prompt to use for generating the voicemail message. Only applicable when type is 'prompt'.","uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.voicemail_message.prompt","typeLabel":"string"},"message":{"type":"string","description":"The specific message to leave as voicemail. Only applicable when type is 'message'.","uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.voicemail_message.message","typeLabel":"string"}},"uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected.voicemail_message","typeLabel":"object"}},"uniqueKey":"telephony_settings.voicemail_detection.on_voicemail_detected","typeLabel":"object"}},"uniqueKey":"telephony_settings.voicemail_detection","typeLabel":"object"},"disable_dtmf":{"type":"boolean","default":false,"description":"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.","uniqueKey":"telephony_settings.disable_dtmf","typeLabel":"boolean"},"recording_settings":{"type":"object","description":"Configuration for call recording format and channel settings.","properties":{"enabled":{"type":"boolean","default":true,"description":"Whether call recording is enabled. When set to false, calls will not be recorded regardless of other recording configuration.","uniqueKey":"telephony_settings.recording_settings.enabled","typeLabel":"boolean"},"channels":{"type":"string","enum":["single","dual"],"default":"dual","description":"The number of channels for the recording. 'single' for mono, 'dual' for stereo.","uniqueKey":"telephony_settings.recording_settings.channels","typeLabel":"enum\u003cstring>"},"format":{"type":"string","enum":["wav","mp3"],"default":"mp3","description":"The format of the recording file.","uniqueKey":"telephony_settings.recording_settings.format","typeLabel":"enum\u003cstring>"},"stop_on_conversation_end":{"type":"boolean","default":false,"description":"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.","uniqueKey":"telephony_settings.recording_settings.stop_on_conversation_end","typeLabel":"boolean"}},"uniqueKey":"telephony_settings.recording_settings","typeLabel":"object"}},"type":"object","title":"TelephonySettings","uniqueKey":"telephony_settings","typeLabel":"TelephonySettings · object"},"messaging_settings":{"properties":{"default_messaging_profile_id":{"type":"string","description":"Default Messaging Profile used for messaging exchanges with your assistant. This will be created automatically on assistant creation.","uniqueKey":"messaging_settings.default_messaging_profile_id","typeLabel":"string"},"delivery_status_webhook_url":{"type":"string","description":"The URL where webhooks related to delivery statused for assistant messages will be sent.","uniqueKey":"messaging_settings.delivery_status_webhook_url","typeLabel":"string"},"conversation_inactivity_minutes":{"type":"integer","minimum":1,"maximum":10000000,"description":"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.","uniqueKey":"messaging_settings.conversation_inactivity_minutes","typeLabel":"integer"}},"type":"object","uniqueKey":"messaging_settings","typeLabel":"object"},"enabled_features":{"items":{"type":"string","enum":["telephony","messaging"],"description":"If `telephony` is enabled, the assistant will be able to make and receive calls. If `messaging` is enabled, the assistant will be able to send and receive messages.","uniqueKey":"enabled_features.items.[INDEX]","typeLabel":"enum\u003cstring>"},"type":"array","uniqueItems":true,"title":"Enabled Features","uniqueKey":"enabled_features","typeLabel":"enum\u003cstring>[]"},"insight_settings":{"properties":{"insight_group_id":{"type":"string","description":"Reference to an Insight Group. Insights in this group will be run automatically for all the assistant's conversations.","uniqueKey":"insight_settings.insight_group_id","typeLabel":"string"},"model":{"oneOf":[{"type":"string","description":"The model that generates the assistant's insights when a conversation ends. It runs every insight in the group, Telnyx-managed insights included. Must be `zai-org/GLM-5.3-Flash` or `meta-llama/Llama-3.3-70B-Instruct`; any other model returns `422`. When omitted on create, it defaults to `zai-org/GLM-5.3-Flash`; when omitted on update, the current model is kept. `null` uses Telnyx's default insight models, which assistants created before this setting have. Insights of messaging conversations, and insights regenerated later, always use Telnyx's default insight models.","example":"zai-org/GLM-5.3-Flash","uniqueKey":"insight_settings.model.oneOf.0","typeLabel":"string"},{"type":"null","description":"The model that generates the assistant's insights when a conversation ends. It runs every insight in the group, Telnyx-managed insights included. Must be `zai-org/GLM-5.3-Flash` or `meta-llama/Llama-3.3-70B-Instruct`; any other model returns `422`. When omitted on create, it defaults to `zai-org/GLM-5.3-Flash`; when omitted on update, the current model is kept. `null` uses Telnyx's default insight models, which assistants created before this setting have. Insights of messaging conversations, and insights regenerated later, always use Telnyx's default insight models.","example":"zai-org/GLM-5.3-Flash","uniqueKey":"insight_settings.model.oneOf.1","typeLabel":"null"}],"uniqueKey":"insight_settings.model","typeLabel":"string | null"}},"type":"object","uniqueKey":"insight_settings","typeLabel":"object"},"privacy_settings":{"properties":{"data_retention":{"type":"boolean","description":"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.","uniqueKey":"privacy_settings.data_retention","typeLabel":"boolean"},"pii_redaction":{"type":"string","enum":["disabled","redact"],"default":"disabled","description":"Controls redaction of personally identifiable information (PII) from the conversation history that is stored for this assistant. `disabled` (default) stores content as-is. `redact` replaces detected PII with `\u003cPII:type/>` placeholders (e.g. `\u003cPII:name/>`, `\u003cPII:phone/>`) as the stored copies are written: message content (user, assistant, and tool-result messages) and tool-call arguments are redacted when written to conversation history, so the stored transcript, its read-back via the history API, and any insights generated from the stored messages contain the placeholders instead of the PII; response bodies returned by webhook tools are redacted too, as stored in the webhook logs — a per-conversation record separate from the transcript. In the Mission Control Portal this field appears as a \"PII Redaction\" on/off toggle, where Enabled corresponds to `redact`. Redaction runs when the stored copy is written, after the LLM has generated its reply: the live conversation is not redacted, the assistant's tools keep receiving the full (unredacted) values during the call, and the LLM still sees full content in its context window. Call recordings (including any recording layout configured under telephony settings) and the payloads of messages/webhooks delivered during the call are never redacted by this setting. The set of detected PII types (names, street addresses, phone numbers, email addresses, government identifiers like SSN and driver's license numbers, credit card and bank account numbers, IP addresses, dates of birth, and other identifiers unique to a person) is fixed by Telnyx and cannot be configured or extended per assistant. Assistants with `redact` cannot be used for SMS/WhatsApp messaging (that combination is rejected with a 400 error); voice and web chat are unaffected.","uniqueKey":"privacy_settings.pii_redaction","typeLabel":"enum\u003cstring>"},"in_transit_data_locality":{"type":"boolean","default":false,"description":"Requires this assistant's conversations to be processed inside your organization's data-locality region, rather than only stored there, on every channel: for web chat, every model call of a turn; for voice, the call's model calls and the Telnyx-hosted speech services it uses; for SMS and WhatsApp, the model calls of each turn (how messages travel through carriers is not covered). Covered processing that cannot be handled in region fails rather than being served elsewhere. 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)), Telnyx-hosted models for the assistant, its fallback, and any conversation-flow node that overrides the model, and, when `insight_settings.model` is set, an insight model available in that region; the request is rejected otherwise. A voice call fails when it starts if its STT model or TTS voice is not self-hosted by Telnyx, if the assistant uses a speech-to-speech model, or if the call's media is anchored outside the region. Once enabled, send web chat requests and WebSocket or WebRTC conversations to your region's API hostname: one entering the platform in another region is refused rather than forwarded, because forwarding it would already have moved the content across the border. See [Data residency](https://developers.telnyx.com/docs/inference/data-residency#in-region-processing-for-ai-assistants). Defaults to false.","uniqueKey":"privacy_settings.in_transit_data_locality","typeLabel":"boolean"}},"type":"object","uniqueKey":"privacy_settings","typeLabel":"object"},"dynamic_variables_webhook_url":{"type":"string","description":"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.","uniqueKey":"dynamic_variables_webhook_url","typeLabel":"string"},"dynamic_variables_webhook_timeout_ms":{"type":"integer","minimum":1,"maximum":10000,"default":1500,"description":"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).","uniqueKey":"dynamic_variables_webhook_timeout_ms","typeLabel":"integer"},"dynamic_variables":{"type":"object","description":"Map of dynamic variables and their values","additionalProperties":true,"uniqueKey":"dynamic_variables","typeLabel":"object"},"import_metadata":{"properties":{"import_provider":{"type":"string","enum":["elevenlabs","vapi","retell"],"description":"Provider the assistant was imported from.","uniqueKey":"import_metadata.import_provider","typeLabel":"enum\u003cstring>"},"import_id":{"type":"string","description":"ID of the assistant in the provider's system.","uniqueKey":"import_metadata.import_id","typeLabel":"string"}},"type":"object","uniqueKey":"import_metadata","typeLabel":"object"},"widget_settings":{"type":"object","properties":{"theme":{"type":"string","enum":["light","dark"],"description":"The visual theme for the widget.","uniqueKey":"widget_settings.theme","typeLabel":"enum\u003cstring>"},"audio_visualizer_config":{"type":"object","properties":{"color":{"type":"string","enum":["verdant","twilight","bloom","mystic","flare","glacier"],"description":"The color theme for the audio visualizer.","uniqueKey":"widget_settings.audio_visualizer_config.color","typeLabel":"enum\u003cstring>"},"preset":{"type":"string","description":"The preset style for the audio visualizer.","uniqueKey":"widget_settings.audio_visualizer_config.preset","typeLabel":"string"}},"title":"AudioVisualizerConfig","uniqueKey":"widget_settings.audio_visualizer_config","typeLabel":"AudioVisualizerConfig · object"},"start_call_text":{"type":"string","description":"Custom text displayed on the start call button.","uniqueKey":"widget_settings.start_call_text","typeLabel":"string"},"default_state":{"type":"string","enum":["expanded","collapsed"],"description":"The default state of the widget.","uniqueKey":"widget_settings.default_state","typeLabel":"enum\u003cstring>"},"position":{"type":"string","enum":["fixed","static"],"description":"The positioning style for the widget.","uniqueKey":"widget_settings.position","typeLabel":"enum\u003cstring>"},"view_history_url":{"oneOf":[{"type":"string","description":"URL to view conversation history.","uniqueKey":"widget_settings.view_history_url.oneOf.0","typeLabel":"string"},{"type":"null","description":"URL to view conversation history.","uniqueKey":"widget_settings.view_history_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"widget_settings.view_history_url","typeLabel":"string | null"},"report_issue_url":{"oneOf":[{"type":"string","description":"URL for users to report issues.","uniqueKey":"widget_settings.report_issue_url.oneOf.0","typeLabel":"string"},{"type":"null","description":"URL for users to report issues.","uniqueKey":"widget_settings.report_issue_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"widget_settings.report_issue_url","typeLabel":"string | null"},"give_feedback_url":{"oneOf":[{"type":"string","description":"URL for users to give feedback.","uniqueKey":"widget_settings.give_feedback_url.oneOf.0","typeLabel":"string"},{"type":"null","description":"URL for users to give feedback.","uniqueKey":"widget_settings.give_feedback_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"widget_settings.give_feedback_url","typeLabel":"string | null"},"agent_thinking_text":{"type":"string","description":"Text displayed while the agent is processing.","uniqueKey":"widget_settings.agent_thinking_text","typeLabel":"string"},"speak_to_interrupt_text":{"type":"string","description":"Text prompting users to speak to interrupt.","uniqueKey":"widget_settings.speak_to_interrupt_text","typeLabel":"string"},"logo_icon_url":{"oneOf":[{"type":"string","description":"URL to a custom logo icon for the widget.","uniqueKey":"widget_settings.logo_icon_url.oneOf.0","typeLabel":"string"},{"type":"null","description":"URL to a custom logo icon for the widget.","uniqueKey":"widget_settings.logo_icon_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"widget_settings.logo_icon_url","typeLabel":"string | null"}},"title":"WidgetSettings","description":"Configuration settings for the assistant's web widget.","uniqueKey":"widget_settings","typeLabel":"WidgetSettings · object"},"interruption_settings":{"type":"object","title":"InterruptionSettings","description":"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`).","properties":{"enable":{"type":"boolean","default":true,"description":"Whether users can interrupt the assistant while it is speaking.","uniqueKey":"interruption_settings.enable","typeLabel":"boolean"},"disable_greeting_interruption":{"type":"boolean","description":"When true, disables user interruptions while the assistant greeting is playing.","uniqueKey":"interruption_settings.disable_greeting_interruption","typeLabel":"boolean"},"start_speaking_plan":{"oneOf":[{"type":"object","title":"StartSpeakingPlan","description":"Presence of this object (even `{}`) enables per-turn transcript endpointing while it is set; setting it to `null` clears the plan and disables per-turn matching entirely. Omitting it from an update leaves the existing plan in place (updates are validated against the merged configuration).","properties":{"wait_seconds":{"type":"number","format":"float","default":0.4,"minimum":0,"description":"Wait used when per-turn endpointing does not select a tier. While the plan is present this applies on every turn without a matching tier (including when `transcription_endpointing_plan` is unset); a matching tier replaces it for that turn, and a tier may be shorter or longer than this value.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.wait_seconds","typeLabel":"number\u003cfloat>"},"transcription_endpointing_plan":{"oneOf":[{"type":"object","title":"TranscriptionEndpointingPlan","description":"Omit (stay null) when unset: the per-turn wait stays on `wait_seconds`. Setting `null` on an update clears a previously configured plan.","properties":{"on_punctuation_seconds":{"type":"number","format":"float","default":0.1,"description":"Seconds to wait after the transcript ends with punctuation.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.0.on_punctuation_seconds","typeLabel":"number\u003cfloat>"},"on_no_punctuation_seconds":{"type":"number","format":"float","default":1.5,"description":"Seconds to wait after the transcript ends without punctuation.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.0.on_no_punctuation_seconds","typeLabel":"number\u003cfloat>"},"on_number_seconds":{"type":"number","format":"float","default":0.5,"description":"Seconds to wait after the transcript ends with a number.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.0.on_number_seconds","typeLabel":"number\u003cfloat>"}},"uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.0","typeLabel":"TranscriptionEndpointingPlan · object"},{"type":"null","description":"Omit (stay null) when unset: the per-turn wait stays on `wait_seconds`. Setting `null` on an update clears a previously configured plan.","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan.oneOf.1","typeLabel":"null"}],"uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0.transcription_endpointing_plan","typeLabel":"TranscriptionEndpointingPlan · object | null"}},"uniqueKey":"interruption_settings.start_speaking_plan.oneOf.0","typeLabel":"StartSpeakingPlan · object"},{"type":"null","description":"Presence of this object (even `{}`) enables per-turn transcript endpointing while it is set; setting it to `null` clears the plan and disables per-turn matching entirely. Omitting it from an update leaves the existing plan in place (updates are validated against the merged configuration).","uniqueKey":"interruption_settings.start_speaking_plan.oneOf.1","typeLabel":"null"}],"uniqueKey":"interruption_settings.start_speaking_plan","typeLabel":"StartSpeakingPlan · object | null"},"interrupt_prediction_threshold":{"oneOf":[{"type":"number","default":0,"minimum":0,"maximum":1,"description":"Interrupt-prediction sensitivity, from 0.0 to 1.0. Set to null or 0.0 to disable interrupt prediction.","uniqueKey":"interruption_settings.interrupt_prediction_threshold.oneOf.0","typeLabel":"number"},{"type":"null","default":0,"minimum":0,"maximum":1,"description":"Interrupt-prediction sensitivity, from 0.0 to 1.0. Set to null or 0.0 to disable interrupt prediction.","uniqueKey":"interruption_settings.interrupt_prediction_threshold.oneOf.1","typeLabel":"null"}],"uniqueKey":"interruption_settings.interrupt_prediction_threshold","typeLabel":"number | null"}},"uniqueKey":"interruption_settings","typeLabel":"InterruptionSettings · object"},"integrations":{"type":"array","items":{"type":"object","title":"AssistantIntegration","description":"Reference to a connected integration attached to an assistant. Discover available integrations with `/ai/integrations` and connected integrations with `/ai/integrations/connections`.","properties":{"integration_id":{"type":"string","description":"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`.","isRequired":true,"uniqueKey":"integrations.items.[INDEX].integration_id","typeLabel":"string"},"allowed_list":{"type":"array","items":{"type":"string","uniqueKey":"integrations.items.[INDEX].allowed_list.items.[INDEX]","typeLabel":"string"},"description":"Optional per-assistant allowlist of integration tool names. When omitted or empty, all tools allowed by the connected integration are available to the assistant.","uniqueKey":"integrations.items.[INDEX].allowed_list","typeLabel":"string[]"}},"required":["integration_id"],"uniqueKey":"integrations.items.[INDEX]","typeLabel":"AssistantIntegration · object"},"default":[],"description":"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`.","uniqueKey":"integrations","typeLabel":"AssistantIntegration · object[]"},"observability_settings":{"properties":{"status":{"type":"string","enum":["enabled","disabled"],"title":"ObservabilityStatus","default":"disabled","uniqueKey":"observability_settings.status","typeLabel":"enum\u003cstring>"},"secret_key_ref":{"title":"Secret Key Ref","type":"string","uniqueKey":"observability_settings.secret_key_ref","typeLabel":"string"},"public_key_ref":{"title":"Public Key Ref","type":"string","uniqueKey":"observability_settings.public_key_ref","typeLabel":"string"},"host":{"title":"Host","type":"string","uniqueKey":"observability_settings.host","typeLabel":"string"},"prompt_name":{"title":"Prompt Name","type":"string","uniqueKey":"observability_settings.prompt_name","typeLabel":"string"},"prompt_version":{"title":"Prompt Version","type":"integer","minimum":1,"uniqueKey":"observability_settings.prompt_version","typeLabel":"integer"},"prompt_label":{"title":"Prompt Label","type":"string","uniqueKey":"observability_settings.prompt_label","typeLabel":"string"},"prompt_sync":{"type":"string","enum":["enabled","disabled"],"title":"PromptSyncStatus","description":"Whether to auto-publish the assistant's instructions as a Langfuse prompt.\n\nWhen ENABLED + prompt_name set, every assistant create/update pushes\n`instructions` to Langfuse via create_prompt and stores the returned\nversion in prompt_version.","default":"disabled","uniqueKey":"observability_settings.prompt_sync","typeLabel":"enum\u003cstring>"}},"type":"object","title":"Observability","uniqueKey":"observability_settings","typeLabel":"Observability · object"},"version_name":{"type":"string","maxLength":50,"default":"New assistant","description":"Human-readable name for the assistant version.","uniqueKey":"version_name","typeLabel":"string"},"related_mission_ids":{"type":"array","items":{"type":"string","uniqueKey":"related_mission_ids.items.[INDEX]","typeLabel":"string"},"default":[],"description":"IDs of missions related to this assistant.","uniqueKey":"related_mission_ids","typeLabel":"string[]"},"tags":{"type":"array","items":{"type":"string","uniqueKey":"tags.items.[INDEX]","typeLabel":"string"},"default":[],"description":"Tags associated with the assistant. Tags can also be managed with the assistant tag endpoints.","uniqueKey":"tags","typeLabel":"string[]"},"post_conversation_settings":{"type":"object","description":"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.","properties":{"enabled":{"type":"boolean","description":"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.","default":false,"uniqueKey":"post_conversation_settings.enabled","typeLabel":"boolean"}},"uniqueKey":"post_conversation_settings","typeLabel":"object"},"delegation_settings":{"type":"object","title":"DelegationSettings","description":"Splits the conversation between a frontend model that talks to the caller and a backend model that does the work. On the GPT-Live route the frontend model cannot call tools at all — when it needs something done it raises a delegation and waits. On the chat completion route the frontend keeps a single `delegate` tool that returns immediately, so the conversation carries on while the backend works. Either way the backend's answer is spoken as commentary or kept as silent context, depending on `speak_results`. Beta feature.","properties":{"enabled":{"type":"boolean","default":true,"description":"Whether the assistant delegates work to a backend model. Defaults to `true`: a GPT-Live assistant with delegation disabled can hold a conversation but can never look anything up or run a tool.","uniqueKey":"delegation_settings.enabled","typeLabel":"boolean"},"mode":{"type":"string","enum":["telnyx","client"],"default":"telnyx","description":"Who answers a delegation. `telnyx` runs the backend model on Telnyx with the assistant's own tools, MCP servers and observability. `client` relays the delegation to a server you host over the WebSocket configured in `websocket_settings`: Telnyx sends a `session.delegation.created` frame and waits for your `session.delegation.completed` answer. That answer is text only, since the socket offers no tool vocabulary. If no socket is connected the delegation is refused and the assistant tells the caller it cannot look things up right now. Defaults to `telnyx`.","uniqueKey":"delegation_settings.mode","typeLabel":"enum\u003cstring>"},"model":{"type":"string","description":"The backend model that answers delegations. Must be a model available for AI Assistants. When enabling `telnyx` delegation, explicitly set this field or `external_llm.model`; a configuration without either backend model is rejected. Only applies when `mode` is `telnyx`.","uniqueKey":"delegation_settings.model","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the backend model's API key. Required for models from providers other than Telnyx, OpenAI and Anthropic. A raw `api_key` is rejected rather than ignored, so that no plaintext credential is stored on the assistant.","uniqueKey":"delegation_settings.llm_api_key_ref","typeLabel":"string"},"instructions":{"type":"string","description":"Extra instructions for the backend model, in addition to the assistant's own. Use this for the business rules the backend needs and the talking model does not.","uniqueKey":"delegation_settings.instructions","typeLabel":"string"},"speak_results":{"type":"boolean","default":true,"description":"Whether the backend's answer is spoken to the caller. When `true` the result is appended as commentary and paraphrased aloud; when `false` it is kept as silent context that informs later answers without being read out. Defaults to `true`.","uniqueKey":"delegation_settings.speak_results","typeLabel":"boolean"},"external_llm":{"type":"object","title":"ExternalLLM","description":"Run the backend on your own OpenAI-compatible endpoint instead of a Telnyx-hosted model. As above, a raw `api_key` here is rejected — reference an integration secret with `external_llm.llm_api_key_ref` instead.","required":["model","base_url"],"properties":{"model":{"type":"string","description":"Model identifier to use with the external LLM endpoint.","isRequired":true,"uniqueKey":"delegation_settings.external_llm.model","typeLabel":"string"},"base_url":{"type":"string","description":"Base URL for the external LLM endpoint.","isRequired":true,"uniqueKey":"delegation_settings.external_llm.base_url","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the external LLM API key.","uniqueKey":"delegation_settings.external_llm.llm_api_key_ref","typeLabel":"string"},"authentication_method":{"type":"string","enum":["token","certificate"],"default":"token","description":"Authentication method used when connecting to the external LLM endpoint.","title":"AuthenticationMethod","uniqueKey":"delegation_settings.external_llm.authentication_method","typeLabel":"enum\u003cstring>"},"certificate_ref":{"type":"string","description":"Integration secret identifier for the client certificate used with certificate authentication.","uniqueKey":"delegation_settings.external_llm.certificate_ref","typeLabel":"string"},"token_retrieval_url":{"type":"string","description":"URL used to retrieve an access token when certificate authentication is enabled.","uniqueKey":"delegation_settings.external_llm.token_retrieval_url","typeLabel":"string"},"forward_metadata":{"type":"boolean","default":false,"description":"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.","uniqueKey":"delegation_settings.external_llm.forward_metadata","typeLabel":"boolean"},"extra_headers":{"oneOf":[{"type":"object","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"delegation_settings.external_llm.extra_headers.oneOf.0.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"delegation_settings.external_llm.extra_headers.oneOf.0","typeLabel":"object"},{"type":"null","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"delegation_settings.external_llm.extra_headers.oneOf.1.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"delegation_settings.external_llm.extra_headers.oneOf.1","typeLabel":"null"}],"uniqueKey":"delegation_settings.external_llm.extra_headers","typeLabel":"object | null"}},"uniqueKey":"delegation_settings.external_llm","typeLabel":"ExternalLLM · object"}},"uniqueKey":"delegation_settings","typeLabel":"DelegationSettings · object"},"websocket_settings":{"type":"object","title":"WebsocketSettings","description":"Streams conversation and telephony events to a WebSocket server you host, and accepts messages injected back into the conversation. Telnyx opens the connection as a client, once per conversation. Delivery is best effort throughout: while the connection is down events are dropped rather than queued, and no socket failure is ever allowed to affect the call. Beta feature.","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether Telnyx opens a WebSocket to `url` for each of this assistant's conversations. Defaults to `false`.","uniqueKey":"websocket_settings.enabled","typeLabel":"boolean"},"url":{"type":"string","description":"The `ws://` or `wss://` endpoint Telnyx connects to. Required when `enabled` is `true`. Must be externally reachable — localhost, private IP ranges and `.local` domains are rejected.","uniqueKey":"websocket_settings.url","typeLabel":"string"},"auth_ref":{"type":"string","description":"Integration secret identifier whose value Telnyx sends as an `Authorization: Bearer \u003cvalue>` header on the upgrade request. Resolved on every connection attempt, so a rotated secret is picked up by the next reconnect.","uniqueKey":"websocket_settings.auth_ref","typeLabel":"string"}},"uniqueKey":"websocket_settings","typeLabel":"WebsocketSettings · object"},"conversation_flow":{"description":"Conversation flow as returned by the API.","example":{"edges":[{"condition":{"prompt":"The caller is asking about a bill or charge.","type":"llm"},"id":"e_intake_to_billing","start_node_id":"n_intake","target":{"node_id":"n_billing","type":"node"}},{"condition":{"prompt":"The caller has explicitly asked for a human.","type":"llm"},"id":"e_intake_to_escalation_assistant","start_node_id":"n_intake","target":{"assistant_id":"assistant-human-handoff","position":{"x":600,"y":80},"type":"assistant","voice_mode":"distinct"}}],"nodes":[{"type":"prompt","id":"n_intake","instructions":"Greet the caller and ask what they're calling about.","name":"Intake","position":{"x":120,"y":80},"shared_tool_ids":["tool-faq-kb"]},{"type":"prompt","id":"n_billing","instructions":"Focus on billing questions. Look up the caller's latest invoice with the billing tool before answering.","instructions_mode":"append","model":"moonshotai/Kimi-K2.6","name":"Billing","position":{"x":420,"y":80},"shared_tool_ids":["tool-billing-lookup"],"tools_mode":"append"}],"start_node_id":"n_intake"},"properties":{"nodes":{"description":"All nodes in the flow.","items":{"oneOf":[{"type":"object","title":"FlowNode","description":"One step in a conversation flow, as returned by the API.","required":["id","instructions"],"properties":{"id":{"type":"string","title":"Id","description":"Caller-supplied unique identifier for this node within the flow.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.id","typeLabel":"string"},"instructions":{"description":"Prompt that drives the LLM while this node is active. Required.","title":"Instructions","type":"string","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.instructions","typeLabel":"string"},"external_llm":{"properties":{"model":{"type":"string","description":"Model identifier to use with the external LLM endpoint.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.model","typeLabel":"string"},"base_url":{"type":"string","description":"Base URL for the external LLM endpoint.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.base_url","typeLabel":"string"},"llm_api_key_ref":{"type":"string","description":"Integration secret identifier for the external LLM API key.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.llm_api_key_ref","typeLabel":"string"},"authentication_method":{"type":"string","enum":["token","certificate"],"default":"token","description":"Authentication method used when connecting to the external LLM endpoint.","title":"AuthenticationMethod","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.authentication_method","typeLabel":"enum\u003cstring>"},"certificate_ref":{"type":"string","description":"Integration secret identifier for the client certificate used with certificate authentication.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.certificate_ref","typeLabel":"string"},"token_retrieval_url":{"type":"string","description":"URL used to retrieve an access token when certificate authentication is enabled.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.token_retrieval_url","typeLabel":"string"},"forward_metadata":{"type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.forward_metadata","typeLabel":"boolean"},"extra_headers":{"oneOf":[{"type":"object","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers.oneOf.0.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers.oneOf.0","typeLabel":"object"},{"type":"null","maxProperties":32,"additionalProperties":{"type":"string","maxLength":4096,"pattern":"^(?:[!-~]|[!-~][ -~]*[!-~])?$","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers.oneOf.1.additionalProperties","typeLabel":"string"},"description":"Custom HTTP headers Telnyx sets on every request to the external LLM endpoint, in addition to the authentication header. Keys are header names, values are static strings. At most 32 headers. Reserved names are rejected: accept-encoding, authorization, connection, content-encoding, content-length, content-type, cookie, expect, host, keep-alive, proxy-authenticate, proxy-authorization, proxy-connection, set-cookie, te, trailer, transfer-encoding, upgrade, x-host-rewrite, x-request-id, x-trace-id, and any x-telnyx-* or x-stainless-* header; '_' counts as '-' when names are compared. Names must be valid HTTP header names (RFC 7230 token, at most 128 characters) and must not repeat (case-insensitive). Values must be printable ASCII, at most 4096 characters, with no leading or trailing whitespace. Values are stored as plain text and returned when the assistant is retrieved.","propertyNames":{"type":"string","pattern":"^(?!(?:[Aa][Cc][Cc][Ee][Pp][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt][-_][Tt][Yy][Pp][Ee]|[Cc][Oo][Oo][Kk][Ii][Ee]|[Ee][Xx][Pp][Ee][Cc][Tt]|[Hh][Oo][Ss][Tt]|[Kk][Ee][Ee][Pp][-_][Aa][Ll][Ii][Vv][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Ee][Nn][Tt][Ii][Cc][Aa][Tt][Ee]|[Pp][Rr][Oo][Xx][Yy][-_][Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Pp][Rr][Oo][Xx][Yy][-_][Cc][Oo][Nn][Nn][Ee][Cc][Tt][Ii][Oo][Nn]|[Ss][Ee][Tt][-_][Cc][Oo][Oo][Kk][Ii][Ee]|[Tt][Ee]|[Tt][Rr][Aa][Ii][Ll][Ee][Rr]|[Tt][Rr][Aa][Nn][Ss][Ff][Ee][Rr][-_][Ee][Nn][Cc][Oo][Dd][Ii][Nn][Gg]|[Uu][Pp][Gg][Rr][Aa][Dd][Ee]|[Xx][-_][Hh][Oo][Ss][Tt][-_][Rr][Ee][Ww][Rr][Ii][Tt][Ee]|[Xx][-_][Rr][Ee][Qq][Uu][Ee][Ss][Tt][-_][Ii][Dd]|[Xx][-_][Tt][Rr][Aa][Cc][Ee][-_][Ii][Dd])$|[Xx][-_][Tt][Ee][Ll][Nn][Yy][Xx][-_]|[Xx][-_][Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss][-_]|[-_]{4}[Ss][Tt][Aa][Ii][Nn][Ll][Ee][Ss][Ss])[!#$%\u0026'*+.^_`|~0-9A-Za-z-]{1,128}$"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm.extra_headers","typeLabel":"object | null"}},"type":"object","required":["model","base_url"],"title":"ExternalLLM","description":"Override for `Assistant.external_llm` while this node is active. Use this to route a node's turns to a different external LLM (different `model`, `base_url`, credentials). Part of the LLM bundle — see `model` for cascade semantics. Mutually exclusive with `model` on the node (a single LLM identity per node).","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.external_llm","typeLabel":"ExternalLLM · object"},"instructions_mode":{"default":"replace","description":"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.","enum":["replace","append"],"title":"Instructions Mode","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.instructions_mode","typeLabel":"enum\u003cstring>"},"llm_api_key_ref":{"description":"Override for `Assistant.llm_api_key_ref` while this node is active. Part of the LLM bundle — see `model` for cascade semantics.","title":"Llm Api Key Ref","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.llm_api_key_ref","typeLabel":"string"},"model":{"description":"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.","title":"Model","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.model","typeLabel":"string"},"name":{"title":"Name","description":"Optional human-readable label, displayed in authoring UIs.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.name","typeLabel":"string"},"position":{"description":"Optional canvas coordinates used by authoring UIs to lay out the graph. Ignored by the runtime; round-trips so frontends can persist graph layout across reloads.","properties":{"x":{"description":"Horizontal coordinate in the authoring canvas.","title":"X","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.position.x","typeLabel":"number"},"y":{"description":"Vertical coordinate in the authoring canvas.","title":"Y","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.position.y","typeLabel":"number"}},"required":["x","y"],"title":"NodePosition","type":"object","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.position","typeLabel":"NodePosition · object"},"shared_tool_ids":{"description":"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.","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.shared_tool_ids.items.[INDEX]","typeLabel":"string"},"title":"Shared Tool Ids","type":"array","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.shared_tool_ids","typeLabel":"string[]"},"tools":{"description":"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.","items":{"description":"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":"array","items":{"oneOf":[{"type":"object","title":"FunctionTool","required":["type","function"],"properties":{"type":{"type":"string","enum":["function"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"},"function":{"properties":{"name":{"type":"string","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.0.function.name","typeLabel":"string"},"description":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.0.function.description","typeLabel":"string"},"parameters":{"type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.0.function.parameters","typeLabel":"object"}},"type":"object","required":["name"],"title":"FunctionDefinition","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.0.function","typeLabel":"FunctionDefinition · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.0.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.0","typeLabel":"FunctionTool · object"},{"type":"object","title":"WebhookTool","required":["type","webhook"],"properties":{"type":{"type":"string","enum":["webhook"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"},"webhook":{"properties":{"name":{"type":"string","description":"The name of the tool.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.name","typeLabel":"string"},"description":{"type":"string","description":"The description of the tool.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.description","typeLabel":"string"},"url":{"description":"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.","type":"string","example":"https://example.com/api/v1/function","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.url","typeLabel":"string"},"method":{"description":"The HTTP method to be used when calling the external tool.","type":"string","enum":["GET","POST","PUT","DELETE","PATCH"],"default":"POST","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.method","typeLabel":"enum\u003cstring>"},"headers":{"description":"The headers to be sent to the external tool.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.headers","typeLabel":"object[]"},"body_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the body parameters.","type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.body_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the body parameters.","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.body_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.body_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.body_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"age":{"description":"The age of the customer.","type":"integer"},"location":{"description":"The location of the customer.","type":"string"}},"required":["age","location"],"type":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.body_parameters","typeLabel":"object"},"path_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the path parameters.","type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.path_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the path parameters.","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.path_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.path_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.path_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"id":{"description":"The id of the customer.","type":"string"}},"required":["id"],"type":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.path_parameters","typeLabel":"object"},"query_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the query parameters.","type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.query_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the query parameters.","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.query_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.query_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.query_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"page":{"description":"The page number.","type":"integer"}},"required":["page"],"type":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.query_parameters","typeLabel":"object"},"preset_body_fields":{"type":"object","additionalProperties":true,"description":"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.","example":{"account_id":"{{customer_id}}","source":"telnyx-assistant"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.preset_body_fields","typeLabel":"object"},"preset_query_params":{"type":"object","additionalProperties":true,"description":"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.","example":{"caller":"{{telnyx_end_user_target}}","channel":"voice"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.preset_query_params","typeLabel":"object"},"async":{"type":"boolean","default":false,"description":"If async, the assistant will move forward without waiting for your server to respond.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.async","typeLabel":"boolean"},"async_timeout_ms":{"type":"integer","minimum":1,"maximum":15000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.async_timeout_ms","typeLabel":"integer"},"store_fields_as_variables":{"type":"array","description":"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.","items":{"type":"object","required":["name","value_path"],"properties":{"name":{"type":"string","minLength":1,"description":"The name of the dynamic variable to store the extracted value in.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX].name","typeLabel":"string"},"value_path":{"type":"string","minLength":1,"description":"A dot-notation path to the value in the webhook response body (e.g. 'customer.name' or 'id').","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX].value_path","typeLabel":"string"}},"additionalProperties":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.store_fields_as_variables","typeLabel":"object[]"},"messages":{"type":"array","description":"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.","items":{"oneOf":[{"type":"object","title":"WebhookToolRequestStartMessage","required":["type","content"],"properties":{"type":{"type":"string","const":"request_start","description":"Speak the filler message immediately when the webhook request begins.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"An optional delay value. This value is ignored for `request_start` messages.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0","typeLabel":"WebhookToolRequestStartMessage · object"},{"type":"object","title":"WebhookToolRequestResponseDelayedMessage","required":["type","content","timing_ms"],"properties":{"type":{"type":"string","const":"request_response_delayed","description":"Speak the filler message after the configured delay if the webhook response is still pending.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"The delay in milliseconds from the start of the webhook request.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1","typeLabel":"WebhookToolRequestResponseDelayedMessage · object"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages.items.[INDEX]","typeLabel":"WebhookToolRequestStartMessage · object | WebhookToolRequestResponseDelayedMessage · object"},"example":[{"type":"request_start","content":"Let me look that up for you."},{"type":"request_response_delayed","content":"Still working on that.","timing_ms":5000}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook.messages","typeLabel":"(WebhookToolRequestStartMessage · object | WebhookToolRequestResponseDelayedMessage · object)[]"}},"type":"object","required":["url","name","description"],"title":"WebhookToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.webhook","typeLabel":"WebhookToolParams · object"},"timeout_ms":{"type":"integer","default":5000,"maximum":60000,"description":"The maximum number of milliseconds to wait for the webhook to respond before the tool call is aborted. Set this at the tool level, as a sibling of `type` — a `timeout_ms` nested inside the `webhook` object is stored but not applied, and the tool runs at this default instead. Applies when `webhook.async` is false.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.timeout_ms","typeLabel":"integer"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.1","typeLabel":"WebhookTool · object"},{"type":"object","title":"ClientSideTool","required":["type","client_side_tool"],"properties":{"type":{"type":"string","enum":["client_side_tool"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.type","typeLabel":"enum\u003cstring>"},"client_side_tool":{"title":"ClientSideToolParams","type":"object","properties":{"name":{"type":"string","description":"The name of the tool.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.client_side_tool.name","typeLabel":"string"},"description":{"type":"string","description":"The description of the tool.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.client_side_tool.description","typeLabel":"string"},"parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the parameters.","type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.client_side_tool.parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the parameters.","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.client_side_tool.parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.client_side_tool.parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.client_side_tool.parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"age":{"description":"The age of the customer.","type":"integer"},"location":{"description":"The location of the customer.","type":"string"}},"required":["age","location"],"type":"object"},"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.client_side_tool.parameters","typeLabel":"object"}},"required":["name","description","parameters"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.client_side_tool","typeLabel":"ClientSideToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.2","typeLabel":"ClientSideTool · object"},{"type":"object","title":"RetrievalTool","required":["type","retrieval"],"properties":{"type":{"type":"string","enum":["retrieval"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.3.type","typeLabel":"enum\u003cstring>"},"retrieval":{"properties":{"bucket_ids":{"items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.3.retrieval.bucket_ids.items.[INDEX]","typeLabel":"string"},"type":"array","description":"List of [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) to use for retrieval-augmented generation.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.3.retrieval.bucket_ids","typeLabel":"string[]"},"max_num_results":{"description":"The maximum number of results to retrieve as context for the language model.","type":"integer","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.3.retrieval.max_num_results","typeLabel":"integer"}},"type":"object","required":["bucket_ids"],"title":"BucketIds","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.3.retrieval","typeLabel":"BucketIds · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.3.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.3","typeLabel":"RetrievalTool · object"},{"type":"object","title":"HandoffTool","description":"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.","required":["type","handoff"],"properties":{"type":{"type":"string","enum":["handoff"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4.type","typeLabel":"enum\u003cstring>"},"handoff":{"properties":{"ai_assistants":{"type":"array","description":"List of possible assistants that can receive a handoff.","items":{"type":"object","properties":{"name":{"type":"string","description":"Helpful name for giving context on when to handoff to the assistant.","example":"Scheduling Specialist","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX].name","typeLabel":"string"},"id":{"type":"string","description":"The ID of the assistant to hand off to.","example":"assistant-1234567890abcdef","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX].id","typeLabel":"string"}},"required":["name","id"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4.handoff.ai_assistants","typeLabel":"object[]"},"voice_mode":{"type":"string","enum":["unified","distinct"],"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4.handoff.voice_mode","typeLabel":"enum\u003cstring>"}},"required":["ai_assistants"],"type":"object","title":"HandoffToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4.handoff","typeLabel":"HandoffToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.4","typeLabel":"HandoffTool · object"},{"type":"object","title":"HangupTool","required":["type","hangup"],"properties":{"type":{"type":"string","enum":["hangup"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.5.type","typeLabel":"enum\u003cstring>"},"hangup":{"properties":{"description":{"type":"string","default":"This tool is used to hang up the call.","description":"The description of the function that will be passed to the assistant.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.5.hangup.description","typeLabel":"string"}},"type":"object","title":"HangupToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.5.hangup","typeLabel":"HangupToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.5.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.5","typeLabel":"HangupTool · object"},{"type":"object","title":"TransferTool","required":["type","transfer"],"properties":{"type":{"type":"string","enum":["transfer"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.type","typeLabel":"enum\u003cstring>"},"transfer":{"properties":{"targets":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"to":{"type":"string","description":"The destination number or SIP URI of the call.","example":"+13129457420","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].to","typeLabel":"string"},"name":{"type":"string","description":"The name of the target.","example":"Support","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].name","typeLabel":"string"},"message":{"type":"string","description":"The warm transfer message to deliver to this specific target. When set, it takes precedence over the message the assistant composes from `warm_transfer_instructions`.","example":"I have a caller asking about a billing issue on invoice 4471.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].message","typeLabel":"string"},"extension":{"type":"string","description":"DTMF digits to send automatically after the transfer destination answers. Useful for reaching an extension behind an IVR (e.g. `\"200\"` to dial extension 200 once the called party picks up). Allowed characters: `0-9`, `A-D`, `w` (0.5s pause), `W` (1s pause), `*`, `#`. Maximum 64 characters. When omitted, no automatic DTMF is sent.","example":"wwww200","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].extension","typeLabel":"string"},"sip_auth_username":{"type":"string","description":"SIP Authentication username used for SIP challenges. Applies when `to` is a SIP URI.","example":"sipuser","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].sip_auth_username","typeLabel":"string"},"sip_auth_password":{"type":"string","description":"SIP Authentication password used for SIP challenges. Applies when `to` is a SIP URI.","example":"sippass","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].sip_auth_password","typeLabel":"string"}},"required":["to"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"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.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.0","typeLabel":"object[]"},{"type":"string","description":"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.","example":"{{ targets }}","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets.oneOf.1","typeLabel":"string"}],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.targets","typeLabel":"object[] | string"},"from":{"type":"string","example":"+35319605860","description":"Number or SIP URI placing the call.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.from","typeLabel":"string"},"diversion":{"type":"string","example":"{{telnyx_agent_target}}","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.diversion","typeLabel":"string"},"warm_transfer_instructions":{"type":"string","example":"Briefly greet the transfer recipient and provide any relevant information from the call. Let them know you will bridge the call right after.","description":"Natural language instructions for your agent for how to provide context for the transfer recipient.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_transfer_instructions","typeLabel":"string"},"warm_transfer_acceptance":{"type":"object","description":"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).","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether the destination must accept the transfer before the calls are bridged.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.enabled","typeLabel":"boolean"},"end_user_target_context_mode":{"type":"string","enum":["private","shared"],"default":"private","description":"Controls whether the private exchange between the assistant and the transfer destination is kept out of the conversation. With `private` (default) the exchange never reaches the conversation history, AI conversations, webhooks or insights, and the transfer tool result is rewritten with the outcome only. With `shared` the exchange stays in the conversation like any other messages.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.end_user_target_context_mode","typeLabel":"enum\u003cstring>"},"require_acceptance":{"type":"boolean","default":false,"description":"Fail closed when the acceptance consult cannot run. Off by default: if the consult cannot be set up for any reason — including where acceptance is unavailable at all (`gather_using_ai`, Conversation Relay or web calls, a conference, or additional invited participants) — the transfer degrades to a plain warm transfer (the warm transfer message is played to the destination as audio and the calls are bridged anyway). Set to true to treat those paths as a decline instead: the destination is disconnected without being asked, the assistant returns to the caller, and no bridge happens without an acceptance. Only consult-setup failures are affected; the destination must still explicitly accept on every consult that does run.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.require_acceptance","typeLabel":"boolean"},"timeout_secs":{"type":"integer","minimum":10,"maximum":600,"default":60,"description":"How long, in seconds, the destination has to accept the transfer, counted from when the private consult starts (right after the destination answers, or after `warm_message_delay_ms`). The caller keeps hearing ringback the whole time. If no acceptance arrives in time, the destination is hung up and the assistant returns to the caller (the transfer fails as a timeout). Raise it for destinations that answer before a human is on the line, such as a call-center queue/ACD or an IVR playing hold audio; keep it as short as practical, since the caller waits on ringback until it expires.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.timeout_secs","typeLabel":"integer"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance","typeLabel":"object"},"description":{"type":"string","description":"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.","example":"Transfer the call to a human agent.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.description","typeLabel":"string"},"bridge_beep":{"type":"object","description":"Plays a short beep once the transfer completes and the calls are bridged, so the transfer destination knows the caller is now on the line. The warm transfer message plays before the bridge; this marks the moment the caller actually joins. Works with and without `warm_transfer_acceptance`.","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether to play the beep when the calls are bridged.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.bridge_beep.enabled","typeLabel":"boolean"},"target_legs":{"type":"string","enum":["self","both"],"default":"self","description":"Who hears the beep. `self` plays it to the transfer destination only; `both` plays it to the destination and the original caller.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.bridge_beep.target_legs","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.bridge_beep","typeLabel":"object"},"warm_message_delay_ms":{"oneOf":[{"type":"integer","example":2000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_message_delay_ms.oneOf.0","typeLabel":"integer"},{"type":"null","example":2000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_message_delay_ms.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.warm_message_delay_ms","typeLabel":"integer | null"},"custom_headers":{"description":"Custom headers to be added to the SIP INVITE for the transfer command.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.custom_headers","typeLabel":"object[]"},"voicemail_detection":{"type":"object","description":"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.","properties":{"detection_mode":{"type":"string","enum":["disabled","premium"],"description":"The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_mode","typeLabel":"enum\u003cstring>"},"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected on the transferred call.","properties":{"action":{"type":"string","enum":["stop_transfer","leave_message_and_stop_transfer"],"description":"The action to take when voicemail is detected. 'stop_transfer' hangs up immediately. 'leave_message_and_stop_transfer' leaves a message then hangs up.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"},"voicemail_message":{"type":"object","description":"Configuration for the voicemail message to leave. Only applicable when action is 'leave_message_and_stop_transfer'.","properties":{"type":{"type":"string","enum":["message","warm_transfer_instructions"],"description":"The type of voicemail message. Use 'message' to leave a specific TTS message, or 'warm_transfer_instructions' to play the warm transfer audio.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"The specific message to leave as voicemail (converted to speech). Only applicable when type is 'message'.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message.message","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message","typeLabel":"object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected","typeLabel":"object"},"detection_config":{"type":"object","description":"Advanced AMD detection configuration parameters. All values are optional - Telnyx will use defaults if not specified.","properties":{"greeting_silence_duration_millis":{"type":"integer","minimum":500,"maximum":50000,"description":"Duration of silence after the greeting to wait before considering the greeting complete.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_silence_duration_millis","typeLabel":"integer"},"greeting_total_analysis_time_millis":{"type":"integer","minimum":500,"maximum":300000,"description":"Maximum time to spend analyzing the greeting.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_total_analysis_time_millis","typeLabel":"integer"},"after_greeting_silence_millis":{"type":"integer","minimum":100,"maximum":5000,"description":"Duration of silence after greeting detection before finalizing the result.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.after_greeting_silence_millis","typeLabel":"integer"},"between_words_silence_millis":{"type":"integer","minimum":10,"maximum":5000,"description":"Maximum silence duration between words during greeting.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.between_words_silence_millis","typeLabel":"integer"},"greeting_duration_millis":{"type":"integer","minimum":100,"maximum":10000,"description":"Expected duration of greeting speech.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_duration_millis","typeLabel":"integer"},"initial_silence_millis":{"type":"integer","minimum":100,"maximum":500000,"description":"Maximum silence duration at the start of the call before speech.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.initial_silence_millis","typeLabel":"integer"},"maximum_number_of_words":{"type":"integer","minimum":1,"maximum":50,"description":"Maximum number of words expected in a human greeting.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.maximum_number_of_words","typeLabel":"integer"},"maximum_word_length_millis":{"type":"integer","minimum":50,"maximum":5000,"description":"Maximum duration of a single word.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.maximum_word_length_millis","typeLabel":"integer"},"silence_threshold":{"type":"integer","minimum":1,"maximum":1000,"description":"Audio level threshold for silence detection.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.silence_threshold","typeLabel":"integer"},"total_analysis_time_millis":{"type":"integer","minimum":500,"maximum":60000,"description":"Total time allowed for AMD analysis.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.total_analysis_time_millis","typeLabel":"integer"},"min_word_length_millis":{"type":"integer","minimum":1,"maximum":1000,"description":"Minimum duration for audio to be considered a word.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.min_word_length_millis","typeLabel":"integer"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config","typeLabel":"object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer.voicemail_detection","typeLabel":"object"}},"type":"object","required":["targets","from"],"title":"TransferToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.transfer","typeLabel":"TransferToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.6","typeLabel":"TransferTool · object"},{"type":"object","title":"InviteTool","required":["type","invite"],"properties":{"type":{"type":"string","enum":["invite"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.type","typeLabel":"enum\u003cstring>"},"invite":{"properties":{"from":{"type":"string","example":"+35319605860","description":"Number or SIP URI placing the call.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.from","typeLabel":"string"},"targets":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"to":{"type":"string","description":"The destination number or SIP URI of the call.","example":"+13129457420","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX].to","typeLabel":"string"},"name":{"type":"string","description":"The name of the target.","example":"Support","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX].name","typeLabel":"string"}},"required":["to"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.targets.oneOf.0","typeLabel":"object[]"},{"type":"string","description":"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.","example":"{{ targets }}","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.targets.oneOf.1","typeLabel":"string"},{"type":"null","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.targets.oneOf.2","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.targets","typeLabel":"object[] | string | null"},"custom_headers":{"description":"Custom headers to be added to the SIP INVITE for the invite command.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.custom_headers","typeLabel":"object[]"},"voicemail_detection":{"type":"object","description":"Configuration for voicemail detection (AMD - Answering Machine Detection) on the invited call.","properties":{"detection_mode":{"type":"string","enum":["disabled","premium"],"description":"The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.voicemail_detection.detection_mode","typeLabel":"enum\u003cstring>"},"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected on the invited call.","properties":{"action":{"type":"string","enum":["stop_invite"],"description":"The action to take when voicemail is detected.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.voicemail_detection.on_voicemail_detected","typeLabel":"object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite.voicemail_detection","typeLabel":"object"}},"type":"object","required":["from"],"title":"InviteToolConfig","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.invite","typeLabel":"InviteToolConfig · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.7","typeLabel":"InviteTool · object"},{"type":"object","title":"SIPReferTool","required":["type","refer"],"properties":{"type":{"type":"string","enum":["refer"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.type","typeLabel":"enum\u003cstring>"},"refer":{"properties":{"targets":{"type":"array","description":"The different possible targets of the SIP refer. The assistant will be able to choose one of the targets to refer the call to.","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the target.","example":"Support","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.targets.items.[INDEX].name","typeLabel":"string"},"sip_address":{"type":"string","description":"The SIP URI to which the call will be referred.","example":"sip:[email protected]","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_address","typeLabel":"string"},"sip_auth_username":{"type":"string","description":"SIP Authentication username used for SIP challenges.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_auth_username","typeLabel":"string"},"sip_auth_password":{"type":"string","description":"SIP Authentication password used for SIP challenges.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_auth_password","typeLabel":"string"}},"required":["name","sip_address"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.targets.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.targets","typeLabel":"object[]"},"sip_headers":{"description":"SIP headers to be added to the SIP REFER. Currently only User-to-User and Diversion headers are supported.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","enum":["User-to-User","Diversion"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX].name","typeLabel":"enum\u003cstring>"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.sip_headers","typeLabel":"object[]"},"custom_headers":{"description":"Custom headers to be added to the SIP REFER.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer.custom_headers","typeLabel":"object[]"}},"type":"object","required":["targets"],"title":"SIPReferToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.refer","typeLabel":"SIPReferToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.8","typeLabel":"SIPReferTool · object"},{"type":"object","title":"DTMFTool","required":["type","send_dtmf"],"properties":{"type":{"type":"string","enum":["send_dtmf"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.9.type","typeLabel":"enum\u003cstring>"},"send_dtmf":{"type":"object","additionalProperties":true,"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.9.send_dtmf","typeLabel":"object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.9.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.9","typeLabel":"DTMFTool · object"},{"type":"object","title":"SendMessageTool","description":"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.","required":["type","send_message"],"properties":{"type":{"type":"string","enum":["send_message"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.10.type","typeLabel":"enum\u003cstring>"},"send_message":{"type":"object","properties":{"message_template":{"oneOf":[{"type":"string","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.10.send_message.message_template.oneOf.0","typeLabel":"string"},{"type":"null","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.10.send_message.message_template.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.10.send_message.message_template","typeLabel":"string | null"}},"additionalProperties":true,"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.10.send_message","typeLabel":"object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.10.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.10","typeLabel":"SendMessageTool · object"},{"type":"object","title":"SkipTurnTool","required":["type","skip_turn"],"properties":{"type":{"type":"string","enum":["skip_turn"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.11.type","typeLabel":"enum\u003cstring>"},"skip_turn":{"properties":{"description":{"type":"string","default":"This tool is used to skip the assistant turn without producing a response.","description":"The description of the function that will be passed to the assistant.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.11.skip_turn.description","typeLabel":"string"}},"type":"object","title":"SkipTurnToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.11.skip_turn","typeLabel":"SkipTurnToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.11.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.11","typeLabel":"SkipTurnTool · object"},{"type":"object","title":"VisionTool","description":"(BETA) Lets the assistant look at recent image frames the client sent into the conversation (for example webcam or screen-share frames). Frames are sent with `conversation.item.create` and `item.buffer: true`; they never trigger a response on their own. The assistant decides when to look and which frames it needs. Requires a model that supports image input.","required":["type"],"properties":{"type":{"type":"string","enum":["vision"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.12.type","typeLabel":"enum\u003cstring>"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.12.shared","typeLabel":"boolean"},"vision":{"properties":{"max_frame_age_secs":{"type":"integer","minimum":1,"default":10,"description":"Frames received longer ago than this many seconds are not shown to the assistant, so it never describes a frozen or disconnected camera as live.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.12.vision.max_frame_age_secs","typeLabel":"integer"}},"type":"object","title":"VisionToolParams","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.12.vision","typeLabel":"VisionToolParams · object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.12","typeLabel":"VisionTool · object"},{"type":"object","title":"PayTool","description":"(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.","required":["type","pay"],"properties":{"type":{"type":"string","enum":["pay"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.type","typeLabel":"enum\u003cstring>"},"pay":{"properties":{"connector_name":{"type":"string","description":"The name of the pay connector configured in the Telnyx API. Must reference an existing pay connector for this organization.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.connector_name","typeLabel":"string"},"currency":{"type":"string","default":"USD","description":"Default currency for payments processed by this tool.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.currency","typeLabel":"string"},"payment_method":{"type":"string","default":"credit-card","description":"Default payment method for payments processed by this tool.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.payment_method","typeLabel":"string"},"description":{"oneOf":[{"type":"string","default":null,"description":"Description of the pay tool shown to the assistant so it knows when to call the tool. Not sent to the payment connector — the per-call `description` argument the assistant passes is what reaches the processor.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.description.oneOf.0","typeLabel":"string"},{"type":"null","default":null,"description":"Description of the pay tool shown to the assistant so it knows when to call the tool. Not sent to the payment connector — the per-call `description` argument the assistant passes is what reaches the processor.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.description.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.description","typeLabel":"string | null"},"connector_parameters":{"type":"object","additionalProperties":true,"description":"Custom key/value parameters forwarded to the pay connector as `parameters` in the processor request. String values may use `{{dynamic_variable}}` templating, resolved per call.","example":{"campaignid":"abc","customer_ref":"CUST-67890"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.connector_parameters","typeLabel":"object"},"valid_card_types":{"type":"array","items":{"type":"string","enum":["visa","mastercard","amex","maestro","discover","optima","jcb","diners-club","enroute"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.valid_card_types.items.[INDEX]","typeLabel":"enum\u003cstring>"},"minItems":1,"description":"Restricts accepted card numbers to the listed card types. When the caller enters a card number that does not match one of the listed types, Pay treats the input as invalid and re-prompts for the card number.","example":["visa","mastercard"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.valid_card_types","typeLabel":"enum\u003cstring>[]"},"postal_code":{"oneOf":[{"type":"string","description":"Controls billing postal code collection for credit-card payments. Set to `false` to skip the postal code prompt without supplying a postal code to the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to prompt the caller. Supply a non-empty string, such as `\"90210\"`, to use that postal code without prompting. This option does not affect ACH debit payments or payments using an existing token.","minLength":1,"pattern":"\\S","example":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.postal_code.oneOf.0","typeLabel":"string"},{"type":"boolean","description":"Controls billing postal code collection for credit-card payments. Set to `false` to skip the postal code prompt without supplying a postal code to the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to prompt the caller. Supply a non-empty string, such as `\"90210\"`, to use that postal code without prompting. This option does not affect ACH debit payments or payments using an existing token.","example":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.postal_code.oneOf.1","typeLabel":"boolean"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.postal_code","typeLabel":"string | boolean"},"min_postal_code_length":{"type":"integer","minimum":1,"maximum":128,"description":"Minimum number of digits the caller must enter when collecting a credit-card billing postal code. Applies only when `postal_code` prompts the caller. Omitted means the platform default (1) applies. The maximum number of digits collected is the greater of 10 and this value. This does not validate the length of a postal code supplied directly in `postal_code`.","example":5,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.min_postal_code_length","typeLabel":"integer"},"max_attempts":{"type":"integer","minimum":1,"maximum":3,"description":"Maximum number of attempts for each payment collection step. Omitted means the platform default (3) applies.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.max_attempts","typeLabel":"integer"},"timeout_millis":{"type":"integer","minimum":1,"maximum":600000,"description":"Time in milliseconds to wait for DTMF input for each collection step. Omitted means the platform default (5000) applies. Increase this for slower entry, e.g. a 16-digit card number.","example":12000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.timeout_millis","typeLabel":"integer"},"inter_digit_timeout_millis":{"type":"integer","minimum":1,"maximum":600000,"description":"Time in milliseconds to wait between consecutive DTMF digits. Omitted means the platform default (5000) applies.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.inter_digit_timeout_millis","typeLabel":"integer"},"prompts":{"type":"object","title":"Pay Tool Prompts","description":"Custom text-to-speech prompts keyed by payment collection step. The AI assistant merges its own card-number prompt into this map, matching on the same step keys.","additionalProperties":false,"properties":{"payment-card-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.payment-card-number","typeLabel":"string | Pay Tool Prompt · object[]"},"expiration-date":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.expiration-date","typeLabel":"string | Pay Tool Prompt · object[]"},"postal-code":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.postal-code","typeLabel":"string | Pay Tool Prompt · object[]"},"security-code":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.security-code","typeLabel":"string | Pay Tool Prompt · object[]"},"bank-routing-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-routing-number","typeLabel":"string | Pay Tool Prompt · object[]"},"bank-account-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts.bank-account-number","typeLabel":"string | Pay Tool Prompt · object[]"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay.prompts","typeLabel":"Pay Tool Prompts · object"}},"required":["connector_name"],"type":"object","title":"PayToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.pay","typeLabel":"PayToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.13","typeLabel":"PayTool · object"},{"type":"object","title":"UpdateDynamicVariablesTool","description":"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`.","required":["type","update_dynamic_variables"],"properties":{"type":{"type":"string","enum":["update_dynamic_variables"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.type","typeLabel":"enum\u003cstring>"},"update_dynamic_variables":{"description":"Configuration for an update_dynamic_variables tool.","properties":{"name":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","description":"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.","example":"collect_details","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.update_dynamic_variables.name","typeLabel":"string"},"description":{"type":"string","description":"Description of the tool passed to the assistant, guiding when to call it and which variables to update.","example":"Collect caller details into conversation variables.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.update_dynamic_variables.description","typeLabel":"string"},"updatable_variables":{"type":"array","description":"The dynamic variables the assistant is allowed to write. At least one is required.","minItems":1,"items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"pattern":"^(?!telnyx_)[a-zA-Z0-9._-]+$","description":"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.","example":"customer_name","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].name","typeLabel":"string"},"type":{"type":"string","description":"Optional hint for the variable's value type (e.g. `string`).","example":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].type","typeLabel":"string"},"description":{"type":"string","description":"Optional description of the variable, guiding the assistant on what value to capture.","example":"The caller's full name.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].description","typeLabel":"string"}},"required":["name"],"additionalProperties":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables","typeLabel":"object[]"}},"required":["name","description","updatable_variables"],"type":"object","title":"UpdateDynamicVariablesToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.update_dynamic_variables","typeLabel":"UpdateDynamicVariablesToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX].oneOf.14","typeLabel":"UpdateDynamicVariablesTool · object"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX].items.[INDEX]","typeLabel":"FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools.items.[INDEX]","typeLabel":"(FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object)[]"},"title":"Tools","type":"array","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools","typeLabel":"((FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object)[])[]"},"tools_mode":{"default":"replace","description":"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.","enum":["replace","append"],"title":"Tools Mode","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.tools_mode","typeLabel":"enum\u003cstring>"},"transcription":{"properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","speechmatics/standard","speechmatics/linden-1","azure/fast","assemblyai/universal-3-6-pro","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","telnyx/basira","distil-whisper/distil-large-v2","openai/whisper-large-v3-turbo"],"description":"The speech to text model to be used by the voice assistant. All Deepgram models are run on-premise.\n\n- `deepgram/flux` is optimized for turn-taking with multilingual language hints.\n- `deepgram/nova-3` is multilingual with automatic language detection.\n- `deepgram/nova-2` is Deepgram's previous-generation multilingual model.\n- `speechmatics/standard` is a Speechmatics model self-hosted by Telnyx; it supports a fixed set of language packs (including bilingual packs such as `ar_en`) and defaults to `en`.\n- `speechmatics/linden-1` (preview) is a vendor-hosted streaming model with no auto-detect; set `language` from Speechmatics' Realtime language list (defaults to `en`).\n- `azure/fast` is a multilingual Azure transcription model.\n- `assemblyai/universal-3-6-pro` (AssemblyAI Universal-3.6 Pro) is a multilingual streaming model with configurable turn detection. The legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming` are still accepted and run the same model.\n- `xai/grok-stt` is a multilingual Grok STT model.\n- `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`.\n- `nvidia/parakeet-v3` is a multilingual transcription model with automatic language detection.\n- `omi-health/omi-med-stt-v1` is an English-only medical transcription model (Parakeet-based).\n- `humain/realtime` is a streaming model with native Arabic and Arabic/English code-switching support.\n- `reson8/turns` is a turn-based streaming model covering 10 European languages with automatic language detection.\n- `cohere/ar-stt` is a non-streaming Arabic and English transcription model.\n- `telnyx/basira` is a non-streaming Arabic transcription model.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.model","typeLabel":"enum\u003cstring>"},"language":{"type":"string","description":"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. For `speechmatics/linden-1`, there is no auto-detect; set a code from Speechmatics' Realtime language list (67 language codes, including `es-bilingual-en` for Spanish and English bilingual, and the spelling and script variants `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant`; `en` alone uses the default spelling); unset defaults to `en`, while an explicit `auto`, `auto_beta`, or `multi` is rejected with a 400.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.language","typeLabel":"string"},"api_key_ref":{"title":"Api Key Ref","type":"string","description":"Integration secret identifier for the transcription provider API key. Currently used for Azure transcription regions that require a customer-provided API key.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.api_key_ref","typeLabel":"string"},"region":{"title":"Region","type":"string","description":"Region on third party cloud providers (currently Azure) if using one of their models. Some regions require `api_key_ref`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.region","typeLabel":"string"},"settings":{"properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings.language_hints","typeLabel":"string[]"}},"type":"object","title":"TranscriptionSettingsConfig","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.settings","typeLabel":"TranscriptionSettingsConfig · object"},"fallback_models":{"oneOf":[{"type":"array","items":{"title":"TranscriptionFallbackModel","description":"A streaming speech-to-text model that takes over transcription when the model in use fails.","type":"object","properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","assemblyai/universal-3-6-pro","assemblyai/universal-3-5-pro","assemblyai/universal-streaming","xai/grok-stt","soniox/stt-rt-v4","soniox/stt-rt-v5","humain/realtime","reson8/turns"],"description":"The fallback model. It must be a streaming model other than `transcription.model` and the other fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` (or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or `reson8/turns`.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].model","typeLabel":"enum\u003cstring>"},"language":{"oneOf":[{"type":"string","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].language.oneOf.0","typeLabel":"string"},{"type":"null","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].language.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].language","typeLabel":"string | null"},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0.language_hints","typeLabel":"string[]"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.0","typeLabel":"TranscriptionSettingsConfig · object"},{"type":"null","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX].settings","typeLabel":"TranscriptionSettingsConfig · object | null"}},"required":["model"],"example":{"model":"deepgram/nova-3","language":"en","settings":{"keyterm":"Telnyx,VoIP,SIP"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0.items.[INDEX]","typeLabel":"TranscriptionFallbackModel · object"},"maxItems":3,"description":"Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a streaming model too, and must support `language` alongside other models. On update, a list replaces the stored one: omit the field to keep the stored list, or send `null` or `[]` to remove it. When an update changes `model` or `language`, stored fallbacks that no longer fit are removed without an error. Can't be combined with `challenger`, the language booster; to replace a stored language booster, send `challenger: null` in the same request.","example":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.0","typeLabel":"TranscriptionFallbackModel · object[]"},{"type":"null","items":{"title":"TranscriptionFallbackModel","description":"A streaming speech-to-text model that takes over transcription when the model in use fails.","type":"object","properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","assemblyai/universal-3-6-pro","assemblyai/universal-3-5-pro","assemblyai/universal-streaming","xai/grok-stt","soniox/stt-rt-v4","soniox/stt-rt-v5","humain/realtime","reson8/turns"],"description":"The fallback model. It must be a streaming model other than `transcription.model` and the other fallbacks: `deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` (or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`), `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, or `reson8/turns`."},"language":{"oneOf":[{"type":"string","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run."},{"type":"null","description":"The language the fallback transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when the fallback model doesn't support the language it would run."}]},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean"},"numerals":{"title":"Numerals","type":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript."},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead."},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters."},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and 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":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn."},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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":{"title":"Context","type":"string","maxLength":10000,"description":"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":{"title":"Language Hints","type":"array","items":{"type":"string"},"description":"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`."}}},{"type":"null","description":"Settings for the fallback, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model."}]}},"required":["model"],"example":{"model":"deepgram/nova-3","language":"en","settings":{"keyterm":"Telnyx,VoIP,SIP"}}},"maxItems":3,"description":"Up to 3 streaming models that take over transcription, in this order, when the model in use fails, at the start of a call or mid-call. `model` must be a streaming model too, and must support `language` alongside other models. On update, a list replaces the stored one: omit the field to keep the stored list, or send `null` or `[]` to remove it. When an update changes `model` or `language`, stored fallbacks that no longer fit are removed without an error. Can't be combined with `challenger`, the language booster; to replace a stored language booster, send `challenger: null` in the same request.","example":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.fallback_models","typeLabel":"TranscriptionFallbackModel · object[] | null"},"challenger":{"oneOf":[{"type":"object","title":"TranscriptionChallenger","description":"The language booster: a second model that transcribes alongside `model`, and the rule that decides which transcript the assistant uses. Both models must be streaming, or both non-streaming, and, except with `merge_words`, `model` must support `language` alongside another model (for example, `cohere/ar-stt` supports only `ar` there). If the language booster can't run, the call runs on `model` alone; if either model fails mid-call, the call continues on the other. On update, omit the field to keep the stored language booster, or send `null` to remove it. When an update changes `model` or `language` and the stored language booster no longer fits, it is removed without an error. Can't be combined with `fallback_models`; to replace stored fallbacks, send `fallback_models: []` in the same request.","required":["model"],"example":{"model":"deepgram/nova-3","language":"en","rule":"best_turn"},"properties":{"model":{"type":"string","enum":["deepgram/flux","deepgram/nova-3","deepgram/nova-2","azure/fast","assemblyai/universal-3-6-pro","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","telnyx/basira","distil-whisper/distil-large-v2","openai/whisper-large-v3-turbo"],"description":"The language booster's model. It must be the same kind of model as `transcription.model`: both streaming (`deepgram/flux`, `deepgram/nova-3`, `deepgram/nova-2`, `assemblyai/universal-3-6-pro` or its legacy aliases `assemblyai/universal-3-5-pro` and `assemblyai/universal-streaming`, `xai/grok-stt`, `soniox/stt-rt-v4`, `soniox/stt-rt-v5`, `humain/realtime`, `reson8/turns`) or both non-streaming (`azure/fast`, `nvidia/parakeet-v3`, `omi-health/omi-med-stt-v1`, `cohere/ar-stt`, `distil-whisper/distil-large-v2`, `openai/whisper-large-v3-turbo`, `telnyx/basira`). It can be the same model as `transcription.model` on a different `language`.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.model","typeLabel":"enum\u003cstring>"},"language":{"oneOf":[{"type":"string","description":"The language this model transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when this model doesn't support the language it would run. It is also rejected when it would run the same model on the same language as `transcription.model`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.language.oneOf.0","typeLabel":"string"},{"type":"null","description":"The language this model transcribes. Omit it or set it to `null` to use the language of `transcription.model`. The request is rejected when this model doesn't support the language it would run. It is also rejected when it would run the same model on the same language as `transcription.model`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.language.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.language","typeLabel":"string | null"},"settings":{"oneOf":[{"type":"object","title":"TranscriptionSettingsConfig","description":"Settings for the language booster, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","properties":{"smart_format":{"title":"Smart Format","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.smart_format","typeLabel":"boolean"},"numerals":{"title":"Numerals","type":"boolean","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.numerals","typeLabel":"boolean"},"eot_threshold":{"title":"Eot Threshold","type":"number","description":"Available only for deepgram/flux. Confidence required to trigger an end of turn. Higher values = more reliable turn detection but slightly increased latency.","minimum":0.5,"maximum":0.9,"default":0.8,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.eot_threshold","typeLabel":"number"},"eot_timeout_ms":{"title":"Eot Timeout Ms","type":"integer","description":"Available only for deepgram/flux. Maximum milliseconds of silence before forcing an end of turn, regardless of confidence.","minimum":500,"maximum":10000,"default":5000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.eot_timeout_ms","typeLabel":"integer"},"eager_eot_threshold":{"title":"Eager Eot Threshold","type":"number","minimum":0.3,"maximum":0.9,"default":0.8,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.eager_eot_threshold","typeLabel":"number"},"keyterm":{"title":"Keyterm","type":"string","description":"A comma-separated list of key terms to boost for recognition during transcription, used by Deepgram, Reson8, Speechmatics Linden 1 and AssemblyAI models. Helps improve accuracy for domain-specific terminology, proper nouns, or uncommon words. At most 1000 characters in total. For assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming), also at most 100 terms of up to 50 characters each. 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.","maxLength":1000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.keyterm","typeLabel":"string"},"remove_disfluencies":{"title":"Remove Disfluencies","type":"boolean","default":false,"description":"Available only for speechmatics/linden-1. When true, filler words such as \"um\" and \"uh\" are removed from the transcript. Disfluency removal is supported only for `ar`, `cmn`, `da`, `de`, `el`, `en`, `es`, `fr`, `he`, `hi`, `hu`, `it`, `ja`, `nl`, `pl`, `pt`, and `ru`, determined by the base language (so `en-US`, `en-GB`, `en-AU`, `cmn-Hans`, and `cmn-Hant` are supported); for other languages, filler words remain in the transcript.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.remove_disfluencies","typeLabel":"boolean"},"end_of_turn_confidence_threshold":{"title":"End Of Turn Confidence Threshold","type":"number","minimum":0,"maximum":1,"description":"Deprecated and ignored. Accepted for backwards compatibility. AssemblyAI turn detection is configured with min_turn_silence and max_turn_silence.","deprecated":true,"x-stainless-deprecation-message":"Ignored. Configure AssemblyAI turn detection with min_turn_silence and max_turn_silence instead.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.end_of_turn_confidence_threshold","typeLabel":"number"},"prompt":{"title":"Prompt","type":"string","maxLength":1750,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Context about the conversation (domain, names, terms) to improve transcription; describe the content, do not give instructions. Leave empty unless needed. At most 1750 characters.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.prompt","typeLabel":"string"},"min_turn_silence":{"title":"Min Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":400,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Minimum duration of silence in milliseconds before a turn can end. Must be less than or equal to max_turn_silence.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.min_turn_silence","typeLabel":"integer"},"max_turn_silence":{"title":"Max Turn Silence","type":"integer","minimum":100,"maximum":5000,"default":1280,"description":"Available only for assemblyai/universal-3-6-pro (and its legacy aliases assemblyai/universal-3-5-pro and assemblyai/universal-streaming). Maximum duration of silence in milliseconds before forcing an end of turn.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.max_turn_silence","typeLabel":"integer"},"interim_results":{"title":"Interim Results","type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.interim_results","typeLabel":"boolean"},"enable_endpoint_detection":{"title":"Enable Endpoint Detection","type":"boolean","default":false,"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.enable_endpoint_detection","typeLabel":"boolean"},"max_endpoint_delay_ms":{"title":"Max Endpoint Delay Ms","type":"integer","minimum":500,"maximum":3000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.max_endpoint_delay_ms","typeLabel":"integer"},"context":{"title":"Context","type":"string","maxLength":10000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.context","typeLabel":"string"},"language_hints":{"title":"Language Hints","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.language_hints.items.[INDEX]","typeLabel":"string"},"description":"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`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0.language_hints","typeLabel":"string[]"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.0","typeLabel":"TranscriptionSettingsConfig · object"},{"type":"null","description":"Settings for the language booster, with the same fields and limits as `transcription.settings`. Fields that don't apply to this model's provider are dropped, and the provider's defaults fill in the rest. Omit it or set it to `null` to use the settings of `transcription.model` where they apply to this model.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.settings","typeLabel":"TranscriptionSettingsConfig · object | null"},"rule":{"type":"string","enum":["best_turn","best_engine","merge_words"],"default":"best_turn","description":"How the assistant picks the transcript it uses. The models are compared on how complete and confident their transcripts are, not on language, so the rules work best when both models understand the callers' language.\n\n- `best_turn` (default): both models transcribe the whole call. Each turn uses the language booster's transcript only when it scores higher than the transcript of `transcription.model` (clearly higher with non-streaming models). With streaming models, `transcription.model` also decides when each turn ends. Available for every pair.\n- `best_engine`: both models transcribe the first turns, then the call continues alone on the model whose transcripts scored higher. If neither clearly leads, `transcription.model` continues. Streaming models only.\n- `merge_words`: both models transcribe each utterance and their words are merged, keeping Arabic and English spoken in the same sentence. Available only for `telnyx/basira` with `cohere/ar-stt`, in either order. The pair runs on the language that applies to `telnyx/basira` (its own, or that of `transcription.model`), which must be Arabic (`ar` or an `ar-` locale), `multi`, or `auto`.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0.rule","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.0","typeLabel":"TranscriptionChallenger · object"},{"type":"null","description":"The language booster: a second model that transcribes alongside `model`, and the rule that decides which transcript the assistant uses. Both models must be streaming, or both non-streaming, and, except with `merge_words`, `model` must support `language` alongside another model (for example, `cohere/ar-stt` supports only `ar` there). If the language booster can't run, the call runs on `model` alone; if either model fails mid-call, the call continues on the other. On update, omit the field to keep the stored language booster, or send `null` to remove it. When an update changes `model` or `language` and the stored language booster no longer fits, it is removed without an error. Can't be combined with `fallback_models`; to replace stored fallbacks, send `fallback_models: []` in the same request.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription.challenger","typeLabel":"TranscriptionChallenger · object | null"}},"type":"object","description":"Per-node transcription override (response form).","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.transcription","typeLabel":"object"},"type":{"const":"prompt","default":"prompt","description":"Node kind discriminator. `prompt` is an LLM-driven step.","title":"Type","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.type","typeLabel":"string"},"voice_settings":{"properties":{"voice":{"type":"string","description":"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.\nTo 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.\u003cmodel_id>.\u003cvoice_id>` (e.g. Telnyx.KokoroTTS.af_heart). For Soniox voices, use `Soniox.tts-rt-v2.\u003cvoice_id>` (e.g. Soniox.tts-rt-v2.Emma); every Soniox voice speaks all supported languages.\nThe 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.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.voice","typeLabel":"string"},"voice_speed":{"type":"number","default":1,"description":"The speed of the voice in the range [0.6, 1.5]. 1.0 is the default speed. Larger numbers make the voice faster, smaller numbers make it slower. Applies to Telnyx `Ultra` voices; values outside this range are rejected by the synthesis engine. Soniox voices support a speed range of 0.7 to 1.3.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.voice_speed","typeLabel":"number"},"api_key_ref":{"type":"string","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.api_key_ref","typeLabel":"string"},"temperature":{"type":"number","default":0.5,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.temperature","typeLabel":"number"},"similarity_boost":{"type":"number","default":0.75,"description":"Determines how closely the AI should adhere to the original voice when attempting to replicate it. Only applicable when using ElevenLabs.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.similarity_boost","typeLabel":"number"},"use_speaker_boost":{"type":"boolean","default":true,"description":"Amplifies similarity to the original speaker voice. Increases computational load and latency slightly. Only applicable when using ElevenLabs.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.use_speaker_boost","typeLabel":"boolean"},"style":{"type":"number","default":0,"description":"Determines the style exaggeration of the voice. Amplifies speaker style but consumes additional resources when set above 0. Only applicable when using ElevenLabs.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.style","typeLabel":"number"},"speed":{"type":"number","default":1,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.speed","typeLabel":"number"},"language":{"oneOf":[{"type":"string","description":"Two-letter ISO 639-1 code of the language the voice speaks, for example `es`. Only applicable to Soniox and AssemblyAI voices, which speak every language of their model. AssemblyAI accepts `en`, `es`, `de`, `fr`, `it`, and `pt`. When unset, the voice speaks English.","default":null,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language.oneOf.0","typeLabel":"string"},{"type":"null","description":"Two-letter ISO 639-1 code of the language the voice speaks, for example `es`. Only applicable to Soniox and AssemblyAI voices, which speak every language of their model. AssemblyAI accepts `en`, `es`, `de`, `fr`, `it`, and `pt`. When unset, the voice speaks English.","default":null,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language","typeLabel":"string | null"},"language_boost":{"oneOf":[{"type":"string","description":"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.","enum":[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"],"default":null,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language_boost.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","description":"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.","enum":[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"],"default":null,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language_boost.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.language_boost","typeLabel":"enum\u003cstring> | null"},"expressive_mode":{"type":"boolean","default":false,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.expressive_mode","typeLabel":"boolean"},"background_audio":{"oneOf":[{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["predefined_media"],"description":"Select from predefined media options.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.0.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","enum":["silence","office"],"default":"silence","description":"The predefined media to use. `silence` disables background audio.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.0.value","typeLabel":"enum\u003cstring>"},"volume":{"type":"number","minimum":0.1,"maximum":1,"multipleOf":0.1,"default":1,"description":"Volume level for the predefined background audio. Supports values from 0.1 to 1.0 in 0.1 increments.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.0.volume","typeLabel":"number"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.0","typeLabel":"object"},{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["media_url"],"description":"Provide a direct URL to an MP3 file. The audio will loop during the call.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.1.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","format":"uri","description":"HTTPS URL to an MP3 file.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.1.value","typeLabel":"string\u003curi>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.1","typeLabel":"object"},{"type":"object","description":"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.","required":["type","value"],"properties":{"type":{"type":"string","enum":["media_name"],"description":"Reference a previously uploaded media by its name from Telnyx Media Storage.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.2.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","description":"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.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.2.value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio.oneOf.2","typeLabel":"object"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.background_audio","typeLabel":"object"},"tool_call_audio":{"oneOf":[{"type":"object","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","required":["type","value"],"example":{"type":"predefined_media","value":"typing","volume":0.5},"properties":{"type":{"type":"string","enum":["predefined_media"],"description":"Select from predefined media options.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.0.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","enum":["typing"],"description":"The predefined media to use. `typing` plays a keyboard typing sound.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.0.value","typeLabel":"enum\u003cstring>"},"volume":{"type":"number","minimum":0,"maximum":1,"multipleOf":0.1,"default":0.5,"description":"Volume level for the predefined media. Supports values from 0.0 to 1.0 in 0.1 increments. `0.0` plays no sound.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.0.volume","typeLabel":"number"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.0","typeLabel":"object"},{"type":"object","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","required":["type","value"],"example":{"type":"predefined_media","value":"typing"},"properties":{"type":{"type":"string","enum":["media_url"],"description":"Provide a direct URL to an MP3 file. The audio loops while the tool runs.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.1.type","typeLabel":"enum\u003cstring>"},"value":{"type":"string","format":"uri","description":"HTTPS URL to an MP3 file.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.1.value","typeLabel":"string\u003curi>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.1","typeLabel":"object"},{"type":"null","description":"Optional sound played to the caller while the assistant runs a tool (for example a webhook or MCP tool). It replaces the background audio until the tool responds, then the background audio resumes. Defaults to null, which plays no sound; send `null` on update to clear it. Not played in conference calls.","example":{"type":"predefined_media","value":"typing","volume":0.5},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio.oneOf.2","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings.tool_call_audio","typeLabel":"object · object · null"}},"type":"object","required":["voice"],"description":"Per-node voice override (response form).","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0.voice_settings","typeLabel":"object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.0","typeLabel":"FlowNode · object"},{"type":"object","title":"ToolNode","description":"A standalone tool step in a conversation flow, as returned by the API.","required":["id","shared_tool_id"],"properties":{"id":{"type":"string","title":"Id","description":"Caller-supplied unique identifier for this node within the flow.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.id","typeLabel":"string"},"shared_tool_id":{"description":"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 `llm` / `expression` edges route the flow on the tool's 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.","title":"Shared Tool Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.shared_tool_id","typeLabel":"string"},"name":{"title":"Name","description":"Optional human-readable label, displayed in authoring UIs.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.name","typeLabel":"string"},"position":{"description":"Optional canvas coordinates used by authoring UIs to lay out the graph. Ignored by the runtime; round-trips so frontends can persist graph layout across reloads.","properties":{"x":{"description":"Horizontal coordinate in the authoring canvas.","title":"X","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.position.x","typeLabel":"number"},"y":{"description":"Vertical coordinate in the authoring canvas.","title":"Y","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.position.y","typeLabel":"number"}},"required":["x","y"],"title":"NodePosition","type":"object","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.position","typeLabel":"NodePosition · object"},"tool":{"description":"Full tool definition resolved from `shared_tool_id` server-side. Populated on responses so clients can render the node without a follow-up fetch. Ignored on input — set `shared_tool_id`.","type":"array","items":{"oneOf":[{"type":"object","title":"FunctionTool","required":["type","function"],"properties":{"type":{"type":"string","enum":["function"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"},"function":{"properties":{"name":{"type":"string","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.0.function.name","typeLabel":"string"},"description":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.0.function.description","typeLabel":"string"},"parameters":{"type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.0.function.parameters","typeLabel":"object"}},"type":"object","required":["name"],"title":"FunctionDefinition","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.0.function","typeLabel":"FunctionDefinition · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.0.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.0","typeLabel":"FunctionTool · object"},{"type":"object","title":"WebhookTool","required":["type","webhook"],"properties":{"type":{"type":"string","enum":["webhook"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"},"webhook":{"properties":{"name":{"type":"string","description":"The name of the tool.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.name","typeLabel":"string"},"description":{"type":"string","description":"The description of the tool.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.description","typeLabel":"string"},"url":{"description":"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.","type":"string","example":"https://example.com/api/v1/function","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.url","typeLabel":"string"},"method":{"description":"The HTTP method to be used when calling the external tool.","type":"string","enum":["GET","POST","PUT","DELETE","PATCH"],"default":"POST","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.method","typeLabel":"enum\u003cstring>"},"headers":{"description":"The headers to be sent to the external tool.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.headers","typeLabel":"object[]"},"body_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the body parameters.","type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.body_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the body parameters.","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.body_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.body_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.body_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"age":{"description":"The age of the customer.","type":"integer"},"location":{"description":"The location of the customer.","type":"string"}},"required":["age","location"],"type":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.body_parameters","typeLabel":"object"},"path_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the path parameters.","type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.path_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the path parameters.","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.path_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.path_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.path_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"id":{"description":"The id of the customer.","type":"string"}},"required":["id"],"type":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.path_parameters","typeLabel":"object"},"query_parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the query parameters.","type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.query_parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the query parameters.","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.query_parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.query_parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.query_parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"page":{"description":"The page number.","type":"integer"}},"required":["page"],"type":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.query_parameters","typeLabel":"object"},"preset_body_fields":{"type":"object","additionalProperties":true,"description":"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.","example":{"account_id":"{{customer_id}}","source":"telnyx-assistant"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.preset_body_fields","typeLabel":"object"},"preset_query_params":{"type":"object","additionalProperties":true,"description":"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.","example":{"caller":"{{telnyx_end_user_target}}","channel":"voice"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.preset_query_params","typeLabel":"object"},"async":{"type":"boolean","default":false,"description":"If async, the assistant will move forward without waiting for your server to respond.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.async","typeLabel":"boolean"},"async_timeout_ms":{"type":"integer","minimum":1,"maximum":15000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.async_timeout_ms","typeLabel":"integer"},"store_fields_as_variables":{"type":"array","description":"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.","items":{"type":"object","required":["name","value_path"],"properties":{"name":{"type":"string","minLength":1,"description":"The name of the dynamic variable to store the extracted value in.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX].name","typeLabel":"string"},"value_path":{"type":"string","minLength":1,"description":"A dot-notation path to the value in the webhook response body (e.g. 'customer.name' or 'id').","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX].value_path","typeLabel":"string"}},"additionalProperties":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.store_fields_as_variables.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.store_fields_as_variables","typeLabel":"object[]"},"messages":{"type":"array","description":"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.","items":{"oneOf":[{"type":"object","title":"WebhookToolRequestStartMessage","required":["type","content"],"properties":{"type":{"type":"string","const":"request_start","description":"Speak the filler message immediately when the webhook request begins.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"An optional delay value. This value is ignored for `request_start` messages.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.0","typeLabel":"WebhookToolRequestStartMessage · object"},{"type":"object","title":"WebhookToolRequestResponseDelayedMessage","required":["type","content","timing_ms"],"properties":{"type":{"type":"string","const":"request_response_delayed","description":"Speak the filler message after the configured delay if the webhook response is still pending.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.type","typeLabel":"string"},"content":{"type":"string","minLength":1,"description":"The text the assistant speaks.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.content","typeLabel":"string"},"timing_ms":{"type":"integer","minimum":100,"maximum":120000,"description":"The delay in milliseconds from the start of the webhook request.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1.timing_ms","typeLabel":"integer"}},"additionalProperties":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX].oneOf.1","typeLabel":"WebhookToolRequestResponseDelayedMessage · object"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages.items.[INDEX]","typeLabel":"WebhookToolRequestStartMessage · object | WebhookToolRequestResponseDelayedMessage · object"},"example":[{"type":"request_start","content":"Let me look that up for you."},{"type":"request_response_delayed","content":"Still working on that.","timing_ms":5000}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook.messages","typeLabel":"(WebhookToolRequestStartMessage · object | WebhookToolRequestResponseDelayedMessage · object)[]"}},"type":"object","required":["url","name","description"],"title":"WebhookToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.webhook","typeLabel":"WebhookToolParams · object"},"timeout_ms":{"type":"integer","default":5000,"maximum":60000,"description":"The maximum number of milliseconds to wait for the webhook to respond before the tool call is aborted. Set this at the tool level, as a sibling of `type` — a `timeout_ms` nested inside the `webhook` object is stored but not applied, and the tool runs at this default instead. Applies when `webhook.async` is false.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.timeout_ms","typeLabel":"integer"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.1","typeLabel":"WebhookTool · object"},{"type":"object","title":"ClientSideTool","required":["type","client_side_tool"],"properties":{"type":{"type":"string","enum":["client_side_tool"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.type","typeLabel":"enum\u003cstring>"},"client_side_tool":{"title":"ClientSideToolParams","type":"object","properties":{"name":{"type":"string","description":"The name of the tool.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.client_side_tool.name","typeLabel":"string"},"description":{"type":"string","description":"The description of the tool.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.client_side_tool.description","typeLabel":"string"},"parameters":{"description":"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","type":"object","properties":{"properties":{"description":"The properties of the parameters.","type":"object","additionalProperties":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.client_side_tool.parameters.properties","typeLabel":"object"},"required":{"description":"The required properties of the parameters.","type":"array","items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.client_side_tool.parameters.required.items.[INDEX]","typeLabel":"string"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.client_side_tool.parameters.required","typeLabel":"string[]"},"type":{"type":"string","enum":["object"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.client_side_tool.parameters.type","typeLabel":"enum\u003cstring>"}},"example":{"properties":{"age":{"description":"The age of the customer.","type":"integer"},"location":{"description":"The location of the customer.","type":"string"}},"required":["age","location"],"type":"object"},"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.client_side_tool.parameters","typeLabel":"object"}},"required":["name","description","parameters"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.client_side_tool","typeLabel":"ClientSideToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.2","typeLabel":"ClientSideTool · object"},{"type":"object","title":"RetrievalTool","required":["type","retrieval"],"properties":{"type":{"type":"string","enum":["retrieval"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.3.type","typeLabel":"enum\u003cstring>"},"retrieval":{"properties":{"bucket_ids":{"items":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.3.retrieval.bucket_ids.items.[INDEX]","typeLabel":"string"},"type":"array","description":"List of [embedded storage buckets](https://developers.telnyx.com/api-reference/embeddings/embed-documents) to use for retrieval-augmented generation.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.3.retrieval.bucket_ids","typeLabel":"string[]"},"max_num_results":{"description":"The maximum number of results to retrieve as context for the language model.","type":"integer","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.3.retrieval.max_num_results","typeLabel":"integer"}},"type":"object","required":["bucket_ids"],"title":"BucketIds","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.3.retrieval","typeLabel":"BucketIds · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.3.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.3","typeLabel":"RetrievalTool · object"},{"type":"object","title":"HandoffTool","description":"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.","required":["type","handoff"],"properties":{"type":{"type":"string","enum":["handoff"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4.type","typeLabel":"enum\u003cstring>"},"handoff":{"properties":{"ai_assistants":{"type":"array","description":"List of possible assistants that can receive a handoff.","items":{"type":"object","properties":{"name":{"type":"string","description":"Helpful name for giving context on when to handoff to the assistant.","example":"Scheduling Specialist","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX].name","typeLabel":"string"},"id":{"type":"string","description":"The ID of the assistant to hand off to.","example":"assistant-1234567890abcdef","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX].id","typeLabel":"string"}},"required":["name","id"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4.handoff.ai_assistants.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4.handoff.ai_assistants","typeLabel":"object[]"},"voice_mode":{"type":"string","enum":["unified","distinct"],"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4.handoff.voice_mode","typeLabel":"enum\u003cstring>"}},"required":["ai_assistants"],"type":"object","title":"HandoffToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4.handoff","typeLabel":"HandoffToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.4","typeLabel":"HandoffTool · object"},{"type":"object","title":"HangupTool","required":["type","hangup"],"properties":{"type":{"type":"string","enum":["hangup"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.5.type","typeLabel":"enum\u003cstring>"},"hangup":{"properties":{"description":{"type":"string","default":"This tool is used to hang up the call.","description":"The description of the function that will be passed to the assistant.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.5.hangup.description","typeLabel":"string"}},"type":"object","title":"HangupToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.5.hangup","typeLabel":"HangupToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.5.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.5","typeLabel":"HangupTool · object"},{"type":"object","title":"TransferTool","required":["type","transfer"],"properties":{"type":{"type":"string","enum":["transfer"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.type","typeLabel":"enum\u003cstring>"},"transfer":{"properties":{"targets":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"to":{"type":"string","description":"The destination number or SIP URI of the call.","example":"+13129457420","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].to","typeLabel":"string"},"name":{"type":"string","description":"The name of the target.","example":"Support","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].name","typeLabel":"string"},"message":{"type":"string","description":"The warm transfer message to deliver to this specific target. When set, it takes precedence over the message the assistant composes from `warm_transfer_instructions`.","example":"I have a caller asking about a billing issue on invoice 4471.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].message","typeLabel":"string"},"extension":{"type":"string","description":"DTMF digits to send automatically after the transfer destination answers. Useful for reaching an extension behind an IVR (e.g. `\"200\"` to dial extension 200 once the called party picks up). Allowed characters: `0-9`, `A-D`, `w` (0.5s pause), `W` (1s pause), `*`, `#`. Maximum 64 characters. When omitted, no automatic DTMF is sent.","example":"wwww200","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].extension","typeLabel":"string"},"sip_auth_username":{"type":"string","description":"SIP Authentication username used for SIP challenges. Applies when `to` is a SIP URI.","example":"sipuser","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].sip_auth_username","typeLabel":"string"},"sip_auth_password":{"type":"string","description":"SIP Authentication password used for SIP challenges. Applies when `to` is a SIP URI.","example":"sippass","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX].sip_auth_password","typeLabel":"string"}},"required":["to"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"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.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.0","typeLabel":"object[]"},{"type":"string","description":"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.","example":"{{ targets }}","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets.oneOf.1","typeLabel":"string"}],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.targets","typeLabel":"object[] | string"},"from":{"type":"string","example":"+35319605860","description":"Number or SIP URI placing the call.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.from","typeLabel":"string"},"diversion":{"type":"string","example":"{{telnyx_agent_target}}","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.diversion","typeLabel":"string"},"warm_transfer_instructions":{"type":"string","example":"Briefly greet the transfer recipient and provide any relevant information from the call. Let them know you will bridge the call right after.","description":"Natural language instructions for your agent for how to provide context for the transfer recipient.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_transfer_instructions","typeLabel":"string"},"warm_transfer_acceptance":{"type":"object","description":"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).","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether the destination must accept the transfer before the calls are bridged.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.enabled","typeLabel":"boolean"},"end_user_target_context_mode":{"type":"string","enum":["private","shared"],"default":"private","description":"Controls whether the private exchange between the assistant and the transfer destination is kept out of the conversation. With `private` (default) the exchange never reaches the conversation history, AI conversations, webhooks or insights, and the transfer tool result is rewritten with the outcome only. With `shared` the exchange stays in the conversation like any other messages.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.end_user_target_context_mode","typeLabel":"enum\u003cstring>"},"require_acceptance":{"type":"boolean","default":false,"description":"Fail closed when the acceptance consult cannot run. Off by default: if the consult cannot be set up for any reason — including where acceptance is unavailable at all (`gather_using_ai`, Conversation Relay or web calls, a conference, or additional invited participants) — the transfer degrades to a plain warm transfer (the warm transfer message is played to the destination as audio and the calls are bridged anyway). Set to true to treat those paths as a decline instead: the destination is disconnected without being asked, the assistant returns to the caller, and no bridge happens without an acceptance. Only consult-setup failures are affected; the destination must still explicitly accept on every consult that does run.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.require_acceptance","typeLabel":"boolean"},"timeout_secs":{"type":"integer","minimum":10,"maximum":600,"default":60,"description":"How long, in seconds, the destination has to accept the transfer, counted from when the private consult starts (right after the destination answers, or after `warm_message_delay_ms`). The caller keeps hearing ringback the whole time. If no acceptance arrives in time, the destination is hung up and the assistant returns to the caller (the transfer fails as a timeout). Raise it for destinations that answer before a human is on the line, such as a call-center queue/ACD or an IVR playing hold audio; keep it as short as practical, since the caller waits on ringback until it expires.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance.timeout_secs","typeLabel":"integer"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_transfer_acceptance","typeLabel":"object"},"description":{"type":"string","description":"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.","example":"Transfer the call to a human agent.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.description","typeLabel":"string"},"bridge_beep":{"type":"object","description":"Plays a short beep once the transfer completes and the calls are bridged, so the transfer destination knows the caller is now on the line. The warm transfer message plays before the bridge; this marks the moment the caller actually joins. Works with and without `warm_transfer_acceptance`.","properties":{"enabled":{"type":"boolean","default":false,"description":"Whether to play the beep when the calls are bridged.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.bridge_beep.enabled","typeLabel":"boolean"},"target_legs":{"type":"string","enum":["self","both"],"default":"self","description":"Who hears the beep. `self` plays it to the transfer destination only; `both` plays it to the destination and the original caller.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.bridge_beep.target_legs","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.bridge_beep","typeLabel":"object"},"warm_message_delay_ms":{"oneOf":[{"type":"integer","example":2000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms.oneOf.0","typeLabel":"integer"},{"type":"null","example":2000,"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.warm_message_delay_ms","typeLabel":"integer | null"},"custom_headers":{"description":"Custom headers to be added to the SIP INVITE for the transfer command.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.custom_headers","typeLabel":"object[]"},"voicemail_detection":{"type":"object","description":"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.","properties":{"detection_mode":{"type":"string","enum":["disabled","premium"],"description":"The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_mode","typeLabel":"enum\u003cstring>"},"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected on the transferred call.","properties":{"action":{"type":"string","enum":["stop_transfer","leave_message_and_stop_transfer"],"description":"The action to take when voicemail is detected. 'stop_transfer' hangs up immediately. 'leave_message_and_stop_transfer' leaves a message then hangs up.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"},"voicemail_message":{"type":"object","description":"Configuration for the voicemail message to leave. Only applicable when action is 'leave_message_and_stop_transfer'.","properties":{"type":{"type":"string","enum":["message","warm_transfer_instructions"],"description":"The type of voicemail message. Use 'message' to leave a specific TTS message, or 'warm_transfer_instructions' to play the warm transfer audio.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message.type","typeLabel":"enum\u003cstring>"},"message":{"type":"string","description":"The specific message to leave as voicemail (converted to speech). Only applicable when type is 'message'.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message.message","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected.voicemail_message","typeLabel":"object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.on_voicemail_detected","typeLabel":"object"},"detection_config":{"type":"object","description":"Advanced AMD detection configuration parameters. All values are optional - Telnyx will use defaults if not specified.","properties":{"greeting_silence_duration_millis":{"type":"integer","minimum":500,"maximum":50000,"description":"Duration of silence after the greeting to wait before considering the greeting complete.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_silence_duration_millis","typeLabel":"integer"},"greeting_total_analysis_time_millis":{"type":"integer","minimum":500,"maximum":300000,"description":"Maximum time to spend analyzing the greeting.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_total_analysis_time_millis","typeLabel":"integer"},"after_greeting_silence_millis":{"type":"integer","minimum":100,"maximum":5000,"description":"Duration of silence after greeting detection before finalizing the result.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.after_greeting_silence_millis","typeLabel":"integer"},"between_words_silence_millis":{"type":"integer","minimum":10,"maximum":5000,"description":"Maximum silence duration between words during greeting.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.between_words_silence_millis","typeLabel":"integer"},"greeting_duration_millis":{"type":"integer","minimum":100,"maximum":10000,"description":"Expected duration of greeting speech.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.greeting_duration_millis","typeLabel":"integer"},"initial_silence_millis":{"type":"integer","minimum":100,"maximum":500000,"description":"Maximum silence duration at the start of the call before speech.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.initial_silence_millis","typeLabel":"integer"},"maximum_number_of_words":{"type":"integer","minimum":1,"maximum":50,"description":"Maximum number of words expected in a human greeting.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.maximum_number_of_words","typeLabel":"integer"},"maximum_word_length_millis":{"type":"integer","minimum":50,"maximum":5000,"description":"Maximum duration of a single word.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.maximum_word_length_millis","typeLabel":"integer"},"silence_threshold":{"type":"integer","minimum":1,"maximum":1000,"description":"Audio level threshold for silence detection.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.silence_threshold","typeLabel":"integer"},"total_analysis_time_millis":{"type":"integer","minimum":500,"maximum":60000,"description":"Total time allowed for AMD analysis.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.total_analysis_time_millis","typeLabel":"integer"},"min_word_length_millis":{"type":"integer","minimum":1,"maximum":1000,"description":"Minimum duration for audio to be considered a word.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config.min_word_length_millis","typeLabel":"integer"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection.detection_config","typeLabel":"object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer.voicemail_detection","typeLabel":"object"}},"type":"object","required":["targets","from"],"title":"TransferToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.transfer","typeLabel":"TransferToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.6","typeLabel":"TransferTool · object"},{"type":"object","title":"InviteTool","required":["type","invite"],"properties":{"type":{"type":"string","enum":["invite"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.type","typeLabel":"enum\u003cstring>"},"invite":{"properties":{"from":{"type":"string","example":"+35319605860","description":"Number or SIP URI placing the call.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.from","typeLabel":"string"},"targets":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"to":{"type":"string","description":"The destination number or SIP URI of the call.","example":"+13129457420","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX].to","typeLabel":"string"},"name":{"type":"string","description":"The name of the target.","example":"Support","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX].name","typeLabel":"string"}},"required":["to"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.targets.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.targets.oneOf.0","typeLabel":"object[]"},{"type":"string","description":"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.","example":"{{ targets }}","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.targets.oneOf.1","typeLabel":"string"},{"type":"null","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.targets.oneOf.2","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.targets","typeLabel":"object[] | string | null"},"custom_headers":{"description":"Custom headers to be added to the SIP INVITE for the invite command.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.custom_headers","typeLabel":"object[]"},"voicemail_detection":{"type":"object","description":"Configuration for voicemail detection (AMD - Answering Machine Detection) on the invited call.","properties":{"detection_mode":{"type":"string","enum":["disabled","premium"],"description":"The AMD detection mode to use. 'premium' enables premium answering machine detection. 'disabled' turns off AMD detection.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.voicemail_detection.detection_mode","typeLabel":"enum\u003cstring>"},"on_voicemail_detected":{"type":"object","description":"Action to take when voicemail is detected on the invited call.","properties":{"action":{"type":"string","enum":["stop_invite"],"description":"The action to take when voicemail is detected.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.voicemail_detection.on_voicemail_detected.action","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.voicemail_detection.on_voicemail_detected","typeLabel":"object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite.voicemail_detection","typeLabel":"object"}},"type":"object","required":["from"],"title":"InviteToolConfig","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.invite","typeLabel":"InviteToolConfig · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.7","typeLabel":"InviteTool · object"},{"type":"object","title":"SIPReferTool","required":["type","refer"],"properties":{"type":{"type":"string","enum":["refer"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.type","typeLabel":"enum\u003cstring>"},"refer":{"properties":{"targets":{"type":"array","description":"The different possible targets of the SIP refer. The assistant will be able to choose one of the targets to refer the call to.","items":{"type":"object","properties":{"name":{"type":"string","description":"The name of the target.","example":"Support","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].name","typeLabel":"string"},"sip_address":{"type":"string","description":"The SIP URI to which the call will be referred.","example":"sip:[email protected]","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_address","typeLabel":"string"},"sip_auth_username":{"type":"string","description":"SIP Authentication username used for SIP challenges.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_auth_username","typeLabel":"string"},"sip_auth_password":{"type":"string","description":"SIP Authentication password used for SIP challenges.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.targets.items.[INDEX].sip_auth_password","typeLabel":"string"}},"required":["name","sip_address"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.targets.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.targets","typeLabel":"object[]"},"sip_headers":{"description":"SIP headers to be added to the SIP REFER. Currently only User-to-User and Diversion headers are supported.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","enum":["User-to-User","Diversion"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX].name","typeLabel":"enum\u003cstring>"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.sip_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.sip_headers","typeLabel":"object[]"},"custom_headers":{"description":"Custom headers to be added to the SIP REFER.","type":"array","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX].name","typeLabel":"string"},"value":{"description":"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.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.custom_headers.items.[INDEX]","typeLabel":"object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer.custom_headers","typeLabel":"object[]"}},"type":"object","required":["targets"],"title":"SIPReferToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.refer","typeLabel":"SIPReferToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.8","typeLabel":"SIPReferTool · object"},{"type":"object","title":"DTMFTool","required":["type","send_dtmf"],"properties":{"type":{"type":"string","enum":["send_dtmf"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.9.type","typeLabel":"enum\u003cstring>"},"send_dtmf":{"type":"object","additionalProperties":true,"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.9.send_dtmf","typeLabel":"object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.9.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.9","typeLabel":"DTMFTool · object"},{"type":"object","title":"SendMessageTool","description":"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.","required":["type","send_message"],"properties":{"type":{"type":"string","enum":["send_message"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.10.type","typeLabel":"enum\u003cstring>"},"send_message":{"type":"object","properties":{"message_template":{"oneOf":[{"type":"string","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.10.send_message.message_template.oneOf.0","typeLabel":"string"},{"type":"null","description":"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.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.10.send_message.message_template.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.10.send_message.message_template","typeLabel":"string | null"}},"additionalProperties":true,"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.10.send_message","typeLabel":"object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.10.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.10","typeLabel":"SendMessageTool · object"},{"type":"object","title":"SkipTurnTool","required":["type","skip_turn"],"properties":{"type":{"type":"string","enum":["skip_turn"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.11.type","typeLabel":"enum\u003cstring>"},"skip_turn":{"properties":{"description":{"type":"string","default":"This tool is used to skip the assistant turn without producing a response.","description":"The description of the function that will be passed to the assistant.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.11.skip_turn.description","typeLabel":"string"}},"type":"object","title":"SkipTurnToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.11.skip_turn","typeLabel":"SkipTurnToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.11.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.11","typeLabel":"SkipTurnTool · object"},{"type":"object","title":"VisionTool","description":"(BETA) Lets the assistant look at recent image frames the client sent into the conversation (for example webcam or screen-share frames). Frames are sent with `conversation.item.create` and `item.buffer: true`; they never trigger a response on their own. The assistant decides when to look and which frames it needs. Requires a model that supports image input.","required":["type"],"properties":{"type":{"type":"string","enum":["vision"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.12.type","typeLabel":"enum\u003cstring>"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.12.shared","typeLabel":"boolean"},"vision":{"properties":{"max_frame_age_secs":{"type":"integer","minimum":1,"default":10,"description":"Frames received longer ago than this many seconds are not shown to the assistant, so it never describes a frozen or disconnected camera as live.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.12.vision.max_frame_age_secs","typeLabel":"integer"}},"type":"object","title":"VisionToolParams","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.12.vision","typeLabel":"VisionToolParams · object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.12","typeLabel":"VisionTool · object"},{"type":"object","title":"PayTool","description":"(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.","required":["type","pay"],"properties":{"type":{"type":"string","enum":["pay"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.type","typeLabel":"enum\u003cstring>"},"pay":{"properties":{"connector_name":{"type":"string","description":"The name of the pay connector configured in the Telnyx API. Must reference an existing pay connector for this organization.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.connector_name","typeLabel":"string"},"currency":{"type":"string","default":"USD","description":"Default currency for payments processed by this tool.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.currency","typeLabel":"string"},"payment_method":{"type":"string","default":"credit-card","description":"Default payment method for payments processed by this tool.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.payment_method","typeLabel":"string"},"description":{"oneOf":[{"type":"string","default":null,"description":"Description of the pay tool shown to the assistant so it knows when to call the tool. Not sent to the payment connector — the per-call `description` argument the assistant passes is what reaches the processor.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.description.oneOf.0","typeLabel":"string"},{"type":"null","default":null,"description":"Description of the pay tool shown to the assistant so it knows when to call the tool. Not sent to the payment connector — the per-call `description` argument the assistant passes is what reaches the processor.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.description.oneOf.1","typeLabel":"null"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.description","typeLabel":"string | null"},"connector_parameters":{"type":"object","additionalProperties":true,"description":"Custom key/value parameters forwarded to the pay connector as `parameters` in the processor request. String values may use `{{dynamic_variable}}` templating, resolved per call.","example":{"campaignid":"abc","customer_ref":"CUST-67890"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.connector_parameters","typeLabel":"object"},"valid_card_types":{"type":"array","items":{"type":"string","enum":["visa","mastercard","amex","maestro","discover","optima","jcb","diners-club","enroute"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.valid_card_types.items.[INDEX]","typeLabel":"enum\u003cstring>"},"minItems":1,"description":"Restricts accepted card numbers to the listed card types. When the caller enters a card number that does not match one of the listed types, Pay treats the input as invalid and re-prompts for the card number.","example":["visa","mastercard"],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.valid_card_types","typeLabel":"enum\u003cstring>[]"},"postal_code":{"oneOf":[{"type":"string","description":"Controls billing postal code collection for credit-card payments. Set to `false` to skip the postal code prompt without supplying a postal code to the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to prompt the caller. Supply a non-empty string, such as `\"90210\"`, to use that postal code without prompting. This option does not affect ACH debit payments or payments using an existing token.","minLength":1,"pattern":"\\S","example":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.postal_code.oneOf.0","typeLabel":"string"},{"type":"boolean","description":"Controls billing postal code collection for credit-card payments. Set to `false` to skip the postal code prompt without supplying a postal code to the payment connector (non-US cards, e.g. Irish Eircodes). Set to `true` to prompt the caller. Supply a non-empty string, such as `\"90210\"`, to use that postal code without prompting. This option does not affect ACH debit payments or payments using an existing token.","example":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.postal_code.oneOf.1","typeLabel":"boolean"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.postal_code","typeLabel":"string | boolean"},"min_postal_code_length":{"type":"integer","minimum":1,"maximum":128,"description":"Minimum number of digits the caller must enter when collecting a credit-card billing postal code. Applies only when `postal_code` prompts the caller. Omitted means the platform default (1) applies. The maximum number of digits collected is the greater of 10 and this value. This does not validate the length of a postal code supplied directly in `postal_code`.","example":5,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.min_postal_code_length","typeLabel":"integer"},"max_attempts":{"type":"integer","minimum":1,"maximum":3,"description":"Maximum number of attempts for each payment collection step. Omitted means the platform default (3) applies.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.max_attempts","typeLabel":"integer"},"timeout_millis":{"type":"integer","minimum":1,"maximum":600000,"description":"Time in milliseconds to wait for DTMF input for each collection step. Omitted means the platform default (5000) applies. Increase this for slower entry, e.g. a 16-digit card number.","example":12000,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.timeout_millis","typeLabel":"integer"},"inter_digit_timeout_millis":{"type":"integer","minimum":1,"maximum":600000,"description":"Time in milliseconds to wait between consecutive DTMF digits. Omitted means the platform default (5000) applies.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.inter_digit_timeout_millis","typeLabel":"integer"},"prompts":{"type":"object","title":"Pay Tool Prompts","description":"Custom text-to-speech prompts keyed by payment collection step. The AI assistant merges its own card-number prompt into this map, matching on the same step keys.","additionalProperties":false,"properties":{"payment-card-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.payment-card-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.payment-card-number","typeLabel":"string | Pay Tool Prompt · object[]"},"expiration-date":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.expiration-date.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.expiration-date","typeLabel":"string | Pay Tool Prompt · object[]"},"postal-code":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.postal-code.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.postal-code","typeLabel":"string | Pay Tool Prompt · object[]"},"security-code":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.security-code.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.security-code","typeLabel":"string | Pay Tool Prompt · object[]"},"bank-routing-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-routing-number","typeLabel":"string | Pay Tool Prompt · object[]"},"bank-account-number":{"oneOf":[{"type":"string","title":"Pay Tool Prompt Value","description":"A default prompt string or an ordered list of qualified prompts.","minLength":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"object","title":"Pay Tool Prompt","description":"A text-to-speech prompt with optional matching qualifiers, mirroring the Voice API PayPrompt schema.","required":["text"],"additionalProperties":false,"properties":{"text":{"type":"string","minLength":1,"description":"Text spoken for the payment collection step.","example":"Please enter your card number.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].text","typeLabel":"string"},"attempt":{"type":"string","description":"Space-separated 1-based attempt numbers (1-9 followed by digits only, e.g. `\"2 3\"`) for which this prompt applies. A prompt qualified with an attempt number above `max_attempts` (default 3) is rejected at write time — it could never play.","example":"2 3","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].attempt","typeLabel":"string"},"error_type":{"type":"string","description":"Step error for which this prompt applies.","enum":["timeout","invalid-card-number","invalid-card-type","invalid-date","invalid-security-code","invalid-postal-code","invalid-bank-routing-number","invalid-bank-account-number","input-matching-failed"],"example":"invalid-card-number","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].error_type","typeLabel":"enum\u003cstring>"},"card_type":{"type":"string","description":"Lowercase, case-sensitive detected card type for which this prompt applies.","enum":["visa","mastercard","amex","optima","discover","diners-club","jcb","maestro","enroute"],"example":"amex","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX].card_type","typeLabel":"enum\u003cstring>"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1.items.[INDEX]","typeLabel":"Pay Tool Prompt · object"},"title":"Pay Tool Prompt List","description":"A default prompt string or an ordered list of qualified prompts.","minItems":1,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-account-number.oneOf.1","typeLabel":"Pay Tool Prompt · object[]"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts.bank-account-number","typeLabel":"string | Pay Tool Prompt · object[]"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay.prompts","typeLabel":"Pay Tool Prompts · object"}},"required":["connector_name"],"type":"object","title":"PayToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.pay","typeLabel":"PayToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.13","typeLabel":"PayTool · object"},{"type":"object","title":"UpdateDynamicVariablesTool","description":"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`.","required":["type","update_dynamic_variables"],"properties":{"type":{"type":"string","enum":["update_dynamic_variables"],"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.type","typeLabel":"enum\u003cstring>"},"update_dynamic_variables":{"description":"Configuration for an update_dynamic_variables tool.","properties":{"name":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","description":"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.","example":"collect_details","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.update_dynamic_variables.name","typeLabel":"string"},"description":{"type":"string","description":"Description of the tool passed to the assistant, guiding when to call it and which variables to update.","example":"Collect caller details into conversation variables.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.update_dynamic_variables.description","typeLabel":"string"},"updatable_variables":{"type":"array","description":"The dynamic variables the assistant is allowed to write. At least one is required.","minItems":1,"items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"pattern":"^(?!telnyx_)[a-zA-Z0-9._-]+$","description":"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.","example":"customer_name","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].name","typeLabel":"string"},"type":{"type":"string","description":"Optional hint for the variable's value type (e.g. `string`).","example":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].type","typeLabel":"string"},"description":{"type":"string","description":"Optional description of the variable, guiding the assistant on what value to capture.","example":"The caller's full name.","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX].description","typeLabel":"string"}},"required":["name"],"additionalProperties":false,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.update_dynamic_variables.updatable_variables","typeLabel":"object[]"}},"required":["name","description","updatable_variables"],"type":"object","title":"UpdateDynamicVariablesToolParams","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.update_dynamic_variables","typeLabel":"UpdateDynamicVariablesToolParams · object"},"shared":{"type":"boolean","description":"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).","readOnly":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14.shared","typeLabel":"boolean"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX].oneOf.14","typeLabel":"UpdateDynamicVariablesTool · object"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool.items.[INDEX]","typeLabel":"FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object"},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.tool","typeLabel":"(FunctionTool · object | WebhookTool · object | ClientSideTool · object | RetrievalTool · object | HandoffTool · object | HangupTool · object | TransferTool · object | InviteTool · object | SIPReferTool · object | DTMFTool · object | SendMessageTool · object | SkipTurnTool · object | VisionTool · object | PayTool · object | UpdateDynamicVariablesTool · object)[]"},"type":{"const":"tool","default":"tool","description":"Node kind discriminator. Always `tool` for a tool node.","title":"Type","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.type","typeLabel":"string"},"message":{"description":"Optional message delivered to the user verbatim immediately before the tool executes — an announcement such as 'One moment while I look that up.' No LLM turn and no customer turn: the message is spoken/sent, then the tool runs, in the same deterministic step. `{{variable}}` placeholders are interpolated from the conversation's dynamic variables (unresolved → empty string); the tool's own result is not yet available when the message is rendered. Omit for a silent tool step.","example":"One moment while I process your payment.","minLength":1,"pattern":"\\S","title":"Message","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1.message","typeLabel":"string"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.1","typeLabel":"ToolNode · object"},{"type":"object","title":"SpeakNode","description":"A standalone scripted-message step in a flow, as returned by the API.","required":["id","message"],"properties":{"id":{"type":"string","title":"Id","description":"Caller-supplied unique identifier for this node within the flow.","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.id","typeLabel":"string"},"message":{"type":"string","title":"Message","description":"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).","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.message","typeLabel":"string"},"type":{"type":"string","const":"speak","title":"Type","description":"Node kind discriminator. Always `speak` for a speak node.","default":"speak","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.type","typeLabel":"string"},"name":{"title":"Name","description":"Optional human-readable label, displayed in authoring UIs.","type":"string","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.name","typeLabel":"string"},"position":{"description":"Optional canvas coordinates used by authoring UIs to lay out the graph. Ignored by the runtime; round-trips so frontends can persist graph layout across reloads.","properties":{"x":{"description":"Horizontal coordinate in the authoring canvas.","title":"X","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.position.x","typeLabel":"number"},"y":{"description":"Vertical coordinate in the authoring canvas.","title":"Y","type":"number","isRequired":true,"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.position.y","typeLabel":"number"}},"required":["x","y"],"title":"NodePosition","type":"object","uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2.position","typeLabel":"NodePosition · object"}},"uniqueKey":"conversation_flow.nodes.items.[INDEX].oneOf.2","typeLabel":"SpeakNode · object"}],"uniqueKey":"conversation_flow.nodes.items.[INDEX]","typeLabel":"FlowNode · object | ToolNode · object | SpeakNode · object"},"title":"Nodes","type":"array","isRequired":true,"uniqueKey":"conversation_flow.nodes","typeLabel":"(FlowNode · object | ToolNode · object | SpeakNode · object)[]"},"start_node_id":{"description":"ID of the node where the conversation begins.","title":"Start Node Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.start_node_id","typeLabel":"string"},"edges":{"description":"Directed transitions between nodes.","items":{"description":"Directed transition from one node to a target, gated by a condition.\n\nThe target is either another node in the same flow (`NodeTarget`) or a\ndifferent assistant (`AssistantTarget`). Multiple edges may share a\n`start_node_id`. On calls, `expression` conditions are evaluated before\nthe model turn and take precedence over `llm` conditions regardless of\ndeclaration order, while `llm` conditions are offered to the assistant's\nmodel as transition tools and fire when the model selects one. On chat\nchannels, an `expression` condition that is true when the turn begins\nroutes before the reply is generated; all conditioned edges that remain\nare considered together in declaration order after the reply, and the\nfirst true one wins.","properties":{"condition":{"oneOf":[{"type":"object","title":"LLMCondition","description":"Edge condition routed by the assistant's LLM from a natural-language\nprompt.\n\nHow the edge is decided depends on the channel. On calls, each outgoing\n`llm` condition is offered to the assistant's model as a transition tool\nalongside the assistant's tools, and the edge fires when the model\nselects it; the platform does not evaluate the prompt itself, and\ninstructions that forbid or discourage tool calls can stop these edges\nfrom firing. On chat channels, the edge prompts are evaluated in a\nseparate model call after the reply, which does not use the assistant's\ninstructions. Use this for fuzzy intents that aren't expressible as a\ndeterministic expression (e.g. 'user wants to escalate to a human').","required":["type","prompt"],"example":{"prompt":"The user has confirmed their booking details.","type":"llm"},"properties":{"prompt":{"description":"Natural-language criterion the model routes on. On calls this is offered to the model as the transition tool's description; on chat channels it is judged as a statement in the post-reply evaluation call.","example":"The user has confirmed their booking details.","title":"Prompt","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.0.prompt","typeLabel":"string"},"type":{"const":"llm","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.0.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.0","typeLabel":"LLMCondition · object"},{"type":"object","title":"ExpressionCondition","description":"Edge condition evaluated as a deterministic expression AST.\n\nThe expression is computed against runtime dynamic variables and must\nevaluate to a boolean. Prefer this over `LLMCondition` when the rule is\na clean function of known variables — it's cheaper and predictable.","required":["type","expression"],"example":{"expression":{"left":{"name":"user_age","type":"variable"},"op":">=","right":{"type":"number_literal","value":18},"type":"comparison"},"type":"expression"},"properties":{"expression":{"oneOf":[{"type":"object","title":"ComparisonExpression","description":"Compare two sub-expressions with a relational or membership operator.\n\nEvaluates to a boolean. Used in edge conditions to gate transitions on\nruntime values, e.g. `user_age >= 18` or `tier == \"gold\"`.","required":["type","op","left","right"],"example":{"left":{"name":"user_age","type":"variable"},"op":">=","right":{"type":"number_literal","value":18},"type":"comparison"},"properties":{"left":{"oneOf":[{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7","isRequired":true}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0.left","typeLabel":"any"},"op":{"description":"Relational/membership operator. `contains` / `not_contains` apply to strings (substring) and arrays (membership).","enum":["==","!=","\u003c","\u003c=",">",">=","contains","not_contains"],"title":"Op","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0.op","typeLabel":"enum\u003cstring>"},"right":{"oneOf":[{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7","isRequired":true}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0.right","typeLabel":"any"},"type":{"const":"comparison","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.0","typeLabel":"ComparisonExpression · object"},{"type":"object","title":"BooleanOpExpression","description":"Combine sub-expressions with a logical operator (`and` / `or` / `not`).\n\n`and` and `or` accept two or more operands; `not` accepts exactly one.","required":["type","op","operands"],"example":{"op":"and","operands":[{"name":"is_premium","type":"variable"},{"left":{"name":"user_age","type":"variable"},"op":">=","right":{"type":"number_literal","value":18},"type":"comparison"}],"type":"bool_op"},"properties":{"op":{"description":"Logical operator. `not` is unary; `and`/`or` are n-ary (>=2).","enum":["and","or","not"],"title":"Op","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.1.op","typeLabel":"enum\u003cstring>"},"operands":{"description":"Operand sub-expressions. Length must be exactly 1 for `not` and >= 2 for `and`/`or`.","items":{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7"},"title":"Operands","type":"array","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.1.operands","typeLabel":"Operands · array"},"type":{"const":"bool_op","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.1.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.1","typeLabel":"BooleanOpExpression · object"},{"type":"object","title":"ArithmeticExpression","description":"Numeric expression: applies an arithmetic operator to two sub-expressions.\n\nUseful for derived numeric checks, e.g. `cart_total + shipping > 50`.\nBoth operands should resolve to numbers at runtime.","required":["type","op","left","right"],"example":{"left":{"name":"cart_total","type":"variable"},"op":"+","right":{"name":"shipping_cost","type":"variable"},"type":"arithmetic"},"properties":{"left":{"oneOf":[{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7","isRequired":true}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2.left","typeLabel":"any"},"op":{"description":"Arithmetic operator applied to `left` and `right`.","enum":["+","-","*","/","%"],"title":"Op","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2.op","typeLabel":"enum\u003cstring>"},"right":{"oneOf":[{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7","isRequired":true}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2.right","typeLabel":"any"},"type":{"const":"arithmetic","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.2","typeLabel":"ArithmeticExpression · object"},{"type":"object","title":"DynamicVariableExpression","description":"Reference a dynamic variable by name.\n\nResolved at runtime from the assistant's dynamic-variables context (see\n`Assistant.dynamic_variables` and the dynamic-variables webhook).","required":["type","name"],"example":{"name":"user_age","type":"variable"},"properties":{"name":{"description":"Variable name to look up in the runtime context.","example":"user_age","title":"Name","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.3.name","typeLabel":"string"},"type":{"const":"variable","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.3.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.3","typeLabel":"DynamicVariableExpression · object"},{"type":"object","title":"StringLiteralExpression","description":"Constant string value.","required":["type","value"],"example":{"type":"string_literal","value":"gold"},"properties":{"type":{"const":"string_literal","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.4.type","typeLabel":"string"},"value":{"description":"Literal string value.","example":"gold","title":"Value","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.4.value","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.4","typeLabel":"StringLiteralExpression · object"},{"type":"object","title":"NumberLiteralExpression","description":"Constant numeric value (float; integers are accepted and stored as float).","required":["type","value"],"example":{"type":"number_literal","value":18},"properties":{"type":{"const":"number_literal","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.5.type","typeLabel":"string"},"value":{"description":"Literal numeric value.","example":18,"title":"Value","type":"number","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.5.value","typeLabel":"number"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.5","typeLabel":"NumberLiteralExpression · object"},{"type":"object","title":"BooleanLiteralExpression","description":"Constant boolean value. Useful for unconditional ('always') edges.","required":["type","value"],"example":{"type":"bool_literal","value":true},"properties":{"type":{"const":"bool_literal","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.6.type","typeLabel":"string"},"value":{"description":"Literal boolean value.","title":"Value","type":"boolean","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.6.value","typeLabel":"boolean"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression.oneOf.6","typeLabel":"BooleanLiteralExpression · object"}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.expression","typeLabel":"ComparisonExpression · object | BooleanOpExpression · object | ArithmeticExpression · object | DynamicVariableExpression · object | StringLiteralExpression · object | NumberLiteralExpression · object | BooleanLiteralExpression · object"},"type":{"const":"expression","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.1","typeLabel":"ExpressionCondition · object"},{"type":"object","title":"DefaultCondition","description":"Fallback edge condition: fires only when no other edge's condition is true.\n\nEvaluated after every conditioned (`llm` / `expression`) edge regardless\nof declaration order, so it routes the flow whenever none of the node's\nother outgoing edges match. Valid **only** on edges leaving a `tool` or\n`speak` node, where the deterministic step auto-advances and must always\nhave somewhere to go. A tool/speak node with any outgoing edge is required\nto carry exactly one `default` edge so it never dead-ends; a tool/speak\nnode with no outgoing edges is a valid terminal step. Carries no parameters.","required":["type"],"example":{"type":"default"},"properties":{"type":{"type":"string","const":"default","title":"Type","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.2.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition.oneOf.2","typeLabel":"DefaultCondition · object"}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].condition","typeLabel":"LLMCondition · object | ExpressionCondition · object | DefaultCondition · object"},"id":{"description":"Caller-supplied unique identifier for this edge within the flow.","example":"e_age_gate","title":"Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].id","typeLabel":"string"},"start_node_id":{"description":"ID of the node this edge transitions away from.","title":"Start Node Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].start_node_id","typeLabel":"string"},"target":{"oneOf":[{"type":"object","title":"NodeTarget","description":"Edge target referencing another node within the same flow.\n\nThe runtime transitions the active node to `node_id` and continues\nprocessing within the current assistant's flow.","required":["type","node_id"],"properties":{"node_id":{"description":"ID of the node this edge transitions into.","example":"n_billing","title":"Node Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.0.node_id","typeLabel":"string"},"type":{"const":"node","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.0.type","typeLabel":"string"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.0","typeLabel":"NodeTarget · object"},{"type":"object","title":"AssistantTarget","description":"Edge target referencing a different assistant.\n\nWhen the edge fires, the conversation hands off to `assistant_id`: the\nactive assistant on the conversation row is rewritten and the new\nassistant's flow starts at its own `start_node_id`. The current turn's\nLLM response is delivered to the user as-is; subsequent turns route\nto the new assistant.","required":["type","assistant_id"],"properties":{"assistant_id":{"description":"ID of the assistant the conversation transitions to.","example":"assistant-billing","title":"Assistant Id","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.assistant_id","typeLabel":"string"},"type":{"const":"assistant","title":"Type","type":"string","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.type","typeLabel":"string"},"position":{"description":"Optional canvas coordinates for rendering the target assistant as a node in authoring UIs. Pure presentation — the runtime ignores it; round-trips so frontends can persist graph layout across reloads. When multiple edges target the same assistant, each edge's `position` is independent (frontends typically use the first non-null one).","properties":{"x":{"description":"Horizontal coordinate in the authoring canvas.","title":"X","type":"number","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.position.x","typeLabel":"number"},"y":{"description":"Vertical coordinate in the authoring canvas.","title":"Y","type":"number","isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.position.y","typeLabel":"number"}},"required":["x","y"],"title":"NodePosition","type":"object","example":{"x":600,"y":80},"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.position","typeLabel":"NodePosition · object"},"voice_mode":{"default":"unified","description":"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`.","enum":["unified","distinct"],"title":"Voice Mode","type":"string","uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1.voice_mode","typeLabel":"enum\u003cstring>"}},"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target.oneOf.1","typeLabel":"AssistantTarget · object"}],"isRequired":true,"uniqueKey":"conversation_flow.edges.items.[INDEX].target","typeLabel":"NodeTarget · object | AssistantTarget · object"}},"required":["id","start_node_id","target","condition"],"title":"FlowEdge","type":"object","uniqueKey":"conversation_flow.edges.items.[INDEX]","typeLabel":"FlowEdge · object"},"title":"Edges","type":"array","uniqueKey":"conversation_flow.edges","typeLabel":"FlowEdge · object[]"}},"required":["start_node_id","nodes"],"title":"ConversationFlow","type":"object","uniqueKey":"conversation_flow","typeLabel":"ConversationFlow · object"}},"type":"object","required":["id","name","created_at","model","instructions"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"id":"\u003cstring>","name":"\u003cstring>","created_at":"2023-11-07T05:31:56Z","model":"\u003cstring>","instructions":"\u003cstring>","version_id":"\u003cstring>","version_created_at":"2023-11-07T05:31:56Z","description":"\u003cstring>","tools":[{"type":"function","function":{"name":"\u003cstring>","description":"\u003cstring>","parameters":{}},"shared":true}],"mcp_servers":[],"a2a_agents":[],"greeting":"\u003cstring>","llm_api_key_ref":"\u003cstring>","external_llm":{"model":"\u003cstring>","base_url":"\u003cstring>","llm_api_key_ref":"\u003cstring>","authentication_method":"token","certificate_ref":"\u003cstring>","token_retrieval_url":"\u003cstring>","forward_metadata":false,"extra_headers":{}},"fallback_config":{"model":"\u003cstring>","llm_api_key_ref":"\u003cstring>","external_llm":{"model":"\u003cstring>","base_url":"\u003cstring>","llm_api_key_ref":"\u003cstring>","authentication_method":"token","certificate_ref":"\u003cstring>","token_retrieval_url":"\u003cstring>","forward_metadata":false,"extra_headers":{}}},"voice_settings":{"voice":"\u003cstring>","voice_speed":1,"api_key_ref":"\u003cstring>","temperature":0.5,"similarity_boost":0.75,"use_speaker_boost":true,"style":0,"speed":1,"language":null,"language_boost":null,"expressive_mode":false,"background_audio":{"type":"predefined_media","value":"silence","volume":1},"tool_call_audio":{"type":"predefined_media","value":"typing","volume":0.5}},"avatar_settings":{"provider":"telnyx","avatar_id":"elena","background_id":"office","model":"foxtrot-1"},"transcription":{"model":"deepgram/flux","language":"\u003cstring>","api_key_ref":"\u003cstring>","region":"\u003cstring>","settings":{"smart_format":true,"numerals":true,"eot_threshold":0.8,"eot_timeout_ms":5000,"eager_eot_threshold":0.8,"keyterm":"\u003cstring>","remove_disfluencies":false,"end_of_turn_confidence_threshold":0.5,"prompt":"\u003cstring>","min_turn_silence":400,"max_turn_silence":1280,"interim_results":false,"enable_endpoint_detection":false,"max_endpoint_delay_ms":1750,"context":"\u003cstring>","language_hints":["\u003cstring>"]},"fallback_models":[{"model":"deepgram/nova-3","language":"en"},{"model":"soniox/stt-rt-v5","settings":{"context":"Telnyx,VoIP,SIP"}}],"challenger":{"model":"deepgram/nova-3","language":"en","rule":"best_turn"}},"telephony_settings":{"default_texml_app_id":"\u003cstring>","supports_unauthenticated_web_calls":true,"noise_suppression":"aicoustics","noise_suppression_config":{"attenuation_limit":100,"mode":"advanced","family":"quail","size":"vf","enhancement_level":0.8},"time_limit_secs":1800,"user_idle_timeout_secs":7205,"user_idle_reply_secs":10,"fallback_destination":"\u003cstring>","send_message_history_updates":true,"conversation_ended_full_history":false,"greeting_delay_ms":1000,"voicemail_detection":{"on_voicemail_detected":{"action":"stop_assistant","voicemail_message":{"type":"prompt","prompt":"\u003cstring>","message":"\u003cstring>"}}},"disable_dtmf":false,"recording_settings":{"enabled":true,"channels":"dual","format":"mp3","stop_on_conversation_end":false}},"messaging_settings":{"default_messaging_profile_id":"\u003cstring>","delivery_status_webhook_url":"\u003cstring>","conversation_inactivity_minutes":5000000},"enabled_features":["telephony"],"insight_settings":{"insight_group_id":"\u003cstring>","model":"zai-org/GLM-5.3-Flash"},"privacy_settings":{"data_retention":true,"pii_redaction":"disabled","in_transit_data_locality":false},"dynamic_variables_webhook_url":"\u003cstring>","dynamic_variables_webhook_timeout_ms":1500,"dynamic_variables":{},"import_metadata":{"import_provider":"elevenlabs","import_id":"\u003cstring>"},"widget_settings":{"theme":"light","audio_visualizer_config":{"color":"verdant","preset":"\u003cstring>"},"start_call_text":"\u003cstring>","default_state":"expanded","position":"fixed","view_history_url":"\u003cstring>","report_issue_url":"\u003cstring>","give_feedback_url":"\u003cstring>","agent_thinking_text":"\u003cstring>","speak_to_interrupt_text":"\u003cstring>","logo_icon_url":"\u003cstring>"},"interruption_settings":{"enable":true,"disable_greeting_interruption":true,"start_speaking_plan":{"wait_seconds":0.4,"transcription_endpointing_plan":{"on_punctuation_seconds":0.1,"on_no_punctuation_seconds":1.5,"on_number_seconds":0.5}},"interrupt_prediction_threshold":0},"integrations":[],"observability_settings":{"status":"disabled","secret_key_ref":"\u003cstring>","public_key_ref":"\u003cstring>","host":"\u003cstring>","prompt_name":"\u003cstring>","prompt_version":2,"prompt_label":"\u003cstring>","prompt_sync":"disabled"},"version_name":"New assistant","related_mission_ids":[],"tags":[],"post_conversation_settings":{"enabled":false},"delegation_settings":{"enabled":true,"mode":"telnyx","model":"\u003cstring>","llm_api_key_ref":"\u003cstring>","instructions":"\u003cstring>","speak_results":true,"external_llm":{"model":"\u003cstring>","base_url":"\u003cstring>","llm_api_key_ref":"\u003cstring>","authentication_method":"token","certificate_ref":"\u003cstring>","token_retrieval_url":"\u003cstring>","forward_metadata":false,"extra_headers":{}}},"websocket_settings":{"enabled":false,"url":"\u003cstring>","auth_ref":"\u003cstring>"},"conversation_flow":{"edges":[{"condition":{"prompt":"The caller is asking about a bill or charge.","type":"llm"},"id":"e_intake_to_billing","start_node_id":"n_intake","target":{"node_id":"n_billing","type":"node"}},{"condition":{"prompt":"The caller has explicitly asked for a human.","type":"llm"},"id":"e_intake_to_escalation_assistant","start_node_id":"n_intake","target":{"assistant_id":"assistant-human-handoff","position":{"x":600,"y":80},"type":"assistant","voice_mode":"distinct"}}],"nodes":[{"type":"prompt","id":"n_intake","instructions":"Greet the caller and ask what they're calling about.","name":"Intake","position":{"x":120,"y":80},"shared_tool_ids":["tool-faq-kb"]},{"type":"prompt","id":"n_billing","instructions":"Focus on billing questions. Look up the caller's latest invoice with the billing tool before answering.","instructions_mode":"append","model":"moonshotai/Kimi-K2.6","name":"Billing","position":{"x":420,"y":80},"shared_tool_ids":["tool-billing-lookup"],"tools_mode":"append"}],"start_node_id":"n_intake"}}}},"exampleType":"generated"}},"headers":{"Idempotent-Replayed":{"description":"Present with value `true` when Edge replayed a stored successful response for the supplied Idempotency-Key. Omitted for first-time requests and error responses.","schema":{"type":"boolean","enum":[true],"example":true}}},"exampleType":"generated"},"830c28a4-8fe9-4cac-b8e0-7a5cf026f2d5":{"description":"Bad Request / Validation Failed (10015). Invalid, duplicate, empty, malformed, or overlong Idempotency-Key headers are rejected by Edge with HTTP 400 and error code 10015. The assistant configuration is validated too: enabling `privacy_settings.in_transit_data_locality` is refused when the organization's data-locality region has no in-region inference, when any model the assistant could use — its `model`, its `fallback_config`, or a conversation-flow node override — is not Telnyx-hosted, or when its `insight_settings.model` is not available in that region.","content":{"application/json":{"schema":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Telnyx error code. Edge idempotency errors use 10015, 10027, or 10036; idempotency protection outages use 10016; replay-cap 413s surface 10007. Fallback 404/500 responses from the framework may use string status codes ('404', '500') instead.","enum":["10007","10015","10016","10027","10036","404","500"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"enum\u003cstring>"},"title":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].title","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"errors.items.[INDEX].detail","typeLabel":"string"},"source":{"type":"object","properties":{"pointer":{"type":"string","uniqueKey":"errors.items.[INDEX].source.pointer","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX].source","typeLabel":"object"}},"required":["code","title"],"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"errors","typeLabel":"object[]"}},"required":["errors"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"errors":[{"code":"10007","title":"\u003cstring>","detail":"\u003cstring>","source":{"pointer":"\u003cstring>"}}]}}},"exampleType":"generated"}},"exampleType":"generated"},"3ff5470f-dc53-4d2f-ab01-914012e2821c":{"description":"A request with the same Idempotency-Key is still being processed (10036). Retry later with the same key and request.","content":{"application/json":{"schema":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Telnyx error code. Edge idempotency errors use 10015, 10027, or 10036; idempotency protection outages use 10016; replay-cap 413s surface 10007. Fallback 404/500 responses from the framework may use string status codes ('404', '500') instead.","enum":["10007","10015","10016","10027","10036","404","500"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"enum\u003cstring>"},"title":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].title","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"errors.items.[INDEX].detail","typeLabel":"string"},"source":{"type":"object","properties":{"pointer":{"type":"string","uniqueKey":"errors.items.[INDEX].source.pointer","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX].source","typeLabel":"object"}},"required":["code","title"],"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"errors","typeLabel":"object[]"}},"required":["errors"],"uniqueKey":"","typeLabel":"object"},"example":{"errors":[{"code":"10036","title":"Resource is being processed","detail":"A request with this Idempotency-Key is already being processed.","source":{"pointer":"/header/Idempotency-Key"}}]},"examples":{"Example":{"title":"Example","value":{"errors":[{"code":"10036","title":"Resource is being processed","detail":"A request with this Idempotency-Key is already being processed.","source":{"pointer":"/header/Idempotency-Key"}}]}}},"exampleType":"examples"}},"exampleType":"examples"},"a16cb406-84d3-4f55-afff-74a3e8272ca8":{"description":"Payload Too Large. A request sent with an Idempotency-Key whose body exceeds the endpoint's Edge replay-protection limit (256 KB) is rejected before it reaches the service. Requests sent without the header are not subject to this limit.","content":{"application/json":{"schema":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Telnyx error code. Edge idempotency errors use 10015, 10027, or 10036; idempotency protection outages use 10016; replay-cap 413s surface 10007. Fallback 404/500 responses from the framework may use string status codes ('404', '500') instead.","enum":["10007","10015","10016","10027","10036","404","500"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"enum\u003cstring>"},"title":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].title","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"errors.items.[INDEX].detail","typeLabel":"string"},"source":{"type":"object","properties":{"pointer":{"type":"string","uniqueKey":"errors.items.[INDEX].source.pointer","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX].source","typeLabel":"object"}},"required":["code","title"],"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"errors","typeLabel":"object[]"}},"required":["errors"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"errors":[{"code":"10007","title":"\u003cstring>","detail":"\u003cstring>","source":{"pointer":"\u003cstring>"}}]}}},"exampleType":"generated"}},"exampleType":"generated"},"8d19f324-3cf8-432e-aa73-2e872c001bdd":{"description":"Validation Error. Reusing an Idempotency-Key with a different request body also returns 422 with error code 10027.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"HTTPValidationError","example":{"detail":[{"loc":["body","name"],"msg":"Field required","type":"missing"}]},"properties":{"detail":{"items":{"properties":{"loc":{"items":{"oneOf":[{"type":"string","uniqueKey":"oneOf.0.detail.items.[INDEX].loc.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"integer","uniqueKey":"oneOf.0.detail.items.[INDEX].loc.items.[INDEX].oneOf.1","typeLabel":"integer"}],"uniqueKey":"oneOf.0.detail.items.[INDEX].loc.items.[INDEX]","typeLabel":"string | integer"},"type":"array","title":"Location","isRequired":true,"uniqueKey":"oneOf.0.detail.items.[INDEX].loc","typeLabel":"(string | integer)[]"},"msg":{"type":"string","title":"Message","isRequired":true,"uniqueKey":"oneOf.0.detail.items.[INDEX].msg","typeLabel":"string"},"type":{"type":"string","title":"Error Type","isRequired":true,"uniqueKey":"oneOf.0.detail.items.[INDEX].type","typeLabel":"string"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError","uniqueKey":"oneOf.0.detail.items.[INDEX]","typeLabel":"ValidationError · object"},"type":"array","title":"Detail","uniqueKey":"oneOf.0.detail","typeLabel":"ValidationError · object[]"}},"uniqueKey":"oneOf.0","typeLabel":"HTTPValidationError · object"},{"type":"object","required":["errors"],"properties":{"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Telnyx error code. Edge idempotency errors use 10015, 10027, or 10036; idempotency protection outages use 10016; replay-cap 413s surface 10007. Fallback 404/500 responses from the framework may use string status codes ('404', '500') instead.","enum":["10007","10015","10016","10027","10036","404","500"],"isRequired":true,"uniqueKey":"oneOf.1.errors.items.[INDEX].code","typeLabel":"enum\u003cstring>"},"title":{"type":"string","isRequired":true,"uniqueKey":"oneOf.1.errors.items.[INDEX].title","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"oneOf.1.errors.items.[INDEX].detail","typeLabel":"string"},"source":{"type":"object","properties":{"pointer":{"type":"string","uniqueKey":"oneOf.1.errors.items.[INDEX].source.pointer","typeLabel":"string"}},"uniqueKey":"oneOf.1.errors.items.[INDEX].source","typeLabel":"object"}},"required":["code","title"],"uniqueKey":"oneOf.1.errors.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"oneOf.1.errors","typeLabel":"object[]"}},"uniqueKey":"oneOf.1","typeLabel":"object"}],"uniqueKey":"","typeLabel":"HTTPValidationError · object | object"},"examples":{"Example":{"title":"Example","value":{"detail":[{"loc":["body","name"],"msg":"Field required","type":"missing"}]}}},"exampleType":"generated"}},"exampleType":"generated"},"6e4d4866-e0bf-4fd5-8bc6-e09c78b28d77":{"description":"Service unavailable (10016), including unavailable Edge idempotency protection for a keyed request.","content":{"application/json":{"schema":{"type":"object","properties":{"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string","description":"Telnyx error code. Edge idempotency errors use 10015, 10027, or 10036; idempotency protection outages use 10016; replay-cap 413s surface 10007. Fallback 404/500 responses from the framework may use string status codes ('404', '500') instead.","enum":["10007","10015","10016","10027","10036","404","500"],"isRequired":true,"uniqueKey":"errors.items.[INDEX].code","typeLabel":"enum\u003cstring>"},"title":{"type":"string","isRequired":true,"uniqueKey":"errors.items.[INDEX].title","typeLabel":"string"},"detail":{"type":"string","uniqueKey":"errors.items.[INDEX].detail","typeLabel":"string"},"source":{"type":"object","properties":{"pointer":{"type":"string","uniqueKey":"errors.items.[INDEX].source.pointer","typeLabel":"string"}},"uniqueKey":"errors.items.[INDEX].source","typeLabel":"object"}},"required":["code","title"],"uniqueKey":"errors.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"errors","typeLabel":"object[]"}},"required":["errors"],"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"errors":[{"code":"10007","title":"\u003cstring>","detail":"\u003cstring>","source":{"pointer":"\u003cstring>"}}]}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"56a3d1db-c9c9-42dd-99ba-415f5aad88ec":{"bearerAuth":{"type":"http","scheme":"bearer","scopes":[],"schemeName":"bearerAuth"}}},"servers":{"e1077638-f2c5-4868-8a50-25633dbe3f9b":{"url":"https://api.telnyx.com/v2","description":"Version 2.0.0 of the Telnyx API"}},"schemas":{"dfae2f72-93a9-4a98-85a5-4e2879e421e7":{"oneOf":[{"type":"object","title":"ComparisonExpression","description":"Compare two sub-expressions with a relational or membership operator.\n\nEvaluates to a boolean. Used in edge conditions to gate transitions on\nruntime values, e.g. `user_age >= 18` or `tier == \"gold\"`.","required":["type","op","left","right"],"example":{"left":{"name":"user_age","type":"variable"},"op":">=","right":{"type":"number_literal","value":18},"type":"comparison"},"properties":{"left":{"oneOf":[{"isRequired":true}],"isRequired":true},"op":{"description":"Relational/membership operator. `contains` / `not_contains` apply to strings (substring) and arrays (membership).","enum":["==","!=","\u003c","\u003c=",">",">=","contains","not_contains"],"title":"Op","type":"string","isRequired":true},"right":{"oneOf":[{"isRequired":true}],"isRequired":true},"type":{"const":"comparison","title":"Type","type":"string","isRequired":true}}},{"type":"object","title":"BooleanOpExpression","description":"Combine sub-expressions with a logical operator (`and` / `or` / `not`).\n\n`and` and `or` accept two or more operands; `not` accepts exactly one.","required":["type","op","operands"],"example":{"op":"and","operands":[{"name":"is_premium","type":"variable"},{"left":{"name":"user_age","type":"variable"},"op":">=","right":{"type":"number_literal","value":18},"type":"comparison"}],"type":"bool_op"},"properties":{"op":{"description":"Logical operator. `not` is unary; `and`/`or` are n-ary (>=2).","enum":["and","or","not"],"title":"Op","type":"string","isRequired":true},"operands":{"description":"Operand sub-expressions. Length must be exactly 1 for `not` and >= 2 for `and`/`or`.","items":{"$circularRef":"dfae2f72-93a9-4a98-85a5-4e2879e421e7"},"title":"Operands","type":"array","isRequired":true},"type":{"const":"bool_op","title":"Type","type":"string","isRequired":true}}},{"type":"object","title":"ArithmeticExpression","description":"Numeric expression: applies an arithmetic operator to two sub-expressions.\n\nUseful for derived numeric checks, e.g. `cart_total + shipping > 50`.\nBoth operands should resolve to numbers at runtime.","required":["type","op","left","right"],"example":{"left":{"name":"cart_total","type":"variable"},"op":"+","right":{"name":"shipping_cost","type":"variable"},"type":"arithmetic"},"properties":{"left":{"oneOf":[{"isRequired":true}],"isRequired":true},"op":{"description":"Arithmetic operator applied to `left` and `right`.","enum":["+","-","*","/","%"],"title":"Op","type":"string","isRequired":true},"right":{"oneOf":[{"isRequired":true}],"isRequired":true},"type":{"const":"arithmetic","title":"Type","type":"string","isRequired":true}}},{"type":"object","title":"DynamicVariableExpression","description":"Reference a dynamic variable by name.\n\nResolved at runtime from the assistant's dynamic-variables context (see\n`Assistant.dynamic_variables` and the dynamic-variables webhook).","required":["type","name"],"example":{"name":"user_age","type":"variable"},"properties":{"name":{"description":"Variable name to look up in the runtime context.","example":"user_age","title":"Name","type":"string","isRequired":true},"type":{"const":"variable","title":"Type","type":"string","isRequired":true}}},{"type":"object","title":"StringLiteralExpression","description":"Constant string value.","required":["type","value"],"example":{"type":"string_literal","value":"gold"},"properties":{"type":{"const":"string_literal","title":"Type","type":"string","isRequired":true},"value":{"description":"Literal string value.","example":"gold","title":"Value","type":"string","isRequired":true}}},{"type":"object","title":"NumberLiteralExpression","description":"Constant numeric value (float; integers are accepted and stored as float).","required":["type","value"],"example":{"type":"number_literal","value":18},"properties":{"type":{"const":"number_literal","title":"Type","type":"string","isRequired":true},"value":{"description":"Literal numeric value.","example":18,"title":"Value","type":"number","isRequired":true}}},{"type":"object","title":"BooleanLiteralExpression","description":"Constant boolean value. Useful for unconditional ('always') edges.","required":["type","value"],"example":{"type":"bool_literal","value":true},"properties":{"type":{"const":"bool_literal","title":"Type","type":"string","isRequired":true},"value":{"description":"Literal boolean value.","title":"Value","type":"boolean","isRequired":true}}}]}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Bearer authentication header of the form `Bearer \u003ctoken>`, where `\u003ctoken>` is your auth token.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"}]},"originalFileLocation":"openapi/source/external/inference/inference-embedding.json"},"subdomain":"telnyx","siteName":"Telnyx","title":"Create an assistant - Telnyx","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-03T15:19:36.810Z","originalFileLocation":"api-reference/assistants/create-an-assistant.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Creates a new AI assistant from the provided configuration, including its model, instructions, and attached tools, and returns the created assistant.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Telnyx\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Create an assistant - Telnyx\">\u003cmeta data-mint-head property=\"og:description\" content=\"Infrastructure for real-time agents. Voice, AI, Edge Compute\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Telnyx\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://telnyx.mintlify.site/_mintlify/api/og/v2?division=Assistants+API\u0026amp;title=Create+an+assistant\u0026amp;description=Creates+a+new+AI+assistant+from+the+provided+configuration%2C+including+its+model%2C+instructions%2C+and+attached+tools%2C+and+returns+the+created+assistant.\u0026amp;theme=0dd46d2166d1a00e34819206\u0026amp;signature=2393b98521800d151a7dfc5738e7d7557342ab584a51fc596876a655c648c84a\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Create an assistant - Telnyx\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Infrastructure for real-time agents. Voice, AI, Edge Compute\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://telnyx.mintlify.site/_mintlify/api/og/v2?division=Assistants+API\u0026amp;title=Create+an+assistant\u0026amp;description=Creates+a+new+AI+assistant+from+the+provided+configuration%2C+including+its+model%2C+instructions%2C+and+attached+tools%2C+and+returns+the+created+assistant.\u0026amp;theme=0dd46d2166d1a00e34819206\u0026amp;signature=2393b98521800d151a7dfc5738e7d7557342ab584a51fc596876a655c648c84a\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/telnyx/MhCJ9JWG11MInbt6/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Telnyx\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#00B688\">\u003clink data-mint-head rel=\"canonical\" href=\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/assistants/create-an-assistant.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://telnyx.com/#organization\",\"name\":\"Telnyx\",\"url\":\"https://telnyx.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://telnyx.com/favicon.ico\"},\"sameAs\":[\"https://x.com/telnyx\",\"https://www.linkedin.com/company/telnyx/\",\"https://github.com/team-telnyx\"]},{\"@type\":\"WebSite\",\"@id\":\"https://developers.telnyx.com#website\",\"name\":\"Telnyx\",\"url\":\"https://developers.telnyx.com\",\"publisher\":{\"@id\":\"https://telnyx.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant#webpage\",\"url\":\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant\",\"name\":\"Create an assistant\",\"description\":\"Creates a new AI assistant from the provided configuration, including its model, instructions, and attached tools, and returns the created assistant.\",\"dateModified\":\"2026-11-03T15:19:36.810Z\",\"isPartOf\":{\"@id\":\"https://developers.telnyx.com#website\"},\"breadcrumb\":{\"@id\":\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Assistants API\",\"item\":\"https://developers.telnyx.com/api-reference/assistants/list-assistants\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Assistants API\",\"item\":\"https://developers.telnyx.com/api-reference/assistants/list-assistants\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Create an assistant\",\"item\":\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant#apireference\",\"headline\":\"Create an assistant\",\"name\":\"Create an assistant\",\"description\":\"Creates a new AI assistant from the provided configuration, including its model, instructions, and attached tools, and returns the created assistant.\",\"url\":\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant\",\"mainEntityOfPage\":{\"@id\":\"https://developers.telnyx.com/api-reference/assistants/create-an-assistant#webpage\"},\"dateModified\":\"2026-11-03T15:19:36.810Z\",\"publisher\":{\"@id\":\"https://telnyx.com/#organization\"},\"isPartOf\":{\"@id\":\"https://developers.telnyx.com#website\"}}]}\u003c/script>","siteName":"Telnyx","nav":{"global":{"anchors":[{"anchor":"Home","icon":"house","href":"/docs/overview"}]},"products":[{"product":"Home","icon":"house","pages":[{"title":"Home","href":"/docs/overview"}]},{"product":"Other APIs","icon":"ellipsis","pages":[{"title":"Other APIs","href":"/docs/other-apis"}]},{"product":"Agent Platform","icon":"circle-nodes","pages":[{"title":"Agent Platform","href":"/docs/agent-platform"}]},{"product":"AI","icon":"microchip-ai","tabs":[{"tab":"Inference","icon":"brain-circuit","pages":[{"title":"Inference","href":"/docs/inference/models"}]},{"tab":"AI Gateway","icon":"key","pages":[{"title":"AI Gateway","href":"/docs/inference/ai-gateway"}]},{"tab":"Embedding","icon":"database","pages":[{"title":"Embedding","href":"/docs/inference/embedding-rag"}]},{"tab":"Assistants","icon":"robot","groups":[{"group":"Guides","pages":[{"group":"Getting Started","pages":[{"title":"Voice Assistant Quickstart","sidebarTitle":"Voice Assistant","href":"/docs/inference/ai-assistants/no-code-voice-assistant"},{"title":"Web Chat Without Voice","sidebarTitle":"Web Chat Without Voice","href":"/docs/inference/ai-assistants/web-chat/index"},{"title":"Importing Assistants from another Provider","sidebarTitle":"Importing Assistants","href":"/docs/inference/ai-assistants/importing/index"},{"title":"Realtime voice conversations over WebSocket","sidebarTitle":"Realtime Conversations","href":"/docs/inference/ai-assistants/realtime-conversations/index"},{"title":"Realtime voice and avatar conversations over WebRTC","sidebarTitle":"WebRTC Conversations","tag":"Beta","href":"/docs/inference/ai-assistants/webrtc-conversations/index"},{"title":"Assistant Deletion and Restore","sidebarTitle":"Deletion and Restore","href":"/docs/inference/ai-assistants/assistant-deletion/index"}]},{"group":"Models \u0026 Voice","pages":[{"title":"Speech-to-speech models","sidebarTitle":"Speech-to-speech models","href":"/docs/inference/ai-assistants/speech-to-speech/index"},{"title":"GPT Live voice assistants","sidebarTitle":"GPT Live","href":"/docs/inference/ai-assistants/gpt-live/index"},{"title":"Configure custom LLM providers for AI assistants","sidebarTitle":"Custom LLMs for Assistants","href":"/docs/inference/ai-assistants/custom-llm/index"},{"title":"Transcription Settings","sidebarTitle":"Transcription Settings","href":"/docs/inference/ai-assistants/transcription-settings/index"},{"title":"Avatars","sidebarTitle":"Avatars","tag":"Beta","href":"/docs/inference/ai-assistants/avatars/index"},{"title":"Interruption Settings","sidebarTitle":"Interruption Settings","href":"/docs/inference/ai-assistants/interruption-settings/index"}]},{"group":"Context \u0026 Memory","pages":[{"title":"Dynamic Variables","sidebarTitle":"Dynamic Variables","href":"/docs/inference/ai-assistants/dynamic-variables/index"},{"title":"How conversations are keyed across channels","sidebarTitle":"Conversation Keying","href":"/docs/inference/ai-assistants/conversation-keying/index"},{"title":"Memory","sidebarTitle":"Memory","href":"/docs/inference/ai-assistants/memory/index"}]},{"group":"Tools \u0026 Integrations","pages":[{"title":"Tools Library","sidebarTitle":"Tools Library","href":"/docs/inference/ai-assistants/tools-library/index"},{"title":"AI assistant integrations","sidebarTitle":"Integrations","href":"/docs/inference/ai-assistants/integrations/index"},{"title":"Add MCP servers to an AI assistant","href":"/docs/development/mcp/assistant-mcp-servers/index"},{"title":"Per-Caller Credentials","sidebarTitle":"Per-Caller Credentials","href":"/docs/inference/ai-assistants/per-caller-credentials/index"},{"title":"Preset Webhook Parameters","sidebarTitle":"Preset Webhook Parameters","href":"/docs/inference/ai-assistants/preset-webhook-parameters/index"},{"title":"Async Tools \u0026 Deferred Context","sidebarTitle":"Async Tools","href":"/docs/inference/ai-assistants/async-tools/index"},{"title":"Webhook Tool Filler Messages","sidebarTitle":"Filler Messages","href":"/docs/inference/ai-assistants/filler-messages/index"},{"title":"Client-Side Tools","sidebarTitle":"Client-Side Tools","href":"/docs/inference/ai-assistants/client-side-tools/index"},{"title":"Vision","sidebarTitle":"Vision","tag":"BETA","href":"/docs/inference/ai-assistants/vision/index"},{"title":"Power AI Assistants with Edge Compute","sidebarTitle":"AI Assistants and Edge Compute","href":"/docs/edge-compute/guides/ai-assistant-backend/index"}]},{"group":"Workflows \u0026 Agents","pages":[{"title":"Conversation Workflows","sidebarTitle":"Conversation Workflows","href":"/docs/inference/ai-assistants/workflows/index"},{"title":"Delegation","sidebarTitle":"Delegation","href":"/docs/inference/ai-assistants/delegation/index"},{"title":"A2A Agents","sidebarTitle":"A2A Agents","tag":"Beta","href":"/docs/inference/ai-assistants/a2a-agents/index"},{"title":"Agent Handoff","sidebarTitle":"Agent Handoff","href":"/docs/inference/ai-assistants/agent-handoff/index"}]},{"group":"Calls \u0026 Transfers","pages":[{"title":"Multi-Participant Voice AI Calls","sidebarTitle":"Multi-Participant Calls","href":"/docs/inference/ai-assistants/multi-participant-calls/index"},{"title":"Warm Transfer Acceptance","sidebarTitle":"Warm Transfer Acceptance","href":"/docs/inference/ai-assistants/warm-transfer-acceptance/index"},{"title":"Voicemail Detection on Transfer","sidebarTitle":"Voicemail Detection on Transfer","href":"/docs/inference/ai-assistants/voicemail-detection-on-transfer/index"},{"title":"Scheduled Events","sidebarTitle":"Scheduled Events","href":"/docs/inference/ai-assistants/scheduled-events/index"}]},{"group":"Testing \u0026 Monitoring","pages":[{"title":"Testing and Traffic Distribution for AI Assistants","sidebarTitle":"Testing, Versions \u0026 Traffic Distribution","href":"/docs/inference/ai-assistants/version-testing-traffic-distribution/index"},{"title":"Stream conversation events to your WebSocket","sidebarTitle":"Conversation Event Stream","href":"/docs/inference/ai-assistants/conversation-event-stream/index"},{"title":"Observability","sidebarTitle":"Observability","href":"/docs/inference/ai-assistants/agent-observability/index"},{"title":"Post-Conversation Processing","sidebarTitle":"Post-Conversation Processing","href":"/docs/inference/ai-assistants/post-conversation-processing/index"}]}]},{"group":"Missions","pages":[{"title":"Voice Outreach with AI Missions","sidebarTitle":"Voice Outreach","href":"/docs/inference/missions/index"}]},{"group":"AI Insights","pages":[{"title":"Creating Insights","sidebarTitle":"Creating insights","href":"/docs/inference/ai-insights/creating-insights/index"},{"title":"AI insights use cases","sidebarTitle":"Use cases","href":"/docs/inference/ai-insights/use-cases/index"},{"title":"Structured data insights","sidebarTitle":"Structured insights","href":"/docs/inference/ai-insights/structured-insights/index"},{"title":"Insight Groups","sidebarTitle":"Insight groups","href":"/docs/inference/ai-insights/insight-groups/index"},{"title":"Telnyx-Managed Insights","sidebarTitle":"Telnyx-managed insights","href":"/docs/inference/ai-insights/telnyx-managed-insights/index"}]},{"group":"Assistants API","pages":[{"group":"Assistants API","pages":[{"title":"List assistants","description":"Retrieve a list of all AI Assistants configured by the user.","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants","href":"/api-reference/assistants/list-assistants"},{"title":"Create an assistant","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants","href":"/api-reference/assistants/create-an-assistant"},{"title":"Delete an assistant","description":"Delete an AI Assistant by `assistant_id`.\n\nBy default this performs a soft delete: the assistant moves to the Recently Deleted list and stays restorable for 30 days, after which it is permanently deleted automatically. The assistant's versions and TeXML application are preserved during the retention window.\n\nPass `hard_delete=true` to skip the retention window and permanently delete the assistant immediately. A hard delete erases the assistant and all of its versions, and deletes its TeXML application unless phone numbers are still assigned to it. It does not delete conversations, recordings, shared tools the assistant referenced, or knowledge-base embeddings.\n\nDeletion fails with `400` if other assistants reference this one through a handoff tool or a conversation-flow edge — remove those references first.","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/assistants/{assistant_id}","href":"/api-reference/assistants/delete-an-assistant"},{"title":"List deleted assistants","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/deleted","href":"/api-reference/assistants/list-deleted-assistants"},{"title":"Get a deleted assistant","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/{assistant_id}/deleted","href":"/api-reference/assistants/get-a-deleted-assistant"},{"title":"Restore an assistant","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/restore","href":"/api-reference/assistants/restore-an-assistant"},{"title":"Get an assistant","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/{assistant_id}","href":"/api-reference/assistants/get-an-assistant"},{"title":"Update an assistant","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}","href":"/api-reference/assistants/update-an-assistant"},{"title":"Assistant Chat","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/chat","href":"/api-reference/assistants/assistant-chat"},{"title":"Assistant Sms Chat","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/chat/sms","href":"/api-reference/assistants/assistant-sms-chat"},{"title":"Assistant WhatsApp Chat","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/chat/whatsapp","href":"/api-reference/assistants/assistant-whatsapp-chat"},{"title":"Clone Assistant","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/clone","href":"/api-reference/assistants/clone-assistant"},{"title":"Enhance Assistant Instructions","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/instructions/enhance","href":"/api-reference/assistants/enhance-assistant-instructions"},{"title":"Import assistants from external provider","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/import","href":"/api-reference/assistants/import-assistants-from-external-provider"},{"title":"List scheduled events","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/{assistant_id}/scheduled_events","href":"/api-reference/assistants/list-scheduled-events"},{"title":"Create a scheduled event","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/scheduled_events","href":"/api-reference/assistants/create-a-scheduled-event"},{"title":"Delete a scheduled event","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/assistants/{assistant_id}/scheduled_events/{event_id}","href":"/api-reference/assistants/delete-a-scheduled-event"},{"title":"Get a scheduled event","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/{assistant_id}/scheduled_events/{event_id}","href":"/api-reference/assistants/get-a-scheduled-event"},{"title":"List assistant tests with pagination","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/tests","href":"/api-reference/assistants/list-assistant-tests-with-pagination"},{"title":"Create a new assistant test","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/tests","href":"/api-reference/assistants/create-a-new-assistant-test"},{"title":"Get all test suite names","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/tests/test-suites","href":"/api-reference/assistants/get-all-test-suite-names"},{"title":"Get test suite run history","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/tests/test-suites/{suite_name}/runs","href":"/api-reference/assistants/get-test-suite-run-history"},{"title":"Trigger test suite execution","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/tests/test-suites/{suite_name}/runs","href":"/api-reference/assistants/trigger-test-suite-execution"},{"title":"Delete an assistant test","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/assistants/tests/{test_id}","href":"/api-reference/assistants/delete-an-assistant-test"},{"title":"Get assistant test by ID","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/tests/{test_id}","href":"/api-reference/assistants/get-assistant-test-by-id"},{"title":"Update an assistant test","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json put /ai/assistants/tests/{test_id}","href":"/api-reference/assistants/update-an-assistant-test"},{"title":"Get test run history for a specific test","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/tests/{test_id}/runs","href":"/api-reference/assistants/get-test-run-history-for-a-specific-test"},{"title":"Trigger a manual test run","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/tests/{test_id}/runs","href":"/api-reference/assistants/trigger-a-manual-test-run"},{"title":"Get specific test run details","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/tests/{test_id}/runs/{run_id}","href":"/api-reference/assistants/get-specific-test-run-details"},{"title":"Get all versions of an assistant","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/{assistant_id}/versions","href":"/api-reference/assistants/get-all-versions-of-an-assistant"},{"title":"Delete a specific assistant version","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/assistants/{assistant_id}/versions/{version_id}","href":"/api-reference/assistants/delete-a-specific-assistant-version"},{"title":"Get a specific assistant version","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/{assistant_id}/versions/{version_id}","href":"/api-reference/assistants/get-a-specific-assistant-version"},{"title":"Update a specific assistant version","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/versions/{version_id}","href":"/api-reference/assistants/update-a-specific-assistant-version"},{"title":"Promote an assistant version to main","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/versions/{version_id}/promote","href":"/api-reference/assistants/promote-an-assistant-version-to-main"},{"title":"Delete Canary Deploy","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/assistants/{assistant_id}/canary-deploys","href":"/api-reference/assistants/delete-canary-deploy"},{"title":"Get Canary Deploy","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/{assistant_id}/canary-deploys","href":"/api-reference/assistants/get-canary-deploy"},{"title":"Create Canary Deploy","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/canary-deploys","href":"/api-reference/assistants/create-canary-deploy"},{"title":"Update Canary Deploy","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json put /ai/assistants/{assistant_id}/canary-deploys","href":"/api-reference/assistants/update-canary-deploy"},{"title":"Get assistant texml","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/{assistant_id}/texml","href":"/api-reference/assistants/get-assistant-texml"},{"title":"Test Assistant Tool","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/tools/{tool_id}/test","href":"/api-reference/assistants/test-assistant-tool"},{"title":"Get All Tags","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/assistants/tags","href":"/api-reference/assistants/get-all-tags"},{"title":"Add Assistant Tag","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/assistants/{assistant_id}/tags","href":"/api-reference/assistants/add-assistant-tag"},{"title":"Remove Assistant Tag","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/assistants/{assistant_id}/tags/{tag}","href":"/api-reference/assistants/remove-assistant-tag"},{"title":"Remove Assistant Tool","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/assistants/{assistant_id}/tools/{tool_id}","href":"/api-reference/assistants/remove-assistant-tool"},{"title":"Add Assistant Tool","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json put /ai/assistants/{assistant_id}/tools/{tool_id}","href":"/api-reference/assistants/add-assistant-tool"}]},{"group":"Avatars API","pages":[{"title":"Create a custom avatar","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/avatars","href":"/api-reference/avatars/create-a-custom-avatar"},{"title":"List avatars","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/avatars","href":"/api-reference/avatars/list-avatars"},{"title":"Get an avatar","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/avatars/{avatar_id}","href":"/api-reference/avatars/get-an-avatar"},{"title":"Update a custom avatar","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json patch /ai/avatars/{avatar_id}","href":"/api-reference/avatars/update-a-custom-avatar"}]},{"group":"Conversation WebSocket","pages":[{"group":"Websockets","pages":[{"asyncapi":"openapi/asyncapi/assistant-conversation/assistant-conversation.yml assistant-conversation-websocket","href":"/api-reference/websockets/talk-to-an-ai-assistant-over-websocket","title":"Talk to an AI Assistant over WebSocket","version":null}]}]},{"group":"Assistant Event Stream","pages":[{"group":"Websockets","pages":[{"asyncapi":"openapi/asyncapi/assistant-events/assistant-events.yml assistant-events-websocket","href":"/api-reference/websockets/assistant-event-stream-websocket-channel","title":"Assistant event stream WebSocket channel","version":null}]}]},{"group":"Integrations API","pages":[{"title":"List Integrations","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/integrations","href":"/api-reference/integrations/list-integrations"},{"title":"List User Integrations","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/integrations/connections","href":"/api-reference/integrations/list-user-integrations"},{"title":"Delete Integration Connection","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/integrations/connections/{user_connection_id}","href":"/api-reference/integrations/delete-integration-connection"},{"title":"Get User Integration connection By Id","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/integrations/connections/{user_connection_id}","href":"/api-reference/integrations/get-user-integration-connection-by-id"},{"title":"List Integration By Id","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/integrations/{integration_id}","href":"/api-reference/integrations/list-integration-by-id"}]},{"group":"MCP Servers API","pages":[{"title":"List MCP Servers","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/mcp_servers","href":"/api-reference/mcp-servers/list-mcp-servers"},{"title":"Create MCP Server","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/mcp_servers","href":"/api-reference/mcp-servers/create-mcp-server"},{"title":"Delete MCP Server","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/mcp_servers/{mcp_server_id}","href":"/api-reference/mcp-servers/delete-mcp-server"},{"title":"Get MCP Server","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/mcp_servers/{mcp_server_id}","href":"/api-reference/mcp-servers/get-mcp-server"},{"title":"Update MCP Server","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json put /ai/mcp_servers/{mcp_server_id}","href":"/api-reference/mcp-servers/update-mcp-server"}]}]},{"group":"Missions API","pages":[{"title":"List missions","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions","href":"/api-reference/missions/list-missions"},{"title":"Create mission","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions","href":"/api-reference/missions/create-mission"},{"title":"List recent events","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/events","href":"/api-reference/missions/list-recent-events"},{"title":"List recent runs","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/runs","href":"/api-reference/missions/list-recent-runs"},{"title":"Delete mission","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json delete /ai/missions/{mission_id}","href":"/api-reference/missions/delete-mission"},{"title":"Get mission","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}","href":"/api-reference/missions/get-mission"},{"title":"Update mission","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json put /ai/missions/{mission_id}","href":"/api-reference/missions/update-mission"},{"title":"Clone mission","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/clone","href":"/api-reference/missions/clone-mission"},{"title":"List runs for mission","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/runs","href":"/api-reference/missions/list-runs-for-mission"},{"title":"Start a run","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/runs","href":"/api-reference/missions/start-a-run"},{"title":"Get run details","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/runs/{run_id}","href":"/api-reference/missions/get-run-details"},{"title":"Update run","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json patch /ai/missions/{mission_id}/runs/{run_id}","href":"/api-reference/missions/update-run"},{"title":"Cancel run","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/runs/{run_id}/cancel","href":"/api-reference/missions/cancel-run"},{"title":"List events","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/runs/{run_id}/events","href":"/api-reference/missions/list-events"},{"title":"Log event","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/runs/{run_id}/events","href":"/api-reference/missions/log-event"},{"title":"Get event details","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/runs/{run_id}/events/{event_id}","href":"/api-reference/missions/get-event-details"},{"title":"Pause run","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/runs/{run_id}/pause","href":"/api-reference/missions/pause-run"},{"title":"Get plan","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/runs/{run_id}/plan","href":"/api-reference/missions/get-plan"},{"title":"Create initial plan","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/runs/{run_id}/plan","href":"/api-reference/missions/create-initial-plan"},{"title":"Add step(s) to plan","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/runs/{run_id}/plan/steps","href":"/api-reference/missions/add-steps-to-plan"},{"title":"Get step details","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/runs/{run_id}/plan/steps/{step_id}","href":"/api-reference/missions/get-step-details"},{"title":"Update step status","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json patch /ai/missions/{mission_id}/runs/{run_id}/plan/steps/{step_id}","href":"/api-reference/missions/update-step-status"},{"title":"Resume run","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/runs/{run_id}/resume","href":"/api-reference/missions/resume-run"},{"title":"List linked Telnyx agents","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/runs/{run_id}/telnyx-agents","href":"/api-reference/missions/list-linked-telnyx-agents"},{"title":"Link Telnyx agent to run","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/runs/{run_id}/telnyx-agents","href":"/api-reference/missions/link-telnyx-agent-to-run"},{"title":"Unlink Telnyx agent","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json delete /ai/missions/{mission_id}/runs/{run_id}/telnyx-agents/{telnyx_agent_id}","href":"/api-reference/missions/unlink-telnyx-agent"},{"title":"List knowledge bases","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/knowledge-bases","href":"/api-reference/missions/list-knowledge-bases"},{"title":"Create knowledge base","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/knowledge-bases","href":"/api-reference/missions/create-knowledge-base"},{"title":"Delete knowledge base","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json delete /ai/missions/{mission_id}/knowledge-bases/{knowledge_base_id}","href":"/api-reference/missions/delete-knowledge-base"},{"title":"Get knowledge base","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/knowledge-bases/{knowledge_base_id}","href":"/api-reference/missions/get-knowledge-base"},{"title":"Update knowledge base","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json put /ai/missions/{mission_id}/knowledge-bases/{knowledge_base_id}","href":"/api-reference/missions/update-knowledge-base"},{"title":"List MCP servers","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/mcp-servers","href":"/api-reference/missions/list-mcp-servers"},{"title":"Create MCP server","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/mcp-servers","href":"/api-reference/missions/create-mcp-server"},{"title":"Delete MCP server","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json delete /ai/missions/{mission_id}/mcp-servers/{mcp_server_id}","href":"/api-reference/missions/delete-mcp-server"},{"title":"Get MCP server","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/mcp-servers/{mcp_server_id}","href":"/api-reference/missions/get-mcp-server"},{"title":"Update MCP server","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json put /ai/missions/{mission_id}/mcp-servers/{mcp_server_id}","href":"/api-reference/missions/update-mcp-server"},{"title":"List tools","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/tools","href":"/api-reference/missions/list-tools"},{"title":"Create tool","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json post /ai/missions/{mission_id}/tools","href":"/api-reference/missions/create-tool"},{"title":"Delete tool","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json delete /ai/missions/{mission_id}/tools/{tool_id}","href":"/api-reference/missions/delete-tool"},{"title":"Get tool","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json get /ai/missions/{mission_id}/tools/{tool_id}","href":"/api-reference/missions/get-tool"},{"title":"Update tool","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-missions.json put /ai/missions/{mission_id}/tools/{tool_id}","href":"/api-reference/missions/update-tool"}]},{"group":"AI Tests API","pages":[{"title":"List test agents","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/aiagents","href":"/api-reference/ai-tests/list-test-agents"},{"title":"Create a test agent","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/aiagents","href":"/api-reference/ai-tests/create-a-test-agent"},{"title":"Delete a test agent","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json delete /ai/tests/test_framework/v1/aiagents/{id}","href":"/api-reference/ai-tests/delete-a-test-agent"},{"title":"Retrieve a test agent","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/aiagents/{id}","href":"/api-reference/ai-tests/retrieve-a-test-agent"},{"title":"Update a test agent","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json put /ai/tests/test_framework/v1/aiagents/{id}","href":"/api-reference/ai-tests/update-a-test-agent"},{"title":"List test personalities","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/personalities","href":"/api-reference/ai-tests/list-test-personalities"},{"title":"List test metrics","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/metrics","href":"/api-reference/ai-tests/list-test-metrics"},{"title":"Create a test metric","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/metrics","href":"/api-reference/ai-tests/create-a-test-metric"},{"title":"Bulk create test metrics","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/metrics/bulk_create","href":"/api-reference/ai-tests/bulk-create-test-metrics"},{"title":"Generate test metrics","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/metrics/generate_metrics","href":"/api-reference/ai-tests/generate-test-metrics"},{"title":"Get test metric generation progress","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/metrics/generate_metrics_progress","href":"/api-reference/ai-tests/get-test-metric-generation-progress"},{"title":"Delete a test metric","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json delete /ai/tests/test_framework/v1/metrics/{id}","href":"/api-reference/ai-tests/delete-a-test-metric"},{"title":"Retrieve a test metric","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/metrics/{id}","href":"/api-reference/ai-tests/retrieve-a-test-metric"},{"title":"Update a test metric","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json patch /ai/tests/test_framework/v1/metrics/{id}","href":"/api-reference/ai-tests/update-a-test-metric"},{"title":"List evaluator scenarios","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/scenarios","href":"/api-reference/ai-tests/list-evaluator-scenarios"},{"title":"Create an evaluator scenario","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/scenarios","href":"/api-reference/ai-tests/create-an-evaluator-scenario"},{"title":"Delete an evaluator scenario","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json delete /ai/tests/test_framework/v1/scenarios/{id}","href":"/api-reference/ai-tests/delete-an-evaluator-scenario"},{"title":"Retrieve an evaluator scenario","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/scenarios/{id}","href":"/api-reference/ai-tests/retrieve-an-evaluator-scenario"},{"title":"Update an evaluator scenario","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json patch /ai/tests/test_framework/v1/scenarios/{id}","href":"/api-reference/ai-tests/update-an-evaluator-scenario"},{"title":"Generate evaluator scenarios","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/scenarios/generate-bg","href":"/api-reference/ai-tests/generate-evaluator-scenarios"},{"title":"Get scenario generation progress","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/scenarios/generate-progress","href":"/api-reference/ai-tests/get-scenario-generation-progress"},{"title":"Run evaluator scenarios","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/scenarios/run_scenarios","href":"/api-reference/ai-tests/run-evaluator-scenarios"},{"title":"Get improve-scenarios progress","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/scenarios/scenario-agent-progress","href":"/api-reference/ai-tests/get-improve-scenarios-progress"},{"title":"Improve evaluator scenarios","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/scenarios/scenario-agent","href":"/api-reference/ai-tests/improve-evaluator-scenarios"},{"title":"Export evaluator scenarios","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/scenarios/export_scenarios","href":"/api-reference/ai-tests/export-evaluator-scenarios"},{"title":"List test run results","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/results","href":"/api-reference/ai-tests/list-test-run-results"},{"title":"Delete a test run result","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json delete /ai/tests/test_framework/v1/results/{id}","href":"/api-reference/ai-tests/delete-a-test-run-result"},{"title":"Retrieve a test run result","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/test_framework/v1/results/{id}","href":"/api-reference/ai-tests/retrieve-a-test-run-result"},{"title":"Rerun a test run result","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/test_framework/v1/results/{id}/rerun","href":"/api-reference/ai-tests/rerun-a-test-run-result"},{"title":"List scheduled test jobs","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/schedules/v1/cron-jobs","href":"/api-reference/ai-tests/list-scheduled-test-jobs"},{"title":"Create a scheduled test job","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json post /ai/tests/schedules/v1/cron-jobs","href":"/api-reference/ai-tests/create-a-scheduled-test-job"},{"title":"Delete a scheduled test job","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json delete /ai/tests/schedules/v1/cron-jobs/{id}","href":"/api-reference/ai-tests/delete-a-scheduled-test-job"},{"title":"Retrieve a scheduled test job","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json get /ai/tests/schedules/v1/cron-jobs/{id}","href":"/api-reference/ai-tests/retrieve-a-scheduled-test-job"},{"title":"Update a scheduled test job","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-ai-tests.json patch /ai/tests/schedules/v1/cron-jobs/{id}","href":"/api-reference/ai-tests/update-a-scheduled-test-job"}]},{"group":"Conversations API","pages":[{"title":"List conversations","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations","href":"/api-reference/conversations/list-conversations"},{"title":"Create a conversation","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/conversations","href":"/api-reference/conversations/create-a-conversation"},{"title":"Aggregate Conversation Insights","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations/conversation-insights/aggregates","href":"/api-reference/conversations/aggregate-conversation-insights"},{"title":"Get Insight Template Groups","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations/insight-groups","href":"/api-reference/conversations/get-insight-template-groups"},{"title":"Create Insight Template Group","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/conversations/insight-groups","href":"/api-reference/conversations/create-insight-template-group"},{"title":"Delete Insight Template Group","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/conversations/insight-groups/{group_id}","href":"/api-reference/conversations/delete-insight-template-group"},{"title":"Get Insight Template Group","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations/insight-groups/{group_id}","href":"/api-reference/conversations/get-insight-template-group"},{"title":"Update Insight Template Group","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json put /ai/conversations/insight-groups/{group_id}","href":"/api-reference/conversations/update-insight-template-group"},{"title":"Assign Insight Template To Group","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/conversations/insight-groups/{group_id}/insights/{insight_id}/assign","href":"/api-reference/conversations/assign-insight-template-to-group"},{"title":"Unassign Insight Template From Group","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/conversations/insight-groups/{group_id}/insights/{insight_id}/unassign","href":"/api-reference/conversations/unassign-insight-template-from-group"},{"title":"Get Insight Templates","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations/insights","href":"/api-reference/conversations/get-insight-templates"},{"title":"Create Insight Template","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/conversations/insights","href":"/api-reference/conversations/create-insight-template"},{"title":"Delete Insight Template","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/conversations/insights/{insight_id}","href":"/api-reference/conversations/delete-insight-template"},{"title":"Get Insight Template","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations/insights/{insight_id}","href":"/api-reference/conversations/get-insight-template"},{"title":"Update Insight Template","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json put /ai/conversations/insights/{insight_id}","href":"/api-reference/conversations/update-insight-template"},{"title":"Delete a conversation","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/conversations/{conversation_id}","href":"/api-reference/conversations/delete-a-conversation"},{"title":"Get a conversation","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations/{conversation_id}","href":"/api-reference/conversations/get-a-conversation"},{"title":"Update conversation metadata","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json put /ai/conversations/{conversation_id}","href":"/api-reference/conversations/update-conversation-metadata"},{"title":"Get insights for a conversation","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations/{conversation_id}/conversations-insights","href":"/api-reference/conversations/get-insights-for-a-conversation"},{"title":"Delete a conversation's insight generation results","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json delete /ai/conversations/{conversation_id}/conversations-insights/{insight_id}","href":"/api-reference/conversations/delete-a-conversations-insight-generation-results"},{"title":"Create Message","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json post /ai/conversations/{conversation_id}/message","href":"/api-reference/conversations/create-message"},{"title":"Get conversation messages","deprecated":null,"version":null,"openapi":"/openapi/source/external/inference/inference-embedding.json get /ai/conversations/{conversation_id}/messages","href":"/api-reference/conversations/get-conversation-messages"}]},{"group":"For AI Agents","pages":[{"title":"Assistants llms.txt","sidebarTitle":"Assistants llms txt","href":"/docs/development/llms/ai-assistants-llms-txt/index"},{"title":"Assistants llms-full.txt","sidebarTitle":"Assistants llms full txt","href":"/docs/development/llms/ai-assistants-llms-full-txt/index"}]}]},{"tab":"LiveKit on Telnyx (Beta)","icon":"waveform-lines","pages":[{"title":"LiveKit on Telnyx (Beta)","href":"/docs/livekit"}]},{"tab":"Web Search","icon":"globe","pages":[{"title":"Web Search","href":"/docs/web-search"}]},{"tab":"AI Search","icon":"magnifying-glass","pages":[{"title":"AI Search","href":"/docs/ai-search"}]},{"tab":"Meeting","icon":"video","pages":[{"title":"Meeting","href":"/docs/meeting"}]}]},{"product":"Voice","icon":"waveform","pages":[{"title":"Voice","href":"/docs/voice/overview"}]},{"product":"Compute","icon":"server","pages":[{"title":"Compute","href":"/docs/edge-compute/platform-overview"}]},{"product":"Storage","icon":"hard-drive","pages":[{"title":"Storage","href":"/docs/cloud-storage/overview"}]},{"product":"Virtual Private Cloud","icon":"cloud","pages":[{"title":"Virtual Private Cloud","href":"/docs/virtual-private-cloud"}]},{"product":"Calling","icon":"phone","pages":[{"title":"Calling","href":"/docs/voice/programmable-voice/voice-api-fundamentals"}]},{"product":"Messaging","icon":"message","pages":[{"title":"Messaging","href":"/docs/messaging/messages/send-message"}]},{"product":"Numbers","icon":"hashtag","pages":[{"title":"Numbers","href":"/docs/numbers/phone-numbers/getting-started"}]},{"product":"Wireless","icon":"broadcast-tower","pages":[{"title":"Wireless","href":"/docs/iot-sim/wireless-overview"}]}]},"basePath":"","title":"Create an assistant - Telnyx","buildId":"dpl_BLQvU86QFwq3AhPofSTw6q8dGWKm","deploymentId":"dpl_BLQvU86QFwq3AhPofSTw6q8dGWKm","dynamics":["10e4515597","c2aa737661","b0f84f53ff","a9bb46feb3","2b790eda92"],"chunks":["BannerMarkdown-DcUtcwZ_.js","dist-CJ9Oly2E.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","clsx-C5EfhVm0.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","OpenApiReferenceProvider-Myd8dsju.js","utils-C2HkQgW0.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-8rSppmTv.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-B6MjiCFm.js","snippetPresets-DwrSAONL.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","Page-CxAy5y67.js","ApiExamples-1-a5UQKQ.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-C541m7wZ.js","shallow-CWELCZ77.js","getApiPlaygroundDisplay-CTo5Zn03.js","CodeSnippet-D--dzvnl.js","CodeSnippets-DM3cXEDh.js","getPastedJson-C-VECgcL.js","icon-BPq2-Mg3.js","MethodPill-D9J5cUHd.js","DuplicateIcon-BqHaxUnD.js","createIcon-CIbcZHp9.js","DynamicMarkdown-BKiHAm_d.js","SectionHeading-DstQXt3H.js","axios-vUo_bRtp.js","Markdown-CpxgzsKA.js","AssistantPageLink-Mk6P3qvh.js"]}