Get Started with TwiML Bins

Meet TwiML Bins

TwiML Bins are a serverless solution that help you provide Twilio-hosted instructions to your Twilio applications. They’re a useful way to prototype and explore Twilio’s capabilities without needing to set up your own web server to respond to requests. Remember, Twilio expects your webhook to respond with properly formed TwiML.

TwiML Bins support templating, meaning that you can include information dynamically in your response. These templates add quite a bit of power to your application, but they do have some limitations, as they are logic-less by design. We’ll explore exactly what that means here in a bit.

If your use case requires complex logic or looping, you should check out another one of our serverless offerings, Twilio Functions

In this tutorial we’ll walk through how to create and use a TwiML Bin that will respond to an incoming Voice call. Then we’ll explore templating with dynamic values.

Sign up and buy a number

You can sign up for a free Twilio trial account here.

  • When you sign up, you'll be asked to verify your personal phone number. This helps Twilio verify your identity and also allows you to make calls to your phone from your Twilio account while in trial mode.
  • Once you verify your number, you'll be asked to create a project. For the sake of this tutorial, you can click on the "Learn and Explore" template. Give your project a name, or just click "skip remaining steps" to continue with the default.
  • Once you get through the project creation flow, you'll arrive at your project dashboard in the Twilio Console. This is where you'll be able to access your Account SID, authentication token, find a Twilio phone number, and more.

If you don't currently own a Twilio phone number with Voice functionality, you'll need to purchase one. After navigating to the Buy a Number page, check the "Voice" box and click "Search."

Search for a Phone Number.png

You’ll then see a list of available phone numbers and their capabilities. Find a number that you like and click "Buy" to add it to your account.

Buy a Phone Number.png

Create a new TwiML Bin

To create a new bin, head over to your console. You’ll find all your TwiML Bins located under the Developer tools section.

If this is your first time here, you’ll be prompted with a button to "Create a new TwiML Bin." Otherwise, you’ll see a + button above your current list of TwiML Bins.

Our demo application is going to simply respond to a caller with the phrase "Hello, World." A TwiML Bin allows you to set a Friendly Name to later identify it. Let’s enter "Hello World" for the Friendly Name.

In the text area, you’ll notice that your TwiML Bin is prepopulated with the proper XML declaration. Right after that declaration, let’s add some valid Voice TwiML.

<?xml version="1.0" encoding="UTF-8"?>
  <Say>Hello, World!</Say>

Remember that TwiML is case sensitive: <say> is different than <Say>

If you’ve done this correctly, you’ll notice a validation success message directly below your TwiML bin.

Finally, click the Create button. Now that we’ve got it created, let's go use it!

Wire your TwiML Bin up to an incoming phone call

To use your new TwiML Bin, you’ll need to set a handler on one of your phone numbers.

Choose a number from your list of phone numbers to use the instructions you provided in your TwiML Bin with this number. Click on this number, then under the Configuration tab, in the Voice & Fax section, choose TwiML from the “A Call Comes In” dropdown menu.

In the "Select a TwiML Bin" dropdown, you’ll see your friendly named TwiML Bin, "Hello World". Choose that, and be sure to Save your phone number. Now go ahead give your number a call. Hello, world indeed!

You might’ve noticed while you were choosing your TwiML Bin from the dropdown that there was a plus button. This is a shortcut to quickly add one of these handy bins, right when you need it.

And just like that, you have a hosted solution that you can quickly update to meet your needs. This static TwiML will get you pretty far in building all sorts of applications.

However, there will most likely come a time where you’ll want to customize the TwiML based on the specific request coming in.

Use dynamic values

We've all encountered a static website where the information is always the same and never changes. Some websites offer more customization to their users. Maybe you’re logged in and you’re greeted by your name. Or maybe the site knows your location and serves location-specific content to you.

Twilio applications can be customized too. You can use information about the incoming request in your TwiML Bin by using the built-in templating language, Mustache.

Nice Mustache

Mustache is a logic-less templating language – that is to say, there aren’t any specific looping constructs, nor are there any branching statements. It’s a popular templating solution with various language implementations. The name comes from the curly braces used in its syntax. If you tilt your head sideways, a { does indeed look like a mustache.

Mustache uses what are known as tags to create your dynamic content. You can create a tag with double opening mustaches, followed by a tag key, and then closing mustaches. Your tag key directly references your dynamic data.

For instance, we should make our TwiML a little more personalized. How about instead of saying "Hello, World!", we personalize it with the caller’s phone number?

<?xml version="1.0" encoding="UTF-8"?>
  <Say>Hello, {{From}}!</Say>

With this template, we can render the caller's phone number using an object, or hash, to produce our dynamic content.

Your TwiML Bin will automatically create that object and then apply it to your template. By default, the Twilio Request Parameters are available for use in these templates.

Go ahead and give your number a call. Yikes, it doesn’t sound the greatest.

They say nothing is more beautiful than the sound of your own name. It'd be nice to be able to pass a customized name through. Let’s do that next.

Pass custom values into a TwiML Bin

In addition to the values from Twilio's Request, your object will also contain any query string parameters on the URL. Remember that Twilio applications can have many events occur that will make webhook requests to specific URLs.

Every TwiML Bin has a unique URL. Go ahead and copy yours now.

TwiML Bins URL copy

When you declared your incoming call webhook, you’ll recall we used the TwiML value in the dropdown. This time, just for the sake of demonstrating how to pass in a custom value, let’s go ahead and switch the dropdown to Webhook. Now paste in the URL that leads to your TwiML Bin.

To add a query string to a URL, add a trailing question mark followed by key and value pairs, all joined together by ampersands.

For instance:


Let’s add a query string to our TwiML Bin that sets the value of FirstName to your name.


And now let's open your TwiML template and make it use the FirstName variable we passed in the query string.

<?xml version="1.0" encoding="UTF-8"?>
  <Say>Hello, {{FirstName}}!</Say>

Now save your phone number and give it a call. Wasn’t that a beautiful sound? (That is of course assuming the text-to-speech pronounced your name correctly.)

There's a potential problem lurking here. Our template now basically requires that we pass in a FirstName variable on the query string. We should deal with the case where there is missing data.

Handle missing data

Even though our templates are logic-less, we can still show and hide parts of a template by using Mustache sections.

In our TwiML template, we want to only say "Hello" when we have a FirstName value. We can define a section for FirstName by including a mustache followed by the pound sign, # (or hashtag if you will).

<?xml version="1.0" encoding="UTF-8"?>
    Hello, {{ . }}!

The code between the tags is relative to the parent section’s data layout. It’s possible to use nested objects as your object. However, in our case, FirstName is only at the top level of our object. To access the current value of a section you use the . notation. See how inside the {{#FirstName}} section we are using the dot . to refer to its value.

Great! Now it will only say Hello, FirstName when the value is available. However, we should probably say Hello World by default, in the case that the FirstName value doesn’t exist.

Good news! We can also define inverted sections. These sections will only display when a value is missing. To define an inverted section, you use the caret ^ symbol followed by the section name.

<?xml version="1.0" encoding="UTF-8"?>
    Hello, {{ . }}!
    Hello, World!

And there you go! Go ahead and change your TwiML Bin's URL to include FirstName as a query parameter. Verify that you hear the first name. Now remove it, and you should hear "Hello World" again.

Even though this example only swaps out text in the body of a TwiML tag, you should note that these sections can also include TwiML tags. Essentially this allows you to optionally include instructions.

Need more power?

You’ll find you can build quite a lot of robust solutions using just TwiML Bins. If you find that you need a bit more power and would like all the perks of remaining serverless, we highly recommend you explore our other serverless products, Twilio Functions and Assets and Twilio Studio.

We can’t wait to see what you build!

Rate this page:

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd by visiting Twilio's Stack Overflow Collective or browsing the Twilio tag on Stack Overflow.

Thank you for your feedback!

Please select the reason(s) for your feedback. The additional information you provide helps us improve our documentation:

Sending your feedback...
🎉 Thank you for your feedback!
Something went wrong. Please try again.

Thanks for your feedback!