Rate this page:

Thanks for rating this page!

We are always striving to improve our documentation quality, and your feedback is valuable to us. How could this documentation serve you better?

TwiML™ for Programmable SMS

What is TwiML?

TwiML (the Twilio Markup Language) is a set of instructions you can use to tell Twilio what to do when you receive an incoming call, SMS, or fax.

TwiML can be generated using one of the Twilio Language Helper Libraries, or written manually to instruct Twilio on what actions to take in response to various SMS related events.

Not sending messages? TwiML powers more than just Twilio Programmable SMS – check out the documentation on how to use TwiML with Programmable Voice and Programmable Fax.

A basic TwiML SMS response example

The following manual TwiML will instruct Twilio to respond to an incoming SMS with a "Hello World!" reply:

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

The same TwiML can also be generated using the examples in these following code samples. The redirect control allows you to point at another TwiML file from your current file.

Toggle between the code in your language of choice and TwiML in the top bar of the code viewer:


        Building an SMS Application? Our SMS Quickstarts will show you how to send, receive, and reply with SMS using your choice of web language.

        Generating TwiML with the Twilio helper libraries

        Twilio provides helper libraries to help you generate TwiML in your favorite language.

        For example, here's code demonstrating how to send two unique messages one after the other using helper libraries. Select your choice of language to see how it's done:


              Twilio's request to your application

              Twilio makes HTTP requests to your application just like a regular web browser, in the format application/x-www-form-urlencoded. By including parameters and values in its requests, Twilio sends data to your application that you can act upon before responding.

              You can configure the URLs and HTTP Methods Twilio uses to make its requests via your account portal or using the REST API.

              Note that Twilio cannot cache POSTs. If you want Twilio to cache static TwiML pages, then have Twilio make requests to your application using GET.

              When Twilio receives a message for one of your Twilio numbers or Channels, it makes a synchronous HTTP request to the message URL configured for that number or Channel and expects to receive TwiML in response.

              Twilio sends the following parameters with its request as POST parameters or URL query parameters, depending on which HTTP method you've configured:

              Request parameters

              MessageSid A 34 character unique identifier for the message. May be used to later retrieve this message from the REST API.
              SmsSid Same value as MessageSid. Deprecated and included for backward compatibility.
              AccountSid The 34 character id of the Account this message is associated with.
              MessagingServiceSid The 34 character id of the Messaging Service associated with the message.
              From The phone number or Channel address that sent this message.
              To The phone number or Channel address of the recipient.
              Body The text body of the message. Up to 1600 characters long.
              NumMedia The number of media items associated with your message

              Twilio also sends the following parameters when there are media, such as images, associated with the message:

              MediaContentType{N} The ContentTypes for the Media stored at MediaUrl{N}. The order of MediaContentType{N} matches the order of MediaUrl{N}. If more than one media element is indicated by NumMedia than MediaContentType{N} will be used, where N is the zero-based index of the Media (e.g. MediaContentType0)
              MediaUrl{N} A URL referencing the content of the media received in the Message. If more than one media element is indicated by NumMedia than MediaUrl{N} will be used, where N is the zero-based index of the Media (e.g. MediaUrl0)

              Twilio also attempts to look up geographic data based on the 'From' and 'To' phone numbers. Twilio sends the following parameters, if available:

              FromCity The city of the sender
              FromState The state or province of the sender.
              FromZip The postal code of the called sender.
              FromCountry The country of the called sender.
              ToCity The city of the recipient.
              ToState The state or province of the recipient.
              ToZip The postal code of the recipient.
              ToCountry The country of the recipient.

              For status callbacks, Twilio also sends status-related parameters:

              MessageStatus The status of the message. Can be: accepted, queued, sending, sent, failed, delivered, undelivered, receiving, received, or read (WhatsApp only). For more information, see detailed descriptions.
              SmsStatus Same as MessageStatus value. Deprecated and included for backward compatibility.

              Data formats

              Phone numbers

              All phone numbers in requests from Twilio are in E.164 format if possible. For example, (415) 555-4345 would come through as '+14155554345'. However, there are occasionally cases where Twilio cannot normalize an incoming caller ID to E.164. In these situations, Twilio will report the raw caller ID string.

              Dates and times

              All dates and times in requests from Twilio are GMT in RFC 2822 format. For example, 6:13 PM PDT on August 19th, 2010 would be 'Fri, 20 Aug 2010 01:13:42 +0000'

              'STOP' and opt-out

              Twilio will handle opt-outs on all long code phone numbers in accordance with industry standards.

              Opt out keywords are passed to your application to notify you that a user has opted out. All future messages to the user will result in an error. 'Start' and 'Yes' keywords will also be passed to your application and to opt users back in.

              When a user has opted out of a phone number that belongs to a Messaging Service, the user has also been opted out of receiving all messages sent from that particular Messaging Service.

              Responding to Twilio

              When a message comes into one of your Twilio numbers, Twilio makes an HTTP request to the message URL configured for that number.

              In your response to that request, you can tell Twilio what to do in response to the message. You can configure your number URLs here.

              Twilio is a well-behaved HTTP client

              Twilio behaves just like a web browser, so there's nothing new to learn.

              • Cookies: Twilio accepts HTTP cookies and will include them in each request, just like a normal web browser.
              • Redirects: Twilio follows HTTP Redirects (HTTP status codes 301, 307, etc.), just like a normal web browser.
              • Caching: Twilio will cache files when HTTP headers allow it (via ETag and Last-Modified headers) and when the HTTP method is GET, just like a normal web browser.


              Twilio will keep cookie state across multiple SMS messages between the same two phone numbers. This allows you to treat the separate messages as a conversation, and store data about the conversation, such as a session identifier, in the cookies for future reference. Twilio will expire the cookies for that conversation after four hours of inactivity.

              Twilio understands MIME types

              Twilio does the right thing when your application responds with different MIME types.

              MIME TYPE BEHAVIOR
              text/xml, application/xml, text/html Twilio interprets the returned document as a TwiML XML Instruction Set. This is the most commonly used response.
              text/plain Twilio returns the content of the text file to the sender in the form of a message.

              How Twilio's TwiML interpreter works

              When your application responds to a Twilio request with XML, Twilio runs your document through the TwiML interpreter. To keep things simple, the TwiML interpreter only understands a few specially-named XML elements. In TwiML parlance, these are divided into three groups: the root <Response> element, "verbs" and "nouns." We discuss each group below.

              The interpreter starts at the top of your TwiML document and executes instructions ("verbs") in order from top to bottom. As an example, the following TwiML Message snippet sends "Hello World" as a message reply to the sender before redirecting control to the TwiML at

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

              You can provide multiple <Message> verbs in one TwiML document to send multiple messages. For example:

              <?xml version="1.0" encoding="UTF-8" ?>
                  <Message>This is message 1 of 2.</Message>
                  <Message>This is message 2 of 2.</Message>

              TwiML elements ("verbs" and "nouns") have case-sensitive names. For example, using <message> instead of <Message> will result in an error. Attribute names are also case sensitive and camelCased. You can use XML comments freely; the interpreter ignores them.

              The <Response> element

              The root element of Twilio's XML Markup is the <Response> element. In any TwiML response to a Twilio request, all verb elements must be nested within this element. Any other structure is considered invalid.


              <?xml version="1.0" encoding="UTF-8"?>
                  <Message>I'm hungry!</Message>

              TwiML messaging verbs

              Most XML elements in a TwiML document are TwiML verbs. Verb names are case sensitive, as are their attribute names. There is only one core TwiML Message verb and one secondary verb, with detailed documentation on each. The core verb is:

              <Message>: Send a message in reply to the incoming message.

              There are certain situations when the TwiML interpreter may not reach verbs in a TwiML document because control flow has passed to a different document. This usually happens when a verb's 'action' attribute is set.

              For example, if a <Message> is followed by a <Redirect>, the <Redirect> is unreachable if the <Message> verb's 'action' URL is set. In this case, SMS session flow continues with the TwiML received in your response to the 'action' URL request.

              The following verbs may impact control flow: <Message> and <Redirect>

              TwiML nouns

              A Noun in TwiML is anything nested inside a verb that is not itself a verb. It's whatever the verb is acting on. This is usually just text. But sometimes, as in the case of <Message> with its <Media> and <Body> nouns, there are nested XML elements that are nouns.

              Status callbacks

              You can use status callbacks to have Twilio reach out to your app when the status of a message has changed.

              Status callbacks do not control application flow, so TwiML does not need to be returned; however, it's recommended that you respond to status callbacks with either a 204 No Content or a 200 OK with Content-Type: text/xml and an empty <Response/> in the body. Failure to respond properly will result in warnings in Debugger.

              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 browsing the Twilio tag on Stack Overflow.