Delivery Reports

    Once the Message API request is successful, your SMS will be put into a queue to be sent to its destination. By default, you will not receive an automatic notification regarding the delivery of your SMS. To get notified on the status of your message, include the url parameter in your API request. You can also find your SMS delivery reports in the SMS Logs of your Plivo account. This will automatically output a notification when your SMS reaches its destination, or if it fails to deliver. Your delivery report will update to show either "queued", "sent", "delivered", "undelivered", or "failed" for each individual recipient.

    Note: Long SMS messages are automatically split and concatenated into a seamless user experience. When checking Message Logs and Delivery Reports for long SMS messages that are split, look for the `ParentMessageUUID`, which is the same in all split messages and identical to the UUID of the first message in the split sequence of messages.
    Advanced Hack: Check out our Message API docs to see how you can get the details of a single message or all your messages in a single `GET` request.

    Getting Started

    1. Sign up for a free Plivo trial account.
    2. Check out our server SDKs page and install the right helper based on the programming language you want to use.
    3. Buy a Plivo phone number (optional).
      Note: A phone number is required only for sending SMS to US and Canadian phone numbers. However, country-specific carrier conditions may still apply. You can buy a US or Canadian phone number through the Buy Numbers tab on your Plivo account UI.
    4. Use a web hosting service to host your web application. There are many inexpensive cloud hosting providers that you can use for just a few dollars a month. Follow the instructions of your hosting provider to host your web application.
      Note: If you are using a Plivo Trial account for this example, you can only send sms to phone numbers that have been verified with Plivo. Phone numbers can be verified at the Sandbox Numbers page.

    Set up a Web Server

    Let’s assume your web server is located at http://example.com. Below is a snippet to set up a route on your webserver. Now when we send an HTTP request to http://example.com/delivery_report/ this route will be invoked. This route will be the 'url' parameter when sending an sms using the Message API.

    Note: For PHP, the route will be example.com/delivery_report.php.
    1. Copy the relevant code below into a text file and save it. Let’s call it, 'delivery_report'.
    2. Customize the delivery report to include the parameters you need.

    Code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    from flask import Flask, request, make_response, Response
    
    app = Flask(__name__)
    
    
    @app.route('/delivery_report/', methods=['GET', 'POST'])
    def inbound_sms():
        # Sender's phone number
        from_number = request.values.get('From')
        # Receiver's phone number - Plivo number
        to_number = request.values.get('To')
        # The text which was received
        text = request.values.get('Text')
        # Message UUID
        uuid = request.values.get('MessageUUID')
        # Print the message
        print('Message received - From: %s, To: %s, Text: %s, MessageUUID: %s' %(from_number, to_number, text, uuid))
    
        return "Delivery status reported"
    
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', debug=True)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    require "sinatra"
    
    post "/delivery_report/" do
      # Sender's phone number
      from_number = params[:From]
      # Receiver's phone number - Plivo number
      to_number = params[:To]
      # The text which was received
      text = params[:Text]
      # Print the message
      puts "Message received - From: #{from_number}, To: #{to_number}, Text: #{text}, MessageUUID: #{uuid}"
    
      puts "Delivery status reported"
    end
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    var express = require('express');
    var bodyParser = require('body-parser');
    var app = express();
    
    app.use(bodyParser.urlencoded({
        extended: true
    }));
    app.use(function (req, response, next) {
        response.contentType('application/xml');
        next();
    });
    app.set('port', (process.env.PORT || 5000));
    app.all('/delivery_report/', function (request, response) {
        // Sender's phone number
        var from_number = request.body.From || request.query.From;
        // Receiver's phone number - Plivo number
        var to_number = request.body.To || request.query.To;
        // The text which was received
        var text = request.body.Text || request.query.Text;
        //Message UUID
        var uuid = request.body.MessageUUID || request.query.MessageUUID;
        //Prints the message
        console.log('Message received - From: ' + from_number + ', To: ' + to_number + ', Text: ' + text + ', MessageUUID: ' + uuid);
    
        console.log('Delivery status reported');
    });
    app.listen(app.get('port'), function () {
        console.log('Node app is running on port', app.get('port'));
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    <?php
        require 'vendor/autoload.php';
        // Sender's phone numer
        $from_number = $_REQUEST["From"];
        // Receiver's phone number - Plivo number
        $to_number = $_REQUEST["To"];
        // The SMS text message which was received
        $text = $_REQUEST["Text"];
        // Message UUID
        $uuid = $_REQUEST["MessageUUID"];
        // Prints the message
        echo("Message received - From $from_number, To: $to_number, Text: $text, MessageUUID: $uuid");
        
        echo("Delivery status reported");
    ?>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    import static spark.Spark.*;
    
    public class Delivery {
        public static void main(String[] args) {
            get("/delivery_sms", (request, response) -> {
                // Sender's phone number
                String from_number = request.queryParams("From");
                // Receiver's phone number - Plivo number
                String to_number = request.queryParams("To");
                // The text which was received
                String text = request.queryParams("Text");
                // Message UUID
                String uuid = request.queryParams("MessageUUID");
                response.type("application/xml");
                // Print the message
                System.out.println(from_number + " " + to_number + " " + text);
    
                return "Message Received";
            });
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    package main
    
    import (
    	"net/http"
    
    	"github.com/go-martini/martini"
    )
    
    func main() {
    	m := martini.Classic()
    	m.Get("/delivery_report", func(w http.ResponseWriter, r *http.Request) string {
    		w.Header().Set("Content-Type", "application/xml")
    		// Sender's phone number
    		fromnumber := r.FormValue("From")
    		// Receiver's phone number - Plivo number
    		tonumber := r.FormValue("To")
    		// The text which was received
    		text := r.FormValue("Text")
    		//Message UUID
    		uuid := r.FormValue("MessageUUID")
    		// Print the message
    		print("Message Received - ", fromnumber, " ", tonumber, " ", text, " ", uuid)
    
    		return "Delivery status reported"
    	})
    	m.Run()
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    using Nancy;
    using System;
    using System.Collections.Generic;
    
    
    namespace NancyStandalone
    {
      public class FunctionsModule : NancyModule
      {
        public FunctionsModule()
        {
          Post("/delivery", parameters =>
          {
              // Sender's phone number
              String from_number = Request.Form["From"];
              // Receiver's phone number
              String to_number = Request.Form["To"];
              // The text which was received
              String text = Request.Form["Text"];
              // Print the message
              Console.WriteLine("Message received - From: {0}, To: {1}, Text: {2}", from_number, to_number, text);
    
              return "Delivery status reported";
          };
        }
      }
    }
    

    Sample Output

    From: 1111111111, To: 3333333333, Status: delivered, MessageUUID: 0936ec98-7c4c-11e4-9bd8-22000afa12b9
    

    SMS Delivery and Notifications

    The following parameters are then sent to the URL:

    ParameterDescription
    MessageUUIDThe unique ID for the message.
    ToPhone number of the recipient.
    FromThe sender ID used as the source address for the message.
    StatusStatus of the message including “queued”, “sent”, “failed”, “delivered”, “undelivered”, or “rejected”.
    UnitsNumber of units into which a long SMS was split
    TotalRateThis is the charge applicable per outbound SMS unit.
    TotalAmountTotal charge for sending the SMS (TotalRate * No. of Units)
    MCCMobile Country Code of the To number. (See here for more details)
    MNCMobile Network Code of the To number. (See here for more details)
    ErrorCodeThe Plivo error code which identifies the reason for the message delivery failure. This parameter is only defined for ‘failed’ or ‘undelivered’ messages.
    ParentMessageUUID (reserved for future use)Same as the MessageUUID. This parameter is reserved for future use, and should be ignored for now.
    PartInfo (reserved for future use)This parameter is reserved for future use, and should be ignored for now.