Rate this page:

Media Support

Programmable Chat has been deprecated and is no longer supported. Instead, we'll be focusing on the next generation of chat: Twilio Conversations. Find out more about the EOL process here.

If you're starting a new project, please visit the Conversations Docs to begin. If you've already built on Programmable Chat, please visit our Migration Guide to learn about how to switch.

Programmable Chat supports media messages, allowing your users to add photos, video or any other type of file to their chat. A media message appears on the channel similar to a text only message but with additional properties that let your client know the media's size as well as an optional content type and default filename. When creating your media message, you will pass media to the Programmable Chat SDK which will be read and saved to your Chat instance. Your application can later request a stream to retrieve the media associated with a message and display it to your users.

Using Media Messaging via the client SDKs (iOS, Android and Javascript)

A typical media message creation will include the following steps with the details depending on your client platform:

  • Create a new message, passing in a stream to the media and its mime content type. (The current maximum size of media accepted is 150mb.)
  • Optionally specify a default download filename to help your application display the media to other users.
  • Programmable Chat will provide you feedback of upload progress as well as an indication your media has been successfully saved. (iOS and Android only)
  • The message is created in the specified channel.

On the receiving side of a media message, you will:

  • Receive a chat message that includes a media SID.
  • When you're ready to display the media to your user, you'll obtain the download URL
  • Your client will display or otherwise make available to the user the message's media content.

Media on messages within Programmable Chat are attachments which live separately from your chat message. They are associated to the owning message by a media SID. Media files cannot exist without their owning message, and deletion of a message will result in cleanup of its associated media. Media files are immutable once created, you can modify other supported attributes of a message that has media content but the media itself is not changeable. Media messages do not contain a per-message text portion, instead being populated by the service with a placeholder message for legacy clients without media attachment support – this placeholder message is developer definable on the service instance.

Most developers will want to implement media caching to avoid unnecessary battery or network consumption should the application need to view the same media multiple times. An example of such a caching mechanism can be found in the helper classes of the Chat demo applications published to GitHub. It is also a good idea to prevent concurrent downloads of the same media in your clients, the helper library also handles queueing up requests for the same media until a single download completes before returning the requested media object.

Required Role Permission

For your users to create messages with media content, their Role must contain the sendMediaMessage and sendMessage permissions. On new Chat instances this is in the default channel roles, but must be added to existing instances if you wish to support it. For an example on how to apply this permission to your Channel User and Admin roles, see Update a Role or Roles and Permissions for more general information on Roles in Programmable Chat.

Downloading Media

On the receiver side, media is exposed with help of temporary URL. Only authenticated and authorized users can request the URL. The URL is valid for 300 seconds. You can request a new temporary URL at any point of time.

Platform Differences for Media

The media creation methods within the client SDK's take a stream or file as a parameter. How the media is expressed in the client SDK will depend on your platform:


For Javascript, you can provide a FormData containing file information (including file name, content type, size and all FormData provided information), a String or a Node.js Buffer containing media byte stream to be used as the source for a new media message.


Media files are uploaded by providing an NSInputStream compliant stream to the TCHMessageOptions for your new message.


For Android, any compliant stream can be used as the source for a new media message.

Creating a Media Message

Creating a media enriched message is very similar to creating a new text-only message - you start by creating a message as usual but instead of body for the content, you provide media for the message:

Loading Code Sample...

        Creating a Media Message

        Checking for Media Content

        Only messages which contain media will have a media SID associated with them. The code sample provided here shows how to detect a media message on each platform:

        Loading Code Sample...

              Checking for Media Content

              Retrieving Message Media Content

              It's important to note that at this time, Programmable Chat does not maintain an internal cache of media so you are encouraged to cache downloaded media in your application to avoid unnecessary downloads. It is also important for best performance to only allow a particular media file to be downloaded one at a time to avoid unnecessary battery and network consumption.

              Loading Code Sample...

                    Retrieving Message Media Content

                    Using Media Messaging via the Chat REST API

                    Your backend services can also use the Media feature off Chat - uploading new files for attachment with Messages, and of course sending Messages with Media attached. This section provides a brief overview of typical Media operations and flows. For a more detailed API description, please refer to Chat Media REST API documentation.

                    At present the underlying Media REST endpoint which is used to create (upload) the media (files) is a separate endpoint and not supported in the Twilio Helper Libraries.

                    Sending a Media Message

                    Sending a Media Message via REST is a 2 step process:

                    1. Upload media to MCS
                    2. Send Media Message to chat channel (linking/attaching the Media created in step 1 to the new Message)

                    Uploading media should be done directly from the source machine, using native HTTP facilities. Using cURL, the equivalent request looks like this:

                    curl -u “<acount_sid>:<account_secret>” --data-binary “@<filename>”<chat_service_sid>/Media

                    That will leave your media on Twilio servers, ready to be bound to a Chat Message by the returned SID. The REST Message endpoint documentation is a good general description for sending Chat messages; the MediaSid parameter accepts the SID from the media upload and binds that media to the message.

                    curl -u “<acount_sid>:<account_secret>” -X POST<chat_service_sid>/Channels/<channel_sid>/Messages -d MediaSid=<media_sid>

                    Now that you're ready to enable your users to share the finest cute animal photos the internet has to offer, let's learn about Result Paging in Chat.

                    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.

                    Loading Code Sample...

                          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!