Signing Messages

You can use signatures with Nexmo when both sending and receiving SMS messages. When sending, you generate a signature to send with your message. When receiving, the incoming webhook will include the signature and all the fields you need to generate the signature in your application to verify that the two signatures match.

You use a signature to:


This document covers how to use signatures with messages, both signing the messages you send and verifying that incoming messages have a correct signature.

Use signatures when sending messages

To send a message with a signature, you will need to use the SIGNATURE_SECRET instead of your API_SECRET when sending the message. You can find the signature secret and choose which signing algorithm to use by visiting the dashboard. The default algorithm is'MD5 hash' and we also support MD5 HMAC, SHA1 HMAC, SHA-256 HMAC and SHA-512 HMAC.

Nexmo strongly recommends you use one of our client libraries to generate or validate signatures. If you can't do this for some reason, you can generate and validate signatures yourself, but this can be complicated and potentially error-prone. Refer to the section on manually generating signatures.

The process for sending a signed message is as follows:

  1. Create a signed request to send an SMS.
  2. Check the response codes and ensure that you sent the request correctly.
  3. Your message is delivered to the handset. The user's handset returns a delivery receipt.
  4. (optional) If you requested signed delivery receipts and inbound messages, you will want to validate the signature for each incoming request.

If you did not generate the signature correctly the status is 14, invalid signature. You can find more information in the troubleshooting section of this guide.

By default, message signatures are optional when sending messages and are not included with incoming webhooks. To enable either signed webhooks or enforce all sent messages to be signed, please contact

The code example below shows how to send a signed message with the SMS API.


Install dependencies

composer require nexmo/client

Write the code

Add the following to send-signed-sms.php:

Copy to Clipboard
$signed = new Nexmo\Client\Credentials\SignatureSecret(
$client = new \Nexmo\Client($signed);

$message = $client->message()->send([
    'to' => TO_NUMBER,
    'from' => FROM_NUMBER,
    'text' => 'Super interesting message',

$response = $message->getResponseData();
echo "Message status: " . $response['messages'][0]['status'] . "\n";

View full source

Run your code

Save this file to your machine and run it:

php send-signed-sms.php

Validate the signature on incoming messages

In order to verify the origin of incoming webhooks to your SMS endpoint, you can enable message signing for incoming messages - contact to request incoming messages be accompanied by a signature. With this setting enabled, the webhooks for both incoming SMS and delivery receipts will include a sig parameter. Use the other parameters in the request with your signature secret to generate the signature and compare it to the signature that was sent. If the two match, the request is valid.

Contact support to enable message signing on your account:

The code example below shows how to verify a signature for an incoming SMS message, using the sig parameter in the query string.


Install dependencies

composer require nexmo/client

Write the code

Add the following to verify-signed-sms.php:

Copy to Clipboard
$inbound = \Nexmo\Message\InboundMessage::createFromGlobals();

    $params = $inbound->getRequestData();
    $signature = new Nexmo\Client\Signature(
    $validSig = $signature->check($params['sig']);

    if($validSig) {
        error_log("Valid signature");
    } else {
        error_log("Invalid signature");

} else {
    error_log('Invalid message');

View full source

Run your code

Save this file to your machine and run it:

php verify-signed-sms.php

Note: A POST request can potentially include query string data too. Sending both POST and query string data is unsupported in the SMS API and the results might be unexpected.

Manually generate a signature

It is highly recommended that you use your Nexmo library's existing functionality for generating and validating signatures. If you aren't using a library with this functionality, you'll need to generate the signature yourself. The technique is slightly different if are generating an 'MD5 hash' signature or one of the HMAC signatures.

Step 1: For both hash and HMAC signatures

If you're generating a signature: Add the current timestamp to the parameters list with the key timestamp. This should be an integer containing the number of seconds since the epoch (this is sometimes also known as UNIX time)

If you're validating a signature from Nexmo: Remove the sig parameter before generating your signature, and use the timestamp provided in the request parameters.


At this point, the process for hash and HMAC will differ, so use the "Step 2" section that fits your needs:

Step 2: For hash

Step 2: For HMAC

Step 3: Additional notes

Bear in mind that although you changed the parameter values while generating the signature, the values passed as HTTP parameters should be unchanged when sending those parameters to the SMS API.

Troubleshooting signatures

Here are some tips and pitfalls to look out for when working with signed messages.

Check the response for details

If the message isn't sent as expected, check the response for any error codes that were returned. This will usually give you more detail on what to do next.

Error 14: Invalid Signature

If the text being sent includes any special characters such as & (ampersand) or = (equals), then these need to be replaced in the text used to create the signature.

To do this, use the following instructions:

The original text can be still be sent/received, the character replacements are only needed to generate the signature.