Build a Conference Call with the Nexmo Voice API and PHP
Published on May 13, 2021

Today's post will show you how to set up a conference call using Nexmo, so you can distribute a phone number and everyone who calls it will be connected to the same conference call. It's an ideal feature for a regular team meeting or another telephonic get-together. We'll be using PHP for the code examples, using no particular framework, and the code if you want it is available on GitHub.

Prepare Your Dependencies

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.

Start a new PHP project and add the Nexmo PHP library as a dependency.

composer require nexmo/client

Answering an Incoming Call with PHP

For this example, users will call a Nexmo number, and your application code will respond to that incoming call. Nexmo does this by using a Nexmo Call Control Object, or NCCO. First, we'll have a spoken text-to-speech greeting, then the user will join the conference call.

To achieve this, we'll add an answer.php file into a public/ directory (this is our webroot) and have it return the NCCO. The NCCO is JSON, so the PHP also needs to include an appropriate Content-Type header:


// return an NCCO to greet users and connect them into the conference call

$json = '[
        "action": "talk",
        "text": "Thank you for joining the call today. You will now be added to the conference.",
        "voiceName": "Nicole"
        "action": "conversation",
        "name": "weekly-team-meeting"

header("Content-Type: application/json");
echo $json;

The `$json` variable holds the NCCO that you will return to Nexmo's server to instruct how an incoming call will be handled. This example has a "talk" action that greets the user and then a "conversation" action to add the user into the conference call. This code uses `header()` to get PHP to send the `Content-Type` header and then the JSON itself. > If you're curious what else you can do with an NCCO, you can find the [NCCO reference documentation](/voice/voice-api/ncco-reference) on our Developer Portal. Serve the Response ------------------ At this point, you can start to test the moving parts of the application. Start the PHP webserver from the `public/` directory: ```blok {"type":"codeBlock","props":{"lang":"text","code":"cd%20public/%0Aphp%20-S%20localhost:8080%0A"}} ``` Check that your application returns the NCCO correctly when you make a request to `http://localhost:8080/answer.php` using your favourite HTTP client (cURL, Postman or even your browser would be good tools to use here). Make the Code Publicly Available -------------------------------- For Nexmo to be able to tell your application about an incoming call, it needs to be able to reach it, so this code needs to be publicly available. One option is to deploy it to a server somewhere, but for development purposes, I prefer to use [Ngrok]( to expose my local development platform. Once you have the webserver running (mine is on port 8080), run ngrok like this: ```blok {"type":"codeBlock","props":{"lang":"text","code":"ngrok%20http%208080%0A"}} ``` This will give you a dashboard showing a link to the web interface (very useful, click it), the https URL of your tunnel (copy this, we'll need it in a moment), and a section that will show the requests arriving when you make some. Try out your new tunnel by checking making a call to your application over it—you can replace `http://localhost:8080` with your ngrok https URL and try the request to `/answer.php` again. Set Up a Number to Call ----------------------- > This section shows buying and configuring a number using the CLI tool because that's how I usually work. If you prefer, you can also do these steps using the [account dashboard]($%7BCUSTOMER_DASHBOARD_URL%7D). First, we'll need a number to call. I'm in the UK so I'll use `GB` as the country code in my search: ```blok {"type":"codeBlock","props":{"lang":"text","code":"nexmo%20number:search%20GB%0A"}} ``` This command returns a list of available numbers; copy the one you want and then paste it into the next command: ```blok {"type":"codeBlock","props":{"lang":"text","code":"nexmo%20number:buy%20%5Bnumber%5D%0A"}} ``` The other thing needed is an application: this holds the configuration for the calls and can be linked to the number(s) you want to use. This separation is very useful if you want to have numbers in different geographies calling into the same conference call. Applications use public/private keys; in this example you are simply receiving an incoming call so the private key isn't used, but this example shows how to save it as `private.key` anyway since if you build something more sophisticated you will need it and be glad you saved it! Creating the application needs you to give it a name and configure some important webhook endpoints: * The answer URL will be the `answer.php` endpoint you created already. * The event URL ... let's call it `event.php` and create it in the next section? Here is the command to create the application, replace your Ngrok URLs before you run it! ```blok {"type":"codeBlock","props":{"lang":"text","code":"nexmo%20app:create%20PHPConfCall%20%5Bngrok_url%5D/answer.php%20%5Bngrok_url%5D/event.php%20--keyfile%20private.key%0A"}} ``` This command outputs the UUID of the application that it created. The final step here is to link this application to the number you bought. The command for that looks like this (again, replace the placeholders as appropriate). ```blok {"type":"codeBlock","props":{"lang":"text","code":"nexmo%20link:app%20%5Bnumber%5D%20%5Bapplication%20UUID%5D%0A"}} ``` .... I think you made it! Call the number and see if you hear the greeting; if so, ask someone else to call and enjoy a natter :) If it doesn't work first time, don't worry. Next is to build the event handling so that you can see what's going on—and if there are errors, this is how you will see them. Handle Call Events ------------------ To keep things really simple, the application expects its event URL to be at `/event.php`—and if you tested this already then you have seen some failing requests arriving there. To create a very simple event handler, create a file `public/event.php` and add the following code: ```blok {"type":"codeBlock","props":{"lang":"text","code":"%3C!--?php%0A%0A$post_params%20=%20json_decode(file_get_contents(%22php://input%22),%20true);%0A$input_params%20=%20$_GET;%0A%0Aif%20(is_array($post_params))%20%7B%0A%20%20%20%20$input_params%20=%20array_merge($input_params,%20$post_params);%0A%7D%0A%0Aif%20(isset($input_params%5B'status'%5D))%20%7B%0A%20%20%20%20error_log(%22Status:%20%22%20.%20$input_params%5B'status'%5D);%0A%7D%0Aerror_log(%22Event%20data:%20%22%20.%20json_encode($input_params));%0A%3C/code--%3E"}} ``` `` It's possible to configure the event URL to use either `GET` or `POST` requests so this code will handle either! It's very simple and writes the data to the error_log, so if you're using the local PHP webserver as I did in this example, you will see the events in the output of the webserver process. In a real-world application you can link your event URL to something more formal; for example try the [voice event logger project]( we built as a starting point. Get The Party Conference Call Started ------------------------------------- If you didn't try it already, then go ahead and call your Nexmo number. Then invite your friends, family, and colleagues to do the same. You'll see the events during the calls arriving to `event.php` and also the various calls being answered with calls to `answer.php`. Your Next Move? --------------- There are a few things you might like to do next, how about: * Look at the [NCCO documentation](/voice/voice-api/ncco-reference) for how to record the calls, play hold music, or have a particular moderator for the call. * View the code for this project [on GitHub]( * Check out our other [code snippets for working with Nexmo Voice API](/voice/voice-api/code-snippets/before-you-begin). * Go a step further and try the [Interactive Voice Response tutorial](/voice/voice-api/guides/interactive-voice-response) (it also uses PHP!). ``

Lorna MitchellVonage Alumni

Lorna is a software engineer with an incurable blogging habit. She tries to tame words and code in equal measure.

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.