Get a delivery receipt with Python

Receiving SMS Delivery Receipts with Python

Published June 03, 2019 by Mark Lewin

You’ve already learned how to send an SMS with Python. But unless you have access to the device you’ve sent it to, how can you be sure that your SMS arrived?

Many networks provide Nexmo with delivery receipts. However, not all networks are created equal. Some will just send you an acknowledgement that they have received your message, but no confirmation that it was actually delivered. Others won’t send you anything or even generate fake receipts. So be aware that depending on which countries you are sending SMS to, it can be a bit of a minefield. The Nexmo Knowledge Base has more information.

To request a delivery receipt you need to create a publicly-accessible webhook and configure your Nexmo account to use it. This post will show you how to do that and the source code is available on Github.


You need a Nexmo account. If you don’t already have one you can sign up here. It’s free to get started.

This tutorial uses Python 3 and Flask to code the webhook. You can install flask with the pip3 package manager:

Lastly, you’ll need to install the Nexmo CLI. You will use this to send a test SMS.

Once you have all those things you are good to go!

Create the Delivery Receipt Webhook

When a network lets Nexmo know that a message has been delivered, Nexmo can forward that information on to your application as an HTTP request. This can be either a GET or POST request depending on how you have configured it in your account settings.

However, we’re going to play it safe and accept both GET and POST requests in this example.

Create a file called and enter the following code:

This code captures any request sent to the /webhooks/delivery-receipt endpoint and unpacks it:

  • request.is_json: Checks to see if the request is in JSON format. By default a request is considered to include JSON data if the mimetype is application/json or application/*+json
  • request.args: Retrieves the key/value pairs in the URL query string.
  • request.form: Retrieves the key/value pairs in the body, from a HTML post form, or any request that isn’t JSON-encoded.

Using this approach, your application can extract the delivery receipt however that request is made.

Having parsed the incoming request data it pretty-prints it to the terminal using pprint and then sends a HTTP 204 status response (success, no content) to Nexmo.

Make Your Webhooks Accessible

For Nexmo’s APIs to make requests to your webhook endpoints they must be accessible over the public internet.

A great tool for exposing your local development environment to the internet is ngrok. Our tutorial shows you how to install and use it.

Launch ngrok using the following command:

Make a note of the public URLs that ngrok creates for you. These will be similar to (but different from) the following:

On their free plan, every time you restart ngrok the URLs change and you will have to update your delivery receipt URL. So leave it running for the duration of this tutorial.

Configure Your Nexmo Account

The next thing you need to do is configure your account with the webhook URL so that Nexmo can forward any delivery receipts it gets from carriers.

Visit the settings page in the developer dashboard. Under “Default SMS Setting” put your ngrok (e.g. URL in the “Delivery receipts” textbox and click the “Save changes” button.

Try it Out

With ngrok running on port 3000 in one terminal window, launch your Python application in another:

Use the Nexmo CLI to send a test SMS to your personal mobile phone. Include the international code in the number but remove any leading zeros. For example, a GB number might look like this: 447700900001.

You will receive a message from DLRTEST. In the terminal window that is running your Python application you should see a delivery receipt that resembles the following (but might vary by country and network as outlined earlier):

As you can see, this example delivery receipt consists of two parts: an acknowledgement that the SMS was received by the carrier (status: accepted) and then delivered to the recipient (status: delivered).

That’s all there is to it!

Further Reading

If you want to learn more about the SMS API, check out the following resources:

Leave a Reply

Your email address will not be published.

Get the latest posts from Nexmo’s next-generation communications blog delivered to your inbox.

By signing up to our communications blog, you accept our privacy policy , which sets out how we use your data and the rights you have in respect of your data. You can opt out of receiving our updates by clicking the unsubscribe link in the email or by emailing us at [email protected].