Private WSP

Deliver highly personalize WhatsApp messages to encrypted phone numbers with great ease!

Many businesses are averse to sharing the contact details of their users with third-party platforms like WebEngage.

We understand your concerns.

This is why, we've made it possible for you to leverage a user's PII (Personally Identifiable Information) for sending WhatsApp campaigns without actually sharing their phone numbers! This can be achieved by setting up a Private WSP API endpoint at your end.

Private WhatsApp Service Provider Basics

You can think of Private WSP as a proxy layer that decrypts phone numbers of a WhatsApp campaign's target audience before sending it to your WSP for delivery to your users. All you need to do is:

Step 1: Pass hashed PII data to WebEngage from your servers.

Step 2: Set up a Private WSP API endpoint to decrypt hashed phone numbers and integrate with WebEngage.

Step 3: Configure Webhooks to ensure that the delivery status notifications (Sent, Delivered, Read, Failed) are relayed for each message from your WSP --> Decryption Layer --> WebEngage dashboard.

Step 4: Select Private WSP as the preferred WSP while creating the WhatsApp campaign.

10561056

PII Hashing


At WebEngage, we refer to User Attributes such as phone and email as PII (Personally Identifiable Information), which can be encrypted to safeguard your user's privacy.

Thus, the term PII Hashing refers to the encryption of these details. If you opt to do so, then instead of passing actual data against the attributes mentioned above, you will need to pass the hashed values against the attributes, hashed_phone and hashed_email, respectively.

Passing Hashed PII Values

All our platform integration SDKs enable you to pass hashed phone numbers and email addresses for each user. Here are a few examples to help you get started:

webengage.user.setAttribute({
  'we_hashed_phone': 'e0ec043b3f9e198ec09041687e4d4e8d',
  'we_hashed_email': '144e0424883546e07dcd727057fd3b62'
});
weUser.setHashedEmail(String hashedEmail)
weUser.setHashedPhoneNumber(String hashedPhoneNumber)
-(void) setHashedEmail:(NSString*)hasdhedemail;
-(void) setHashedPhone:(NSString*)hashedphone;

Please Note:

  • The values passed against hashed_phone must be encrypted in a format that you can decrypt later through the Private SSP.
  • The encrypted value can be a maximum of 512 characters. Additional characters will be truncated.
  • Please ensure that the actual phone number is never passed through this method.

🚧

Start Here!

How to Configure Private WSP

Now that you're sending us encrypted user data, let's show you how you can leverage it to engage users (while keeping their identity a top-secret!)

14291429

Click to enlarge

As shown above:

Step 1: Access Integrations > Channels > WhatsApp

  • Click on Add WhatsApp Service Provider to get started.

  • In doing so, you will be prompted by a pop-up. Click the first dropdown and select Private WSP.

Step 2: Add Business Number

Step 3: Add URL

  • As shown above, Add the endpoint URL of your Private WSP layer.

  • Each time you launch a campaign, where Private WSP is selected as the preferred WSP, we will POST an API call to this URL in JSON.

Step 4: Specify Request Type

Before configuring this field, please check with your WSP about the type of data they are willing to ingest from your Private WSP endpoint. While some WSPs prefer to ingest the entire message (containing the whitelisted template's text and values of personalization variables) in the message payload, others prefer to receive only the personalization tokens.

14291429

Click to enlarge

As shown above:

  • Select Send Entire Message to pass the template's text and personalization variables from WebEngage to your Private WSP layer. (Sample Request Payload)

  • Select Send Personalization Variables to pass only values of the personalization variables from WebEngage to your Private WSP layer. This way, your WSP will populate the selected message template (that has been whitelisted by them) with only the personalization variables for each user before delivery. (Sample Request Payload)

👍

Understanding Request Type

For example, let's assume that your template is:

Hey {{1}}, we're delighted to have you aboard! Here's your code, {{2}} to help you get started!

Where,

Variable {{1}} = Name

Variable {{2}} = Unique Password

Then the WhatsApp message received by the user, Sophie would be:

Hey Sophie, we're delighted to have you aboard! Here's your code, Sph512X to help you get started!

Thus, if you've selected Send Entire Message against Request Type, then you will receive the above message in the payload.

However, if you select Send Personalization Variables against Request Type, then you will receive only values of the template variables - [Sophie, Sph512X] in the message payload.

Step 5 (Optional): Add Custom Headers

14291429

Click to enlarge

  • You can choose to pass custom data as key-value pairs by adding them here in JSON. This field can also be used to pass Authorization Headers.

  • Click Add Headers to continue adding custom data.

  • Click Add WSP to save the details.

Step 6: Add WebEngage Webhook URL to Private WSP

Adding the WebEngage Webhook to your decryption layer will enable us to receive Delivery Status Notifications (DSNs) for each user. This includes campaign performance indicators like message delivered, failed, and queued.

Here's how you can go about it:

14291429

Click to enlarge

Step 6.1.: As shown above, you will find the integrated Private WSP under the section, Your WhatsApp Service Provider List. Click the Actions overflow menu on the right-side.

Step 6.2: Click View Webhook URL.

  • In doing so, a pop-up containing the static endpoint URL will appear on the screen.

  • Copy the URL and configure it as the WebEngage endpoint for sending POST API response containing the DSN.

Step 6.3: Request your Onboarding Manager for a security token (Auth Token/ API Key). This must be added to your DSN request as an authorization header, for example: Authorization: Bearer <Security Token>. You can also drop in a message at [email protected] to get your Auth Token. (How it works)

👍

Congratulations!

You have successfully integrated your Private WSP with WebEngage.

You can test the integration by creating a campaign targeting opted-in internal users (aka your teammates) to ensure everything's running smoothly.

Request

🚧

About Link Wrapping/Shortening in Message

If your Private WSP is performing additional link wrapping on the links already wrapped by WebEngage (original URL) anywhere in the request payload, then the wrapped domain must ask the caller to follow the original URL-encoded location.

For example, let's assume that the message has the following hyperlink:

<a href=“https://google.co.in/?param=%3D%3D%2B%20%20abcd”> Link </a>

We have a parameter named param with a value of ==+ abcd here.

Thus, if you are further wrapping this link, then the wrapped domain must ask the caller to follow the URL-encoded location (https://google.co.in/?param=%3D%3D%2B%20%20abcd), and not the decoded one (https://google.co.in/?param===+ abcd).

Sample POST Request

Here's a sample code snippet to help you understand the format in which you will receive the payload from WebEngage:

curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "TEXT",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction  
            "language": "en"
        }
    },
    "metadata": {
        "campaignType": "PROMOTIONAL",
        "timestamp": "2018-01-25T10:24:16+0000",
        "messageId": "webengage-message-id"
    }
}'
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "VIDEO",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "IMAGE",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "DOCUMENT",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "fileName": "<file-name if added>",  
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "LOCATION",
      "longitude":15.946519,
      "latitude":45.946519,
      "locationName":"Name of the location",       
      "locationAddress":"Address",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}

Let's break down each parameter included in the whatsAppData container:

Key

What It Means

version

Indicates the payload contract. If there is any change in the payload structure in future, the version will be updated.

toNumber

The recipient’s encoded phone number along with prefixed country code.

fromNumber

The WhatsApp Business Number you are using to send the campaign.

templateName

Name of the whitelisted template being used by you.

message

Indicates the exact message that needs to be delivered to a user (as per the template and template variables populated at Step 3: Message while creating the WhatsApp campaign).

This key is included in the payload only if you select Send Entire Message against Request Type during configuration.

templateVariables

Indicates string values of all personalization variables, in the exact sequence, as per the template selected at Step 3: Message while creating the WhatsApp campaign.

This key is included in the payload only if you select Send Personalization Variables against Request Type during configuration.

language

Indicates the language in which the WhatsApp Message template was created in WebEngage.

buttonUrlParam

Indicates the Dynamic call to Action placeholder value

This key is included in the payload only if Dynamic CTA buttons are added in the WhatsApp template

type

Indicates the WhatsApp media template type

This key is included in the payload only for media templates: TEXT, VIDEO, IMAGE, DOCUMENT, LOCATION

mediaUrl

Resource URL link which is to be sent

This key is included for VIDEO, IMAGE, DOCUMENT media templates

longitude

Longitude value

This key is included for LOCATION template only

latitude

Latitude value

This key is included for LOCATION template only

locationName

Name of the location

This key is included for LOCATION template only

locationAddress

Address of the location

This key is included for LOCATION template only

Here's what each parameter included in the metadata container denotes:

Key

What It Means

campaignType

The value of this key can be either PROMOTIONAL or TRANSACTIONAL, as selected at Step 1: Audience while creating the WhatsApp campaign in your dashboard.

timestamp

Indicates the time at which the message was sent from WebEngage to your Private SSP. It follows the ISO date format: yyyy-MM-ddTHH:mm:ss±hhmm.

messageId

A unique ID assigned to each message sent from your campaign. Please ensure that this ID is specified in each Delivery Status Notification sent in Response from your Private WSP.

Request Containing Only Personalization Variables in Payload

Here's a sample cURL POST API request sent from WebEngage to your Private WSP for Request Type: Send Personalization Variables.

curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "templateVariables": ["john", "world"],
      "type" : "TEXT",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction  
            "language": "en"
        }
    },
    "metadata": {
        "campaignType": "PROMOTIONAL",
        "timestamp": "2018-01-25T10:24:16+0000",
        "messageId": "webengage-message-id"
    }
}'
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "templateVariables": ["john", "world"],
      "type" : "VIDEO",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "templateVariables": ["john", "world"],
      "type" : "IMAGE",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "templateVariables": ["john", "world"],
      "type" : "DOCUMENT",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "fileName": "<file-name if added>",  
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "templateVariables": ["john", "world"],
      "type" : "LOCATION",
      "longitude":15.946519,
      "latitude":45.946519,
      "locationName":"Name of the location",       
      "locationAddress":"Address",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}

Request Containing Entire Message in Payload

Here's a sample cURL POST API request sent from WebEngage to your Private WSP for Request Type: Send Entire Message.

curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "TEXT",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction  
            "language": "en"
        }
    },
    "metadata": {
        "campaignType": "PROMOTIONAL",
        "timestamp": "2018-01-25T10:24:16+0000",
        "messageId": "webengage-message-id"
    }
}'
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "VIDEO",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "IMAGE",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "DOCUMENT",
      "mediaUrl":"https://www.webenagege.com/webengage-logo.png",
      "fileName": "<file-name if added>",  
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}
curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "whatsAppData": {
        "toNumber": "ENCODEDXYZ123PHONENUMBER",
        "fromNumber": "44000000099",
        "templateData": {
            "templateName": "templatexyz",
            "message": "hello john, welcome to new world",
            "templateVariables": ["john", "world"],
      "type" : "LOCATION",
      "longitude":15.946519,
      "latitude":45.946519,
      "locationName":"Name of the location",       
      "locationAddress":"Address",
      "buttonUrlParam" : "XYZ.pdf", // In the case of dynamic CallToAction
      "language": "en"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2018-01-25T10:24:16+0000",
    "messageId": "webengage-message-id"
  }
}

Request Containing Key-Value Pairs in Payload

🚧

Must Read

Leveraging Key-Value Pairs to Send Additional User Data to Your Servers & Personalize User Experience

You can choose to pass additional data in the message payload to your Private WSP by adding Key-Value Pairs at Step 3: Message, while creating the WhatsApp campaign. This comes in handy when for various custom requirements, for example: passing specific user data to your servers through Key-Value pairs like promo code/ offer type included in WhatsApp message, user type, details of the product purchased, and so on.

As shown below, all Keys and their corresponding Values are included in the customdata container in the message payload sent from WebEngage.

curl --location --request POST '<PRIVATE-WSP-API-END-POINT>' \
--header '<HEADERS-PROVIDED-BY-YOU-IN-CONFIGURATION>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "version": "1.0",
  "whatsAppData": {
    "toNumber": "+919167714989",
    "fromNumber": "9167714989",
    "templateData": {
      "templateName": "Hello Test",
      "message": "This is a test template",
      "language": "en",
      "type": "TEXT"
    },
    "customData": {
      "Key 1": "Value 1",
      "Key2": "Value 2",
      "Name": "Rajesh"
    }
  },
  "metadata": {
    "campaignType": "PROMOTIONAL",
    "timestamp": "2020-11-20T10:52:57+0000",
    "messageId": "c5d5457e-6c43-41a0-8f02-35d6957d92a0"
  }
}'

🚧

Please Note

  • All personalization variables are supported in customdata.

  • While you can add links in customdata, link wrapping is not supported. Thus, clicks will not be tracked in your dashboard for links specified in Key-Value pairs.

Response (Delivery Status Notification)

For each message forwarded to your Private WSP, we expect a response containing a Delivery Status Notification (DSN). These are asynchronous updates like message delivered, expired, rejected and so on. It enables you to analyze your campaign's performance against several performance indicators in your dashboard.

DSNs can be sent as POST API requests to the WebEngage Webhook URL added to your Private WSP during configuration.

Here's a sample DSN response containing the unique Auth Token provided specifically for DSN authorization by the WebEngage support team:

curl --location --request POST '<STATIC-DSN-END-POINT-OF-WEBENGAGE>' \
--header 'Authorization: Bearer <AUTH-TOKEN-PROVIDED-BY-WEBENGAGE>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "version": "1.0",
    "messageId" : "webengage-message-id",
    "toNumber" : "ENCODEDXYZ123PHONENUMBER",
    "status": "whatsapp_sent",
    "statusCode" : 0,
    "reason": "sent successfully to user",
    "timestamp": "2018-01-25T10:24:16+0000"
}'
  • DSN parameters must include the messageId previously passed in metadata so that we're able to map it to a specific message.

  • WebEngage will respond to the API call with an HTTP 2XX response code and will enqueue the event to process it.

Here's what each parameter in the above code snippet denotes:

Key

What It Means

version

This indicates the payload contract of the request. If there is any change in the payload structure in future, the version will be updated.

messageId

This is the unique ID assigned to the message which is used to identify a message uniquely.

This is received by the service provider in the request body. The length of this string can be up to 500 characters. The messageId provided in DSNs must be the same as that received from WebEngage in the request. You must not modify it.

toNumber

The message recipient’s phone number along with prefixed country code.

status

The message status being reported by this DSN. This can be either whatsapp_sent,whatsapp_failed or whatsapp_read.

statusCode

Status code of this DSN. This must be one of the status codes listed here.

reason

It is an optional field (must be given when statusCode doesn’t fulfill failed reason, or when statusCode is 9988).

timestamp

The time when the message was triggered from the WebEngage system. This follows the ISO date format: yyyy-MM-ddTHH:mm:ss±hhmm.

Synchronous Response Examples

Example 1: Message Accepted Successfully

HTTP 200 OK
{
    "status" : "whatsapp_accepted",
    "statusCode": 0
}

Example 2: Message Cannot Be Sent Further

NOTE: If the status code is not 0, then please send the message property too.

HTTP 200 OK
{
    "status": "whatsapp_rejected",
    "statusCode": 2000,
    "message": "Not enough credit to send message"
}

Example 3: Payload Not Acceptable

The following snippet depicts a scenario where there is a mismatch in the payload version of the API contract (currently we're using v1.0).

HTTP 400 BAD REQUEST
{
    "status" : "whatsapp_rejected",
    "statusCode" : 2010,
    "message" : "Version not supported",
    "supportedVersion" : "2.0" // Mandatory in case of statusCode 2010
}

Status Codes

These status codes are to be used for both, synchronous responses and asynchronous Delivery Status Notifications (DSNs). Please ensure that you send the appropriate HTTP status corresponding to the status codes.

Status Code

Description

HTTP Status

0

Message delivery is successful!

200

2000

Insufficient credit balance

200

2001

The IP has not been whitelisted

401

2002

Empty message body

400

2003

Invalid mobile number

400

2004

Invalid Business Number

400

2005

Authorization failure

403

2006

User blocked the Business Number

200

2007

Maximum length of the message body has been exceeded

413

2008

The message has expired

200

2009

The message was not delivered by the operator

200

2010

Payload version unsupported.

In this case the supportedVersion is to be sent mandatorily, i.e., the version supported by the service provider. For example:

HTTP 400 BAD REQUEST
{
    "status" : "sms_rejected",
    "statusCode" : 2010,
    "message" : "Version not supported",
    "supportedVersion" : "2.0"
}

400

2011

Authentication failure (e.g. mobile number might be unverified)

401

2014

Maximum number of retries to send the message have been exhausted.

200

2015

Throttling error.

To handle the loads with an increasing customer base, WebEngage has introduced autoscaling which can occasionally result in higher call rates. WebEngage supports throttling from the WSP's end to handle such cases. Sending this status code will activate throttling for that request and WebEngage will send that request at a later time.

Note:

  1. WebEngage will retry sending the message 10 times if this status is received.
  2. The time interval between retries follows binary exponential backoff: 0ms, 200ms, 400ms, 800ms...

429

2019

The message format is invalid

400

2021

Template Missing

400

2022

Template Parameter Format Mismatch

400

2023

Template did not match

400

2024

User isn't opted in for template message

200

2025

User is not Opted in and is inactive

200

9988

Unknown or other failures

200

We hope this has enabled you to set up a decryption layer for sending WhatsApp campaigns to encrypted phone numbers. Please feel free to drop in a few lines at [email protected] in case you have further queries. We're always just an email away!


Did this page help you?