Twilio Verify Node.js Phone Verification Quickstart

Phone verification is an important, high-confidence step in a registration flow to verify that a user has the device they claim to have. Adding phone verification to your application will greatly reduce your number of fraudulent registrations and protect future application users from having their numbers registered by scammers.

This quickstart guides you through creating a Node.js, AngularJS, and MongoDB app that requires a phone verification step to create an account. Two channels of phone verification are demoed: SMS and voice.

Ready to add phone verification to a demo app and keep the bad actors away? Enter stage left!

Sign Into - or Create- a Twilio Account

Either sign up for a free Twilio trial, or sign into an existing Twilio account.

Create a New Verify Application

Once logged in, visit the Verify in the Twilio Console. Click on the big red plus ('+') to create a new Verify application then name it something memorable.

Twilio will redirect you to the Settings page next:

Account Security API Key

Click the eyeball icon to reveal your Production API Key, and copy it somewhere safe. You will use the API Key during the application setup step below.

Install and Launch MongoDB

While Twilio's Verify API doesn't return any user information you'll need to store, to continue working on the app after this Quickstart you'll want a database. For this demo, we built our user database on top of MongoDB.

Instructions for installing MongoDB vary depending on platform. Please follow the appropriate link for instructions on how to install MongoDB for your platform.

After you install MongoDB, launch it. On *NIX and OSX, this command may be as simple as:

mongod

Clone and Setup the Verification Application

Start by cloning our Node.js repository. Enter the directory and use npm to install all of our dependencies:

npm install
  1. Open the file .env.example
  2. Change ACCOUNT_SECURITY_API_KEY to the API Key from the above step
  3. Now, save the file as .env

If your file is saved as .env, the server will load it automatically as it starts up.

Loading Code Samples...
Language
export ACCOUNT_SECURITY_API_KEY='ENTER_SECRET_HERE'
export PORT=1337
Enter the API Key from the Account Security console and optionally change the port.
Enter an Application API Key

Enter the API Key from the Account Security console and optionally change the port.

And then... actually, that's all the setup you'll need.

Now, launch Node with:

node .

Assuming your API Key is correctly entered and MongoDB is running, you'll soon get a message that the app is up!

Use the Node.js Phone Verification Demo

Keeping your phone at your side, vist the phone verification page of the demo at http://localhost:1337/verification/

Enter a Country Code and Phone Number, then choose which channel to request verification over, 'SMS' or 'CALL' (Voice). Finally, hit the blue 'Request Verification' button and wait.

Phone Verification by SMS or Voice

You won't be waiting long - you'll either receive a phone call or an SMS with the verification token. If you requested a phone call, as an additional security feature you may need to interact to proceed (by entering a number on the phone keypad).

Loading Code Samples...
Language
var request = require('request');
var VERSION = "0.1";


module.exports = function (apiKey, apiUrl) {
    return new PhoneVerification(apiKey, apiUrl);
};

function PhoneVerification(apiKey, apiUrl) {
    this.apiKey = apiKey;
    this.apiURL = apiUrl || "https://api.authy.com";
    this.user_agent = "PhoneVerificationRegNode/" + VERSION + " (node " + process.version + ")";
    this.headers = {};

    this.init();
}

PhoneVerification.prototype.init = function () {
    this.headers = {
        "User-Agent": this.user_agent
    };
};

/**
 * Verify a phone number
 *
 * @param {!string} phone_number
 * @param {!string} country_code
 * @param {!string} token
 * @param {!function} callback
 */
PhoneVerification.prototype.verifyPhoneToken = function (phone_number, country_code, token, callback) {

    console.log('in verify phone');
    this._request("get", "/protected/json/phones/verification/check", {
            "api_key": this.apiKey,
            "verification_code": token,
            "phone_number": phone_number,
            "country_code": country_code
        },
        callback
    );
};

/**
 * Request a phone verification
 *
 * @param {!string} phone_number
 * @param {!string} country_code
 * @param {!string} via
 * @param {!function} callback
 */
PhoneVerification.prototype.requestPhoneVerification = function (phone_number, country_code, via, callback) {

    this._request("post", "/protected/json/phones/verification/start", {
            "api_key": this.apiKey,
            "phone_number": phone_number,
            "via": via,
            "country_code": country_code,
            "code_length": 4
        },
        callback
    );
};

PhoneVerification.prototype._request = function (type, path, params, callback, qs) {
    qs = qs || {};
    qs['api_key'] = this.apiKey;

    options = {
        url: this.apiURL + path,
        form: params,
        headers: this.headers,
        qs: qs,
        json: true,
        jar: false,
        strictSSL: true
    };

    console.log(options.url);

    var callback_check = function (err, res, body) {
        if (!err) {
            if (res.statusCode === 200) {
                callback(null, body);
            } else {
                callback(body);
            }
        } else {
            callback(err);
        }
    };

    switch (type) {
        case "post":
            request.post(options, callback_check);
            break;

        case "get":
            request.get(options, callback_check);
            break;
    }
};
This function allows you to send the verification code over SMS or Voice depending on the 'via' variable.
Send a Phone Verification via SMS or Voice

This function allows you to send the verification code over SMS or Voice depending on the 'via' variable.

Either way you requested the passcode, enter the token into the Verification entry form and click 'Verify Phone':

Phone Verification Entry Box

Loading Code Samples...
Language
var request = require('request');
var VERSION = "0.1";


module.exports = function (apiKey, apiUrl) {
    return new PhoneVerification(apiKey, apiUrl);
};

function PhoneVerification(apiKey, apiUrl) {
    this.apiKey = apiKey;
    this.apiURL = apiUrl || "https://api.authy.com";
    this.user_agent = "PhoneVerificationRegNode/" + VERSION + " (node " + process.version + ")";
    this.headers = {};

    this.init();
}

PhoneVerification.prototype.init = function () {
    this.headers = {
        "User-Agent": this.user_agent
    };
};

/**
 * Verify a phone number
 *
 * @param {!string} phone_number
 * @param {!string} country_code
 * @param {!string} token
 * @param {!function} callback
 */
PhoneVerification.prototype.verifyPhoneToken = function (phone_number, country_code, token, callback) {

    console.log('in verify phone');
    this._request("get", "/protected/json/phones/verification/check", {
            "api_key": this.apiKey,
            "verification_code": token,
            "phone_number": phone_number,
            "country_code": country_code
        },
        callback
    );
};

/**
 * Request a phone verification
 *
 * @param {!string} phone_number
 * @param {!string} country_code
 * @param {!string} via
 * @param {!function} callback
 */
PhoneVerification.prototype.requestPhoneVerification = function (phone_number, country_code, via, callback) {

    this._request("post", "/protected/json/phones/verification/start", {
            "api_key": this.apiKey,
            "phone_number": phone_number,
            "via": via,
            "country_code": country_code,
            "code_length": 4
        },
        callback
    );
};

PhoneVerification.prototype._request = function (type, path, params, callback, qs) {
    qs = qs || {};
    qs['api_key'] = this.apiKey;

    options = {
        url: this.apiURL + path,
        form: params,
        headers: this.headers,
        qs: qs,
        json: true,
        jar: false,
        strictSSL: true
    };

    console.log(options.url);

    var callback_check = function (err, res, body) {
        if (!err) {
            if (res.statusCode === 200) {
                callback(null, body);
            } else {
                callback(body);
            }
        } else {
            callback(err);
        }
    };

    switch (type) {
        case "post":
            request.post(options, callback_check);
            break;

        case "get":
            request.get(options, callback_check);
            break;
    }
};
This function verifies the token for a user delivered over the Voice or SMS channel.
Verify a Token

This function verifies the token for a user delivered over the Voice or SMS channel.

And with that, your demo app is protected with Twilio Verify! You can now log out to try the other channel.

What's Next?

Your demo app is now keeping hordes of fraudulent users from registering with your business and polluting the database. Next, you should check out all of the variables and options available to you in the Verify API Reference. Also, for protecting your customers in an ongoing manner (with this same codebase) try the Node.js Authy Two-Factor Authentication Quickstart.

After that, take a stroll through the Docs for more Account Security demos and tutorials - as well as sample web applications using all of Twilio's products. Encore!

Need some help?

We all do sometimes; code is hard. Get help now from our support team, or lean on the wisdom of the crowd browsing the Twilio tag on Stack Overflow.

Loading Code Samples...
export ACCOUNT_SECURITY_API_KEY='ENTER_SECRET_HERE'
export PORT=1337
var request = require('request');
var VERSION = "0.1";


module.exports = function (apiKey, apiUrl) {
    return new PhoneVerification(apiKey, apiUrl);
};

function PhoneVerification(apiKey, apiUrl) {
    this.apiKey = apiKey;
    this.apiURL = apiUrl || "https://api.authy.com";
    this.user_agent = "PhoneVerificationRegNode/" + VERSION + " (node " + process.version + ")";
    this.headers = {};

    this.init();
}

PhoneVerification.prototype.init = function () {
    this.headers = {
        "User-Agent": this.user_agent
    };
};

/**
 * Verify a phone number
 *
 * @param {!string} phone_number
 * @param {!string} country_code
 * @param {!string} token
 * @param {!function} callback
 */
PhoneVerification.prototype.verifyPhoneToken = function (phone_number, country_code, token, callback) {

    console.log('in verify phone');
    this._request("get", "/protected/json/phones/verification/check", {
            "api_key": this.apiKey,
            "verification_code": token,
            "phone_number": phone_number,
            "country_code": country_code
        },
        callback
    );
};

/**
 * Request a phone verification
 *
 * @param {!string} phone_number
 * @param {!string} country_code
 * @param {!string} via
 * @param {!function} callback
 */
PhoneVerification.prototype.requestPhoneVerification = function (phone_number, country_code, via, callback) {

    this._request("post", "/protected/json/phones/verification/start", {
            "api_key": this.apiKey,
            "phone_number": phone_number,
            "via": via,
            "country_code": country_code,
            "code_length": 4
        },
        callback
    );
};

PhoneVerification.prototype._request = function (type, path, params, callback, qs) {
    qs = qs || {};
    qs['api_key'] = this.apiKey;

    options = {
        url: this.apiURL + path,
        form: params,
        headers: this.headers,
        qs: qs,
        json: true,
        jar: false,
        strictSSL: true
    };

    console.log(options.url);

    var callback_check = function (err, res, body) {
        if (!err) {
            if (res.statusCode === 200) {
                callback(null, body);
            } else {
                callback(body);
            }
        } else {
            callback(err);
        }
    };

    switch (type) {
        case "post":
            request.post(options, callback_check);
            break;

        case "get":
            request.get(options, callback_check);
            break;
    }
};
var request = require('request');
var VERSION = "0.1";


module.exports = function (apiKey, apiUrl) {
    return new PhoneVerification(apiKey, apiUrl);
};

function PhoneVerification(apiKey, apiUrl) {
    this.apiKey = apiKey;
    this.apiURL = apiUrl || "https://api.authy.com";
    this.user_agent = "PhoneVerificationRegNode/" + VERSION + " (node " + process.version + ")";
    this.headers = {};

    this.init();
}

PhoneVerification.prototype.init = function () {
    this.headers = {
        "User-Agent": this.user_agent
    };
};

/**
 * Verify a phone number
 *
 * @param {!string} phone_number
 * @param {!string} country_code
 * @param {!string} token
 * @param {!function} callback
 */
PhoneVerification.prototype.verifyPhoneToken = function (phone_number, country_code, token, callback) {

    console.log('in verify phone');
    this._request("get", "/protected/json/phones/verification/check", {
            "api_key": this.apiKey,
            "verification_code": token,
            "phone_number": phone_number,
            "country_code": country_code
        },
        callback
    );
};

/**
 * Request a phone verification
 *
 * @param {!string} phone_number
 * @param {!string} country_code
 * @param {!string} via
 * @param {!function} callback
 */
PhoneVerification.prototype.requestPhoneVerification = function (phone_number, country_code, via, callback) {

    this._request("post", "/protected/json/phones/verification/start", {
            "api_key": this.apiKey,
            "phone_number": phone_number,
            "via": via,
            "country_code": country_code,
            "code_length": 4
        },
        callback
    );
};

PhoneVerification.prototype._request = function (type, path, params, callback, qs) {
    qs = qs || {};
    qs['api_key'] = this.apiKey;

    options = {
        url: this.apiURL + path,
        form: params,
        headers: this.headers,
        qs: qs,
        json: true,
        jar: false,
        strictSSL: true
    };

    console.log(options.url);

    var callback_check = function (err, res, body) {
        if (!err) {
            if (res.statusCode === 200) {
                callback(null, body);
            } else {
                callback(body);
            }
        } else {
            callback(err);
        }
    };

    switch (type) {
        case "post":
            request.post(options, callback_check);
            break;

        case "get":
            request.get(options, callback_check);
            break;
    }
};