Playbook · Business case to production
Eight parts. Each one pairs a decision you need to make with the API call that makes it real. Pick your industry and every example on the page adapts.
# install the Telnyx CLI, then create your first agentgo install github.com/team-telnyx/telnyx-cli/cmd/telnyx@latestexport TELNYX_API_KEY="YOUR_API_KEY"telnyx ai:assistants create \ --name "Front Desk" \ --model moonshotai/Kimi-K2.6 \ --instructions "You book, confirm and reschedule patient appointments for Riverside Family Clinic."Examples for
Highlighted values change with your pick.
Part 01
The goal, the platform decision and the business case. 10 minute read.
Cost, coverage or conversion. An agent tuned for all three delivers none. Write the goal as a number you can read from the call log.
# one goal, one metric, read from the call logindustry: Healthcaregoal: Reduce no showsmetric: no_show_ratebaseline: 18%target: 11%window: 90 daysowner: ops_leadnot_optimizing_for: [handle_time, csat] # yetA stitched stack takes telephony from one vendor, speech and the model from three more, and an orchestrator on top. It can win on model choice. It loses on vendor hops, on who owns an incident, and on the latency budget.
| Concern | Stitched, 4 to 5 vendors | Telnyx |
|---|---|---|
| Media path | Public internet between vendors | Telnyx's private global network, with edge PoPs in 9 regions |
| Round trip | The sum of every vendor hop | Under 200 ms round trip, GPU clusters co-located with telephony PoPs |
| Numbers and compliance | Separate number and compliance vendors | Licensed carrier in 45+ countries, numbers and voice coverage in 140+ countries |
| Model choice | Any model | Telnyx-hosted models, or your own LLM endpoint |
| Who you page at 2 a.m. | Four or five status pages | One |
Part 02
Call journeys, hotspots and the scope of v1. 8 minute read.
Rate each call type on volume, how repetitive it is, and the blast radius when the agent gets it wrong. Start with the highest volume and the lowest blast radius. Everything else waits for v2.
| Call type | Volume | Repetitive | Blast radius | Verdict |
|---|---|---|---|---|
| Appointment reschedule | High | High | Low | Start here |
| Prescription refill status | High | High | Medium | v2 |
| New patient intake | Medium | Medium | Medium | v2 |
| Clinical questions | Low | Low | High | Never |
Supported intents, refused intents and the escalation rule. If a request is not on the list, the agent transfers. This file becomes the first version of your instructions.
# scope.md (this becomes v1 of the instructions)## Supported intents- reschedule_appointment- confirm_appointment- cancel_appointment- clinic_hours_and_directions## Refused- clinical advice- billing disputes- anything about another patient## Escalation ruleTransfer to the front desk queue after one clarifying question.## Done whenno_show_rate moves from 18% toward 11% in 90 daysPart 03
Instructions, persona, dynamic variables and escalation. 14 minute read.
Short sections, one rule per line, and the escalation path spelled out. Callers interrupt and change topic. The instructions decide what happens when they do.
curl -X POST https://api.telnyx.com/v2/ai/assistants \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Front Desk", "model": "moonshotai/Kimi-K2.6", "instructions": "You book, confirm and reschedule patient appointments for Riverside Family Clinic. The caller is {{full_name}}. Never confirm an action before the tool returns. Ask one clarifying question, then transfer.", "greeting": "Thanks for calling Riverside Family Clinic. This call may be recorded. How can I help?", "voice_settings": { "voice": "Telnyx.KokoroTTS.af_heart" }, "transcription": { "model": "deepgram/flux" }, "telephony_settings": { "noise_suppression": "krisp" }, "dynamic_variables": { "full_name": "there" } }'Caller name, location and department arrive as dynamic variables with each call. Send them in the API request, in a SIP header, or from a webhook your server answers when the call starts. The prompt stays short and identical for every caller.
curl -X POST https://api.telnyx.com/v2/texml/ai_calls/{connection_id} \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "From": "+13125550100", "To": "+13125550123", "AIAssistantId": "{assistant_id}", "AIAssistantDynamicVariables": { "full_name": "Maria Alves", "location": "Riverside Family Clinic", "department": "Primary Care" } }'# the instructions reference them as {{full_name}}, {{location}}, {{department}}# inbound: send X-Full-Name as a SIP header, or answer the dynamic variables webhookPart 04
Latency budget, tool contracts, telephony and data. 18 minute read.
A turn feels natural at under about a second, voice to voice. Every component spends from that budget. Measure each one with your real prompt, not a test prompt.
Your turn latency
Inside the 1,000 ms budget, with 70 ms of headroom for tool calls.
Example values for planning. Replace them with your own measurements.
Purpose, typed inputs, a timeout, and an error taxonomy mapped to spoken responses. Any gap you leave undefined, the model fills by guessing.
"tools": [ { "type": "webhook", "webhook": { "name": "book_appointment", "description": "Book a confirmed appointment slot for a verified patient", "url": "https://api.riversideclinic.example/v1/appointments", "method": "POST", "timeout_ms": 3000, "headers": [{ "name": "Authorization", "value": "Bearer YOUR_TOOL_TOKEN" }], "body_parameters": { "type": "object", "properties": { "patient_id": { "type": "string" }, "slot_id": { "type": "string" }, "idempotency_key": { "type": "string" } }, "required": ["patient_id", "slot_id", "idempotency_key"] } } }, { "type": "transfer", "transfer": { "from": "+13125550100", "targets": [{ "name": "Front desk", "to": "+13125550199" }] } }]# error taxonomy, each mapped to a spoken response in the instructions# NO_AVAILABILITY offer the next two slots# PATIENT_NOT_FOUND verify date of birth once, then transfer# EHR_TIMEOUT retry once, then offer a callbackOutbound answer rates collapse when numbers get flagged. On Telnyx, caller ID name, STIR/SHAKEN signing and number reputation sit with the same carrier that runs the agent.
Concurrency calculator
Provision for peak plus 30%. Assumes calls spread evenly across the window.
# caller ID name on each outbound number, 15 characters maxcurl -X PATCH https://api.telnyx.com/v2/phone_numbers/{phone_number_id}/voice \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "cnam_listing": { "cnam_listing_enabled": true, "cnam_listing_details": "RIVERSIDE CARE" } }'# recording consent in the greeting, background noise suppressedcurl -X POST https://api.telnyx.com/v2/ai/assistants/{assistant_id} \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "greeting": "Thanks for calling Riverside Family Clinic. This call may be recorded. How can I help?", "telephony_settings": { "noise_suppression": "krisp" } }'Audio, transcript, model context, tool logs and storage. Classify each one and set its control before launch.
| Data | Class | Control |
|---|---|---|
| Audio recording | PHI | Consent in the greeting, retention period set |
| Transcript | PHI | Access by role, every read audited |
| LLM context | PHI | Telnyx-hosted model, nothing kept after the call |
| Tool logs | PHI | Patient ID only, never date of birth |
| Storage | PHI | BAA in place with every vendor in the path |
Part 05
Tool tests, conversation tests and the pilot. 8 minute read.
Test each tool against every error code first. Then run scripted conversations scored against a rubric. Then put real calls on it: a pilot on a slice of inbound, with exit criteria written down before it starts.
# conversation test: a scripted caller, scored against a rubriccurl -X POST https://api.telnyx.com/v2/ai/assistants/tests \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Front Desk happy path", "destination": "+13125550100", "telnyx_conversation_channel": "phone_call", "instructions": "Caller wants to move a Tuesday appointment to Thursday afternoon.", "rubric": [ { "name": "Tool first", "criteria": "Never confirms a booking before book_appointment returns" }, { "name": "Refusal", "criteria": "Declines clinical questions and offers a transfer" } ], "max_duration_seconds": 180 }'# run it against a new version before you promote that versioncurl -X POST https://api.telnyx.com/v2/ai/assistants/tests/{test_id}/runs \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "destination_version_id": "{version_id}" }'Part 06
Graduated rollout, the readiness gate and change management. 8 minute read.
Save the new instructions as a version, send a slice of traffic to it, and watch the same dashboards you will watch for the life of the agent. Promote when the numbers hold. Rolling back is one call.
# save new instructions as a version, without promoting itcurl -X POST https://api.telnyx.com/v2/ai/assistants/{assistant_id} \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "instructions": "<v2 instructions for Front Desk>", "promote_to_main": false }'# send 10% of calls to the new version; the rest stay on maincurl -X POST https://api.telnyx.com/v2/ai/assistants/{assistant_id}/canary-deploys \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "rules": [ { "serve": { "rollout": [ { "version_id": "{version_id}", "weight": 10 } ] } } ] }'# numbers hold for a week: promote. Otherwise delete the canary deploy.curl -X POST https://api.telnyx.com/v2/ai/assistants/{assistant_id}/versions/{version_id}/promote \ -H "Authorization: Bearer $TELNYX_API_KEY"No agent reaches production until every item is checked. Add a week to the plan for it. It saves six.
0 of 6 checked
Not yetPart 07
Three layers of monitoring, structured insights and the weekly loop. 12 minute read.
Infrastructure: call setup and latency per component. Conversation: containment, transfer reasons and silence gaps. Business: the number from Part 01. Alert on the first two. Review the third weekly.
# stream conversation events to your monitoring, trace every turn in Langfusecurl -X POST https://api.telnyx.com/v2/ai/assistants/{assistant_id} \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "websocket_settings": { "enabled": true, "url": "wss://events.riversideclinic.example/telnyx", "auth_ref": "events_token" }, "observability_settings": { "status": "enabled", "host": "https://cloud.langfuse.com", "public_key_ref": "langfuse_public_key", "secret_key_ref": "langfuse_secret_key" } }'# thresholds live in your own alerting, for example:# p95 turn latency > 1000 ms page# transfer rate > 35% review# no_show_rate weekly business reviewDefine the fields you want from each conversation as a JSON schema, and send the results to a webhook. Your weekly review reads a table, not a folder of recordings.
# 1. define the fields to extract from every conversationcurl -X POST https://api.telnyx.com/v2/ai/conversations/insights \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "no_show_drivers", "instructions": "Extract the fields below from the conversation.", "json_schema": { "type": "object", "properties": { "reschedule_reason": { "type": "string" }, "new_slot_offered": { "type": "boolean" }, "transferred": { "type": "boolean" }, "transfer_reason": { "type": "string" } } } }'# 2. group insights and deliver results to your webhookcurl -X POST https://api.telnyx.com/v2/ai/conversations/insight-groups \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "weekly_review", "webhook": "https://api.riversideclinic.example/telnyx/insights" }'# 3. assign the insight to the group, then set it on the assistant:# "insight_settings": { "insight_group_id": "{group_id}" }curl -X POST https://api.telnyx.com/v2/ai/conversations/insight-groups/{group_id}/insights/{insight_id}/assign \ -H "Authorization: Bearer $TELNYX_API_KEY"Part 08
From one agent to five, handling drift, and building the skill in house. 8 minute read.
The second agent starts from the first: shared tools, shared escalation rules, a different scope file. A clone copies everything except telephony and messaging settings. Version every change and keep the last version ready to promote.
# the second agent starts from the firstcurl -X POST https://api.telnyx.com/v2/ai/assistants/{assistant_id}/clone \ -H "Authorization: Bearer $TELNYX_API_KEY"# rename it, then assign numbers: clones skip telephony and messaging settingscurl -X POST https://api.telnyx.com/v2/ai/assistants/{new_assistant_id} \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Front Desk Dental" }'# already running on Vapi, ElevenLabs or Retell? import itcurl -X POST https://api.telnyx.com/v2/ai/assistants/import \ -H "Authorization: Bearer $TELNYX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "provider": "vapi", "api_key_ref": "vapi_api_key" }'Prompts drift as people add rules. Backends drift as APIs change. Callers drift as the business changes. A monthly review of transfer reasons catches all three.
# Telnyx skills for your coding agentnpx skills add team-telnyx/ai --skill <SKILL> --agent <AGENT># or, in Claude Code, the Telnyx plugin/plugin marketplace add team-telnyx/ai/plugin install telnyx-ai@telnyx# remote MCP server, authenticated with your API keyhttps://api.telnyx.com/v2/mcpAuthorization: Bearer $TELNYX_API_KEYWhere it runs
One platform, not a list of vendor recommendations. Carrier, network and inference sit together and are exposed through the APIs above.
Carrier
Telnyx originates calls as a licensed carrier in 45+ countries, with numbers and voice coverage in 140+ countries.
Network
Voice traffic stays on Telnyx's private global network, with edge PoPs in 9 regions and under 200 ms round-trip latency.
Inference
GPU clusters are co-located with telephony PoPs, so speech, model and voice run where the call does.
Identity
A-level STIR/SHAKEN attestation on eligible US outbound calls, plus Branded Calling and Number Reputation.
Edge Compute
Functions, KV, Object Storage and Inference, colocated with the carrier facilities your calls terminate on.
Compliance
SOC 2 Type II, ISO/IEC 27001, PCI DSS and GDPR. For PHI, confirm BAA coverage with your account team.
Who this is for
Use case selection, scoping and the roadmap from v1 to v5.
Latency budget, tool contracts, telephony and observability.
Escalation, QA, change management and frontline adoption.
Portal, CLI or API. The same assistant either way.