Overview

A DNIs Pool is a rotating pool of Dynamic Number Insertion (DNI) numbers that allows you to connect to your Virtual Agent hosted on PolyAI’s infrastructure.

This integration enables you to:

  • Share structured JSON metadata with your Agent at the beginning of a call.
  • Retrieve call state information at the end of the conversation.

This is particularly useful when:

  • You’re using PSTN, which by definition does not support sharing metadata.
  • You’re using SIP installations that do not support custom SIP headers.

A typical use case is sending a shared ID (or other metadata) at call start, and using it later to retrieve handoff details, such as whether the call completed successfully or needs escalation to a human agent.

You can follow the docs to learn how to integrate your telephony stack with PolyAI’s DNIs Pooling solution.

Requirements

To set up the DNIs Pool integration, you’ll need the following from your PolyAI contact:

  • API token for the Reserve DNI endpoint
  • API token for the Get Handoff endpoint
  • Your account_id and project_id
  • Agree with your PolyAI contact on the attributes the Agent will need to extract

Integration Runtime

The integration involves two main API endpoints:

Figure: A visual overview of how DNIs Pool integration works in practice.

The flow works as follows:

  1. Client sends project-specific attributes to the Reserve DNI endpoint. An example payload would look like this:
{
    "attributes": {
        "shared_id": "1234567",
        "ani": "+44123456789"
    }
}
  1. PolyAI stores the attributes and returns a reserved DNI (e.g., +12345).
  2. Client initiates a call to the DNI.
  3. PolyAI looks up the attributes for that DNI.
  4. Attributes are forwarded to the Virtual Agent based on your API Key.
  5. The Virtual Agent handles the conversation and stores any agreed data (e.g., handoff status).
  6. The call ends, and PolyAI sends a SIP BYE message.
  7. Client queries the Get Handoff endpoint to retrieve the call outcome. An example response will look like this - note that the shared_id is the same ID you would have sent above:
{
    "data": {
        "handoff_to": "default_queue",
        "handoff_reason": "test_reason"
    },
    "id": "POLYAI_CALL_SID",
    "shared_id": "1234567"
}
  1. If a handoff state is present, the Client can transfer the call to a human agent; otherwise, the call is considered complete.

With this in mind, let’s have a look at how to set up the Agent to cope with this!

Agent setup

As a first step, head over to your project. For the integration to work, we will need your Agent to:

  • Store the attributes you are sending through the Reserve DNI API.
  • Save the handoff info into state to have the Get Handoff API to show them when invoked.

Store attributes

Attributes received from the API can only be accessed in the start_function. Not doing it here would mean losing them for all the conversations, making it impossible for the integration to work.

In your start_function, attributes are stored in the integration_attributes field as a dictionary. Retrieve them like this (assuming the attributes sent are the ones in the example above):

#### anywhere in start_function ####

# Retrieve DNIs Pooling Attributes
shared_id = conv.integration_attributes.get("shared_id")
ani = conv.integration_attributes.get("ani")
if not (shared_id or ani):
  # In case no attributes are received, make sure to handoff to a default queue 
  # on your side if you can't handle the call without the data
  conv.state.handoff_to = "DEFAULT_QUEUE"

print(f"shared_id: {shared_id}, ani: {ani}")  # you can optionally print the attributes

# Store them in the state to use them later in the conversation
conv.state.shared_id = shared_id
conv.state.ani = ani

You can then use those attributes in other functions, in the Knowledge Base or elsewhere in your Agent. This will be useful to customise your Agent behaviour, or use those attributes in other API calls to your infrastructure for example.

Save handoff info

As we outlined above, the bot will always need to end the conversation with this integration. For this reason, we need to configure the handoff information in other ways, which is: prepare them to be exposed by the Handoff API.

The Handoff API can be configured to expose all the state variables that you desire. The most useful variables are often:

  • the handoff reason, which is usually stored in conv.state.handoff_reason
  • the handoff destination, which is usually stored in conv.state.handoff_to But you can always expose more based on your use case.

As long as you store your desired value in the state variables, the Handoff API will expose them (as long as it is configured to do so).

At the moment, configuration can only be done by your PolyAI contact. Send them all the variables you want to expose, and they will be able to set up the Handoff API accordingly.

Pool size

It’s important to make sure that every customer hitting your solution gets to PolyAI. In a DNIs Pooling integration, the pool size is fundamental, as it will dictate how many concurrent calls you will be able to handle. As a rule of thumb, the pool size should be set to at least the maximum number of concurrent calls you expect to handle at peak times to avoid disruptions to your service.

The pool size can be controlled by your PolyAI contact, so you can simply share with them the max number of concurrent calls you expect at peak times.

Fallback

In the unfortunate case in which no DNI is available for the call you are sending to the PolyAI infrastructure, the API response status code will be a 404. You should set up your telephony system to handle this case, making sure calls go to a fallback queue. On the PolyAI side, we have per-project monitors in place to be notified when that happens, so we can act on extending the pool size immediately.