Two-factor Authentication API

You can use Two-factor Authentication API to prove a user's identity. Provision a US Short Code with a standard or custom template that specifies the custom parameters for two-factor authentication (2FA) messages. These APIs support 2FA for the US and Canada.

Two-factor authentication (also known as 2FA) provides user identification by combining two different components. In this case, a phone number associated with your user and a PIN. Before you use this API you have to Setup a Pre-approved Short Code for 2FA.

The workflow for Two-factor Authentication API is:

Two-factor Authentication workflow

  1. Send a 2FA request.
  2. Check the response codes in the response and ensure that you sent the request to Nexmo correctly.
  3. Nexmo delivers your PIN to your user's handset. Your user enters this PIN into your APP.
  4. Receive the delivery receipt at your webhook endpoint and verify delivery.

To ensure that your traffic is send over the best possible route, use Conversion API to tell us about the reliability of your 2FA communication. Adding your conversion data means Nexmo delivers your messages faster and more reliably.

Note: quality of delivery (QoD) statistics are based on delivery receipts (DLR). For the US we only receive intermediate and not handset DLRs. This means Dashboard analytics cannot show QoD statistics for short codes.

Implementing the Two-factor Authentication API workflow

To use the 2FA API you:

  1. Send a 2FA request.

    var https = require('https');
    
    var data = JSON.stringify({
     api_key: 'API_KEY',
     api_secret: 'API_SECRET',
     to: '441632960960',
     pin: 'A_PIN'
    });
    
    var options = {
     host: 'rest.nexmo.com',
     path: '/sc/us/2fa/json',
     port: 443,
     method: 'POST',
     headers: {
       'Content-Type': 'application/json',
       'Content-Length': Buffer.byteLength(data)
     }
    };
    
    var req = https.request(options);
    
    req.write(data);
    req.end();
    
    var responseData = '';
    req.on('response', function(res){
     res.on('data', function(chunk){
       responseData += chunk;
     });
    
     res.on('end', function(){
       console.log(JSON.parse(responseData));
     });
    });
    

  2. Check the response codes in the response and ensure that you sent the request to Nexmo correctly.

    // Decode the json object you retrieved when you ran the request.
    
    var decodedResponse = JSON.parse(responseData);
    
    console.log('You sent ' + decodedResponse['message-count'] + ' messages.\n');
    
    decodedResponse['messages'].forEach(function(message) {
        if (message['status'] === "0") {
          console.log('Success ' + decodedResponse['message-id']);
        }
        else {
          console.log('Error ' + decodedResponse['status']  + ' ' +  decodedResponse['error-text']);
        }
    });
    

  3. Nexmo delivers your PIN to your user's handset. Your user enters this PIN into your APP.

  4. Receive the delivery receipt at your webhook endpoint so you can see:

    1. If the status was successful.
    2. When and how the call was made.
    3. How much the call cost.
    var app = require('express')();
    app.set('port', (process.env.PORT || 5000));
    app.use(require('body-parser').urlencoded({
        extended: false
    }));
    // Handle GET webhook
    app.get('/delivery-receipt-webhook', function(req, res) {
        handleWebhook(req.query, res);
    });
    // Handle POST webhook
    app.post('/delivery-receipt-webhook', function(req, res) {
        handleWebhook(req.body, res);
    });
    
    function handleWebhook(params, res) {
        if (!params['status'] || !params['messageId']) {
            console.log('This is not a delivery receipt');
        } else {
            //This is a DLR, check that your message has been delivered correctly
            if (params['status'] !== 'delivered') {
                console.log("Fail:", params['status'], ": ", params['err-code']);
            } else {
                console.log("Success");
              /*
                * The following parameters in the delivery receipt should match the ones
                * in your request:
                * Request - from, dlr - to\n
                * Response - message-id, dlr - messageId
                * Request - to, Responese - to, dlr - msisdn
                * Request - client-ref, dlr - client-ref
               */
            }
        }
        res.sendStatus(200);
    }
    app.listen(app.get('port'), function() {
        console.log('Example app listening on port', app.get('port'));
    });
    

Note: remember to return a status code when you receive the delivery receipt.