Rate this page:


Twilio Assets is a static file hosting service that allows developers to quickly upload and serve the files needed to support their applications. With Twilio Assets you can host your files that support web, voice, and messaging applications. Twilio Assets is frequently used to host .mp3 audio files used in TwiML and Studio Flows, to serve images sent through MMS, or to store configuration used by Twilio Functions.

How Assets work

Twilio provides you with three different types of Assets: public, protected, and private. The primary difference between the types is how they are accessed:

  • Public Assets are served over HTTPS from the Twilio CDN to ensure that they are highly available and secure, and are accessible by anyone with the Asset's URL.
  • Protected Assets are accessible via the Twilio CDN by URL as well, but require a valid Twilio request signature, or they will return a 403 error.
  • Private Assets are not accessible by URL or exposed to the web; instead, they are packaged with your Twilio Functions at build time.

If you would like to learn more about Asset visibility, we have a document that goes over the distinctions between public, protected, and private assets in greater detail.

Warning about use of public Assets

Anyone with the URL to a public asset will be able to access it. Therefore, customers should be thoughtful about what data they include in a public asset.

Metadata warning

Asset files are uploaded as is, with all metadata persisted. If your Asset files contain metadata, that will be stored with the file. An example would be EXIF metadata stored with an image. If you are making files available, please note that metadata is persisted and not removed/changed by the Assets product in any way.

Get started with Assets

Start by opening one of your existing Services, or by creating a new one. Once you're in the Functions Editor UI for your Service there are three points of interest:

  1. The Assets pane, which lists your Assets, their Visibility, a context menu for adjusting visibility, and another menu for other actions.
  2. The Add+ button which allows you to upload files as Assets, or create a new Asset.
  3. The Deploy All button, which will trigger an upload and deploy of your Assets (along with any Functions)

Assets UI points of interest

Upload a file by clicking Add+ and then Upload File in the resulting menu, which will open up a standard file upload dialogue. Once you've selected a file or files, you'll be presented with options to set the visibility of each Asset, as well as the ability to remove or add other files. Click Upload to begin uploading your selection of files with the desired settings.

upload assets UI

While the Asset has been uploaded, it will not be immediately accessible via a URL or in your Functions yet. This will be indicated by the gray circle next to the Asset's name. To deploy the Asset (and the rest of your Service), click the Deploy All button. After a brief period, the deployment will finish, and you should see a green check appear next to all deployed Assets.

Assets once deployed

Get the URL of an Asset

In general the URL of one of your Assets can be determined by taking the URL of your Service, for example, and appending the name of your Asset.

In the case of an Asset such as example.json in that Service, it can be accessed at

For a point and click solution, the Functions Editor UI also provides two ways to copy the URL of an Asset to your clipboard:

  • Open the context menu of an Asset, and click Copy URL
  • Open an Asset in the Functions Editor, and click the Copy URL button that will appear below the content editor and above the logs pane

Copy an Asset url

Using public Assets

Public assets are publicly accessible once deployed, and can be used by referencing their URL. For example: given a Service with the URL of and a public Asset named ahoy.mp3, the Asset will be available at

Using protected Assets

The process for determining the URL of a protected Asset is the same as that of a public Asset. However, the Asset will only be accessible from Twilio code such as a Function, Studio Flow, or Flex.

For example, suppose we have an image grumpy.jpg that's been deployed to We would like to be able to send this image to users as part of an MMS, but have the file be inaccessible in all other cases. If the following code were deployed to a Function in the same Service and executed, the recipient will receive the image of grumpy cat, but anybody else trying to access the file by URL will be returned a 403 Forbidden error instead.

Loading Code Sample...

        Use a protected Asset in a Function

        Similarly, suppose you have audio or messaging to include in your Studio Flow, but don't want that audio to be accessible to the entire internet. If the audio were uploaded as protected Asset, you could then reference its URL in the Studio Say/Play widget, and the audio will play for anybody that hits that part of your Flow.

        For example, if the audio were a protected Asset deployed at, it could be referenced in your Studio Flow as shown below:

        Say/Play a protected Asset

        Using private Assets

        When Twilio builds your Function for deployment it will bundle any and all Private Assets that you have uploaded. This makes Private Assets perfect for storing sensitive configuration files, templates, and shared code that supports your application.

        In order to access a private Asset, you will need to leverage the Runtime.getAssets method and open the file directly using either the open helper method, or by using helper methods from the fs module as shown in the following examples.

        Loading Code Sample...
              Example of how to read the contents of a Private Asset

              Read the content of a Private Asset

              Example of how to read the contents of a Private Asset
              Loading Code Sample...
                    Example of how to serve an audio file from a Private Asset

                    Serve an audio file from a Private Asset

                    Example of how to serve an audio file from a Private Asset

                    Hosting a Root Asset

                    In some cases, such as when hosting an app with a landing page, you want the root URL of your Service to return an Asset in the browser. For example, you can visit which serves static HTML solely via Assets.

                    To reproduce this behavior, you will need to use one of two special paths for a public Asset for your file (whether it be HTML, an image, or anything else).


                    You may rename an Asset's path to /, and that Asset will be served on requests to the root URL of your Service. In the Console UI, it would look like this:

                    Root Asset Path


                    This path applies only to HTML files. Renaming an HTML file's path to /assets/index.html will cause the Service to return that page on requests to the root URL of your Service. It would look like this in the Console UI:

                    Assets Index.html Path

                    You can practice this yourself using the following index.html example code:

                    Loading Code Sample...

                          Root Asset index.html

                          If you want to deploy a root Asset using the Serverless Toolkit instead, you will need to create the /assets/index.html path within the existing assets/ folder that exists for your project.

                          The resulting path in your local filesystem will be /assets/assets/index.html, and the folder heirarchy will be as follows:

                          ├── assets
                          │ └── assets
                          │ └── index.html
                          ├── functions
                          └── package.json


                          All Builds have limitations on the maximum allowable file size and quantity of each Asset type that can be included:

                          Asset Type Maximum Size Quantity
                          Public 25 MB 1000 Assets
                          Private 10 MB 50 Assets
                          Protected 25 MB 1000 Assets

                          These limits apply only to individual Builds, so Assets used in a Build by a Subaccount won't affect the limits of other Subaccounts or the main Account.

                          Using Environments further expands your options, as you can create Builds containing different sets of Assets and deploy them to separate Environments.

                          When using the Serverless API (either directly, via the Helper Libraries, or through the CLI), you can create more Assets and Asset Versions within a Service, for example, to have different Assets in different Environments. However, a particular Build can only include so many Assets, as indicated in the table above.

                          This flexibility is currently not supported by the Console UI. Every Asset listed in the UI will be included in the deployed Build, and you will be unable to upload Assets in excess of the stated limits.

                          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!