Webhook API

Telerivet's Webhook API allows your server to receive asynchronous event notifications from Telerivet, such as when an incoming message is received, when an outgoing message is sent or has an error, or when a message or contact is updated via the Telerivet web app.

When an event occurs, Telerivet will make a HTTP POST request to your Webhook URL (a script on your own web server), sending data about the event in the POST request body.

Request Format

Webhooks are just HTTP POST requests that Telerivet makes to your web server. Data is formatted as normal URL-encoded POST parameters (application/x-www-form-urlencoded). The POST parameters for each event are described in the sections below.

In particular, note that Webhook request data is not JSON encoded.

Example

POST /incoming_message.php HTTP/1.1
Host: yourserver.example.com
Content-Type: application/x-www-form-urlencoded
...

event=incoming_message&from_number=%2B16505550123&content=Hello+world...

Response Format

Your Webhook URL should return a response with HTTP status code 200. Any other HTTP response code will be treated as a failure. It is not necessary for your Webhook response to return any content.

If your Webhook takes 10 seconds or longer to return a response, Telerivet will also treat it as a failure. If you are performing any operations during a webhook that may take longer than a couple seconds, consider performing the operation asynchronously instead of within the webhook itself.

Telerivet will retry failed webhooks periodically for up to a day, until receiving a response with HTTP code 200.

Receiving Incoming Messages

To configure your Webhook URL to receive incoming messages, add a new service in your Telerivet project and click "Webhook API", or click the button below:

Create Webhook Service

When Telerivet receives an incoming message on one of your phones, it will make a HTTP POST request to the URL you define in your Webhook service.

Example

<?php
    $webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE';
    
    if ($_POST['secret'] !== $webhook_secret)
    {
        header('HTTP/1.1 403 Forbidden');
        echo "Invalid webhook secret";
    }
    else 
    {
        if ($_POST['event'] == 'incoming_message')
        {
            $content = $_POST['content'];
            $from_number = $_POST['from_number'];
            $phone_id = $_POST['phone_id'];
            
            // do something with the message, e.g. send an autoreply            
            header("Content-Type: application/json");
            echo json_encode(array(
                'messages' => array(
                    array('content' => "Thanks for your message!")
                )
            ));
        }
    }

Request Parameters

When an incoming message is received, Telerivet will make a POST request to your Webhook URL with the following POST parameters:

event
string
The type of event that triggered this webhook, always set to incoming_message.
id
string, maximum length 34 characters
Telerivet's unique ID for the message (string, maximum length 34 characters).
message_type
string
Either sms, mms, ussd, or call. Other message types may be added in the future.
content
string
The text of the SMS message, or the content of the text/plain part of an MMS message.
from_number
string
The phone number (or alphanumeric sender ID) that the message was sent from.
For USSD responses, this is the USSD/MMI code that was requested. This is always the raw sender ID provided by the mobile network or SMS gateway API, so it may have a different format depending on the mobile network or SMS gateway API.
from_number_e164
string
The phone number that the message was sent from, normalized to E.164 format relative to the country property of the phone that received the message. Often this is identical to the from_number parameter. This parameter is not set for messages received from alphanumeric sender IDs, shortcodes, or other phone numbers that cannot be normalized to E.164 format.
to_number
string
The phone number that received the message (your own phone number).
time_created
integer (Unix timestamp)
The time Telerivet received the message.
time_sent
integer (Unix timestamp)
The time the SMS message was sent, if available.
(This time is given by the mobile network, and may not always be reliable.)
contact_id
string, maximum length 34 characters
The unique ID of the contact that sent the message
phone_id
string, maximum length 34 characters
The ID of the phone that received the message.
service_id
string, maximum length 34 characters
The ID of the Telerivet service that is invoking this Webhook
project_id
string, maximum length 34 characters
The ID of the Telerivet project associated with this message
secret
string
A secret parameter associated with your Webhook, so you can verify that the request came from Telerivet.
You can set this secret parameter when you create the Webhook service.
mms_parts[0][cid]
mms_parts[0][type]
mms_parts[0][filename]
mms_parts[0][size]
mms_parts[0][url]
...

Information about each of the multimedia files in an MMS message.

The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an array of objects.

To learn more about MMS parts, see the REST API documentation.

contact[name]
contact[time_created]
contact[message_count]
contact[vars][foo]
...

Information about the contact that sent the message, as stored in your Telerivet contacts database.

The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.

The Webhook API sends the same contact properties as are available in the REST API. See all

state[id]
state[time_created]
state[vars][foo]
...

Information about the current state of the contact for this service.

The state[id] parameter lets you keep track of the contact's current state within a multi-step conversation flow. Your webhook can also update the contact's current state to move them to the next step in the conversation flow. Learn more

The Webhook API sends the same properties as are available in the REST API. See all

phone[name]
phone[phone_type]
phone[country]
phone[vars][foo]
...

Information about the phone/gateway that received the message.

The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.

The Webhook API sends the same contact properties as are available in the REST API. See all


In addition to the parameters documented above, Telerivet also passes all other REST API message properties as POST parameters.

Since numeric fields like time_created are converted to strings when encoded as Webhook POST parameters, your script may need to convert them back to integers.

We recommend keeping track of the id field on your server. This will let you detect if a Webhook was sent multiple times for the same message (if your URL didn't return a 200 response within the 10 second limit).

Sending Autoreplies

Optionally, your webhook URL can send one or more SMS messages (or USSD requests) in response to an incoming message by returning a JSON object containing a messages property with an array of messages to send.

When returning JSON, your webhook response should include the HTTP header Content-Type: application/json.

Each entry in the messages array should be a JSON object, which may contain the following properties:

content
string
The content of the SMS message to send. (Ignored if the message_type is ussd)
to_number
string, optional
The optional phone number to send the message to. If omitted, Telerivet will send a reply to the same phone number that sent the incoming message.
message_type
string, optional
Either sms or ussd. The default is sms.
status_url
string, optional
An optional Webhook URL that Telerivet will notify via a HTTP POST when the message status changes, such as when the message is sent or fails to send. See Message Status Notifications for more details.
status_secret
string, optional
An optional string that Telerivet will pass as the secret POST parameter to your status_url, so you can verify that the request came from Telerivet.
route_id
string, optional
The optional ID of the phone or route you want to send the message from. If omitted, Telerivet will use the same phone that received the incoming message.


As an alternative to using the Webhook API for sending auto-replies, it's also possible to use the REST API to send auto-replies. The REST API provides additional functionality for sending messages that is not available in the Webhook API.

If you send auto-replies using the REST API, we recommend doing so asynchronously, instead of in the Webhook response itself, to ensure that your Webhook returns a response within the 10 second limit.

Example

HTTP/1.1 200 OK
Content-Type: application/json
...

{
 "messages":[
  {
   "content":"Reply message text"
  },
  {
   "content":"Another message text",
   "to_number":"+16505550123",
   "route_id":"YOUR_PHONE_ID"
  },
  {
   "to_number":"*104*12312312*456#",
   "message_type":"ussd",
  }
 ]
}

Integrating with Rules Engine

In addition to using a Webhook service, it's also possible to add a Webhook action within other Telerivet services, such as Custom Actions or a Poll.

To add a Webhook action within Custom Actions, click "Add action...", then "Notify webhook URL".

Your Webhook can also directly update any variable within the Rules Engine, including contact.name (the current contact's name), state.id (the contact's current state within this service), and temporary variables like $foo.

To set variables within the Rules Engine, return a property named variables in your JSON response, with an object containing the variable names and values to update, for example:

{
    "variables": {
        "contact.name": "John Smith",
        "$foo": 42
    }
}

For a list of all available variables, see the Rules Engine documentation.

It's possible to have multiple services active at the same time, such as a Webhook service and Custom Actions, or multiple Webhook services.

In this case, make sure the Webhook service(s) are at the top of the list on the Services page, before any non-Webhook services.

By default, Telerivet will only "fall-through" to the next active service if a Webhook service does not send any messages. If you want Telerivet to fall-through to the next service even if you send a message, set the variable return_value to false, (for example, {"variables": {"return_value": false}}).

Example

Custom Actions:
if [[word1]] is foo
notify webhook URL http://example.com/path/to/webhook_script
show log message:
foo = [[$foo]]
Your Webhook Script:
<?php
    $webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE';
    
    if ($_POST['secret'] !== $webhook_secret)
    {
        header('HTTP/1.1 403 Forbidden');
        echo "Invalid webhook secret";
    }
    else 
    {
        if ($_POST['event'] == 'incoming_message')
        {
            header("Content-Type: application/json");
            echo json_encode(array(
                'variables' => array(
                    'contact.name' => "John Smith",
                    '$foo' => 42,
                )
            ));
        }
    }

Message Status Notifications

If you enable the Webhook for "Message status notifications" in your Project Settings, Telerivet will notify your URL via a Webhook whenever the status of an outgoing message changes (e.g. when it is sent or fails to send).

Telerivet will also notify your URL when an outgoing message is first queued, except when sending an individual message via the REST API.

If you send a message via the REST API or Webhook API and specify a status_url, Telerivet will notify that URL for that message, instead of the URL specified in your Project Settings.

When the status of an outgoing message changes, Telerivet will make a HTTP POST request to your URL with the following POST parameters:

event
string
This will be set to send_status.
id
string, maximum length 34 characters
Telerivet's unique ID for the message (same as returned by the REST API).
status
One of the following codes representing the current message status:
sentthe message has been successfully sent to the mobile network
queuedthe message has not been sent yet
failedthe message has failed to send
failed_queuedthe message has failed to send, but Telerivet will try to send it again later
deliveredthe message has been delivered to the recipient phone (if delivery reports are enabled)
not_deliveredthe message could not be delivered (if delivery reports are enabled)
cancelledthe message was cancelled by the user
error_message
string
A description of why the message was not sent successfully (if available).
message_type
string
Either sms, mms, ussd, or call. Other message types may be added in the future.
from_number
string
The phone number that the message was sent from (a string, not an integer).
For USSD responses, this is the USSD/MMI code that was requested.
to_number
string
The phone number that the message was sent to
contact_id
string, maximum length 34 characters
The ID of the contact that the message was sent to
phone_id
string, maximum length 34 characters
The ID of the phone that the message was sent from
content
string
The text of the SMS message
time_created
integer (Unix timestamp)
The time the message was first queued for sending
time_sent
integer (Unix timestamp)
The time the SMS message was sent, as a Unix timestamp (UTC), if available.
This parameter will be absent if the message has not been sent yet.
project_id
string, maximum length 34 characters
The ID of the Telerivet project associated with this message
secret
string
An optional secret string that you previously specified, so that you can verify that the request came from Telerivet.
contact[name]
contact[time_created]
contact[message_count]
contact[vars][foo]
...

Information about the contact who sent or received the message, as stored in your Telerivet contacts database.

The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.

The Webhook API sends the same contact properties as are available in the REST API. See all


In addition to the parameters documented above, Telerivet also passes all other REST API message properties as POST parameters.

Your Webhook URL should return a response with HTTP status code 200. Any other HTTP response code will be treated as a failure.

Example

<?php
    $webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE';
    
    if ($_POST['secret'] !== $webhook_secret)
    {
        header('HTTP/1.1 403 Forbidden');
        echo "Invalid webhook secret";
    }
    else 
    {
        if ($_POST['event'] == 'send_status')
        {
            $id = $_POST['id'];
            $status = $_POST['status'];
            $error_message = $_POST['error_message'];
            
            // do something with the message status, e.g. update your database
        }
    }

Simulating Status Codes

When sending messages via a Test Number, you can use the following special phone numbers for the to_number parameter in the REST API to send particular status codes to your Webhook:

+15005550011
Simulates the status failed with error message: "Example error message."
+15005550012
Simulates the status sent, followed by delivered.
+15005550013
Simulates the status sent, followed by not_delivered with error message: "Example delivery failure message."
+15005550014
Simulates the status failed_queued with error message: "Example temporary failure message.", followed by the status sent.
all other numbers
Simulates the status sent.

Broadcast Notifications

If you enable the Webhook for "Broadcast sent" in your Project Settings, Telerivet will notify your URL via a Webhook whenever a broadcast is sent via Telerivet. The webhook is triggered shortly after the broadcast is first created. Some messages may have been sent before the webhook is triggered.

When a broadcast is sent, Telerivet will make a HTTP POST request to your URL with the following POST parameters:

event
string
This will be set to send_broadcast.
id
string, maximum length 34 characters
Telerivet's unique ID for the broadcast.
recipients_str
string
A string with a human readable description of the first few recipients (possibly truncated)
recipients[0][type]
recipients[0][....]
...

Details about each of the recipients for the broadcast.

The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.

The Webhook API sends the same properties for the recipients as are available in the REST API. See all

estimated_count
integer
The approximate number of messages expected to be sent in this broadcast when complete. The actual number of messages may differ from the estimated_count, for example if there are any blocked contacts or if the group membership changes while the broadcast is being sent.
content
string
The text of the SMS message sent.
route_id
string, maximum length 34 characters
The ID of the route or phone that the broadcast is sent from.
project_id
string, maximum length 34 characters
The ID of the Telerivet project associated with this broadcast
user_name
string
The name of the Telerivet user that sent this broadcast
user_email
string
The email address of the Telerivet user that sent this broadcast
secret
string
An optional secret string that you previously specified, so that you can verify that the request came from Telerivet.

In addition to the parameters documented above, Telerivet also passes all other REST API broadcast properties as POST parameters.

Your Webhook URL should return a response with HTTP status code 200. Any other HTTP response code will be treated as a failure.

Example

<?php
    $webhook_secret = 'YOUR_WEBHOOK_SECRET_HERE';
    
    if ($_POST['secret'] !== $webhook_secret)
    {
        header('HTTP/1.1 403 Forbidden');
        echo "Invalid webhook secret";
    }
    else 
    {
        if ($_POST['event'] == 'send_broadcast')
        {
            $id = $_POST['id'];
            $estimated_count = (int)$_POST['estimated_count'];
            $recipients_str = $_POST['recipients_str'];
            $content = $_POST['content'];

            // do something with the broadcast, e.g. update your database
        }
    }

Synchronizing Contacts

If you enable the Webhook for "Contact added or updated" in your Project Settings, Telerivet will notify your URL each time a contact is added or updated, making it easy to keep an external application automatically synchronized with Telerivet's contacts database.

Telerivet will make a HTTP POST request to your URL with the following POST parameters:

event
string
This will be set to contact_update.
update_type
string
A code representing the type of update. May be add, auto_add, update, update_field, add_group, remove_group, block_send, or unblock_send
id
string, maximum length 34 characters
Telerivet's unique ID for the contact
phone_number
string
Phone number of the contact
name
string
Name of the contact
send_blocked
boolean
1 if Telerivet is blocked from sending messages to this contact
vars[foo]
vars[bar]
...
Custom variables for the contact
group_ids[0]
group_ids[1]
...
Array of string IDs of Group
List of IDs of groups applied to this contact
secret
string
An optional secret string that you specified in your Project Settings, so that you can verify that the request came from Telerivet.

In addition to the parameters documented above, Telerivet also passes all other REST API contact properties as POST parameters.

Note that this webhook is not triggered for contacts added or updated via Telerivet's REST API or Cloud Script API. It is also not triggered when a new message is sent or received for a contact, except when a new contact is created.

Synchronizing Message Metadata

If you enable the Webhook for "Message metadata updated" in your Project Settings, Telerivet will notify your URL when a user updates the metadata for a message (e.g. labels and stars) via the Telerivet web interface.

Telerivet will make a HTTP POST request to your URL with the following POST parameters:

event
string
This will be set to message_metadata.
update_type
string
May be star, unstar, add_label, or remove_label
id
string, maximum length 34 characters
Telerivet's unique ID for the message (same as returned by the REST API).
starred
boolean
1 if the message is starred, 0 otherwise
label_ids[0]
label_ids[1]
...
Array of string IDs of Label
List of IDs of labels applied to this message
secret
string
An optional secret string that you specified in your Project Settings, so that you can verify that the request came from Telerivet.
contact[name]
contact[time_created]
contact[message_count]
contact[vars][foo]
...

Information about the contact who sent or received the message, as stored in your Telerivet contacts database.

The POST parameters are named so that some languages (including PHP) will automatically parse the parameters into an object.

The Webhook API sends the same contact properties as are available in the REST API. See all


In addition to the parameters documented above, Telerivet also passes all other REST API message properties as POST parameters.

Note that this webhook is not triggered for messages updated via Telerivet's REST API or Cloud Script API.

Debugging Webhooks

If your webhook script doesn't work as expected, then you'll need to debug it.

When a webhook fails because it returned a status code other than 200 or took longer than 10 seconds, Telerivet sends an email notification to the address(es) listed in your Project Settings, and also adds an entry in your service logs. (You can also view the service logs from the Services page, by clicking "More" then "View logs").

In some cases, the information in the notification email or on the service logs page may be enough for you to figure out why the webhook is failing and how to fix it.

Common errors and solutions include:

  • HTTP 403: This is returned by our sample code when the secret in your code does not match the 'secret' parameter sent by Telerivet (see your Services page). Update the secrets so they match.
  • HTTP 301 or HTTP 302: Your webhook is redirecting to another URL. Change your webhook URL to the target of the redirect.
  • "timed out": Your webhook took more than 10 seconds to return a response. Move long-running tasks out of your webhook script and perform them asynchronously (e.g. invoking REST API methods).

If it is not clear from Telerivet's logs how to resolve the error, the next step would be to add debugging code at various points in your Webhook script to write information to your server's error logs.

For example in PHP you can use error_log("..."); to write text to your server's error log. The location of the log file depends on your web server. On Linux servers this is usually somewhere in /var/log, for example /var/log/nginx/error.log or /var/log/apache2/error.log.

Testing Webhooks in Development

In order for Telerivet to send a Webhook to your application, your web server generally needs to be available on the public internet.

However, many software developers build and test their applications on their own private computers before deploying the application to a public production environment.

In order to test the Telerivet Webhook API for receiving incoming messages and status notifications in your development environment, you can temporarily expose a port on your development computer to the public internet, using a process known as tunneling.

There are two basic ways to set up a tunnel to your private computer – using a third-party service, or using one of your own SSH servers.

Third-Party Tunneling Services

There are a few popular third-party services that make it easy to set up a tunnel that exposes a port on your development computer. Visit their sites to learn more:

Tunneling through your own SSH server

Note: This approach only works if you run your own Linux-based server or VPS (virtual private server). It is typically not available with shared hosting providers.

A reverse SSH tunnel allows Telerivet to send HTTP POST requests to your development computer via an SSH server:

Telerivet's servers <----> SSH Server <----> Your computer

If you have a Linux-based web server, it is probably already running SSH server software called sshd.

By default, sshd is configured to disable reverse SSH tunneling. To enable this functionality, edit the /etc/ssh/sshd_config file on your SSH server and add the following line:

GatewayPorts yes

Be sure to remove any other line starting with GatewayPorts.

Then, connect to your SSH server using the -R flag to set up an SSH tunnel:

ssh <username>@<hostname> -R <publicport>:localhost:<localport>

Replace the parameters shown in brackets as follows:

  • <username>: Your username on your ssh server. Example: root
  • <hostname>: The hostname or IP address of your ssh server. Example: myapp.example.com
  • <publicport>: The port number to publicly expose on your SSH server. Telerivet's Webhook API only allows the following port numbers: 80, 443, 8000, 8080, or 8443. Additionally, the port number must not already be in use by other applications on your SSH server. Often, ports 80 and 443 are already used by your public web server, so they can't be used for reverse SSH tunneling. Recommended: 8000 or 8080
  • <localport>: The port number on your local development computer where your application is running. There are no restrictions to the port numbers you can use. Example: 3000