How to Publish Add-ons
The Twilio Marketplace is an API-enabled platform for third parties to offer products and services that are built on or complementary to Twilio’s products, for sale to Twilio’s massive developer community.
Developers can discover and install API-driven services through a central self-serve experience, and invoke them in a standard manner as part of the core Twilio API. Twilio manages the listing, configuration, developer-facing API endpoints, billing, and publisher payment for its third-party offerings.
This guide is designed for publishers who wish to integrate their services into the Twilio Marketplace in the form of an Add-on. It provides an overview of marketplace offerings and API requirements.
Add-Ons overview
At a functional level, Add-ons package publisher APIs, and annotate the content that Twilio provides by tapping into the publisher’s data sources or using a publisher’s technology to analyze the content. Examples include phone number based queries for demographic and marketing data, number fraud/spam blocklists, recording transcriptions, and message sentiment analysis.
Currently, the following Twilio content is available for Add-on publishers to build with: phone numbers, incoming message bodies, and call recordings.
Add-on Type | Available Integration Point(s) for Customers | Data available to Publishers | Consumption Mode |
---|---|---|---|
Phone Number Add-on | Lookups, Incoming SMS, Incoming Voice | Phone Number (single, to, from) | Synchronous |
Message Analysis Add-on | Incoming SMS | Phone Numbers, Message Body | Synchronous |
Recording Analysis Add-on | Recordings | Audio File (single channel) | Asynchronous |
Developers select an Add-on and configure it for their account, making it available for use. They can then specify that they want it invoked when using a supporting Twilio API.
The figure below illustrates the timeline and flow of information between a developer, Twilio, and a publisher’s Add-on. If a developer sets up a recording Add-on to respond to voice calls, the voice call will be accepted by Twilio and sent to the developer’s webhook. Afterwards, the call could be recorded and the information sent back to Twilio. Twilio would then give the data to the recording Add-on for processing, and once the Add-on returns the relevant data to Twilio, Twilio sends the data to the developer.
Pricing and billing
The Twilio Marketplace allows publishers to share their Add-ons with developers. Add-on publishers set their own pricing scheme and then invoke the Twilio Billing System, which meters usage of Add-ons by developers and deducts credit from their accounts. Finally, the billed amounts are distributed to Add-on publishers, by invoice, after Twilio levies a transaction fee.
Publishers can choose to package one service/API into one Add-on, or deliver a service/API as multiple Add-ons. Delivering a service as multiple Add-ons may allow developers to adjust their expenses in accordance with their usage or the extent to which they need an Add-on.
Since Add-on publishers set their own pricing, billing models may be different between Add-ons. The following billing models are supported by the Add-on Marketplace:
- Pay-per-use.
- Pay-per-minute: For rranscription/recording Add-ons.
- Pay-per-success: Conditional billing subject to the absence of certain JSON elements in the response and HTTP status codes.
Publisher accounts
Twilio supports one ‘source’ account per publisher offering, and will use that to make all API requests.
To illustrate this, here’s an example of how your account will make API requests, and how that will function as an Add-on. Let’s say you have a web service that takes a phone number and returns all the English words you can spell with it. You’d like to let any Twilio customer access your service via the Twilio Lookup API to see potential results, and you want to charge $0.0001 per lookup.
Assume that this is delivered by the following API (ignoring credentials for the time being):
https://www.example.com/twilio_phone_number_example?e164=+18778894546"
This results in the following JSON response:
{
"anagrams": ["+18778TWILIO", ...]
}
You deliver this service as a Marketplace Add-on, ‘Anagram’. A Twilio developer finds and installs this service on their account. They now have the ability to use the Anagram Add-on in the Lookup API, when buying/provisioning phone numbers, receiving incoming calls or messages, or making outgoing calls or messages, if appropriate. Afterwards, they would be able to make the following curl
request:
curl -X GET https://lookups.twilio.com/v1/PhoneNumbers/18778894546 \
-d "AddOns=publisher_anagrams" \
-u ${TwilioAccountSid}:${TwilioAuthToken}
This would result in a 200 OK
response with the body:
{
"country_code": "US",
"phone_number": "+18778894546",
"national_format": "1 (877) 889-4546",
"url": "https://lookups.twilio.com/v1/PhoneNumber/+551155256325",
"add_ons": {
"status": "successful",
"message": null,
"code": null,
"results": {
"publisher_anagrams": {
"request_sid": "XRc1479687aadf64c62e6ab2b6e0077a1a",
"status": "successful",
"message": null,
"code": null,
"result": {
"anagrams": ["+18778TWILIO"]
}
}
}
}
}
When invoked, Twilio will call out to your HTTP service and post the requested phone number. Upon receiving the results, it will take the JSON body of those results and include them in the response payload along with the other types requested.
Discovery and usage
Developers will discover and install your Add-on using the Marketplace inside the Console. For more information on this process please refer to the Add-ons overview documentation.
Add-On API requirements
These specifications will detail how Twilio will make requests to your service, what fields you can expect for each supported Add-on type, and how their success and error responses must be formatted and returned.
For most Add-on types, the interface is a simple RESTful HTTP protocol. For Add-ons such as phone number lookup, a synchronous request/response model is used, where Twilio POST
s data to the publisher in a specified format, and they reply with a valid result set or error in the response body.
For other Add-ons, such as recording analysis, an asynchronous model is used. This time, Twilio POST
s data to the publisher and expects a 202 Accepted
response back. The publisher will then post results back to a REST API exposed by Twilio some time later. In this model, Twilio will ask the developer for a callback URL at configuration time and take responsibility for relaying any asynchronous results back to them.
Publisher API requirements: requests
Twilio will be directly consuming publisher’s JSON/REST API, and transforming the returned data and error codes into a form compatible with the Twilio API style and format.
API parameters
Twilio supports passing vendor-specific fields, template fields, and constants to your API via one or more of the following parameters:
API Parameter | Request Type |
---|---|
Querystring Parameters | GET , POST |
JSON Dictionary | POST |
www-form-encoded | POST |
HTTP Headers | GET , POST |
You can provide us with the parameters in your API that should be filled with the available template fields for the type of Add-on. Refer to the sections below for list of available fields. You should request only those template fields that you absolutely require, so that Twilio can enable your Add-on across the widest possible range of integration points.
You can also tell us which parameters are user configurable, which ones should be hard-coded to specific values and which ones should be specified by the developer at request time.
Request time parameters are only supported for Lookup at this time.
Common template fields
The following table lists the common template fields available to you.
Template Field | Provided by Integration Points | Add-on Type | Description |
---|---|---|---|
CONSTANT |
All | All | Vendor specific constant data that you require us to hard code as an API parameter. This value will be passed by Twilio for every call to the Vendor API |
{{request_sid}} |
All | All | Alphanumeric Unique identifier for every request. Use if you need a unique identifier in your API |
{{vendor defined runtime field}} |
Lookup | Any Vendor specific data beyond the ones in this list. This parameter will have to be passed explicitly by the user in the API call and is not automatically filled in by Twilio |
|
{{custom configuration field}} |
All | All | Any Vendor specific data beyond the ones in this list. This parameter will be configured by the user in the Console and is not automatically filled in by Twilio |
{{SHA256:template_field}} |
All | All | A SHA256 hash of any field, e.g., {{SHA256:primary_address}} for a SHA256 hash of {{primary_address}} template field in Phone Number integration |
{{unix_timestamp}} |
All | All | A Unix timestamp |
Add-on type-specific template fields
See the Requirements for Specific Add-on Types section for additional template fields that you can use.
Custom configuration template fields
For instances where you may need additional parameters to be passed to your API, you can define custom fields that can be configured by the user in the Console. Once configured, Twilio will pass these parameters to your API just like other template fields.
User configurable parameters are specified as a JSON schema, provided in the “Configuration JSON Schema”. These parameters are mapped into the corresponding UI elements inside the Console, and the configured values are made available to the Add-on as template fields.
The Configuration JSON Schema supports the following JSON elements:
Type-specific Keywords
- string (presented as a text field in the UI).
- number & integer (presented as text field in the UI with number validation).
- boolean (presented as checkbox in the UI).
Object and array keywords are not supported.
Generic keywords
- enum (presented as a dropdown list).
- name (used to render the field label in the UI).
- _help (used to render a tooltip next to the field in the UI).
- element_name in the schema is used to define the template variable name.
Combining Schemas and Regular expressions
- Supported for input validation and the relevant error message shall be displayed when the input does not validate against the configuration schema.
Example schema:
{
"title": "Config schema",
"type": "object",
"properties": {
"language": {
"type": "string",
"name": "Language",
"_help": "Select the language for your recordings: US English (en_US), UK English (en_UK), Spanish (es)",
"enum": ["en_US","en_UK","es"]
},
"combine_tracks": {
"type": "boolean",
"name": "Combine Audio Tracks",
"_help": "Combine transcriptions from different tracks into one list or keep them separated"
},
"keywords": {
"type": "string",
"name": "Keywords to detect",
"_help": "Identify the presence and timestamps for these keywords (Comma separated) in the audio"
},
"phone_number": {
"type": "string",
"name": "Phone Number",
"_help": "E164 formatted phone numbers. Only +1 prefixes allowed",
"pattern": "^\\+(1)+[0-9]*$"
}
},
"required": [
"language"
]
}
This schema generates the following UI, and makes the template fields {{language}}
, {{combine_tracks}}
, {{keywords}}
, and {{phone_number}}
available to your API.
Authentication
Since Twilio currently only supports one account per Publisher offering, it follows that there will be one set of authentication credentials for the publisher’s service supported per Add-on. The Publisher can choose to use a single set of credentials across all their offerings if so desired.
Following authentication schemes are supported:
- Passing credentials in the URL query string.
- Passing credentials in the
POST
request body (WWW-form-encoded or JSON-encoded). - HTTP header based authentication (Basic, Bearer).
Default HTTP headers
Twilio will always pass the following set of headers along with the GET
/POST
request to the publisher API that may be used for security and debugging purposes if the publisher so desires.
Header Name | Value |
---|---|
X-Twilio-VendorAccountSid |
The Account Sid of the publisher (your) account. Example: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
X-Twilio-Signature |
The signature of this request, signed by the publisher’s account, and used to verify the request came from Twilio unmodified. See the ‘Validating Requests are coming from Twilio’ section of the API security docs for details of the signature algorithms used. Example: 0FqS203W44/lM2UEM+51hRzwat4= |
X-Twilio-RequestSid |
The unique identifier of this particular publisher request. Used for billing and debugging. Example: MRxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
X-Twilio-AddOnSid |
The unique identifier for the Add-on being invoked. Use this to identify which of your Add-ons is generating this request. Example: XBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
X-Twilio-AddOnVersionSid |
The unique identifier of the Add-on version being used by the developer. Use it to identify if the developer is using an older version of your Add-on. Example: XCxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
X-Twilio-AddOnInstallSid |
The unique identifier for a developers install of an Add-on. Use this to distinguish between developers using this particular Add-on. Example: XDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
X-Twilio-AddOnConfigurationSid |
The unique identifier for an instance of the installed Add-on. Example: XExxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
Request Validation Schema
If you desire, Twilio can validate the Add-on request using a Request Validation JSON Schema prior to invoking your API. This is typically useful in cases where your service cannot fulfill certain requests, and you wish to avoid a degraded customer experience or limit the load on your system.
When an Add-on request fails to validate, Twilio will return Error 61003: "Requirements to invoke Add-ons have not been met" to the user and will not count it against your SLA.
The Request Validation Schema will be applied to a JSON dictionary containing the template fields specified above.
JSON schema tools
Example schema
Use this to limit the Add-on to specific phone number prefixes. This example limits Vendor Add-on to phone numbers with +91 or +1 prefixes only.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"primary_address": {
"type": "string",
"pattern": "^\\+(91|1)+[0-9]*$"
}
},
"required": [
"primary_address"
]
}
Test the validity of the schema using the schema validator with the Input JSON field set to {"primary_address": "+12345678901"}
|
Publisher API requirements: responses
Both success and error responses are expected to be in a standard JSON object format. The server is expected to return a 2xx response for all requests, even error requests. This is to disambiguate publisher errors that may affect SLA from legitimately rejected requests due to misconfiguration or other. For successfully synchronous Add-on requests, a 200 OK response is expected, with a content-type application/json
and a JSON object returned in the body. For successful asynchronous Add-on requests, a 202 Accepted
response is expected, with no body returned. For both sync and async cases error cases, a 200 OK
is expected with a content-type application/json
and a JSON object describing the error condition.
Any 4xx or 5xx errors returned will be considered publisher misconfiguration, or outage, will be logged in the error reporting system and will count against the publisher's SLA. For 4xx errors, Twilio will fail the request immediately. For 5xx errors, Twilio will retry up to N times, or until the TTL has passed. Publishers should expect retries, using the request_sid
as an idempotency token.
For async requests, the publisher is responsible for POSTing back the JSON object body to Twilio once the async task is completed. This JSON body will be the same format as above, for both success or failure.
Response Validation Schema
If specified, the Response Validation Schema ensures your response contains at minimum certain specific fields for it to be considered valid, and therefore, billed to the user.
To build a Response Validation Schema:
- Paste your API response into the JSON schema generator (paste in JSON form field).
- Delete all the fields from the result that are not required
- Test Schema generated using the schema validator: http://www.jsonschemavalidator.net/ (Paste generated Schema from Code View and the full response from your API and ensure it validates)
Example schema
For instance, If you wanted to validate that your API response (below) always contains the args.e164
parameter to be considered valid.
Example API response
{
"args": {
"e164": "+13233633791",
"test": "1"
},
"origin": "184.73.170.150",
}
JSON schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"args": {
"type": "object",
"properties": {
"e164": {
"type": "string"
}
},
"required": [
"e164"
]
}
},
"required": [
"args"
]
}
Response cleaning
Use response cleaning JSON Paths to ask Twilio to delete specific elements from your Response. This typically includes API Keys (if they are returned), usage counters, vendor-specific resource URIs, etc.
You can specify one or more JSON elements to remove using JSON Path
- What is JSON Path
- Tools to get JSON Path: JSON Path Tool, Chrome Extension
- Tools to test your JSON Path: Paste your API response and JSON Path into the JSONPath Tool
Requirements for specific Add-on types
Phone Number Add-on
The Phone Number Lookup Add-on is used to expose 3rd party data publishers that use an e164 phone number as their query parameter. Examples of these are carrier dips, CNAM caller ID lookups, GPS lookups, demographic database queries, and so forth.
Add-on Request Fields
When invoked, Twilio can supply the following fields to the publisher API.
Template Field | Provided by Integration Points | Description |
---|---|---|
{{primary_address}} |
Incoming SMS, Incoming Voice call, Lookup | The phone number being dipped, in E.164 format: +<country code><phone number> |
{{secondary_address}} |
Incoming SMS, Incoming Voice call | To number, in E.164 format: +<country code><phone number> |
This request will be synchronous. Twilio will expect a 200 OK
with a valid response body.
Add-on SLA
Because this request is returned synchronously, either as part of a lookup API request or in the flow of a call or SMS setup, performance is key. A service exposing this should return in a median time of approx 200ms and 99% under 1500 ms. Any request taking longer than 2000 ms will be failed by Twilio, an error payload will be sent, and the developer will not be billed.
Add-on Response Size Limit
As a synchronous Add-on, this response for this is limited to a maximum of 50KB. Any response larger than this maximum will be failed by Twilio, an error payload will be sent, and the developer will not be billed.
Message Analysis Add-on
The Message Analysis Add-on passes a message body to a 3rd party for content analysis. Possible use cases are translation or intent analysis.
Add-on Request Fields
When invoked, Twilio can supply the following fields to the publisher API.
Template Field | Provided by Integration Points | Description |
---|---|---|
{{primary_address}} |
Incoming SMS | The phone number being dipped, in E.164 format: +<country code><phone number> |
{{secondary_address}} |
Incoming SMS | To number, in E.164 format +<country code><phone number> |
{{body}} |
Incoming SMS | The UTF-8 body of the SMS Message |
This request will be synchronous. Twilio will expect a 200 OK
with a valid response body.
Add-on SLA
Because this request is returned synchronously, in the flow of the SMS delivery, performance is key. A service exposing this should return in a median time of approx 200msand 99% under 1500ms. Any request taking longer than 2000ms will be failed by Twilio, an error payload will be sent, and the developer will not be billed.
Add-on Response Size Limit
As a synchronous Add-on, this response for this is limited to a maximum of 64KB. Any response larger than this maximum will be failed by Twilio, an error payload will be sent, and the developer will not be billed.
Recording Analysis Add-on
The Recording Analysis Add-on Type is used to expose 3rd party publishers who can analyze audio and return results as structured data. Examples of this are audio transcription, sentiment analysis services, audio indexing services, etc.
Add-on request fields
When invoked, Twilio can supply the following fields to the publisher API.
Template Field | Provided by Integration Points | Description |
---|---|---|
{{audio_data}} |
Recordings | Audio file binary bytestream, in HTTP request body or HTTP multipart request (POST/PUT) with a name you specify |
{{callback_url}} |
Recordings | One time use URL to be used to provide Analysis results |
{{channels}} |
Recordings | Number of channels contained in audio |
{{duration}} |
Recordings | Duration of the audio in milliseconds |
{{format}} |
Recordings | Audio Mimetype. Default recording format is audio/x-wav |
{{media_sid}} |
Recordings | Recording SID |
{{size}} |
Recordings | Size of the audio in bytes |
This request is asynchronous. A 202 or 204 response with no body is expected upon receiving this request. After processing the audio, publishers are expected to POST the JSON results to the Callback URL within the request timeout agreed upon. After the timeout expires, the request will be considered failed, and the developer will not be billed.
Add-on Callback authentication
To authenticate the Callback HTTP request containing the audio analysis, we ask that you use basic authentication with the Account SID and Auth Token or an API Key created from the vendor account that the Add-on belongs to.
Add-on Callback SLA
Because this request is returned asynchronously, there are no hard requirements. A service exposing this is recommended to return in a median time of 3x audio duration and a 99% under 5x audio duration. Any request taking longer than 10x duration will be failed by Twilio, an error payload will be sent, and the developer will not be billed.
Add-on Callback size limit
As an asynchronous Add-on, the response for this is limited to a maximum of 100MB. Any response larger than this maximum will be failed by Twilio, an error payload will be sent, and the developer will not be billed.
Security and privacy requirements
It is important to secure communication between Twilio and publishers, for both Twilio’s security as well as the publisher’s. Because publishers are opening up an HTTP endpoint to the public Internet, all efforts should be made to make certain the endpoint doesn’t expose the publisher to fraud or attack. To ensure this, a number of mechanisms will be in place:
- Twilio only supports HTTPS/TLSv1.2.
- To help mitigate any DDoS attack exposure, Twilio requests can be set up to only come from specific IPs. Twilio will contact publishers before adding any IPs to this range. If you require such a setup, let us know. The default behavior is that they will not come from specific IPs.
- 174.129.222.33
- 174.129.222.200
- 184.73.170.150
- 23.21.226.67
- Twilio signs every request with the publisher’s shared secret key. Publishers are strongly encouraged to validate the signature of the requests they receive to confirm they're coming from their Twilio account.
- Twilio sends a unique request SID with each invocation. Publishers are encouraged to treat this as an idempotency token, allowing them to thwart replay attacks.
- Twilio also sends an invocation date (UTC) and TTL as part of each signed payload. Checking this TTL (with a reasonable accommodation for clock-skew) further protects publishers from replay attacks.
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.