Create inbound routing policy
Creates a webhook-backed policy for pre-answer inbound call routing. PHONE_NUMBER policies target one active inbound-enabled Vobiz, Plivo, or VoiceLink DID, AGENT policies target an active agent, and PARTNER policies apply as the account-wide default.
curl --request POST \
--url https://api.vocobase.com/api/v2/inbound-route-policies \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"scope": "PHONE_NUMBER",
"phone_number_id": "f1a2c3d4-1111-2222-3333-444455556666",
"name": "Inbound owner routing",
"enabled": true,
"webhook_url": "https://app.example.com/webhooks/vocobase/inbound-route",
"timeout_ms": 2000,
"failure_action": "ANSWER_WITH_AI",
"allowed_actions": [
"ANSWER_WITH_AI",
"SELECT_AGENT",
"TRANSFER",
"REJECT"
]
}
'import requests
url = "https://api.vocobase.com/api/v2/inbound-route-policies"
payload = {
"scope": "PHONE_NUMBER",
"phone_number_id": "f1a2c3d4-1111-2222-3333-444455556666",
"name": "Inbound owner routing",
"enabled": True,
"webhook_url": "https://app.example.com/webhooks/vocobase/inbound-route",
"timeout_ms": 2000,
"failure_action": "ANSWER_WITH_AI",
"allowed_actions": ["ANSWER_WITH_AI", "SELECT_AGENT", "TRANSFER", "REJECT"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
scope: 'PHONE_NUMBER',
phone_number_id: 'f1a2c3d4-1111-2222-3333-444455556666',
name: 'Inbound owner routing',
enabled: true,
webhook_url: 'https://app.example.com/webhooks/vocobase/inbound-route',
timeout_ms: 2000,
failure_action: 'ANSWER_WITH_AI',
allowed_actions: ['ANSWER_WITH_AI', 'SELECT_AGENT', 'TRANSFER', 'REJECT']
})
};
fetch('https://api.vocobase.com/api/v2/inbound-route-policies', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vocobase.com/api/v2/inbound-route-policies",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'scope' => 'PHONE_NUMBER',
'phone_number_id' => 'f1a2c3d4-1111-2222-3333-444455556666',
'name' => 'Inbound owner routing',
'enabled' => true,
'webhook_url' => 'https://app.example.com/webhooks/vocobase/inbound-route',
'timeout_ms' => 2000,
'failure_action' => 'ANSWER_WITH_AI',
'allowed_actions' => [
'ANSWER_WITH_AI',
'SELECT_AGENT',
'TRANSFER',
'REJECT'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vocobase.com/api/v2/inbound-route-policies"
payload := strings.NewReader("{\n \"scope\": \"PHONE_NUMBER\",\n \"phone_number_id\": \"f1a2c3d4-1111-2222-3333-444455556666\",\n \"name\": \"Inbound owner routing\",\n \"enabled\": true,\n \"webhook_url\": \"https://app.example.com/webhooks/vocobase/inbound-route\",\n \"timeout_ms\": 2000,\n \"failure_action\": \"ANSWER_WITH_AI\",\n \"allowed_actions\": [\n \"ANSWER_WITH_AI\",\n \"SELECT_AGENT\",\n \"TRANSFER\",\n \"REJECT\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.vocobase.com/api/v2/inbound-route-policies")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"scope\": \"PHONE_NUMBER\",\n \"phone_number_id\": \"f1a2c3d4-1111-2222-3333-444455556666\",\n \"name\": \"Inbound owner routing\",\n \"enabled\": true,\n \"webhook_url\": \"https://app.example.com/webhooks/vocobase/inbound-route\",\n \"timeout_ms\": 2000,\n \"failure_action\": \"ANSWER_WITH_AI\",\n \"allowed_actions\": [\n \"ANSWER_WITH_AI\",\n \"SELECT_AGENT\",\n \"TRANSFER\",\n \"REJECT\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vocobase.com/api/v2/inbound-route-policies")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"scope\": \"PHONE_NUMBER\",\n \"phone_number_id\": \"f1a2c3d4-1111-2222-3333-444455556666\",\n \"name\": \"Inbound owner routing\",\n \"enabled\": true,\n \"webhook_url\": \"https://app.example.com/webhooks/vocobase/inbound-route\",\n \"timeout_ms\": 2000,\n \"failure_action\": \"ANSWER_WITH_AI\",\n \"allowed_actions\": [\n \"ANSWER_WITH_AI\",\n \"SELECT_AGENT\",\n \"TRANSFER\",\n \"REJECT\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"policy": {
"id": "clxj3rx7z000008l51s9vh3hf",
"scope": "PHONE_NUMBER",
"phone_number_id": "f1a2c3d4-1111-2222-3333-444455556666",
"phone_number": {
"id": "f1a2c3d4-1111-2222-3333-444455556666",
"number": "+918065480085"
},
"agent_id": null,
"agent": null,
"name": "Inbound owner routing",
"enabled": true,
"webhook_url": "https://app.example.com/webhooks/vocobase/inbound-route",
"has_webhook_secret": false,
"timeout_ms": 2000,
"failure_action": "ANSWER_WITH_AI",
"allowed_actions": [
"ANSWER_WITH_AI",
"SELECT_AGENT",
"TRANSFER",
"REJECT"
],
"created_at": "2026-07-01T11:00:00.000Z",
"updated_at": "2026-07-01T11:00:00.000Z"
}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "agent_name is required and must be max 50 characters"
}
}{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}{
"success": false,
"error": {
"code": "POLICY_ALREADY_EXISTS",
"message": "A policy already exists for this scope target"
}
}{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred"
}
}Authorizations
API key in format: rg_live_xxxx. Pass as a Bearer token in the Authorization header.
Body
Create a webhook-backed inbound routing policy. PHONE_NUMBER requires phone_number_id, AGENT requires agent_id, and PARTNER rejects both target IDs.
Policy scope. Runtime resolution priority is PHONE_NUMBER, then AGENT, then PARTNER.
PHONE_NUMBER, AGENT, PARTNER Policy label used in admin tooling.
1 - 200HTTPS endpoint that receives the inbound.route event.
Required when scope is PHONE_NUMBER. Must reference an active inbound-enabled Vobiz, Plivo, or VoiceLink DID owned by the account. TRANSFER cannot be listed in allowed_actions for a VoiceLink DID.
Required when scope is AGENT. Must reference an active agent owned by the account.
When false, the policy is stored but not evaluated.
Optional webhook signing secret. Write-only; never returned.
Policy decision webhook timeout in milliseconds.
250 <= x <= 5000Fallback action used when the policy webhook times out, fails, or returns an invalid response.
ANSWER_WITH_AI, REJECT Optional allowlist for webhook response actions. If omitted, all four actions are allowed.
Action values supported by inbound route policy responses.
ANSWER_WITH_AI, SELECT_AGENT, TRANSFER, REJECT curl --request POST \
--url https://api.vocobase.com/api/v2/inbound-route-policies \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"scope": "PHONE_NUMBER",
"phone_number_id": "f1a2c3d4-1111-2222-3333-444455556666",
"name": "Inbound owner routing",
"enabled": true,
"webhook_url": "https://app.example.com/webhooks/vocobase/inbound-route",
"timeout_ms": 2000,
"failure_action": "ANSWER_WITH_AI",
"allowed_actions": [
"ANSWER_WITH_AI",
"SELECT_AGENT",
"TRANSFER",
"REJECT"
]
}
'import requests
url = "https://api.vocobase.com/api/v2/inbound-route-policies"
payload = {
"scope": "PHONE_NUMBER",
"phone_number_id": "f1a2c3d4-1111-2222-3333-444455556666",
"name": "Inbound owner routing",
"enabled": True,
"webhook_url": "https://app.example.com/webhooks/vocobase/inbound-route",
"timeout_ms": 2000,
"failure_action": "ANSWER_WITH_AI",
"allowed_actions": ["ANSWER_WITH_AI", "SELECT_AGENT", "TRANSFER", "REJECT"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
scope: 'PHONE_NUMBER',
phone_number_id: 'f1a2c3d4-1111-2222-3333-444455556666',
name: 'Inbound owner routing',
enabled: true,
webhook_url: 'https://app.example.com/webhooks/vocobase/inbound-route',
timeout_ms: 2000,
failure_action: 'ANSWER_WITH_AI',
allowed_actions: ['ANSWER_WITH_AI', 'SELECT_AGENT', 'TRANSFER', 'REJECT']
})
};
fetch('https://api.vocobase.com/api/v2/inbound-route-policies', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vocobase.com/api/v2/inbound-route-policies",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'scope' => 'PHONE_NUMBER',
'phone_number_id' => 'f1a2c3d4-1111-2222-3333-444455556666',
'name' => 'Inbound owner routing',
'enabled' => true,
'webhook_url' => 'https://app.example.com/webhooks/vocobase/inbound-route',
'timeout_ms' => 2000,
'failure_action' => 'ANSWER_WITH_AI',
'allowed_actions' => [
'ANSWER_WITH_AI',
'SELECT_AGENT',
'TRANSFER',
'REJECT'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vocobase.com/api/v2/inbound-route-policies"
payload := strings.NewReader("{\n \"scope\": \"PHONE_NUMBER\",\n \"phone_number_id\": \"f1a2c3d4-1111-2222-3333-444455556666\",\n \"name\": \"Inbound owner routing\",\n \"enabled\": true,\n \"webhook_url\": \"https://app.example.com/webhooks/vocobase/inbound-route\",\n \"timeout_ms\": 2000,\n \"failure_action\": \"ANSWER_WITH_AI\",\n \"allowed_actions\": [\n \"ANSWER_WITH_AI\",\n \"SELECT_AGENT\",\n \"TRANSFER\",\n \"REJECT\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.vocobase.com/api/v2/inbound-route-policies")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"scope\": \"PHONE_NUMBER\",\n \"phone_number_id\": \"f1a2c3d4-1111-2222-3333-444455556666\",\n \"name\": \"Inbound owner routing\",\n \"enabled\": true,\n \"webhook_url\": \"https://app.example.com/webhooks/vocobase/inbound-route\",\n \"timeout_ms\": 2000,\n \"failure_action\": \"ANSWER_WITH_AI\",\n \"allowed_actions\": [\n \"ANSWER_WITH_AI\",\n \"SELECT_AGENT\",\n \"TRANSFER\",\n \"REJECT\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vocobase.com/api/v2/inbound-route-policies")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"scope\": \"PHONE_NUMBER\",\n \"phone_number_id\": \"f1a2c3d4-1111-2222-3333-444455556666\",\n \"name\": \"Inbound owner routing\",\n \"enabled\": true,\n \"webhook_url\": \"https://app.example.com/webhooks/vocobase/inbound-route\",\n \"timeout_ms\": 2000,\n \"failure_action\": \"ANSWER_WITH_AI\",\n \"allowed_actions\": [\n \"ANSWER_WITH_AI\",\n \"SELECT_AGENT\",\n \"TRANSFER\",\n \"REJECT\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"policy": {
"id": "clxj3rx7z000008l51s9vh3hf",
"scope": "PHONE_NUMBER",
"phone_number_id": "f1a2c3d4-1111-2222-3333-444455556666",
"phone_number": {
"id": "f1a2c3d4-1111-2222-3333-444455556666",
"number": "+918065480085"
},
"agent_id": null,
"agent": null,
"name": "Inbound owner routing",
"enabled": true,
"webhook_url": "https://app.example.com/webhooks/vocobase/inbound-route",
"has_webhook_secret": false,
"timeout_ms": 2000,
"failure_action": "ANSWER_WITH_AI",
"allowed_actions": [
"ANSWER_WITH_AI",
"SELECT_AGENT",
"TRANSFER",
"REJECT"
],
"created_at": "2026-07-01T11:00:00.000Z",
"updated_at": "2026-07-01T11:00:00.000Z"
}
}
}{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "agent_name is required and must be max 50 characters"
}
}{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}{
"success": false,
"error": {
"code": "POLICY_ALREADY_EXISTS",
"message": "A policy already exists for this scope target"
}
}{
"success": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred"
}
}