This Twilio product is currently available as a Beta release. Some features are not yet implemented and others may be changed before the product is declared as Generally Available. Beta products are not covered by a Twilio SLA. Learn more about beta product support.
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.
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.
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.
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.
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:
- The Assets pane, which lists your Assets, their Visibility, a context menu for adjusting visibility, and another menu for other actions.
- The Add+ button which allows you to upload files as Assets, or create a new Asset.
- The Deploy All button, which will trigger an upload and deploy of your Assets (along with any Functions)
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.
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.
In general the URL of one of your Assets can be determined by taking the URL of your Service, for example
https://example-1234.twil.io, 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
Public assets are publicly accessible once deployed, and can be used by referencing their URL. For example: given a Service with the URL of
https://example-1234.twil.io and a public Asset named
ahoy.mp3, the Asset will be available at
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
https://twilio-assets-1967.twil.io/grumpy.jpg. We would like to be able to send this image to users as part of an MMS, but otherwise have the file inaccessible. 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.
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
https://twilio-assets-1967.twil.io/sensitive-message.mp3, it could be referenced in your Studio Flow as shown below:
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.
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 root-asset-5802.twil.io/ 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:
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:
You can practice this yourself using the following
index.html example code:
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
│ └── index.html
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.
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.