Skip to Content
FeaturesVoiceXML Template Builder

XML Template Builder

Create and manage VoxiXML scripts for advanced voice call logic. XML templates give you complete programmatic control over call flow behavior for outbound campaigns across all telephony providers with provider-specific tag transforms.

Overview

The XML Template Builder allows you to write and manage XML-based call scripts that define the complete call experience — from the moment the recipient answers to the final hangup — using structured XML markup. Unlike the IVR Flow Builder’s visual approach, XML templates let you define every nuance of call behavior with precise markup control.

ℹ️

XML templates work across all providers. VoxiXML scripts are automatically transformed into provider-specific tags for SignalWire, Plivo, and Indian Route. You can use the same XML template regardless of which provider you choose for your campaign.

When to Use XML vs IVR Builder

ConsiderationIVR Flow BuilderXML Template Builder
Learning curveLow — visual drag-and-dropModerate — requires XML knowledge
Provider supportSignalWire, Plivo, Indian RouteSignalWire, Plivo, Indian Route
Flow complexityGood for standard branchingExcellent for deeply nested logic
Dynamic contentLimited to variablesFull programmatic control
API integrationNot availableCan trigger webhooks mid-call
Version controlManual snapshotsXML files can be stored in Git
Error handlingBuilt-in defaultsCustom error paths per element
Rapid prototypingFaster for simple flowsFaster for replicating existing scripts

Features

Create XML Scripts

  1. Navigate to XML Builder from the sidebar.
  2. Click Create Script.
  3. Enter a Script Name (e.g., “Payment Reminder Flow v2”).
  4. Write or paste your XML content in the editor. Use the element reference below as a guide.
  5. The editor provides syntax highlighting and basic validation as you type.
  6. Click Save. The system validates your XML for well-formedness and supported elements.
🖼
[Screenshot: XML Builder editor showing the script name field and XML code editor area]
Highlight: XML code editor with save button

Manage Scripts

  • Edit — Modify existing XML scripts. Changes take effect immediately for any campaign using the script.
  • Duplicate — Create a copy of a script as a starting point for a new one.
  • Delete — Remove scripts no longer in use. You cannot delete a script currently referenced by an active campaign.

VoxiXML Element Reference

Below is the complete reference of supported VoxiXML elements and their attributes:

<voxixml>

Root element. All VoxiXML scripts must be wrapped in <voxixml>.

<answer>

Begins the call session. Must be the first child of <voxixml>. Contains all call flow logic.

<playaudio>

Plays an audio file to the caller.

AttributeTypeRequiredDescription
srcURLYesFull HTTPS URL of the audio file. Must be publicly accessible.
loopIntegerNoNumber of times to repeat (1–10). Default: 1.
<playaudio>https://cdn.example.com/greeting.mp3</playaudio>

<say>

Converts text to speech using the configured TTS engine. Text content is read aloud.

AttributeTypeRequiredDescription
languageStringNoLanguage code (e.g., en-IN, hi-IN). Defaults to en-IN.
voiceStringNoSpeaker voice name (e.g., female, male). Defaults to provider default.
speedFloatNoSpeech rate multiplier (0.5–2.0). Default: 1.0.
<say language="hi-IN" voice="female">Namaste, aapka payment reminder hai.</say>

<gather>

Listens for DTMF (keypad) input from the caller. Can contain nested <playaudio> or <say> elements that play before listening.

AttributeTypeRequiredDescription
maxdigitsIntegerNoMaximum number of digits to collect (1–10). Default: 1.
timeoutIntegerNoSeconds to wait for input (1–15). Default: 5.
terminatorStringNoKey that signals end of input (# or *). Default: #.
numdigitsIntegerNoExact number of digits to collect. Overrides maxdigits.
retryIntegerNoNumber of retry attempts if no input received. Default: 0.
<gather maxdigits="1" timeout="5" retry="2"> <say>For Sales, press 1. For Support, press 2.</say> </gather>

<switch>

Evaluates a condition and routes to the matching <case>.

AttributeTypeRequiredDescription
onStringNoThe variable or expression to evaluate. Defaults to the last gathered input.

<case>

Defines a route branch within a <switch>. Executes if the key matches.

AttributeTypeRequiredDescription
keyStringYesThe value to match against. Supports exact match and wildcard (*).

<default>

Defines the fallback branch within a <switch>. Executes when no <case> matches.

<dial>

Initiates a call transfer to another phone number.

AttributeTypeRequiredDescription
timeoutIntegerNoSeconds to ring before timing out. Default: 30.
callerIdStringNoOverride caller ID for this transfer.
<dial timeout="25">+919XXXXXXXXX</dial>

<hangup>

Ends the call immediately. No further elements are processed.

<pause>

Inserts a silent pause in the call.

AttributeTypeRequiredDescription
durationIntegerYesDuration of silence in seconds (1–30).
<pause duration="2" />

<record>

Records the caller’s audio during a call segment.

AttributeTypeRequiredDescription
maxdurationIntegerNoMaximum recording duration in seconds. Default: 60.
terminatorStringNoKey to stop recording (# or *).
beepBooleanNoPlay a beep before recording starts. Default: true.

<webhook>

Makes an HTTP request to an external URL during the call. The call flow pauses until a response is received.

AttributeTypeRequiredDescription
urlStringYesThe HTTPS URL to call.
methodStringNoHTTP method: GET or POST. Default: POST.
timeoutIntegerNoSeconds to wait for a response. Default: 10.

Simple Script Example

A basic script that plays a message, gathers input, and routes:

<voxixml> <answer> <playaudio>https://cdn.example.com/welcome.mp3</playaudio> <gather maxdigits="1" timeout="5"> <playaudio>https://cdn.example.com/menu.mp3</playaudio> </gather> <switch> <case key="1"> <dial timeout="25">+919XXXXXXXXX</dial> </case> <case key="2"> <playaudio>https://cdn.example.com/info.mp3</playaudio> <hangup/> </case> <default> <playaudio>https://cdn.example.com/error.mp3</playaudio> <hangup/> </default> </switch> </answer> </voxixml>

Advanced Script Example

A more complex script incorporating TTS, retry logic, recording, webhook integration, and multi-level routing:

<voxixml> <answer> <!-- Welcome with dynamic TTS --> <say language="en-IN" voice="female"> Hello, this is a call from Acme Services regarding your recent inquiry. </say> <!-- Main menu with DTMF gathering --> <gather maxdigits="1" timeout="5" retry="2"> <say language="en-IN" voice="female"> To speak with a sales representative, press 1. To check your order status, press 2. To leave feedback, press 3. To hear these options again, press 9. </say> </gather> <switch> <!-- Option 1: Transfer to Sales --> <case key="1"> <say language="en-IN" voice="female"> Connecting you to our sales team. Please hold. </say> <dial timeout="30">+919XXXXXXXXX</dial> <!-- Fallback if transfer fails --> <say language="en-IN" voice="female"> Sorry, no one is available at the moment. We will call you back. </say> <webhook url="https://api.example.com/callback-requests" method="POST" timeout="10" /> <hangup/> </case> <!-- Option 2: Order Status via Webhook --> <case key="2"> <say language="en-IN" voice="female"> Let me look up your recent orders. One moment please. </say> <webhook url="https://api.example.com/order-status" method="POST" timeout="8" /> <pause duration="2" /> <say language="en-IN" voice="female"> Your most recent order 45281 is out for delivery today. Thank you for your patience. Goodbye. </say> <hangup/> </case> <!-- Option 3: Record Feedback --> <case key="3"> <say language="en-IN" voice="female"> Please record your feedback after the beep. Press the hash key when done. </say> <record maxduration="60" terminator="#" beep="true" /> <say language="en-IN" voice="female"> Thank you for your valuable feedback. Have a great day. </say> <hangup/> </case> <!-- Option 9: Repeat Menu --> <case key="9"> <gather maxdigits="1" timeout="5" retry="1"> <say language="en-IN" voice="female"> Sales, press 1. Order status, press 2. Feedback, press 3. </say> </gather> <switch> <case key="1"> <dial timeout="30">+919XXXXXXXXX</dial> </case> <case key="2"> <webhook url="https://api.example.com/order-status" method="POST" timeout="8" /> <hangup/> </case> <case key="3"> <record maxduration="60" terminator="#" beep="true" /> <hangup/> </case> <default> <say language="en-IN" voice="female"> Sorry, we could not process your selection. Goodbye. </say> <hangup/> </default> </switch> </case> <!-- Default: No valid input after retries --> <default> <say language="en-IN" voice="female"> We did not receive a valid selection. Goodbye. </say> <hangup/> </default> </switch> </answer> </voxixml>

Using XML Scripts in Campaigns

When creating a Voice Campaign:

  1. Select XML Script as the calling type.
  2. Choose your saved script from the dropdown.
  3. The platform automatically transforms your VoxiXML into provider-specific tags at runtime, so it works with any configured provider (SignalWire, Plivo, or Indian Route).
  4. Launch the campaign.
⚠️

Audio URL accessibility: All audio file URLs referenced in your VoxiXML script must be publicly accessible over HTTPS. The provider fetches audio files at call time. Audio files stored in the Voxvaani Audio Library are automatically served with public URLs and are safe to reference. If you host audio externally, verify that the URLs are reachable from the internet — not restricted by IP whitelisting or authentication.

ℹ️

Provider-specific tag transforms: VoxiXML scripts are provider-agnostic at the authoring level. When a campaign launches, the system automatically maps VoxiXML elements to the native XML tags of the selected provider (SignalWire XML, Plivo XML, or VoxiXML for Indian Route). You do not need to write separate scripts for each provider.

Validation Tips

The XML Builder validates your scripts on save. To avoid common errors:

  • Well-formed XML: Every opening tag must have a matching closing tag. Self-closing tags (like <hangup/> and <pause/>) must end with />.
  • Nesting order: Elements must be properly nested. For example, <playaudio> inside <gather> is valid, but <gather> inside <playaudio> is not.
  • Attribute types: Ensure numeric attributes (maxdigits, timeout, retry) contain integer values. The builder flags non-numeric values.
  • URL format: All URLs in src and url attributes must start with https://. HTTP URLs are rejected.
  • Required parent elements: <case> and <default> must be direct children of <switch>. Placing them elsewhere produces a validation error.
  • Supported elements: Only the elements listed in this reference are supported. Unknown elements trigger a validation warning and are ignored at runtime.
💡

Test before launching: Create a campaign with a single test contact (your own number) to verify the script executes correctly. Pay attention to audio latency, DTMF responsiveness, and webhook response times. Issues caught in testing save voice minutes and prevent poor caller experiences at scale.