Getting Started with Nexmo’s Number Insight APIs on Koa.js
Published on May 21, 2021

Nexmo's Number Insight API delivers real-time intelligence about the validity, reachability, and roaming status of a phone number and tells you how to format the number correctly in your application.

There are three levels of Number Insight API available: Basic, Standard, and Advanced, each returning an increasing amount of information about the queried phone number. The advanced API is available asynchronously as well as synchronously.

In this blog post we're going to look at how to use the API with Node.js and the Koa.js framework.

Prerequisites

  • A basic understanding of Javascript

  • Node.js installed on your machine

DT API Account

To complete this tutorial, you will need a DT API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the DT API Dashboard.

This tutorial will take you through the process from scratch. If you'd like to see the finished code, you can clone the git repository for this project or remix it on Glitch. Note that they are slight differences for the Glitch implementation to cater for how projects are hosted on the platform.

Starting a Koa.js project from scratch

Create a project folder on your local machine, then run the following command to set up a new Node.js project.

npm init

This will trigger a series of prompts that will generate your package.json file. You can choose to leave the answers blank to use the default values if you wish.

Configuring package.jsonConfiguring package.json

Next, install Koa.js. Do note that Koa requires node v7.6.0 or higher for ES2015 and async function support.

npm install koa --save

Create a server.js file in your project folder.

touch server.js

Paste the following code into your newly created file.

const Koa = require('koa')

const port = process.env.PORT || 3000
const app = new Koa()

app.use(async ctx => {
  ctx.body = 'Hello Dinosaur ?'
})

const listener = app.listen(port, function() {
  console.log('Your app is listening on port ' + listener.address().port)
})

Run the server.js file.

node server.js

If you navigate to http://localhost:3000 from your browser, you should see an empty page with the text, “Hello Dinosaur ?”.

Check that server is runningCheck that server is running

You should also install dotenv, which allows you to load environment variables stored in a .env file into process.env.

npm install dotenv --save

And now you can create the .env file and it should contain at least the following variables:

NEXMO_API_KEY=''
NEXMO_API_SECRET=''

To access environment variables, you'll have to require it, ideally at the top of your server.js file.

require('dotenv').config()

If you haven't signed up for a Nexmo account yet, now is a pretty good time to do it. Once you've logged into the dashboard, your API credentials should be the first thing you see. Be sure to enclose both your key and secret with quotes.

Getting to Know the Number Insights API

First off, install the Nexmo REST API client for Node.js:

npm install nexmo --save

Next, initialise a new Nexmo instance.

const Nexmo = require('nexmo')

const nexmo = new Nexmo({
  apiKey: process.env.NEXMO_API_KEY,
  apiSecret: process.env.NEXMO_API_SECRET
})

As mentioned earlier, there are three levels for the Number Insight API, and you can pick one depending on the type of information you require. This is how the API is structured.

nexmo.numberInsight.get({
  level: 'basic | standard | advancedSync', // set Number Insight level here
  number: INSIGHT_NUMBER // phone number to be queried
}, (error, result) => {
  if (error) {
    console.error(error)
  }
  else {
    console.log(result)
  }
})

You can refer to our API reference to see how the response JSON is structured.

Obtaining Number Insights

You will need some way to input the phone number to be queried, so let's create a basic web page to do that.

Create a public folder in your project and add an index.html, styles.css and scripts.js to the folder. Your project structure should now look something like this:

PROJECT_FOLDER/ |-- public/ | |-- index.html | |-- scripts.js | `-- styles.css |-- .env `-- server.js

Add the following your index.html page:

<title>Number Insight API</title>
    <meta name="description" content="Exploring Nexmo's Number Insight API">
    <link id="favicon" rel="icon" href="https://www.nexmo.com/favicon.ico" type="image/x-icon">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="styles.css">
    <script src="scripts.js" defer=""></script>
  

  
    <main>
      <h1>Retrieve Number Insights</h1>
      <form>
        <input type="tel" placeholder="Enter phone number">
        <button type="button">Submit</button>
      </form>
      <hr>
      <pre><code>Awaiting results…</code></pre>
    </main>

You can also add some basic styles to the page by adding the following to the styles.css file:

@import url('https://fonts.googleapis.com/css?family=Gudea:400,700');

html {
  box-sizing: border-box;
  height: 100%;
  font-size: calc(1vmin + 1em);
}

*,
*::before,
*::after {
  box-sizing: inherit;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Gudea', sans-serif;
  height: 100%;
  display: flex;
  flex-direction: column;
  min-width: 15em;
  background-color: gainsboro;
}

main {
  flex: 1;
  margin: auto;
  padding: 1em;
}

h1 {
  margin-bottom: 0.5em;
}

form {
  display: flex;
  align-items: center;
  width: 100%;
  min-width: 10em;
}

input {
  font-size: inherit;
  padding: 0.5em;
  border: 0;
  flex: 1;
}

button {
  font-size: inherit;
  height: 100%;
  background-color: #2e689b;
  color: #fff;
  padding: 0.5em 0.75em;
  border: 0;
}

hr {
  margin: 1em 0;
}

pre {
  background-color: #333;
  padding: 0.5em;
  border-radius: 0.5em;
  color: lightblue;
  white-space: pre-wrap;
}

The next step is to send the input to the server so you can plug it into the Number Insight API and check it. To do that, trigger a POST request to a route that will handle the form content. The sample code below uses the Fetch API for this.

const phone = document.querySelector('input')
const submit = document.querySelector('button')
const insights = document.querySelector('code')

submit.addEventListener('click', send, false)

function send(event) {
  fetch('/submit', {
    method: 'post',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      phone: phone.value
    })
  })
  .then(function(res){ return res.json() })
  .then(function(insight){ parseInsight(insight) })
  .catch(function(error){ console.log(error) })
}

function parseInsight(data) {
  insights.innerHTML = JSON.stringify(data, null, 2)
}

You will need to handle this POST request on the server side. Unlike other popular Node.js frameworks like Express or Hapi.js, Koa.js is much more modular. Features like routing or serving static files are supported, but in seperate modules, which need to be installed:

npm install koa-router koa-bodyparser koa-static --save

Update your server.js file to use these new dependencies. First, instead of serving up a “Hello Dinosaur! ?“ message, modify your server.js file to use the index.html file instead by replacing

app.use(async ctx => {
  ctx.body = 'Hello Dinosaur ?'
})

with

const serve = require('koa-static')
app.use(serve('./public'))

Next, set up the route for incoming POST requests to /submit.

const bodyParser = require('koa-bodyparser')
const Router = require('koa-router')

const router = new Router()

app.use(bodyParser())

router.post('/submit', async (ctx, next) => {
  const payload = await ctx.request.body
  const number = await payload.phone
  const insight = await getInsight(number)
  ctx.status = 200
  ctx.body = insight
})

async function getInsight(number) {
  return new Promise(function(resolve, reject){
    nexmo.numberInsight.get({
      level: 'basic', 
      number: number
    }, (error, result) => {
      if (error) {
        console.error(error)
        reject(error)
      }  
      else {
        resolve(result)
      }
    })
  })
}

app.use(router.routes()).use(router.allowedMethods())

Basic API

If everything is set up correctly, you should be able to enter a phone number and get the resulting information about that number on your web page. With the Basic API, you can determine:

  • The country where a number is registered

  • The local and international representation of that number

With such information, you could discover which country a number belongs to and use the information to format the number correctly.

Basic Number APIBasic Number API

Standard API

The Number Insight Standard API provides all the information from the Number Insight Basic API together with the following additional data:

  • The line type (mobile/landline/virtual number/premium/toll-free)

  • The Mobile Country Code (MCC) and Mobile Network Code (MNC)

  • The name of the caller (USA only)

A common use-case for this would be to determine the best type of communication for a number (SMS or voice) and block virtual numbers.

Standard Number APIStandard Number API

Advanced API

Finally, the Number Insight Advanced API provides all the data from the Number Insight Standard API together with the following additional information:

  • If the number is likely to be valid

  • If the number is ported

  • If the number is reachable

  • If the number is roaming and, if so, the carrier and country

Often, such information is used to determine the risk associated with a number.

Advanced Number APIAdvanced Number API

The Advanced Number API can also be used asychronously to return the insight data when it becomes available, via a webhook. Note that this feature is not available for the Basic and Standard APIs.

Where Next?

If you are keen to do more with these APIs, here are some links that might be helpful to you:

Hui Jing ChenVonage Alumni

Hui Jing is a Developer Advocate at Nexmo. She has an inordinate love of CSS and typography, and is generally passionate about all things web.

Ready to start building?

Experience seamless connectivity, real-time messaging, and crystal-clear voice and video calls-all at your fingertips.