Webhooks

Information resulting from requests to the SMS API, Voice API, Number Insight API, US Short Codes API and Nexmo virtual numbers is sent in an HTTP request to your webhook endpoint on an HTTP server.

workflow_callbacks

Nexmo sends and retrieves the following information using webhooks:

  • SMS API - sends the delivery status of your message and receives inbound SMS
  • Voice API - retrieves the Nexmo Call Control Objects you use to control the call from one webhook endpoint, and sends information about the call status to another
  • Number Insight Advanced API - receives complete information about a phone number
  • US Short Codes API - sends the delivery status of your message and receives inbound sms

This section explains

Setting the webhook endpoint for the Nexmo APIs

You set the your webhook endpoint either in Dashboard or through the API. The hierarchy for these calls is:

  • Account - using the Settings in Dashboard, set the webhook endpoint that handles Inbound Messages and Delivery Receipts. These webhooks also handle US Short Codes API.
  • Virtual Number - using the Number settings in Dashboard set the webhook endpoints associated with each virtual number you rent.
  • App - use the Application API to set or update the default webhook endpoints for all communication with this app.
  • Request - using the request parameters set the webhook endpoint for each request.
  • NCCO - for Voice API, set the webhook endpoints used for each action in the NCCO stack

By default, all connections to your webhook endpoints use a GET request. Use the request parameters to reception POST requests. For GET requests, values are sent in parameters appended to the URL. For POST requests these values are sent in the request body.

The following table shows how to set the webhook endpoint for the Nexmo APIs:

API Request and return parameters
Application API Set or update the answer_url parameter used to retrieve NCCOs and the event_url parameter used to send call status information.
Call API
Note: this API is deprecated, use Voice API
Send information about the Call to this endpoint when the Call is terminated.
  Nexmo retrieves the VoiceXML that controls your Call from this endpoint when the Call is answered.
  Retrieve the VoiceXML that controls the call if an error occurs either requesting or executing your VoiceXML from this endpoint.
Developer API Developer API does not use webhooks.
NCCO The webhooks endpoints you set in an NCCO receive data about an action:
  • record.eventUrl - set the webhook endpoint that receives information about the recording for a Call or Conversation
  • conversation.eventUrl - set the URL to the webhook endpoint Nexmo calls asynchronously when a conversation changes state for this conversation action
  • connect.eventUrl - set the URL to the webhook endpoint Nexmo calls asynchronously when a conversation changes state for this connect action
  • input.eventUrl - set the URL to the webhook endpoint Nexmo sends the digits pressed by the callee
  • stream.streamUrl - set an array of URLS pointing to the webhook endpoints hosting the audio file to stream to the Call or Conversation
Number Insight Advanced API Send information about this request to callback in a single callback.
SMS API Send the delivery receipt to this endpoint.
  Send inbound messages to this endpoint.
Text-To-Speech API
Note: this API is deprecated, use Voice API
Send information about the TTS to this endpoint when the TTS is terminated.
Text-To-Speech Prompt API
Note: this API is deprecated, use Voice API
Send information about the TTS Prompt to this endpoint when the TTS Prompt is terminated.
Verify API Verify API does not use webhooks.
US Short Codes API Uses the same webhook endpoints as the SMS API.
Voice API For an individual call, set the answer_url parameter used to retrieve NCCOs and the event_url parameter used to send call status information. Note: you set the default webhook endpoints for all calls with the Application API, you set the webhook endpoints for individual actions in a call using NCCOs.

Working with the Nexmo webhooks

To interact with Nexmo webhooks:

  1. You:
    1. Create a Nexmo account.
    2. Write scripts to handle the information sent or requested by Nexmo. Your scripts must always respond with HTTP 200 to inbound messages from Nexmo.
    3. Put your scripts on your HTTP server.
    4. Send a request with the webhook endpoint set.
  2. Information about your request is sent to your webhook endpoint.

The following code examples are webhooks for the SMS API:

<?php
// work with get or post
$request = array_merge($_GET, $_POST);

// Check that this is a delivery receipt.
if (!isset($request['messageId']) OR !isset($request['status'])) {
    error_log('This is not a delivery receipt');
    return;
}

//Check if your message has been delivered correctly.
if ($request['status'] == 'delivered') {
    error_log("Your message to {$request['msisdn']} (message id {$request['messageId']}) was delivered.");
    error_log("The cost was {$request['price']}.");
} elseif ($request['status'] == 'accepted') {
    error_log("Your message to {$request['msisdn']} (message id {$request['messageId']}) was accepted by the carrier.");
    error_log("The cost was {$request['price']}.");
} else {
    error_log("Your message to {$request['msisdn']} has a status of: {$request['status']}.");
    error_log("Check err-code {$request['err-code']} against the documentation.");
}
#To run this code, replace the MyHandler in
#https://wiki.python.org/moin/BaseHttpServer With the following code,
from urlparse import urlparse, parse_qs
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(s):
        """Tell Nexmo that you have recieved the GET request."""
        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()
        """Parse parameters in the GET request"""
        parsed_path = urlparse(s.path)
        try:
                delivery_receipt = dict(
                [p.split('=') for p in parsed_path[4].split('&')])
        except:
                delivery_receipt = {}

            """Check the is a delivery receipt"""
        if 'text' in delivery_receipt:
            print ("This is not a delivery receipt")
        elif delivery_receipt['status'] != "delivered":
            print "Fail:" + delivery_receipt['status']
            + ": " + delivery_receipt['err-code'] +  ".\n"
        else:
            print "success"
                """Handle the DLR for a message sent succesfully
                    The following parameters in the delivery receipt should
                    match the ones in your request:
                     * Request - from, dlr - to
                     * Response - message-id, dlr - messageId
                     * Request - to, Responese - to, dlr - msisdn
                     * Request - client-ref, dlr - client-ref
                    Use the documentation to check the values."""
require 'socket'
require 'uri'

def handle_delivery_receipt(request_line)
#Parse the parameters and check if the message was delivered
  params = URI::decode_www_form(request_line).to_h
  if params["status"].nil? or params["messageId"].nil?
    p ('This is not a delivery receipt')
  elsif params["status"] != 'delivered'
    p ("Your request " + params["status"] +
    "because of " + params["err-code"] );
  else
    p ("Success for request " + params['messageId'] )
  end
end

# Initialize a TCPServer
server = TCPServer.new('', 9999)

# Wait for connections
loop do
  # Wait until a client connects
  socket = server.accept

  method, path = socket.gets.split
  handle_delivery_receipt(path)

  # Return the 200 so Nexmo does not send the DLR to you repeatedly
  resp = "Thank you"
  headers = ["HTTP/1.1 200 OK",
             "Content-Type: text/html; charset=iso-8859-1",
             "Content-Length: #{resp.length}\r\n\r\n"].join("\r\n")
  socket.puts headers
  socket.puts resp
  # Close the socket, terminating the connection
  socket.close
end
var app = require('express')();
app.set('port', (process.env.PORT || 5000));
app.use(require('body-parser').urlencoded({
    extended: false
}));
// Handle GET webhook
app.get('/delivery-receipt-webhook', function(req, res) {
    handleWebhook(req.query, res);
});
// Handle POST webhook
app.post('/delivery-receipt-webhook', function(req, res) {
    handleWebhook(req.body, res);
});

function handleWebhook(params, res) {
    if (!params['status'] || !params['messageId']) {
        console.log('This is not a delivery receipt');
    } else {
        //This is a DLR, check that your message has been delivered correctly
        if (params['status'] !== 'delivered') {
            console.log("Fail:", params['status'], ": ", params['err-code']);
        } else {
            console.log("Success");
          /*
            * The following parameters in the delivery receipt should match the ones
            * in your request:
            * Request - from, dlr - to\n
            * Response - message-id, dlr - messageId
            * Request - to, Responese - to, dlr - msisdn
            * Request - client-ref, dlr - client-ref
           */
        }
    }
    res.sendStatus(200);
}
app.listen(app.get('port'), function() {
    console.log('Example app listening on port', app.get('port'));
});

Configuring your firewall

If you restrict inbound traffic (including delivery receipts), you need to whitelist the following IP addresses in your firewall. Inbound traffic from Nexmo might come from any of the following:

  • 174.37.245.32/29
  • 174.36.197.192/28
  • 173.193.199.16/28
  • 119.81.44.0/28
Previous   Next