Custom code (TwiML)
Overview
A custom code extension hands the call to a web address of your own. We fetch that address, and whatever TwiML it returns is what the caller hears next. When your code is finished the call comes back and continues where you tell it to.
This is the escape hatch for developers. Everything a normal hotline needs is already a building block, so reach for this only when you need behavior the built-in extensions do not cover, such as answers that depend on live data from your own system.
In the sidebar it lives under Advanced, listed as Twimls. Everywhere a destination is picked, and on My Hotline, it is called Custom code.
How It Works
- The caller reaches the custom code extension.
- We send the call to your TwiML URL with a
GETrequest. The call really moves there; we do not proxy it. - Your server answers with TwiML, and the caller hears whatever it says.
- When your TwiML sends the call back to us, the Afterwards route decides where the caller goes next.
Your code is responsible for the caller from the moment we hand the call over. If your address is unreachable or returns something that is not valid TwiML, the call stops there.
Settings
- TwiML Name (required) — For your reference. On My Hotline it is just the extension's name.
- TwiML URL — The address we fetch. It must return TwiML: XML instructions such as
<Play>,<Say>or<Dial>. On My Hotline this field is called Code URL. Usehttps://. The form does not force you to fill it in, but an extension with no URL has nothing to run. - HTTP Method — GET. It is the only option.
- Active — Turn the extension off without deleting it. Callers routed to an extension that is off do not run your code.
- Phone System Reference → Extension ID — Only shown when your account has phone-system references turned on. See Settings.
Routing
| Route | When it fires |
|---|---|
| Afterwards | Your TwiML finishes and sends the call back to us |
Set it on the form, or from the extension's ⚙ settings on My Hotline. Point it at your main menu so callers land somewhere sensible when your code is done. Leave it empty and the call ends there.
Code in the hotline (a TwiML bin)
You do not need a server. Choose In the hotline as the source and paste the TwiML into the editor. The hotline keeps it, fills in the values of each call, and runs it. The call never leaves the hotline, so the call trace keeps recording.
<Response>
{{#if From == 18455551234}}
<Say>Welcome back, {{caller_name}}.</Say>
<Dial><Number>18455550000</Number></Dial>
{{#elseif Digits == 1}}
<Redirect>{{return_url}}</Redirect>
{{#else}}
<Gather action="{{self_url}}" numDigits="1">
<Say>Press 1 to continue on the hotline.</Say>
</Gather>
{{/if}}
</Response>
Variables
| Variable | Meaning |
|---|---|
{{From}} / {{To}} |
The caller's number and the number they dialed, digits only |
{{Digits}} |
What the caller pressed in a <Gather> whose action is {{self_url}} |
{{CallSid}} |
The call id |
{{caller_name}} / {{contact_labels}} |
Filled when the number matches one of your contacts |
{{hotline_name}} |
The name of your hotline |
{{return_url}} |
Continue with this extension's Afterwards route |
{{self_url}} |
Run this code again, which is how a <Gather> reports its digits back to it |
Values are escaped for XML, so a contact name with special characters cannot break the code.
Conditions
{{#if …}}, {{#elseif …}}, {{#else}} and {{/if}}, nested as you need. Compare with ==, !=, contains, starts_with and ends_with, combine with and, or, not and parentheses. Values with spaces go in quotes. Phone numbers compare loosely, so From == "+1 (845) 555-1234" and From == 18455551234 both match a caller shown as 18455551234. The syntax is the one Telnyx TeXML uses, so their examples run unchanged.
The editor checks the code when you save: it must render, be valid XML with a <Response> root, and use only these verbs: Play, Say, Gather, Record, Dial, Pause, Redirect, Pay, Conference, Hangup. A mistake is reported with the line, never discovered by a caller.
Coming back into the hotline
Your TwiML can hand the call back whenever it likes with a <Redirect> to the extension's return link, shown on the extension's page as Link for custom code. Every extension has such a link, so you can send the call to a specific menu, audio player or message box, not only back to where it came from:
<Response>
<Say>Thanks, back to the hotline.</Say>
<Redirect>https://hotlines.callmagic.app/public/go/5f1c…</Redirect>
</Response>
- The custom-code extension's own link continues with its Afterwards route.
- Another extension's link enters that extension as if a caller had pressed its key.
- The link is an opaque id: it does not reveal how the hotline's own URLs are built, and it only works for calls that are already on your hotline.
What the call trace shows
The call trace records every step the hotline handles. The moment the call is handed to your code it logs "custom code" with your host name, and everything up to that point is saved at once. What your code does afterwards is not traced, since those requests go to your server. If your code sends the call back through a return link, the trace continues from there with "entered via link".
What it costs
A custom code extension is a $20 a month add-on, one per extension, bought under Advanced options on the Plans & Add-ons page. The base plans include no advanced options, so buy one for each custom code extension you need. See Billing.
Writing the TwiML
Most standard Twilio TwiML verbs work. The platform also understands a handful of non-standard attributes, mainly for conferences and for interactive playback. They are all listed in Custom TwiML.
If you are building something that reads or changes the hotline itself rather than handling a single call, the Hotline API is usually the better tool.
Tips
- Keep it short. Hand the call back to the hotline as soon as your part is done, and let the built-in extensions do the rest.
- Test the URL in a browser first. If it does not return XML when you open it, it will not work on a call either.
- Use the test line while you develop, so real callers never hit a half-finished handler.
- Watch the call trace on Reports to see exactly where a call left the hotline and whether it came back.