> ## Documentation Index
> Fetch the complete documentation index at: https://www.vobiz.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Twilio to Vobiz Code: Answer Calls with XML

> Side-by-side Twilio and Vobiz code for answering a call - build VobizXML instead of TwiML and serve it from your answer URL in Flask, FastAPI, or Express.

Part of the [Twilio to Vobiz code snippets](https://www.vobiz.ai/docs/compare/twilio/code-snippets): each task shows the **Twilio** code and the equivalent **Vobiz** code in Python and Node - copy the Vobiz tab. The snippets use the `client` from [Set up the client](https://www.vobiz.ai/docs/compare/twilio/code-snippets#set-up-the-client).

> [!NOTE]
>
> Set your credentials once: `AUTH_ID` is your Vobiz Auth ID (`MA_…`), `AUTH_TOKEN` is your Auth Token. In the Vobiz SDK, `api_key` **is** the Auth ID, and every account-scoped method takes that `auth_id` explicitly.

## Answer a call with XML (TTS + menu)

The XML builder maps verb-for-verb: `VoiceResponse()` → `ResponseElement()`, and `Gather` keeps its name. On the builder, `response.gather(...)` → `resp.add_gather(...)`, nested `.say()` → `.add_speak()`, and `str(response)` → `resp.to_string()`. Twilio's `input`/`timeout` become Vobiz's `input_type`/`execution_timeout`; `num_digits` carries over unchanged.

| Change | Twilio | Vobiz |
| - | - | - |
| Builder | `VoiceResponse()` | `vobizxml.ResponseElement()` |
| Gather (Python) | `resp.gather(...)` | `resp.add_gather(...)` |
| Gather (Node) | `resp.gather({...})` | `resp.addGather({...})` |
| Input type | `input` | `input_type` / `inputType` |
| Timeout | `timeout` | `execution_timeout` / `executionTimeout` |
| Digits | `num_digits` / `numDigits` | `num_digits` / `numDigits` |
| Speak text | `.say()` | `.add_speak()` / `.addSpeak()` |
| Render (Python) | `str(resp)` | `resp.to_string()` |

```python Twilio · Python theme={null}
from twilio.twiml.voice_response import VoiceResponse, Gather

resp = VoiceResponse()
menu = resp.gather(input='dtmf', num_digits=1, timeout=10,
                   action='https://example.com/menu', method='POST')
menu.say('Press 1 for sales, 2 for support.')
print(str(resp))
```

```python Vobiz · Python theme={null}
from vobiz import vobizxml

resp = vobizxml.ResponseElement()
menu = resp.add_gather(input_type='dtmf', num_digits=1, execution_timeout=10,
                       action='https://example.com/menu', method='POST')
menu.add_speak('Press 1 for sales, 2 for support.')
print(resp.to_string())
```

```javascript Twilio · Node theme={null}
const { twiml } = require('twilio');

const resp = new twiml.VoiceResponse();
const menu = resp.gather({ input: 'dtmf', numDigits: 1, timeout: 10, action: 'https://example.com/menu', method: 'POST' });
menu.say('Press 1 for sales, 2 for support.');
console.log(resp.toString());
```

```javascript Vobiz · Node theme={null}
import { vobizxml } from '@vobiz/sdk';

const resp = new vobizxml.ResponseElement();
const menu = resp.addGather({ inputType: 'dtmf', numDigits: 1, executionTimeout: 10, action: 'https://example.com/menu', method: 'POST' });
menu.addSpeak('Press 1 for sales, 2 for support.');
console.log(resp.toString());
```

Vobiz emits the same document shape your TwiML app already returns - see the full verb table in [TwiML → VobizXML](https://www.vobiz.ai/docs/compare/twilio/twiml-to-vobizxml.md), and validate the incoming request on your answer URL as shown in [Webhooks](https://www.vobiz.ai/docs/compare/twilio/webhooks.md).

## Serve the answer URL (Flask / FastAPI / Express)

When Vobiz rings your number it fetches your `answer_url` over HTTP - return the VobizXML from any web framework, exactly as your Twilio voice URL returned TwiML. Just build the response with `vobizxml` instead of `VoiceResponse`, and send it as `application/xml`.

| Framework | Route | Returns |
| - | - | - |
| Flask | `@app.route('/answer', methods=['POST'])` | `Response(resp.to_string(), mimetype='application/xml')` |
| FastAPI | `@app.post('/answer')` | `Response(content=resp.to_string(), media_type='application/xml')` |
| Express | `app.post('/answer', ...)` | `res.type('application/xml').send(resp.toString())` |

```python Twilio · Flask theme={null}
from flask import Flask, Response
from twilio.twiml.voice_response import VoiceResponse

app = Flask(__name__)

@app.route('/answer', methods=['POST'])
def answer():
    resp = VoiceResponse()
    resp.say('Hello from Twilio.')
    return Response(str(resp), mimetype='application/xml')
```

```python Vobiz · Flask theme={null}
from flask import Flask, Response
from vobiz import vobizxml

app = Flask(__name__)

@app.route('/answer', methods=['POST'])
def answer():
    resp = vobizxml.ResponseElement()
    resp.add_speak('Hello from Vobiz.')
    return Response(resp.to_string(), mimetype='application/xml')
```

```python Vobiz · FastAPI theme={null}
from fastapi import FastAPI, Response
from vobiz import vobizxml

app = FastAPI()

@app.post('/answer')
async def answer():
    resp = vobizxml.ResponseElement()
    resp.add_speak('Hello from Vobiz.')
    return Response(content=resp.to_string(), media_type='application/xml')
```

```javascript Vobiz · Express theme={null}
import express from 'express';
import { vobizxml } from '@vobiz/sdk';

const app = express();

app.post('/answer', (req, res) => {
  const resp = new vobizxml.ResponseElement();
  resp.addSpeak('Hello from Vobiz.');
  res.type('application/xml').send(resp.toString());
});
```

> [!TIP]
>
> Building the XML is the only thing that changes - swap `VoiceResponse()`/`str(resp)` for `vobizxml.ResponseElement()`/`resp.to_string()` and keep the same route. The full verb map is in [TwiML → VobizXML](https://www.vobiz.ai/docs/compare/twilio/twiml-to-vobizxml.md), and validating the signed request on this endpoint is covered in [Webhooks](https://www.vobiz.ai/docs/compare/twilio/webhooks.md).

## More Twilio to Vobiz code snippets

* [Set up the client and make an outbound call](https://www.vobiz.ai/docs/compare/twilio/code-snippets)
* [Live calls](https://www.vobiz.ai/docs/compare/twilio/code-snippets/live-calls.md)
* [Numbers and conferences](https://www.vobiz.ai/docs/compare/twilio/code-snippets/numbers-and-conferences.md)
* [Call records, webhooks and errors](https://www.vobiz.ai/docs/compare/twilio/code-snippets/call-records-webhooks-errors.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.