Skip to content

Concept

Call-control documents

When a call needs a decision — what to play, whether to gather digits, where to route — TelVox asks your application. Your answer_url returns a call-control document: a JSON object with an ordered list of instructions that TelVox runs against the live call. This is the primary model for driving calls in Connect.

Developer preview

The JSON documents on this page are illustrative — they show the shape of the model, not a finalized contract. Verb names, fields and defaults may change before general availability. The underlying primitives (play, collect digits, bridge, record, queue, transfer) are real and shipped in TelVox's 12-node IVR and ACD engine; the programmable document surface is in preview.

The answer-URL loop

Call control is a request/response loop. When a call reaches your application — an inbound call, or an outbound call you started with an answer_url — TelVox sends an HTTP request to that URL with the call's context. Your handler responds with a call-control document. Some instructions (like gather) carry their own action_url; when they complete, TelVox calls that URL with the result and expects the next document, continuing the loop until the call ends.

POSTyour answer_url
POST /voice/answer HTTP/1.1
Host: your.app
Content-Type: application/json

{
  "call_sid": "CA9f3a2b...",
  "direction": "inbound",
  "from": "+14155550199",
  "to": "+14155550100",
  "status": "ringing"
}
your app → TelVox
// Your answer_url returns this document. TelVox runs the
// instructions top to bottom, against the live call.
{
  "instructions": [
    { "verb": "play", "url": "https://your.app/audio/greeting.wav" },
    {
      "verb": "gather",
      "num_digits": 1,
      "timeout": 5,
      "action_url": "https://your.app/voice/menu",
      "prompt": { "verb": "play", "url": "https://your.app/audio/menu.wav" }
    }
  ]
}
200 ok · application/json

Document shape

A document is an object with an instructions array. Each instruction has a verb and its parameters. TelVox executes them in order: control flows top to bottom, and an instruction that hands off (gather, dial) pauses the list until it resolves, then continues — or hands control to its action_url, which returns a fresh document. Anything after a hangup is ignored.

Core instructions

These map to real nodes in TelVox's IVR and ACD engine. The catalog below covers the core verbs; routing, queueing and transfer compose from the same building blocks.

play

Play audio to the caller, by URL or as spoken text. The foundation for greetings, prompts and announcements.

play
// Play an audio file, or speak text, to the caller.
{ "verb": "play", "url": "https://your.app/audio/greeting.wav", "loop": 1 }

// Speech alternative (text rendered to audio):
{ "verb": "play", "say": "Thanks for calling. Please hold." }

gather

Collect DTMF digits from the caller, optionally with a prompt, then POST the result to action_url. The basis of menus and data entry.

gather
// Collect DTMF digits, then POST them to action_url.
// TelVox calls action_url and expects the NEXT document back.
{
  "verb": "gather",
  "num_digits": 4,
  "finish_on": "#",
  "timeout": 6,
  "action_url": "https://your.app/voice/collected",
  "prompt": { "verb": "play", "say": "Enter your account number." }
}

dial

Bridge the caller to one or more destinations — a PSTN number, a SIP address, or a registered WebRTC client — and report the outcome to action_url.

dial
// Bridge the caller to one or more destinations: a PSTN
// number, a SIP address, or a registered WebRTC client.
{
  "verb": "dial",
  "caller_id": "+14155550100",
  "timeout": 20,
  "targets": [
    { "type": "number", "to": "+14155550123" },
    { "type": "client", "identity": "agent_42" }
  ],
  "action_url": "https://your.app/voice/after-dial"
}

record

Record the call or a segment of it. Recordings are encrypted at rest with AES-256-GCM and retrieved through short-lived signed URLs; a recording-status callback fires when the recording is ready.

record
// Record the call (or a segment). Recordings are encrypted
// at rest with AES-256-GCM; retrieval is via short-lived
// signed URL. A recording-status callback fires when done.
{
  "verb": "record",
  "channels": "dual",
  "max_length": 3600,
  "play_beep": true,
  "recording_status_callback": "https://your.app/voice/recorded"
}

hangup

End the call. Terminal — any instructions after it are ignored.

hangup
// End the call. Any instructions after a hangup are ignored.
{ "verb": "hangup" }

A small menu, end to end

Composed, the verbs form a flow. This document greets the caller, offers a one-digit menu that routes via action_url, and falls through to a goodbye-and-hangup if nothing is pressed.

answer.json
{
  "instructions": [
    { "verb": "play", "say": "Welcome to Acme support." },
    {
      "verb": "gather",
      "num_digits": 1,
      "timeout": 5,
      "action_url": "https://your.app/voice/route",
      "prompt": { "verb": "play", "say": "Press 1 for sales, 2 for support." }
    },
    { "verb": "play", "say": "We didn't catch that. Goodbye." },
    { "verb": "hangup" }
  ]
}
200 ok · application/json

An XML markup dialect (roadmap)

Some teams migrating from other voice platforms prefer an XML markup dialect — the genre convention popularized by TwiML and TeXML. An XML call-control dialect for Connect is on the roadmap, not implemented today. The JSON document model above is the supported way to drive calls in the preview. The snippet below is illustrative only — it does not run.

VoxML · roadmap — does not run
<!-- ROADMAP — not implemented. The JSON document above is the
     supported model today. This XML dialect is illustrative only. -->
<Response>
  <Play say="Welcome to Acme support." />
  <Gather numDigits="1" timeout="5" action="https://your.app/voice/route">
    <Play say="Press 1 for sales, 2 for support." />
  </Gather>
  <Hangup />
</Response>

Build against JSON today; if and when the XML dialect ships, it will map one-to-one onto the same verbs, so flows carry over.

Next: Webhooks & status callbacks · Calls reference