Delivery Report

Delivery reports are a way to track if your messages are getting sent properly.


What is a delivery report?

After receiving a message, the handset responds to the operator with Delivery Report (DLR) so that Messente knows if and when the message was delivered.

Each time you send a message, Messente generates an ID that is unique to this particular message.

There are 2 ways you can get the status of the sent messages.

  1. Add a callback URL to your message. Messente will make a POST request with the relevant information to the callback any time the message status changes (suggested option).
  2. You can request a delivery report by manually making a call to the API.

The easiest way to use Omnichannel API is with our official libraries. They will take care of authentication, request validation and response handling automatically.

Option 1. Add a callback URL to the message

Messente will make a HTTP POST request to the URL in dlr_url property for every status update.

Callback URL

Requests to the Callback URL are done from the following IPs:

  • 5.9.48.210
  • 5.9.235.252
  • 213.239.195.15

The provided Delivery report URL (drl_url) endpoint should respond with a HTTP status code within the range 200-399, otherwise the DRL will be considered undelivered.

# 1. Get a temporary WebHook URL from https://webhook.site/ .
# Leave the website open. This is where you'll see your incoming delivery reports.

# 2. Edit the previous code example by adding the delivery URL to the request.
var omnimessage = new Omnimessage(to: "RECIPIENT_PHONE_NUMBER", messages: messages, dlr_url: "YOUR_WEBHOOK_URL");

# 3. Send an SMS with the script and monitor the incoming requests in the webhook website.
    
# 1. Get a temporary WebHook URL from https://webhook.site/ .
# Leave the website open. This is where you'll see your incoming delivery reports.

# 2. Edit the previous code example by adding the delivery URL to the request.
curl https://api.messente.com/v1/omnimessage \
    -u MESSENTE_API_USERNAME:MESSENTE_API_PASSWORD \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{ "to": "RECIPIENT_PHONE_NUMBER", "messages": [{ "channel": "sms", "sender": "YOUR_PHONE_NUMBER", "text": "Happy messaging!" }] }, "dlr_url": "YOUR_WEBHOOK_URL"'

# 3. Send an SMS with the script and monitor the incoming requests in the webhook website.
    
// 1. Get a temporary WebHook URL from https://webhook.site/ .
// Leave the website open. This is where you'll see your incoming delivery reports.

// 2. Edit the previous code example by adding the delivery URL to the request.
omnimessage.setTo("RECIPIENT_PHONE_NUMBER");
omnimessage.setDlrUrl("YOUR_WEBHOOK_URL");

// 3. Send an SMS with the script and monitor the incoming requests in the webhook website.
    
// 1. Get a temporary WebHook URL from https://webhook.site/ .
// Leave the website open. This is where you'll see your incoming delivery reports.

// 2. Edit the previous code example by adding the delivery URL to the request.
const omnimessage = OmnichannelApi.Omnimessage.constructFromObject({
	messages: [sms],
	to: "RECIPIENT_PHONE_NUMBER",
	dlr_url: "YOUR_WEBHOOK_URL"
});

// 3. Send an SMS with the script and monitor the incoming requests in the webhook website.
// 1. Get a temporary WebHook URL from https://webhook.site/ .
// Leave the website open. This is where you'll see your incoming delivery reports.

// 2. Edit the previous code example by adding the delivery URL to the request.
$omnimessage = new Omnimessage(["to" => "RECIPIENT_PHONE_NUMBER", "dlr_url" => "YOUR_WEBHOOK_URL"]);

// 3. Send an SMS with the script and monitor the incoming requests in the webhook website.
    
# 1. Get a temporary WebHook URL from https://webhook.site/ .
# Leave the website open. This is where you'll see your incoming delivery reports.

# 2. Edit the previous code example by adding the delivery URL to the request.
omnimessage = Omnimessage(to="RECIPIENT_PHONE_NUMBER", messages=(sms,), dlr_url="YOUR_WEBHOOK_URL")

# 3. Send an SMS with the script and monitor the incoming requests in the webhook website.
    
# 1. Get a temporary WebHook URL from https://webhook.site/ .
# Leave the website open. This is where you'll see your incoming delivery reports.

# 2. Edit the previous code example by adding the delivery URL to the request.
omnimessage.dlr_url = 'YOUR_WEBHOOK_URL'

# 3. Send an SMS with the script and monitor the incoming requests in the webhook website.
    

Report structure in callback request

Example of a successful message

{
    "status": "DELIVRD",
    "sender": "MySender",
    "err": 0,
    "message_id": "3e28ec48-d620-4191-a96e-d91ba8ecc949",
    "to": "+3725555555",
    "channel": "sms",
    "error": null,
    "omnimessage_id": "d7248cda-6c1a-4436-acf5-aaf249bb67d3"
}

Option 2. Make an API call

For most cases using dlr_url is a more suitable approach. Sometimes it's useful (usually for debugging purposes) to request the status of a specific message. In that case you can make a request to the API with the Omnimessage ID you need status of.

try
{
    DeliveryReportResponse result = apiInstance.RetrieveDeliveryReport(OMNIMESSAGE_ID);
    Debug.WriteLine(result);
}
catch (Exception e)
{
    Debug.Print("Exception when calling DeliveryReportApi.RetrieveDeliveryReport: " + e.Message );
}
    
curl https://api.messente.com/v1/omnimessage/OMNIMESSAGE_ID/status \
    -u MESSENTE_API_USERNAME:MESSENTE_API_PASSWORD \
    -H "Content-Type: application/json" \
    -H "Accept: application/json"
    
try {
    DeliveryReportResponse result = apiInstance.retrieveDeliveryReport(OMNIMESSAGE_ID);
    System.out.println(result);
} catch (ApiException e) {
    System.err.println("Exception when calling DeliveryReportApi#retrieveDeliveryReport");
    e.printStackTrace();
}
    
api.retrieveDeliveryReport(OMNIMESSAGE_ID, (error, data) => {
  if (error) {
    console.error(error);
  } else {
    console.log('API called successfully. Returned data: ', data);
  }
});
try {
    $result = $apiInstance->retrieveDeliveryReport(OMNIMESSAGE_ID);
    print_r($result);
} catch (Exception $e) {
    echo 'Exception when calling DeliveryReportApi->retrieveDeliveryReport: ', $e->getMessage(), PHP_EOL;
}
    
try:
    api_response = api_instance.retrieve_delivery_report(OMNIMESSAGE_ID)
    pprint(api_response)
except ApiException as e:
    print("Exception when calling DeliveryReportApi->retrieve_delivery_report: %s\n" % e)
    
begin
  result = api_instance.retrieve_delivery_report(OMNIMESSAGE_ID)
  p result
rescue Omnichannel::ApiError => e
  puts "Exception when calling DeliveryReportApi->retrieve_delivery_report: #{e}"
end
    

Requesting regular updates for every message via API calls is very resource heavy and costly approach. Before implementing please consider using Option 1.

Report structure in API response

Example of a successful message

{
  "omnimessage_id": "6e29aeef-f43d-4dc0-bd12-195374c845fa",
  "statuses": [
    {
      "status": "DELIVRD",
      "sender": "MySender",
      "err": 0,
      "message_id": "3e28ec48-d620-4191-a96e-d91ba8ecc949",
      "to": "+3725555555",
      "channel": "sms",
      "error": null,
      "omnimessage_id": "d7248cda-6c1a-4436-acf5-aaf249bb67d3"
    }
  ],
  "to": "RECIPIENT"
}

Failed message

{
    "status": "DELIVRD",
    "sender": "MySender",
    "err": 0,
    "message_id": "3e28ec48-d620-4191-a96e-d91ba8ecc949",
    "to": "+3725555555",
    "channel": "sms",
    "error": null,
    "omnimessage_id": "d7248cda-6c1a-4436-acf5-aaf249bb67d3"
}

Difference between omnimessage_id and message_id

message_id is a unique identifier for a single message and omnimessage_id groups messages that are sent with multi-channel fallback.

Although Omnichannel API can easily be used to send single messages we've built it with multi-channel capabilities in mind. To allow easy migration between the two we add omnimessage_id to every message.


List of Message Statuses

There can be various reasons why a message wasn't delivered or hasn't been delivered yet.

Status Constant Description
ACK Operator has accepted the message for delivery
DELIVRD The message has been successfully delivered to the handset
UNDELIV Unable to deliver message to the handset
FAILED Failed to deliver message to the handset
UNKNOWN Unknown status has been reported by the operator
ACCEPTD
Message has been accepted for the delivery and is in the operators's delivery queue
REJECTD The message was rejected by the operator
EXPIRED Delivery of the message expired
NACK
The message delivery has been rejected
SEEN The message has been seen by the recipient