https://a.storyblok.com/f/270183/1368x665/9af4c311b6/25sep_dev-blog_ruby-inbound-call.jpg

How to Receive Phone Calls With Ruby on Rails

Published on September 11, 2025

Time to read: 4 minutes

Now that your Ruby on Rails app can make phone calls and track call statuses with call events, the next step is handling incoming phone calls. After all, how happy will your customers be if they can’t return your calls? In this article, we’ll show you exactly how to set that up.

In this tutorial, you will learn how to receive an inbound phone call by implementing a webhook endpoint in Ruby on Rails.

>> TL;DR Skip ahead and find all the Quickstart code on GitHub.

Prerequisites

To buy a virtual phone number, go to your API dashboard and follow the steps shown below.

Steps on how to purchase a phone number from the dashboard, from selecting the number and confirming the selection.Purchase a phone number

  1. Go to your API dashboard

  2. Navigate to BUILD & MANAGE > Numbers > Buy Numbers.

  3. Choose the attributes needed and then click Search

  4. Click the Buy button next to the number you want and validate your purchase

  5. To confirm you have purchased the virtual number, go to the left-hand navigation menu, under BUILD & MANAGE, click Numbers, then Your Numbers

How Does an Inbound Call Work?

When someone calls your Vonage virtual number, the Voice API needs to know what to do next: should it play a greeting, connect the call to another number, start recording, or something else?

That’s where the Answer Webhook comes in.

As soon as an inbound call is answered, Vonage makes an HTTP request to the answer_url you’ve configured in your application settings. This webhook tells your server, "Hey, you have a call, what should happen next?" Your server responds with an NCCO (a Vonage Call object) that defines the actions the Voice API should take for the call.

Learn more about Answer Webhook configurations.

How to Publicly Expose Our Ruby on Rails App With Ngrok

Our Ruby on Rails application is running in development on port 3000, so we can access it locally at localhost:3000. However, that only works on our computer!

You can use ngrok to safely expose your local server publicly over HTTP. So now, in a separate tab from your Rails server, open an ngrok tunnel on port 3000.

ngrok http 3000

Be sure to add your ngrok URL as a config.host in your development.rb file. We’ll use the environment variable VONAGE_SERVER_HOSTNAME, to make our app more dynamic.

For more help, seehow to get started and use ngrok in Rails.

# config/environments/development.rb

Rails.application.configure do
   config.hosts << ENV['VONAGE_SERVER_HOSTNAME']

Now in our .env file, set your 'VONAGE_SERVER_HOSTNAME' to your ngrok URL.

# .env

# ngrok URL, don't include the protocol (https://)
VONAGE_SERVER_HOSTNAME=''

We’ll also need to edit our Vonage application (from the previous articles) in the dashboard to add the ngrok URL in our webhooks. In the Answer URL field, add your ngrok URL followed by /inbound_calls. Ensure the request is being sent as POST.

Screenshot of Vonage Voice API settings panel with configured webhooks for Answer URL, Event URL using HTTP POST, and Fallback URL, along with region selection options.Vonage Voice API configuration showing Answer, Event, and Fallback URLs, including an ngrok URL for answer and event callbacks.

How to Handle Answer Event Webhooks in Rails

Now that Vonage is forwarding a phone call payload to the /inbound_calls route, let’s update our application and create a route to handle it.

# config/routes.rb


Rails.application.routes.draw do
 resources :inbound_calls, only: [:create]


	...previous routes...

When a call has been placed to your virtual Vonage number, Vonage will notify your application by sending a webhook. A typical payload for an inbound call will look something like this.

{
  "from": "442079460000",
  "to": "447700900000",
  "uuid": "aaaaaaaa-bbbb-cccc-dddd-0123456789ab",
  "conversation_uuid": "CON-aaaaaaaa-bbbb-cccc-dddd-0123456789ab"
}

How to Store a Phone Call in Rails

Now that we have all the required information based on our call model as previously defined, we can create some logic to store our inbound phone call. We’ll also send back a simple NCCO with a robot to respond to our caller, so they know the call is working.  Let’s generate a new controller to handle this.

rails g controller InboundCalls create

Inside our controller, we’ll have a simple create method that parses the webhook and enters a call into our database.

# app/controllers/inbound_calls_controller.rb
class InboundCallsController < ApplicationController
  # We disable CSRF for this webhook call
  skip_before_action :verify_authenticity_token

  def create
    Call.where(conversation_uuid: params[:conversation_uuid])
        .first_or_create
        .update(
          to: params[:to],
          from: params[:from],
          uuid: params[:uuid],
          is_inbound: true

        )

    render json: [
      {
        action: 'talk',
        voiceName: 'Jennifer',
        text: 'Hello, thank you for calling. This is Jennifer from Vonage. Ciao.'
      }
    ]
  end
end

Although storing and updating the call details is not really necessary, it's useful to keep track of current call statuses, durations, and any other information that might benefit your application. This action returns a new Vonage Call Control Object (NCCO) that will play back a simple voice message to the recipient as specified. Explore other NCCO actions like record, connect, or input to build advanced call flows.

OK, now start your server, ensure you have ngrok running, and make a voice call to your Vonage number to test the greeting!

>> See how all the code fits together in the full inbound_calls_controller.rb file.

Conclusion

Congratulations! You’ve successfully built a Ruby on Rails Voice application that can receive inbound phone calls using a Vonage webhook. And thus you’ve completed the Voice portion of the Ruby on Rails Quickstart. We’ll add Rich Communication Services (RCS) capabilities with the Vonage Messages API in future tutorials.

If you have any questions or want to request a functionality for the Quickstart application, join the conversation on the Vonage Community Slack or reach out on X (formerly Twitter). We’d love to hear what you build next!

Share:

https://a.storyblok.com/f/270183/384x384/e4e7d1452e/benjamin-aronov.png
Benjamin AronovDeveloper Advocate

Benjamin Aronov is a developer advocate at Vonage. He is a proven community builder with a background in Ruby on Rails. Benjamin enjoys the beaches of Tel Aviv which he calls home. His Tel Aviv base allows him to meet and learn from some of the world's best startup founders. Outside of tech, Benjamin loves traveling the world in search of the perfect pain au chocolat.