Direct your customers' calls to the right agent
Build your own smart-routing system in just a few lines of code!

Select a language:

    You wish you could direct incoming calls to the right agent based on their skillset or territory (or any other criteria)? That's now possible with Aircall's API.

    But why would you want to do that?

    By directing the call to the right agent, you will increase your team productivity and improve your customer satisfaction.

    You will be able to build smart routing capabilities with Aircall API: - forward your customer's call to the agent they talked to the last time they called, - transfer incoming calls to specific agents based on the caller’s origin or the company’s industry, - redirect all incoming calls to a user on specific hour.

    In this tutorial, we will create a middleware application which will forward all incoming calls to specific agents:

    Call flow

    Getting started

    Before starting to code, we need to have:

    1. An Aircall account - sign up here if you don't have one yet;
    2. Your API ID and your API Token. You can create one in the Company section of your Aircall Dashboard;
    3. A server running your application with a valid webhook endpoint (See the Create a Webhook integration tutorial to learn more about it);
    4. Your own database where you can match a phone number to a contact of yours.

    Step by step

    Now we are all setup, here are the steps we are going to follow:

    1. Receive new incoming call events,
    2. Retrieve caller's number and find the agent we want to forward the call to in a custom database,
    3. Forward the call to an agent.

    1. Receive new incoming call events

    Aircall sends the event type in the body of the requests made to the route /aircall/calls of your application, set as the event attribute.

    The call.created Webhook event is sent by Aircall when a call is starting on all your Aircall numbers, regardless if it is an inbound or an outbound call. You may want to create a demo account to avoid being spammed by your production environment.

    We only want to handle incoming newly created calls so we're going to check the direction of the call, set as the direction attribute:

    /**
     *  [POST] /aircall/calls will listen to Aircall webhook
     */
    app.post('/aircall/calls', (req, res) => {
      // req.body contains the Webhook payload
      if (req.body.event === 'call.created') {
        if (req.body.data.direction === 'inbound') {
          // TODO: do something with this call
        }
        else {
          console.info('Event direction non-handled:', req.body.data.direction);
        }
      }
      else {
        console.info('Event non-handled:', req.body.event);
      }
      res.status(200);
    });
    

    2. Retrieve caller's number and find the agent we want to forward the call to

    Now that we filtered all inbound calls, we need to retrieve some custom information from your backend, like who the caller is and to which agent the call should be redirected to. Every company has its own redirection strategy - we assume here that you are able to match one of your customer to one of your agent in your backend.

    Get the contact

    We need to figure out who the caller is. You need to match a contact in your own database or CRM with a phone number: the caller's number is specified in the data.raw_digits field.

    With this phone number, request your Database to retrieve the associated contact. Your method to fetch a contact in your Database should return a contact object:

    /**
     *  Your App framework
     */
    const myApp = {
      /**
       *  Retrieve a contact in a custom Database
       *  @phoneNumber: the contact phoneNumber, e164 formatted
       */
      getContact: (phoneNumber) => {
        // TODO: Search for a contact in your Database here
        // and set the contactFetched variable:
        const contactFetched = ...; // your secret recipe
        return contactFetched;
      }
    }
    

    Match the associated agent

    Once you found the matching contact in your Database, we have to associate it to one of your agents. You can for example find out that your customer Alice is used to speak with your agent Bob:

    const myApp = {
      ...
      /**
       *  Match a contact to an agent
       *  Return the agent email
       *  @contact: a contact id of your own
       */
      getAssociatedAgentEmail: (contact) => {
        // TODO: Match the associated agent with the contact param
        // and set the associatedAgentEmail variable:
        const associatedAgentEmail = ...; // your secret recipe again
        return associatedAgentEmail;
      }
    }
    

    3. Forward the call to an agent

    Now that we have the associated agent to forward the call to, we'll need to find its Aircall id. It can be found by requesting the /v1/users route. Here is an example of a response Aircall can send you:

    {
      "meta": {
        "total": 9,
        "count": 9,
        "current_page": 1,
        "per_page": 20,
        "next_page_link": null,
        "previous_page_link": null
      },
      "users": [
        {
          "id": 2048,
          ...
          "email": "john.doe@aircall.io",
          "name": "John Doe"
        }
        ...
      ]
    }
    

    Let's write a function to match your agent's email address to find its Aircall id:

    const myApp = {
      ...
      /**
       *  Match a contact to an agent
       *  @agentEmail: your agent email address
       */
      getAgentAircallID: (agentEmail, callback) => {
        // Populate Aircall API url with API_ID ann API_TOKEN
        const uri = `https://${API_ID}:${API_TOKEN}@api.aircall.io/v1/users`;
    
        request.get(uri, (error, response, body) => {
          // We use ES6 `Array.prorotype.find` function to find
          // a user in the body.users array:
          const data = JSON.parse(body);
          const agent = data.users.find((user) => {
            return user.email === agentEmail;
          });
          callback(agent.id);
        });
      }
      ...
    }
    

    Don't forget to fetch the other pages if you have more than 20 agents in your Aircall account!

    Last, we need to write the function that hits the API route to forward the current incoming call. Send a POST request to the /v1/calls/:callId/transfers route. It takes a callId param in the URL and a userId in the body:

    const myApp = {
      ...
    
      /**
       *  Forward a call to a user
       *  @callId: the call you want to be transferred
       *  @userId: the user you want to forward the call to
       */
      forwardCall: (callId, userId) => {
        const API_ID = '<your_api_id>';
        const API_TOKEN = '<your_api_token>';
    
        // Populate Aircall API url with API_ID, API_TOKEN and callid
        const uri = `https://${API_ID}:${API_TOKEN}@api.aircall.io/v1/calls/${callId}/transfers`;
    
        request.post(uri,
          {
            json: {
              user_id: userId
            }
          },
          (error, response, body) => {
            console.log(`Call ${callId} transferred to ${userId}`);
          }
        );
      }
      ...
    }
    

    So now that we:

    1. have all the functions to match a contact to an agent,
    2. know the agent's Aircall id,
    3. are able to transfer a call...

    ... let's write the full code to forward the call:

    const app = require('express')(),
          bodyParser = require('body-parser'),
          request = require('request');
    
    const API_ID = 'YOUR_APP_ID';
    const API_TOKEN = 'YOUR_APP_TOKEN';
    
    app.use(bodyParser.json());
    
    
    /**
     *  Your App framework
     */
    const myApp = {
      /**
       *  Return a contact found in your Database
       *  @phoneNumber: the contact phoneNumber, e164 formatted
       */
      getContact: (phoneNumber) => {
        // TODO: Search for a contact in your Database here
        // and set the contactFetched variable:
        const contactFetched = ...; // your secret recipe
        return contactFetched;
      },
    
      /**
       *  Match a contact to an agent
       *  Return the agent email
       *  @contact: a contact ID of your own
       */
      getAssociatedAgentEmail: (contact) => {
        // TODO: Match the associated agent with the contact param
        // and set the associatedAgentEmail variable:
        const associatedAgentEmail = ...; // your secret recipe again
        return associatedAgentEmail;
      },
    
      /**
       *  Match a contact to an agent
       *  @agentEmail: your agent email address
       */
      getAgentAircallID: (agentEmail, callback) => {
        // Populate Aircall API url with API_ID ann API_TOKEN
        const uri = `https://${API_ID}:${API_TOKEN}@api.aircall.io/v1/users`;
    
        request.get(uri, (error, response, body) => {
          // We use ES6 `Array.prorotype.find` function to find
          // a user in the body.users array:
          const data = JSON.parse(body);
          const agent = data.users.find((user) => {
            return user.email === agentEmail;
          });
          callback(agent.id);
        });
      },
    
      /**
       *  Forward a call to a user
       *  @callId: the call you want to be transferred
       *  @userId: the user you want to forward the call to
       */
      forwardCall: (callId, userId) => {
        // Populate Aircall API url with API_ID ann API_TOKEN
        const uri = `https://${API_ID}:${API_TOKEN}@api.aircall.io/v1/calls/${callId}/transfers`;
    
        request.post(uri,
          {
            json: {
              user_id: userId
            }
          },
          (error, response, body) => {
            console.log(`Call ${callId} transferred to ${userId}`);
          }
        );
      }
    };
    
    
    /**
     *  [GET] / route will show a basic JSON file
     */
    app.get('/', (req, res) => {
      res.json({'message': 'Server is running'});
    });
    
    
    /**
     *  [POST] /aircall/calls will listen to Aircall webhook
     */
    app.post('/aircall/calls', (req, res) => {
      if (req.body.event === 'call.created') {
        if (req.body.data.direction === 'inbound') {
          // 1. Get the caller contact:
          const contact = myApp.getContact(req.body.data.raw_digits);
    
          // 2. Get the associated agent's email
          const agentEmail = myApp.getAssociatedAgentEmail(contact);
    
          // 3. Retrieve the agent's Aircall id in a callback
          myApp.getAgentAircallID(agentEmail, (agentId) => {
            // 5. Save the call id in variable
            const callId = req.body.data.id;
    
            // 6. Finally, forward the call to the agent
            myApp.forwardCall(callId, agentId);
          });
        }
        else {
          console.info('Event direction non-handled:', req.body.data.direction);
        }
      }
      else {
        console.info('Event non-handled:', req.body.event);
      }
      res.status(200);
    });
    
    
    /**
     *  Start Express server on port 8080
     */
    app.listen(8080, () => {
      console.log('View your app at `http://localhost:8080`');
    });
    

    And we are done! All your Aircall incoming calls are now going through your smart routing system! 💪

    Error handling has not been implemented in those code examples to make the code simplier to read.
    You must handle it before using your code in production!

    We wrote other tutorials to help you out
    building awesome integrations

    Discover them now!