Messente avatar logo

Delivery Report

After receiving 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 an sms, Messente generates MessageID that is unique to this particular message.

When the message gets delivered to the handset, Messente will also receive a Delivery Report (DLR) with the same MessageID. There are two ways of receiving this in your service:

Asynchronous DLR

In case of asynchronous DLR, Messente makes a HTTP GET request to your service when the DLR is received from the handset.

Asynchronous DLR via dlr-url callback URL is the preferred method of receiving DLR to your service. It has several benefits over synchronous DLR.

Benefits of asynchronous DLR:

  • Instantly receive DLR when it was delivered to the handset
  • Extended error code support
  • Less load on your service
  • Easier to set up compared to synchronous DLR
  • Automated 5 retries in case of server failure

Example of receiving Asynchronous DLR from Messente

// dlr-url set when making API call with messaging API:
// https://myservice.com/dlr/messente/239d8/

$MessageID = $_GET['sms_unique_id'];
$stat = strtoupper($_GET['stat']);
$err = (int)$_GET['err'];

syslog(LOG_DEBUG, "Received DLR with stat ".$stat." for MessageID ".$MessageID);

// TODO: Update Message status in your database
// UPDATE sms SET dlr_stat = :stat, dlr_time = NOW() WHERE msgid = :MessageID

// Check if and why the message failed
if ($stat != 'DELIVRD') {
  switch ($err) {
    case 4:
      syslog(LOG_CRIT, "Messente Account out of credits, stop sending until credit added - ".$MessageID);
      break;  
    case 6:
      syslog(LOG_ERR, "Too many identical messages - ".$MessageID);
      break;
    case 7:
      syslog(LOG_ERR, "Unverified SenderID used - ".$MessageID);
      break;
    case 999:
      syslog(LOG_ERR, "Temporary error, retry sending MessageID ".$MessageID);
      break;
    // TODO: Check all possible error codes  
    default:
      syslog(LOG_ERR, "Delivery of message ".$MessageID." failed with err ".$err);
  }
}
import urlparse

url = "https://myservice.com/dlr/messente/239d8/?sms_unique_id=sms123&stat=DELIVRD&err="

request = urlparse.urlparse(url)
parameters = urlparse.parse_qs(request.query)
sms_unique_id = parameters["sms_unique_id"]
if parameters["stat"] != "DELIVRD":
    code = int(parameters["err"])
    if code == 4:
        print("Messente Account out of credits, stop sending until credit added")
    elif code == 6:
        print("Too many identical messages")
    elif code == 7:
        print("Unverified SenderID used")
    elif code == 999:
        print("Temporary error, retry sending MessageID", sms_unique_id)
    else:
        print("Delivery of message %s failed with err %s " % (sms_unique_id, code))

      

API Reference

For full list of response codes and HTTPI API request parameters, refer to the API Reference - Delivery Reports.

Libraries

Messente has HTTP API libraries for various languages including PHP, Python, Java and C#. Check out the Messente Libraries section in our documentation.

Notes

Always make sure to secure your DLR endpoint URL as stated in our Security section and return HTTP 200 response code.

Messente has request timeout for Async DLR set to 10 seconds and connection timeout set to 1 second. This is usually enough for every service to handle incoming DLR even under high loads.

Synchronous DLR

In case you are unable to use asynchronous DLR (no external HTTP calls allowed), you always have option to use synchronous DLR.

In case of synchronous DLR, your service will have to regularly poll Messente's DLR API to see if the message has been delivered.

Downsides of synchronous DLR:

  • You will have to constantly poll to see if the message has been delivered
  • Delivery reports available for 48 hours
  • More complex logic on service side needed
  • Limited feature set - only 3 basic statuses supported

API ENDPOINT

You can send SMS to any number by making a HTTP GET or HTTP POST call to Messente API.

API endpoint for sending SMS is https://api2.messente.com/get_dlr_response/.
Backup URL is https://api3.messente.com/get_dlr_response/.

Example of requesting for DLR via synchronous API

Refer to API Reference for full list of parameters and response codes.

// Messente API username and password
define('MESSENTE_API_USERNAME', '34edae9e1a5e563f5eced203f09f229e');
define('MESSENTE_API_PASSWORD', '385c064fc6d687c01e529348d3685cb1');


// Initial message statuses
$MessageID = 'd92bb23c3c68f0180fc9de257573d19a';

// Make HTTP call to Messente API
$url = 'https://api2.messente.com/get_dlr_response/?'.
http_build_query(
  array(
    'username' => MESSENTE_API_USERNAME,
    'password' => MESSENTE_API_PASSWORD,
    'sms_unique_id' => $MessageID
  )
);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$response = curl_exec($ch);

list($resp, $stat) = explode(' ', $response);
// Check if the sms delivery request was successful
if ($resp == 'OK') {
  // TODO: Update message status in database
  // UPDATE sms SET dlr_stat = :stat, dlr_time = NOW() WHERE msgid = :MessageID
  syslog(LOG_DEBUG, "Received final DLR for message ".$MessageID." - ".$stat);
} else {
  syslog(LOG_ERR, 'Failed to request for DLR - '.$MessageID.' with response '.$response);
}
import messente

api = messente.Messente(
    username="34edae9e1a5e563f5eced203f09f229e",
    password="385c064fc6d687c01e529348d3685cb1"
)

response = api.delivery.get_dlr_response(
"sms_id-1234567890"
)
if response.is_ok() and response.get_result() == "DELIVERED": print("Delivered") else: # handle error here print("Delivery error:", response.get_full_error_msg())

API Reference

For full list of response codes and HTTPI API request parameters, refer to the API Reference - Delivery Reports.

Libraries

Messente has HTTP API libraries for various languages including PHP, Python, Java and C#. Check out the Messente Libraries section in our documentation.