Forward a Call Via Voice Proxy With Koa.js
Published on April 30, 2024


This tutorial shows you how to add voice capabilities to your application. We will use Koa, a web framework for Node.js, to create a server that handles incoming calls and events and the Vonage Voice API to forward calls to another phone number. Let's get started.

Project outline

By the end of this project, this is what your project folder should look like:

[node_modules] .env .private.key forward_a_call.js package-lock.json package.json vonage_app.json


To follow along with this tutorial, you'll need:

  • Node.js installed

  • Ngrok is installed to expose your local development server to the internet.

  • A Vonage Developer account to access our Voice API.

    Vonage API Account

    To complete this tutorial, you will need a Vonage 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 Vonage API Dashboard.

    This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.

Setup Ngrok

For us to be able to expose endpoints from our local machines without having to deploy our application to a live environment, we will make our local server accessible to the internet using ngrok

Once installed, in a new terminal/command prompt window, start ngrok on port 3000:

ngrok http 3000

Set Up Vonage

Set Up the Vonage CLI

You can create and manage Vonage applications using the Vonage CLI. Install it if you haven't already:

npm install @vonage/cli -g

Set the API Key and API Secret Configuration

Execute the command to set the API Key and API Secret Configuration. After this, you'll see Configuration saved on your terminal or in the command prompt.

The VONAGE_KEY and VONAGE_SECRET can be found on the Vonage Dashboard.

It shows where the API Key and API Secrets are. Right under the text 'API key and API Secret'Vonage Dashboard

vonage config:set --apiKey= --apiSecret=

Create an Application

Use the CLI to create a new application with voice capabilities and make a note of the application ID provided upon creation. Run the command to create a new Vonage Application.

vonage apps:create

After that, a prompt with some fields will pop up, and you call fill as follows.

✔ Application Name … "Forward a Call" ✔ Select App Capabilities › Voice ✔ Create voice webhooks? … yes ✔ Answer Webhook - URL … -> the URL of your current ngrok session followed by `/answer` ✔ Answer Webhook - Method › GET ✔ Event Webhook - URL … -> the URL of your current ngrok session followed by `/event` ✔ Event Webhook - Method › POST ✔ Allow use of data for AI training? Read data collection disclosure - … no

You should get a response similar to this:

Creating Application... done Application Name: Forward Application ID: APPLICATION_ID Voice Settings Event Webhook: Address: HTTP Method: POST Answer Webhook: Address: HTTP Method: GET Public Key -----BEGIN PUBLIC KEY----- A Long string -----END PUBLIC KEY----- App Files Vonage App File: `../vonage_app.json` Private Key File: ...`fileName.key` Improve AI: false

Rent a Virtual Number

Next, we'll need a virtual number acting as our "public face" for incoming calls. This number will be linked to our Vonage application, and here's how to acquire one:

  1. Search for available numbers in your desired region. Thankfully, we can purchase numbers directly from the CLI like this! vonage numbers:search US (replace US with your country code if needed).

  2. Buy a number: vonage numbers:buy 12079460000 US.

Remember that some numbers cannot be purchased via the Command Line, so you must purchase them via the dashboard. You can do so by going to the Vonage Dashboard and the Buy Numbers page. Tick 'Voice' in the search filter and select the country where you want to buy a number.

With our number chosen, it’s time to connect it to our Vonage application. You can link a virtual phone number directly from the Vonage Dashboard or via the CLI. Linking ensures that calls to your virtual number are correctly routed through your application.

vonage apps:link --number=12079460000 APPLICATION_ID

You can also do it from the dashboard. Go to the Application page and click on the application you created earlier. Click the 'Link' button in the Voice section next to the number you want to link.

Create the Node.js Project

  1. Create a new directory for your project and navigate into it. (Example folder VoiceWithVonage)

  2. Initialize a new Node.js project with npm init -y to accept all default settings.

Install Dependencies

Our project relies on a few dependencies, which we will install with a single command:

npm install @vonage/server-sdk koa @koa/router koa-bodyparser dotenv

Environment Variables

We'll use environment variables to store sensitive information like API keys and phone numbers to keep our application secure and manageable.

Create a .env file in your project root and add your variables refer to Michael's blog post for a better explanation of how to use environment variables in Node.js

// .env
VONAGE_API_KEY= Your Vonage API key, used for authenticating API requests.
VONAGE_API_SECRET= Your Vonage API secret
VONAGE_APPLICATION_ID= The ID of your Vonage application. Vonage applications allow you to manage your communication services and define how they interact with your web application.
VONAGE_PRIVATE_KEY= The path to your Vonage application's private key file. When you create a Vonage application that uses voice capabilities, you generate a public/private key pair. The private key authenticates your application when making API requests. It will  look like nameOfTheFile.key.
FROM_NUMBER= The Vonage virtual number (purchased through Vonage) that calls will come from. It is the number displayed to the user receiving the call.
YOUR_SECOND_NUMBER= The destination phone number to which the call will be forwarded. It should be in [E.164 format](

Initialize Vonage

The Vonage Server SDK makes integration with Vonage's services straightforward. Initialize it in your project to enable voice functionality, ensuring that placeholder values are replaced with your API credentials stored in your .env file.

Create a file called forward_a_call.js and the code below.

// forward_a_call.js
const { Vonage } = require("@vonage/server-sdk");

// Initialize the Vonage Server SDK with your credentials
const vonage = new Vonage({
 apiKey: process.env.VONAGE_API_KEY,
 apiSecret: process.env.VONAGE_API_SECRET,
 applicationId: process.env.VONAGE_APPLICATION_ID,
 privateKey: process.env.VONAGE_PRIVATE_KEY,

Set Up Koa

We begin by setting up our server environment:

const Koa = require("koa");
const Router = require("@koa/router");
const koaBody = require("koa-bodyparser");

const app = new Koa();
const router = new Router();


Here, we import the necessary modules and initialize our Koa application. dotenv loads environment variables (like your Vonage API credentials and phone numbers) from a .env file.

The koaBodyparser middleware is applied to parse the body of incoming requests, which is essential for reading JSON payloads in our /event webhook.

Additionally, we use @koa/router, a routing middleware, to define and manage routes within our application. This allows us to specify actions for different paths, such as /answer for answering calls and /event for processing webhook events.

Answer Calls with NCCO

The /answer route is defined as responding to incoming calls. When the Vonage platform receives a call to your virtual number, it requests that this /answer endpoint retrieve instructions, known as an NCCO (Call Control Object), on handling the call.

In this example, the NCCO instructs Vonage first to play a message ("Please wait while we connect your call.") and then connect the call to another specified number (YOUR_SECOND_NUMBER), using your Vonage number (FROM_NUMBER) as the caller ID.

router.get("/answer", async (ctx) => {
  const ncco = [
      action: "talk",
      text: "Please wait while we connect your call.",
      action: "connect",
      eventUrl: [],
      from: process.env.FROM_NUMBER,
      endpoint: [
          type: "phone",
          number: process.env.YOUR_SECOND_NUMBER,
  ctx.body = ncco;

Process Events, Apply Routes and Start the Server

The /event route captures and logs events related to the call. This endpoint is essential for debugging and monitoring your calls' lifecycle. Events can include call statuses such as answered, completed, or failed. By logging these events, we can gain insights into call flow and troubleshoot any issues

Finally, we apply our routes to the Koa application and start the server."/event", async (ctx) => {
  ctx.status = 204; // No content to send back


app.listen(3000, () => console.log("Server running on port 3000"));

The application listens on port 3000 and logs a message to the console once the server runs. Here, the routes we defined become accessible, allowing the Vonage platform to interact with our server based on the URLs specified in the Vonage Dashboard for our application's answer and event webhooks.

Run and Test the Application

With everything in place, start your server by running the command:

node forward_a_call.js

Test the call forwarding by dialing your Vonage virtual number. The call should be redirected to the number specified in your .env file.

Conclusion and Connect with Us

Congratulations! You've now mastered the art of call forwarding with Vonage. If you have any questions or suggestions or want to share what you’ve built, join our Vonage Developer Slack Community or reach out on X, formerly known as Twitter.

Further Reading

Build an Escape Plan With the Vonage Voice API and Get a Ghost Call

Transfer a Call with NCCO

Amanda CavallaroDeveloper Advocate

Ready to start building?

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

Subscribe to Our Developer Newsletter

Subscribe to our monthly newsletter to receive our latest updates on tutorials, releases, and events. No spam.