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
| Consideration | IVR Flow Builder | XML Template Builder |
|---|---|---|
| Learning curve | Low — visual drag-and-drop | Moderate — requires XML knowledge |
| Provider support | SignalWire, Plivo, Indian Route | SignalWire, Plivo, Indian Route |
| Flow complexity | Good for standard branching | Excellent for deeply nested logic |
| Dynamic content | Limited to variables | Full programmatic control |
| API integration | Not available | Can trigger webhooks mid-call |
| Version control | Manual snapshots | XML files can be stored in Git |
| Error handling | Built-in defaults | Custom error paths per element |
| Rapid prototyping | Faster for simple flows | Faster for replicating existing scripts |
Features
Create XML Scripts
- Navigate to XML Builder from the sidebar.
- Click Create Script.
- Enter a Script Name (e.g., “Payment Reminder Flow v2”).
- Write or paste your XML content in the editor. Use the element reference below as a guide.
- The editor provides syntax highlighting and basic validation as you type.
- Click Save. The system validates your XML for well-formedness and supported elements.
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.
| Attribute | Type | Required | Description |
|---|---|---|---|
src | URL | Yes | Full HTTPS URL of the audio file. Must be publicly accessible. |
loop | Integer | No | Number 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.
| Attribute | Type | Required | Description |
|---|---|---|---|
language | String | No | Language code (e.g., en-IN, hi-IN). Defaults to en-IN. |
voice | String | No | Speaker voice name (e.g., female, male). Defaults to provider default. |
speed | Float | No | Speech 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.
| Attribute | Type | Required | Description |
|---|---|---|---|
maxdigits | Integer | No | Maximum number of digits to collect (1–10). Default: 1. |
timeout | Integer | No | Seconds to wait for input (1–15). Default: 5. |
terminator | String | No | Key that signals end of input (# or *). Default: #. |
numdigits | Integer | No | Exact number of digits to collect. Overrides maxdigits. |
retry | Integer | No | Number 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>.
| Attribute | Type | Required | Description |
|---|---|---|---|
on | String | No | The variable or expression to evaluate. Defaults to the last gathered input. |
<case>
Defines a route branch within a <switch>. Executes if the key matches.
| Attribute | Type | Required | Description |
|---|---|---|---|
key | String | Yes | The 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.
| Attribute | Type | Required | Description |
|---|---|---|---|
timeout | Integer | No | Seconds to ring before timing out. Default: 30. |
callerId | String | No | Override 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.
| Attribute | Type | Required | Description |
|---|---|---|---|
duration | Integer | Yes | Duration of silence in seconds (1–30). |
<pause duration="2" /><record>
Records the caller’s audio during a call segment.
| Attribute | Type | Required | Description |
|---|---|---|---|
maxduration | Integer | No | Maximum recording duration in seconds. Default: 60. |
terminator | String | No | Key to stop recording (# or *). |
beep | Boolean | No | Play 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.
| Attribute | Type | Required | Description |
|---|---|---|---|
url | String | Yes | The HTTPS URL to call. |
method | String | No | HTTP method: GET or POST. Default: POST. |
timeout | Integer | No | Seconds 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:
- Select XML Script as the calling type.
- Choose your saved script from the dropdown.
- The platform automatically transforms your VoxiXML into provider-specific tags at runtime, so it works with any configured provider (SignalWire, Plivo, or Indian Route).
- 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
srcandurlattributes must start withhttps://. 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.