Proxy Voice Calls Anonymously with Express
Published on May 20, 2021

We've all been there: you've gotten out of your cab and a few minutes later you realise you've left your umbrella behind. Alternatively, you're starving, staring out the window whenever you hear a car drive by, wondering where the food delivery you ordered an hour ago is.

Girl waiting on delivery"Girl waiting on delivery"

Perhaps it's the other way around. Maybe you're making a delivery and you need some directions to the address.

In all these situations you're going to need to call the other person, but you don't want to be giving your phone number out to strangers. So instead you can use a virtual number that connects the two parties but is only usable for the duration of the current transaction.

Renting a Virtual Number

In this tutorial, we're going to use the Vonage CLI to rent our virtual number, but you can also manage your numbers and voice applications via the Vonage dashboard if you'd prefer to use a GUI. If you haven't done so already, you can install the Vonage CLI via npm/yarn. Full instructions are in the Github repository.

At the time of writing, you can rent virtual numbers in 85 different countries. I'm going to use GB (Great Britain) in my example; you can see a complete list of countries and prices on our pricing page.

vonage numbers:search GB vonage numbers:buy [NUMBER] [COUNTRYCODE]

Creating Our Voice Proxy Server

At the moment if you attempt to call the virtual number we just rented, nothing happens.

Man on the phone"Man on the phone"

We have to associate the virtual number with an application. You can link multiple numbers to the same voice application, allowing you to have multiple numbers—even in different countries—all powered by a single backend.

In this example, we're going to create our backend with Node and Express and deploy it on Glitch. You can view the code on Github or remix it directly on Glitch.

Remix on Glitch"Remix on Glitch"

Our Express server has a single endpoint, which looks like this:

app.get("/", (request, response) => {
                "action": "connect",
                "eventUrl": [`${process.env.EVENTS_URL}`],
                "from": `${process.env.FROM_NUMBER}`,
                "endpoint": [
                        "type": "phone",
                        "number": `${process.env.TO_NUMBER}`

The route defined above returns an NCCO (Call Control Object), a JSON file that is used to provide instructions to the Vonage API when someone answers an inbound or outbound call. An NCCO can contain many different types of actions. You can view the available actions in our developer docs.

Our proxy server requires a single action connect. With this, we can proxy our incoming call to a range of different endpoints: another phone number, a WebSocket, or even a SIP URI. In the example above we connect to another phone number.

One of the requirements of the connect action is that the process.env.FROM_NUMBER must be a Vonage Virtual Number. This virtual number is what your call recipient sees. You can use the same virtual number you rented above, that way your caller and callee see the same virtual number, keeping their numbers private.

When you remix the app, you need to configure the FROM_NUMBER and TO_NUMBER in your Glitch .env file. These numbers need to be in the E.164 format. We're not using the EVENTS_URL in this example, but if you're interested in how you can track analytics about your voice calls, then you should watch our webinar "Inbound Voice Call Campaign Tracking with Vonage Virtual Numbers and Mixpanel" or read the accompanying blog post.

Linking Our Virtual Number to Our Proxy Server

To link our virtual number to our proxy server on Glitch we first need to create a Vonage Voice Application. You can create a voice application and link it to your number using the Vonage dashboard, or via the Vonage CLI.

vonage apps:create "Application name" --voice_answer_url= --voice_event_url= vonage apps:link --number=

The Application Overview and the Vonage CLI README contain more information on apps:create and the expected arguments.

Where to Next?

Read the "private voice communication" tutorial for a more in-depth example. For an example of the proxy server in Kotlin, watch my webinar. Alternatively, for more information on what else you can do with Vonage Voice APIs view our example use cases or read the developer documentation.

Aaron BassettVonage Alumni

Aaron was a developer advocate at Nexmo. A seasoned software engineer and wannabe digital artist Aaron is frequently found creating things with code, or electronics; sometimes both. You can customarily tell when he's working on something new by the smell of burning components in the air.

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.