10DLC Callbacks

    Registering your number with 10DLC requires you to interact with different Plivo APIs.

    For every Brand, Campaign, Number Linking, and Number Unlinking request you send, Plivo sends a status update to a URL you configure as a callback. You can store this information on your server for delivery status analysis.

    SMS callbacks

    The webhooks you integrate with Plivo are triggered by changes in the status of Brand, Campaign, or Number requests (e.g. successful registration of your brand with TCR). Upon one of these events, Plivo makes an HTTP request (POST or GET) to the endpoint URL you’ve configured for the webhook. To handle a webhook, you must create a listener (web app) that can accept these HTTP requests from Plivo.

    Create Brand

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    // Available in versions >= 4.30.0 (https://github.com/plivo/plivo-node/releases/tag/v4.30.0)
    
    let plivo = require('plivo');
    
    let client = new plivo.Client("<auth_id>", "<auth_token>");
    var callback = {"url":"https://foo.com/tendlc_status/", "method":"POST"}
    
    client.brand.create("govt", "<profile_uuid>", "STANDARD", true, callback)
        .then(function (response) {
            console.log(JSON.stringify(response));
        }).catch(function (error) {
            console.log("err");
            console.log(error);
        });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    <?php
    
    # Available in versions >= 4.29.0 (https://github.com/plivo/plivo-php/releases/tag/v4.29.0)
    
    require '/etc/plivo-php/vendor/autoload.php';
    use Plivo\RestClient;
    $client = new RestClient("<auth_id>", "<auth_token>");
    $client
        ->client
        ->setTimeout(60);
    try
    {
        $callback = array("url"=>"https://foo.com/tendlc_status/", "method"=>"POST");
        $res = $client
            ->brand
            ->create("govt321", "<profile_uuid>", "STANDARD", true, $callback);
        print_r($res);
    }
    catch(PlivoRestException $ex)
    {
        print_r($ex);
    }
    ?>
    
    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
    30
    31
    
    // Available in versions >= 5.9.0 (https://github.com/plivo/plivo-dotnet/releases/tag/v5.9.0)
    
    using System;
    using System.Collections.Generic;
    using Plivo;
    using Plivo.Exception;
    
    namespace dotnet_project
    {
        class Ten_dlc
        {
            static void Main(string[] args)
            {
     
                    var api = new PlivoApi("<auth_id>","<auth_token>");
    
                    // Create Brand
                try
                {
                    var response = api.Brand.Create("brand_001", "201faedc-7df9-4840-9ab1-3997ce3f7cf4", "STANDARD", true, "https://foo.com/tendlc_status/", "POST");
                    Console.WriteLine(response);
                }
                catch (PlivoRestException e)
                {
                        Console.WriteLine("Exception: " + e.Message);
                }
    
                    
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    curl -i --user auth_id:auth_token \
        -H "Content-Type: application/json" \
        -d '{
                "brand_alias": "gov234t",
                "profile_uuid": "d61eaaaa-18b1-4473-8810-0b9d80573aa9",
                "brand_type":"STANDARD",
                "secondary_vetting":true,
                "url": "https://foo.com/tendlc_status/",
                "method": "POST"
            }' \
            https://api.plivo.com/v1/Account/{auth_id}/10dlc/Brand/
    

    Create Campaign

    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
    30
    31
    32
    
    // Available in versions >= 4.30.0 (https://github.com/plivo/plivo-node/releases/tag/v4.30.0)
    
    let plivo = require('plivo');
    
    let client = new plivo.Client("<auth_id>", "<auth_token>");
    var callback = {"url":"https://foo.com/tendlc_status/", "method":"POST"}
    client.campaign.create(
            "<brand_id>", //brand_id
            "campaign name sssample", //campaign_alias
            "INSURANCE", //vertical
            "MIXED", //usecase
            [
                "CUSTOMER_CARE", //sub_usecases
                "2FA" //sub_usecases
            ],
            "sample description text", //description
            false, //embedded_link
            false, //embedded_phone
            false, //age_gated
            false, //direct_lending 
            true, //subscriber_optin
            true, //subscriber_optout
            true, //subscriber_help
            "hey", //sample1
            "test", //sample2
            callback) //callback_url & method
        .then(function(response) {
            console.log(JSON.stringify(response));
        }).catch(function(error) {
            console.log("err");
            console.log(error);
        });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    <?php
    
    # Available in versions >= 4.29.0 (https://github.com/plivo/plivo-php/releases/tag/v4.29.0)
    
    require '/etc/plivo-php/vendor/autoload.php';
    use Plivo\RestClient;
    $client = new RestClient("<auth_id>", "<auth_token>");
    $client
        ->client
        ->setTimeout(60);
    try
    {
        $callback = array("url"=>"https://foo.com/tendlc_status/", "method"=>"POST");
        $res = $client
            ->campaign
            ->create("<brand_id>", "campaign name sssample", "INSURANCE", "MIXED", ["CUSTOMER_CARE", "2FA"], "sample description text", False, False, False, False, True, True, True, "test 1", "test 2", $callback);
        print_r($res);
    }
    catch(PlivoRestException $ex)
    {
        print_r($ex);
    }
    ?>
    
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    
    // Available in versions >= 5.9.0 (https://github.com/plivo/plivo-dotnet/releases/tag/v5.9.0)
    
    using System;
    using System.Collections.Generic;
    using Plivo;
    using Plivo.Exception;
    
    namespace dotnet_project
    {
        class Ten_dlc
        {
            static void Main(string[] args)
            {
    
                var api = new PlivoApi("<auth_id>", "<auth_token>");
    
                // Create Campaign
                Console.WriteLine("Create Campaign");
                try
                {
                    var response = api.Campaign.Create(
                    brand_id: "BMIORKY",
                    vertical: "INSURANCE",
                    usecase: "2FA",
                    sub_usecases:  new List<string>() {"2FA","MARKETING"},
                    description: "OTP Campaign",
                    embedded_link: false,
                    embedded_phone: false,
                    direct_lending: true,
                    age_gated: false,
                    subscriber_optin: true,
                    subscriber_optout: true,
                    subscriber_help: true,
                    sample1: "sample message 1",
                    sample2: "sample message 2",
                    url: "https://foo.com/tendlc_status/",
                    method: "POST"
            );
                    Console.WriteLine(response);
                }
                catch (PlivoRestException e)
                {
                    Console.WriteLine("Exception: " + e.Message);
                }
    
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    curl -i --user auth_id:auth_token \
        -H "Content-Type: application/json" \
        -d '{
                "brand_id": "{brand_id}",
                "vertical": "INSURANCE",
                "usecase": "MIXED",
                "sub_usecases":["2FA","ACCOUNT_NOTIFICATION", "CUSTOMER_CARE", "DELIVERY_NOTIFICATION", "FRAUD_ALERT"],
                "description": "OTP registration",
                "direct_lending": true,
                "affiliate_marketing": false,
                "embedded_link": false,
                "embedded_phone": false,
                "age_gated": false,
                "subscriber_optin": true,
                "subscriber_optout": true,
                "subscriber_help": true,
                "sample1": "Hi User, Your OTP to login is 1234",
                "sample2": "Your order {ID} is out for delivery.",
                "url": "https://foo.com/tendlc_status/",
                "method": "POST"
            }' \
        https://api.plivo.com/v1/Account/{auth_id}/10dlc/Campaign/
    

    Handle callbacks in your web app

    To handle callbacks in your application, your endpoint should capture HTTP requests and respond to them. When Plivo sends the HTTP request callbacks to the webhook during an event, you should capture the request (POST or GET based on the method you’ve defined for the URL) and respond with a 200 OK response. You can store the callback data in your database.

    Note: Plivo automatically retries webhooks three times if an HTTP 200 status code is not returned:
    • First at 60 seconds after the original attempt.
    • Second at 120 seconds after the first retry attempt.
    • Third at 240 seconds after the second retry attempt.

    Possible status values

    EndpointStatusExplanation
    brandcreatedBrand creation request was submitted to TCR for processing.
    rejectedBrand creation was rejected by TCR. Reach out to our support team to learn why.
    registeredBrand was registered with TCR. You can now create campaigns using this brand.
    campaigncreatedCampaign creation request was submitted to TCR for processing.
    rejectedCampaign creation request was rejected by TCR. Reach out to our support team to learn why.
    registeredCampaign was registered with TCR. You can now link your Plivo long codes with this campaign.
    number_linkingcreatedRequest to link your Plivo long code with the campaign was submitted to operators.
    failedRequest to link your Plivo long code with the campaign was rejected by operators. Retry the request; if the issue persists, contact our support team.
    successRequest to link your Plivo long code with the campaign was processed by operators.
    number_unlinkingcreatedRequest to unlink your Plivo long code with the campaign was submitted to operators.
    failedRequest to unlink your Plivo long code with the campaign was rejected by operators. Retry the request; if the issue persists, contact our support team.
    successRequest to unlink your Plivo long code with the campaign was processed by operators. This number can now be linked to other campaigns.

    Test and Validate

    Let’s take a look at an example. Typically, you would include a URL that points to your web app, but we’ll use a URL from RequestBin, a service that lets you collect, analyze, and debug HTTP requests, so we can check the callbacks.

    • Create a new bin in RequestBin.
    • Replace the “url” placeholder with the URL of the new bin.
    • Run the code that appear above. You should see callback requests in RequestBin similar to the screenshots below for various callback events.

    Brand created callback

    Brand created callback

    Brand registered callback

    Brand registered callback

    Campaign created callback

    Campaign created callback

    Campaign registered callback

    Campaign registered callback

    Number linking created callback

    Number Linking created callback

    Number unlinking created callback

    Number unlinking created callback

    Validating callbacks

    To avoid spoof attacks, you can validate the callbacks that your server URL receives. All requests made by Plivo to your server URLs include X-Plivo-Signature-V2, X-Plivo-Signature-Ma-V2, and X-Plivo-Signature-V2-Nonce HTTP headers. You can use them to validate that a request is from Plivo, as we discuss in our signature validation guide.