Get the list of bought numbers API
/{channel} /v1/account/numbers
Get the list of bought numbers API
Filters
| Parameter | Data Type | Required | Description |
|---|---|---|---|
| user_plan_id | String | No | user_plan_id you get from account_info get API |
| expiry_time | String | No | Expiry time of the number it should be greater than current time and less than or equal to the plan expiry time |
| number | String | No | number you want to allocate get from the AvailablePhoneNumbers API |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/numbers/"
headers = {
'authorization':"XXXXXX-XXXX-XXXX-XXXXXXXXX",
'x-api-key':"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
response =requests.request("GET", url,headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/numbers/",
"method": "GET",
"headers": {
"authorization":"XXXXXXX-XXXX-XXXX-XXXXXXX",
"x-api-key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/numbers/",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_HTTPHEADER =>array(
"authorization:XXXXXX-XXXX-XXXX-XXXXXXXXXX",
"x-api-key:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel: Basic
Sample Response
{
"meta": {
"limit": 1000,
"next": "",
"offset": 0,
"previous": "",
"total_count": 9
},
"objects": [
{
"cli_type": "NONE",
"created_time":"2016-10-21 07:25:05+00:00",
"expiry_time":"2017-10-20 18:30:00+00:00",
"is_expired": false,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
},
{
"cli_type": "NONE",
"created_time":"2016-10-20 06:27:59+00:00",
"expiry_time":"2017-10-19 18:30:00+00:00",
"is_expired": false,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
},
{
"cli_type": "NONE",
"created_time":"2017-01-02 04:35:14+00:00",
"expiry_time":"2017-10-19 18:30:00+00:00",
"is_expired": false,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
},
{
"cli_type": "NONE",
"created_time":"2016-10-20 14:53:35+00:00",
"expiry_time":"2017-10-19 18:30:00+00:00",
"is_expired": false,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
},
{
"cli_type": "NONE",
"created_time":"2017-04-25 04:42:16+00:00",
"expiry_time":"2017-04-25 18:30:00+00:00",
"is_expired": true,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
},
{
"cli_type": "NONE",
"created_time":"2017-04-24 13:47:55+00:00",
"expiry_time":"2017-04-24 18:30:00+00:00",
"is_expired": true,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
},
{
"cli_type": "NONE",
"created_time":"2017-04-24 13:46:38+00:00",
"expiry_time":"2017-04-24 18:30:00+00:00",
"is_expired": true,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
},
{
"cli_type": "NONE",
"created_time":"2017-04-24 13:55:42+00:00",
"expiry_time":"2017-04-24 18:30:00+00:00",
"is_expired": true,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
},
{
"cli_type": "NONE",
"created_time":"2017-04-24 13:51:26+00:00",
"expiry_time":"2017-04-24 18:30:00+00:00",
"is_expired": true,
"number_type": "1",
"phone_number":"+91XXXXXXXXXX",
"number_rating": -1
}
]
}
Create Order - OBD Call Center
/{channel} /v1/account/call-center/create_order/
Call Center API to create an order.
Body Description
| Parameter | Data Type | Required | Description |
|---|---|---|---|
| sound_id/ivr_id | Integer | Yes | Id of the approved sound or Ivr |
| phonebook | String | No | Id of the phonebook. It will be required if user is not passing any additional_number |
| timezone | String | Yes | Timezone in which user want to place campaign |
| priority | Integer | No | The value should be in between 1 and 10 |
| order_throttling | Integer | No | Maximum parallel calls |
| start_time | string | Yes | Start time of the order and it should be in the format yyyy-MM-dd HH:mm |
| end_time(optional) | string | No | End time of the order and it should be in the format yyyy-MM-dd HH:mm |
| call_scheduling | string | No | Weekdays on which user want to schedule the campaign.Representing it in array format like "[1, 1, 1, 1, 1, 0, 0]" starting from monday to sunday, 1 if user want to schedule the call on the day and 0 otherwise. |
| call_scheduling_start_time | string | No | Campaign start time per day. Default is 9:00 |
| call_scheduling_stop_time | string | No | Campaign stop time per day. Default is 21:00 |
| k_number | string | Yes | SR number of Enterprise Plan |
| additional_number | string | No | Numbers on which user want to run the campaign. "additonal_number" field is mandatory.It has to be passed everytime. Required if phonebook is not provided or if some numbers need to be added other than the numbers in the phonebook |
| is_transactional | string | No |
Value will be True/False
or true/false or 1/0, and
if the value is
True/true/1 then
transactional campaign
will be created otherwise
promotional and default
value is False/false/0.
Any value other than these
will lead to placing a
Promotional call.
. |
| outbound_callcenter | Integer | No | Value will be "1", Required when creating a Outbound Call Center Order |
| user_plan_id | Integer | No | Value will be corresponding to the plan id of the User . |
| Ivr_disp_num | string | Yes | Mandatory paramter. SR number belonging to Enterprise SIVR Plan |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/call-center/create_order/"
payload = "{\n \"ivr_id\":\"100xxxxx20\",\n \"additional_number\":\"+919xxxxxxx89\",\n \"timezone\":\"Asia/Kolkata\",\n \"priority\":10, \n \"order-throttling\":2,\n \"start_time\":\"2018-07-2018:17\", \n \"call_scheduling_start_time\":\"09:00\",\n \"call_scheduling_stop_time\":\"23:00\",\n \"is_transactional\":1 ,\n \"user_plan_id\":440274 ,\n \"outbound_callcenter\":1 ,\n \"call_scheduling\":[1,1,1,1,1,1,1],\n \"end_time\":\"2018-07-2018:35\"\n}"
headers = {
'authorization':"550xxxxxxxxxxxxxxxxxxa97e612",
'content-type':"application/json",
'x-api-key':"NRMxxxxxxxxxxxxxxxxxx8rxsDMlo",
}
response =requests.request("POST", url,data=payload, headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/call-center/create_order/",
"method": "POST",
"headers": {
"authorization":"550xxxxxxxxxxxxxxx4a97e612",
"content-type":"application/json",
"x-api-key":"NRxxxxxxxxxxxxxxxxxxxxxxxx4iVH768rxsDMlo",
},
"processData": false,
"data": "{\n \"ivr_id\":\"10xxxxxxxx0520\",\n \"additional_number\":\"+91xxxxxx589\",\n \"timezone\":\"Asia/Kolkata\",\n \"priority\":10, \n \"order-throttling\":2,\n \"start_time\":\"2018-07-2018:17\", \n \"call_scheduling_start_time\":\"09:00\",\n \"call_scheduling_stop_time\":\"23:00\",\n \"is_transactional\":1 ,\n \"user_plan_id\":44xx74 ,\n \"outbound_callcenter\":1 ,\n \"call_scheduling\":[1,1,1,1,1,1,1],\n \"end_time\":\"2018-07-2018:35\"\n}"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/call-center/create_order/",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "POST",
CURLOPT_POSTFIELDS =>"{\n \"ivr_id\":\"10xxxxxx0\",\n \"additional_number\":\"+9199xxxxx589\",\n \"timezone\":\"Asia/Kolkata\",\n \"priority\":10, \n \"order-throttling\":2,\n \"start_time\":\"2018-07-2018:17\", \n \"call_scheduling_start_time\":\"09:00\",\n \"call_scheduling_stop_time\":\"23:00\",\n \"is_transactional\":1 ,\n \"user_plan_id\":4xxx74 ,\n \"outbound_callcenter\":1 ,\n \"call_scheduling\":[1,1,1,1,1,1,1],\n \"end_time\":\"2018-07-2018:35\"\n}",
CURLOPT_HTTPHEADER =>array(
"authorization:5508xxxxxxxxxxxxxxxxxxxx8874a97e612",
"cache-control:no-cache",
"content-type:application/json",
"x-api-key:NRMxxxEB9xxxxxxxxxxxxxxxxxxxxxx8rxsDMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
{
"ivr_id":"100xxxxxxxx",
"additional_number":"+9199xxxxxxx",
{ " "}"timezone":"Asia/Kolkata",
"priority":10,
"order-throttling":2,
"start_time":"2018-07-1818:17",
"call_scheduling_start_time":"09:00" ,
"call_scheduling_stop_time":"23:00" ,
"is_transactional":1 ,
"user_plan_id":44xx4 ,
"outbound_callcenter":1 ,
"call_scheduling":[1,1,1,1,1,1,1] ,
"end_time":"2018-07-18 18:35"
}
Sample Response
{
"order_id": 175,
"result": "placed ordersuccessfully",
"status_code": 1
}
ADD Call to order - OBD Call Center
/{channel} /v1/account/call-center/add_call_to_order
API to add number in a campaign,by assiging it to an existing order_id whose status is either in progress or pending.
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/call-center/add_call_to_order"
payload = "{\n \"order_id\":19xxxx88, \n \"phone_numbers\":\"+9191xxxxx66\",\n \"call_times_retry\":3, \n \"retry_timedelta\":1 \n}"
headers = {
'authorization':"5508exxxxxxxxxxxxxxxx874a97e612",
'x-api-key':"NRMxxxxxxxxxxxxxiVH768rxsDMlo",
'content-type':"application/json",
}
response =requests.request("PUT", url,data=payload, headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/call-center/add_call_to_order",
"method": "PUT",
"headers": {
"authorization":"5508ed2xxxxxxxxxx874a97e612",
"x-api-key":"NRMPGxxxxxxxxxxxH768rxsDMlo",
"content-type":"application/json",
},
"processData": false,
"data": "{\n \"order_id\":19xxx488, \n \"phone_numbers\":\"+91xxxx69466\",\n \"call_times_retry\":3, \n \"retry_timedelta\":1 \n}"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/call-center/add_call_to_order",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "PUT",
CURLOPT_POSTFIELDS =>"{\n \"order_id\":19xxxxx88, \n \"phone_numbers\":\"+9xxxxxx9466\",\n \"call_times_retry\":3, \n \"retry_timedelta\":1 \n}",
CURLOPT_HTTPHEADER =>array(
"authorization:550xxxxxxxxxxxxx7e612",
"content-type:application/json",
"x-api-key:NRMPGExxxxxxxxxxxxxxxxxxxxxxxxxxxxsDMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
{
"order_id":1xxx488,
{ " "}"phone_numbers":"+9191xxxxx466",
"call_times_retry":3,
"retry_timedelta":1
}
Sample Response
{
"result": "call addedsuccessfully"
"status_code":1
}
Get Circle API
/{channel} /v1/account/numbers/Circle
Lists out all the circle ids against a telco-circle. Optional. If want to get circles for of the provided country. If not provided then it will pick the country from your account setting
Body Description
| Parameter | Data Type | Required | Description |
|---|---|---|---|
| country | String | No |
Australia
Austria Belgium Brazil Canada France Germany India Liechtenstein Luxembourg Malaysia Monaco Netherlands New Zealand Nigeria Philippines Singapore South Africa Switzerland Thailand Turkey UK United Arab Emirates US Western Europe |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/numbers/Circle"
headers = {
'authorization':"XXXXXX-XXXXX-XXXX-XXXXXX",
'x-api-key':"XXXXXXXXXXXXXXXXXXXXXXXXXXX",
}
response =requests.request("GET", url,headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/numbers/Circle",
"method": "GET",
"headers": {
"authorization":"XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX",
"x-api-key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/numbers/Circle",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_HTTPHEADER =>array(
"authorization:"XXXXXXX-XXXX-XXXX-XXXXXXXX",
"x-api-key:XXXXXXXXXXXXXXXXXXXXXXXXXXX"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization:SR_API_KEY
Path:
channel: Basic
QueryParameter:
country:country available inlist
Sample Response
Success: 200
[
{
city: "Andhra Pradesh",
id:3
}
]
Error: 401
{
message: "The SR API Key used toauthenticate is incorrect."
}
Error: 400
{
message: "You have providedinvalid country name. For moreinformation contact support."
}
Get plans API
/{channel}/account/plans
Lists out all the plan details associated with an account
Body Description
| Parameter | Data Type | Required | Description |
|---|---|---|---|
| id | String | No | Id of the userplan |
| plan | String | No | Plan of the user |
| plan_type | String | No | E(Enterprise), D(demo), P(paid),I(internal), T(international), H(Channel partner), C(Complementary) |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/plans"
headers = {
'authorization':"XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX",
'x-api-key':"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
response =requests.request("GET", url,headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/plans",
"method": "GET",
"headers": {
"authorization":"XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX",
"x-api-key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/plans",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_HTTPHEADER =>array(
"authorization:XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX",
"x-api-key:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization:USERNAME:SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
Sample Response
Status code: 200
{
meta: {
limit: 1000,
next: "",
offset: 0,
previous: "",
total_count: 3
},
objects: [
{
userplan_id: 407890,
plan_name: "Premium",
is_active:"false",
created_date:"2016-10-20 14:53:34+00:00",
expiry_time: "2017-10-1918:30:00+00:00",
plan_type: "I"
}]}
Status code: 401
{
error: "The SR API Key used toauthenticate is incorrect."
}
Get Available number API
/{channel} /v1/account/numbers/AvailablePhoneNumbers
Lists out all the available phone numbers in the telco-circles
Body Description
| Parameter | Data Type | Required | Description |
|---|---|---|---|
| circle_id | Integer | Yes | Id of the circle of which you want the available number list. You can get the circle id using the Get Circle API |
| cli_type | Integer | No | If you want the outgoing number to set as caller id while doing C2C pass the cli_type in parameter giving the value as 1 and no need to pass if you want incoming number. |
| number_rating | Integer | No |
If one wants to see all
star rating numbers then
provide -1 as value
Number rating is defined in 0 to 5, default value is 0 and categorizes as Platinum - 5, Diamond - 4, Gold - 3, Silver - 2, Fancy - 1, Regular - 0 |
| number_type | String | No | Number type can be mobile, landline, tollfree |
| pattern | String | No | You can define pattern of number in 3 ways - starts with, contains, and ends with. For starts with, use ^ followed by the number, example %5E%2B919069, where %5E is for ^ and %2B for +. For contains simply pass the number like 9069. For ends with pass the number followed with $, for example 8967%24 where %24 is for $ |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/numbers/AvailablePhoneNumbers"
querystring = {"circle_id":"1"}
headers = {
'authorization':"XXXXXXX-XXXX-XXXX-XXXXXXXXXX",
'x-api-key':"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
}
response =requests.request("GET", url,headers=headers,params=querystring)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/numbers/AvailablePhoneNumbers?circle_id=1",
"method": "GET",
"headers": {
"authorization":"XXXXXX-XXXX-XXXX-XXXXXXXXXXXXXX",
"x-api-key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/numbers/AvailablePhoneNumbers?circle_id=1",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_HTTPHEADER =>array(
"authorization:XXXXXXX-XXXXXX-XXX-XXXXXXX",
"x-api-key:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization:USERNAME:SR_API_KEY
content-type :application/json
Path:
channel: Basic
Sample Response
Status code: 200
{
numbers: [
{
number_type: "MOBILE",
number_rating: 0,
circle_id: 1,
number: "+91XXXXXXXX",
provider_name: "Vodafone"
}
]
}
Status code: 401
{
message: "The SR API Key used toauthenticate is incorrect."
}
Status code: 400
{
message: "Provide some input.For more information contact support."
}
or
{
message: "You have providedincorrect input. For more informationcontact support."
}
Buy the available numbers API
/{channel} /v1/account/numbers
Allocate the available phone numbers in the telco-circles for a particular plan id with an expiry time
Body Description
| Parameter | Data Type | Required | Description |
|---|---|---|---|
| user_plan_id | String | Yes | user_plan_id you get from account_info get API |
| expiry_time | String | Yes | Expiry time of the number it should be greater than current time and less than or equal to the plan expiry time |
| number | String | Yes | number you want to allocate get from the AvailablePhoneNumbers API |
| cli_type | String | No | Required if you want to allocate cli number. In this case its value will be 'OUTGOING' |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/numbers"
payload = "{\"user_plan_id\":\"XXXX\",\n\"expiry_time\":\"2017-04-2500:00:00\",\n\"number\":\"+91XXXXXXXXXX\"\n}"
headers = {
'authorization':"XXXXXX-XXXX-XXXX-XXXXXXX",
'content-type':"application/json",
'x-api-key':"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
response =requests.request("POST", url,data=payload, headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/numbers",
"method": "POST",
"headers": {
"authorization":"XXXXXX-XXXX-XXXX-XXXXXXX",
"content-type":"application/json",
"x-api-key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
},
"processData": false,
"data": "{\"user_plan_id\":\"XXXX\",\n\"expiry_time\":\"2017-04-2500:00:00\",\n\"number\":\"+91XXXXXXXXXX\"\n}"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/numbers",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "POST",
CURLOPT_POSTFIELDS =>"{\"user_plan_id\":\"XXXX\",\n\"expiry_time\":\"2017-04-2500:00:00\",\n\"number\":\"+91XXXXXXXXXX\"\n}",
CURLOPT_HTTPHEADER =>array(
"authorization:XXXXXX-XXXX-XXXX-XXXXXXX"
"content-type:application/json",
"x-api-key:XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel: Basic
Request Body:
{
user_plan_id:407890,
expiry_time:"2017-04-25 00:00:00",
number:"+91XXXXXXXXXX"
}
Sample Response
Status code: 200
{
message:"Your provided numberhas been allocated to youSuccessfully",
Number:phone_number
}
Status code: 401
{
message: "The SR API Key used toauthenticate is incorrect."
}
Status code: 400
{
"message": "You have providedincorrect input. For more informationcontact support."
}
Sound API
The Sound API is an important
tool to upload and list sound
under an account.
Once the developer upload a
sound it goes under approval
process. Then Knowlarity's
support team authorize the sound
on the basis of the content and
mark it as "Approved" or
"Rejected".
The developer can use only
approved sound in the campaigns.
Using Sound API the developer can:
- 1. Upload a sound file
- 2. List all the sound files.
Phonebook API
This API allows developers upload phonebook which they can use in campaign API.
This API includes:
- 1. Uploading of phonebook
- 2. Listing of uploaded phonebook
Get Phonebook API
/{channel} /v1/account/contacts/phonebook/
Get list of phonebooks associated with the SR account.
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/contacts/phonebook/"
headers = {
'authorization':"046XXXXXXXXXXXXXXXXXXXXXXXXXXXX301",
'x-api-key':"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
'cache-control':"no-cache"
}
response =requests.request("GET", url,headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/contacts/phonebook/",
"method": "GET",
"headers": {
"authorization":"046XXXXXXXXXXXXXXXXXXXXXXXXXXXX301",
"x-api-key":"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
"cache-control":"no-cache"
}
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/contacts/phonebook/",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_HTTPHEADER =>array(
"authorization:046XXXXXXXXXXXXXXXXXXXXXXXXXXXX301",
"cache-control:no-cache",
"x-api-key:NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Sample Response
{
"meta": {
"limit": 1000,
"next": "",
"offset": 0,
"previous": "",
"total_count": 1
},
"objects": [
{
"description": "",
"duplicates_count": 0,
"id": 1,
"invalid_count": 0,
"ndnc_count": 0,
"phonebookfile":"https://xyz.com/phonebook_1.csv",
"phonebookname":"phonebook_1",
"row_count": 2,
"timestamp": "Thu, 30 Mar2017 18:24:24 +0530"
}
]
}
Post Phonebook API
/{channel} /v1/account/contacts/phonebook/
Upload a phonebook in associated SR account.
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/contacts/phonebook"
payload = "{\n\"phonebookname\":\"phonebook_1\",\n\"numbers\":\"+91XXXXXXXXXX;+91XXXXXXXXXX\"\n}\n"
headers = {
'authorization':"046XXXXXXXXXXXXXXXXXXXXXXXXXX301",
'x-api-key':"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
'content-type':"application/json",
'cache-control':"no-cache",
}
response =requests.request("POST", url,data=payload, headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/contacts/phonebook",
"method": "POST",
"headers": {
"authorization":"046XXXXXXXXXXXXXXXXXXXXXXXXXX301",
"x-api-key":"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
"content-type":"application/json",
"cache-control":"no-cache",
},
"processData": false,
"data": "{\n\"phonebookname\":\"phonebook_1\",\n\"numbers\":\"+91XXXXXXXXXX;+91XXXXXXXXXX\"\n}\n"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/contacts/phonebook",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "POST",
CURLOPT_POSTFIELDS =>"{\n\"phonebookname\":\"phonebook_1\",\n\"numbers\":\"+91XXXXXXXXXX;+91XXXXXXXXXX\"\n}\n",
CURLOPT_HTTPHEADER =>array(
"authorization:046XXXXXXXXXXXXXXXXXXXXXXXXXX301",
"cache-control:no-cache",
"content-type:application/json",
"x-api-key:NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
{
"phonebookname":"phonebook_1",
"numbers":"+91XXXXXXXXX;+91XXXXXXXXXX"
}
Sample Response
{
"msg": [
"Successfully added phonebook"
],
"id": 1
}
Get Sound API
/{channel}/v1/account/sound
Get list of sounds associated with the SR account.
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/sound"
headers = {
'authorization':"046XXXXXXXXXXXXXXXXXXXXXXXXXXX301",
'x-api-key':"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
'cache-control':"no-cache",
}
response =requests.request("GET", url,headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/sound",
"method": "GET",
"headers": {
"authorization":"046XXXXXXXXXXXXXXXXXXXXXXXXXXX301",
"x-api-key":"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
"cache-control":"no-cache",
}
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/sound",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_HTTPHEADER =>array(
"authorization:046XXXXXXXXXXXXXXXXXXXXXXXXXXX301",
"cache-control:no-cache",
"x-api-key:NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Sample Response
Status_code - 200
{
"meta": {
"limit": 1000,
"next": "",
"offset": 0,
"previous": "",
"total_count": 1
},
"objects": [
{
"comment": "",
"date": "Fri, 1 Jul 201616:45:37 +0530",
"description": "",
"id": "1",
"language": "english",
"soundfile":"https://xyz.com/test.mp3",
"soundname": "test.mp3",
"status": "1"
}
]
}
Agent API
This API allows developers to
handle agent-related
customizations. This powerful
API has many uses, including but
not limited to defining factors
for call routing, providing
role-based access rights and
tracking agent work schedules.
It helps manage the users in a
contact center solution.
Agent Details - In order to
create an agent, you must enter
correct values for name, phone
number and email address. This
will help generate a unique ID
for each agent in your account.
Role - This attribute
assigns hierarchical roles to
the agents in the account.
Supervisors and Agents have
different levels of access in
the account and the agent API
allows you to set the correct
access level for every agent.
Status - This attribute
gives us the availability of an
agent to receive a call. In
addition, this helps keep a
track of agent performance.
Call Groups - This
attribute allows segmentation of
users based on their teams. The
call groups can be defined based
on your team structure and this
information can be utilized
while deciding the call flow.
Post Sound API
/{channel}/v1/account/sound
Upload sound to the associated SR account.
After uploading sound, user will
get it's status as '0' which
means the sound is under
approval process which is done
by Knowlarity's support team.
Status description -
Under Approval : '0'
Approved : '1'
Rejected : '2'
| Parameter | Data Type | Description |
|---|---|---|
| soundname | string | Name of the sound file |
| soundfile | string | Public url of the sound file and it should be in mp3 or wav format |
| language | string | Optional:Language of the sound |
| description | string | Optional:Description of the sound |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/sound/"
payload = "{\n \"soundname\":\"test\",\n \"soundfile\":\"https://XXXXXXXXXXXXXXXXXXXX.mp3\",\n \"description\":\"test\",\n \"language\":\"eng\"\n \n}\n\n\n"
headers = {
'authorization':"046XXXXXXXXXXXXXXXXXXXXXX301",
'x-api-key':"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
'content-type':"application/json",
'cache-control':"no-cache",
}
response =requests.request("POST", url,data=payload, headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/sound/",
"method": "POST",
"headers": {
"authorization":"046XXXXXXXXXXXXXXXXXXXXXX301",
"x-api-key":"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
"content-type":"application/json",
"cache-control":"no-cache",
},
"processData": false,
"data": "{\n \"soundname\":\"test\",\n \"soundfile\":\"https://XXXXXXXXXXXXXXXXXXXX.mp3\",\n \"description\":\"test\",\n \"language\":\"eng\"\n \n}\n\n\n"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/sound/",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "POST",
CURLOPT_POSTFIELDS =>"{\n \"soundname\":\"test\",\n \"soundfile\":\"https://XXXXXXXXXXXXXXXXXXXX.mp3\",\n \"description\":\"test\",\n \"language\":\"eng\"\n \n}\n\n\n",
CURLOPT_HTTPHEADER =>array(
"authorization:046XXXXXXXXXXXXXXXXXXXXXX301",
"cache-control:no-cache",
"content-type:application/json",
"x-api-key:NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
{
"soundname": "test",
"soundfile":"https://xyz.com/sound.mp3",
"language": "English",
"description": "Testing"
}
Sample Response
{
"msg": [
"Successfully added sound"
],
"status": "0",
"id": 157777
}
Get Campaign API
/{channel} /v1/account/call/campaign
List out all the campaigns created via the SR account.
Filters Description
| Parameter | Data Type | Description |
|---|---|---|
| order_id | string | Id of the campaign created |
| created_time__gte | string | created time of the order greater than equal to given time |
| created_time__lte | string | created time of the order less than equal to given time |
| end_time__gt | string | end time of the order greater than the given value |
| end_time__gte | string | end time of the order greater than equal to the given value |
| end_time__lt | string | end time of order less than the given value |
| end_time__lte | string | end time of order less than equal to the given value |
| is_transactional | string | if transactional provide "True" and if promotional provide "False" |
| ivr_id | string | ivr id |
| phonebook_id | string | phonebook id |
| start_time__gt | string | start time of the order greater than the given value |
| start_time__gte | string | start time of the order greater than equal to the given value |
| start_time__lt | string | start time of order less than the given value |
| start_time__lte | string | start time of order less than equal to the given value |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/call/campaign"
querystring = {"start_time__gt":"2017-04-10","start_time__lt":"2017-04-12"}
headers = {
'authorization':"046XXXXXXXXXXXXXXXXXXXXXXXX301",
'x-api-key':"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
'cache-control':"no-cache",
}
response =requests.request("GET", url,headers=headers,params=querystring)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/call/campaign?start_time__gt=2017-04-10&start_time__lt=2017-04-12",
"method": "GET",
"headers": {
"authorization":"046XXXXXXXXXXXXXXXXXXXXXXXX301",
"x-api-key":"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
"cache-control":"no-cache",
}
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/call/campaign?start_time__gt=2017-04-10&start_time__lt=2017-04-12",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_HTTPHEADER =>array(
"authorization:046XXXXXXXXXXXXXXXXXXXXXXXX301",
"cache-control:no-cache",
"x-api-key:NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Sample Response
{
"meta": {
"limit": 1000,
"next": "",
"offset": 0,
"previous": "",
"total_count": 1
},
"objects": [
{
"additional_number":"+91XXXXXXXXXX",
"call_scheduling": "[1, 1,1, 1, 1, 0, 0]",
"call_scheduling_start_time":"09:00:00 +0530",
"call_scheduling_stop_time":"21:00:00 +0530",
"caller_id": "",
"created_time": "Tue, 11 Apr2017 14:19:37 +0530",
"end_time": "",
"is_transactional": "False",
"ivr": "sound_obd_ivr_1",
"ivr_id": "1",
"ndnc_count": 0,
"optin_key": "",
"order_id": "170",
"order_status": "Pending",
"order_throttling": "0/10",
"phonebook_id": "",
"priority": 1,
"retry_duration": 15,
"start_time": "Tue, 11 Apr2017 15:55:00 +0530",
"max_retry": 3,
"timezone": "Asia/Kolkata",
"total_calls": 1
}
]
}
Post Campaign API
/{channel} /v1/account/call/campaign
API to create a campaign
Body Description
| Parameter | Data Type | Required | Description |
|---|---|---|---|
| sound_id/ivr_id | Integer | Yes | Id of the approved sound or Ivr |
| phonebook | String | No | Id of the phonebook. It will be required if user is not passing any additional_number |
| timezone | String | Yes | Timezone in which user want to place campaign |
| priority | Integer | No | The value should be in between 1 and 10 |
| order_throttling | Integer | No | Maximum parallel calls |
| retry_duration | Integer | No | Duration (in mins) between two retries |
| max_retry | Integer | No | Number of retries if a call fails |
| start_time | string | Yes | Start time of the order and it should be in the format yyyy-MM-dd HH:mm |
| end_time | string | No | End time of the order and it should be in the format yyyy-MM-dd HH:mm |
| call_scheduling | string | No | Weekdays on which user want to schedule the campaign.Representing it in array format like "[1, 1, 1, 1, 1, 0, 0]" starting from monday to sunday, 1 if user want to schedule the call on the day and 0 otherwise. |
| call_scheduling_start_time | string | No | Campaign start time per day. Default is 9:00 |
| call_scheduling_stop_time | string | No | Campaign stop time per day. Default is 21:00 |
| k_number | string | Yes | SR number of Enterprise Plan |
| additional_number | string | No | Numbers on which user want to run the campaign. Required if phonebook is not provided |
| is_transactional | string | No | Value will be "True"/"False", and if the value is True then transactional campaign will be created otherwise promotional and default value is False. |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/call/campaign"
payload = "{\"sound_id\":1,\n\"phonebook\":1,\n\"timezone\":\"Asia/Kolkata\",\n\"priority\":1,\n\"order_throttling\":10,\n\"retry_duration\":15,\n\"max_retry\":1,\n\"start_time\":\"2017-04-1118:26\",\n\"call_scheduling\":\"[1,1, 1, 1, 1, 0,0]\",\n\"call_scheduling_start_time\":\"9:00\",\n\"call_scheduling_stop_time\":\"21:00\",\n\"k_number\":\"+91XXXXXXXXXX\",\n\"additional_number\":\"\"\n}"
headers = {
'authorization':"046XXXXXXXXXXXXXXXXXXXX301",
'x-api-key':"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
'content-type':"application/json",
'cache-control':"no-cache",
}
response =requests.request("POST", url,data=payload, headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/call/campaign",
"method": "POST",
"headers": {
"authorization":"046XXXXXXXXXXXXXXXXXXXX301",
"x-api-key":"NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo",
"content-type":"application/json",
"cache-control":"no-cache",
},
"processData": false,
"data": "{\"sound_id\":1,\n\"phonebook\":1,\n\"timezone\":\"Asia/Kolkata\",\n\"priority\":1,\n\"order_throttling\":10,\n\"retry_duration\":15,\n\"max_retry\":1,\n\"start_time\":\"2017-04-1118:26\",\n\"call_scheduling\":\"[1,1, 1, 1, 1, 0,0]\",\n\"call_scheduling_start_time\":\"9:00\",\n\"call_scheduling_stop_time\":\"21:00\",\n\"k_number\":\"+91XXXXXXXXXX\",\n\"additional_number\":\"\"\n}"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/call/campaign",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "POST",
CURLOPT_POSTFIELDS =>"{\"sound_id\":1,\n\"phonebook\":1,\n\"timezone\":\"Asia/Kolkata\",\n\"priority\":1,\n\"order_throttling\":10,\n\"retry_duration\":15,\n\"max_retry\":1,\n\"start_time\":\"2017-04-1118:26\",\n\"call_scheduling\":\"[1,1, 1, 1, 1, 0,0]\",\n\"call_scheduling_start_time\":\"9:00\",\n\"call_scheduling_stop_time\":\"21:00\",\n\"k_number\":\"+91XXXXXXXXXX\",\n\"additional_number\":\"\"\n}",
CURLOPT_HTTPHEADER =>array(
"authorization:046XXXXXXXXXXXXXXXXXXXX301",
"content-type:application/json"
"x-api-key:NRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
{
"sound_id": 1,
"phonebook": 1,
"timezone": "Asia/Kolkata",
"priority": 10,
"order_throttling": 10,
"retry_duration": 15,
"start_time": "2017-01-0100:00",
"max_retry": 1,
"call_scheduling": "[1, 1, 1, 1,1, 0, 0]",
"call_scheduling_start_time":"09:00",
"call_scheduling_stop_time":"21:00",
"k_number": "+91XXXXXXXXXX",
"additional_number":"+91XXXXXXXX;+91XXXXXXXX"
}
Sample Response
{
"order_id": 175,
"result": "placed ordersuccessfully",
"status_code": 1
}
PUT Campaign API
/{channel} /v1/account/call/campaign
API to control the campaign.
Status can be pause, resume and stop
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/call/campaign/1xx"
payload = "{\n \"status\": \"stop\"\n}"
headers = {
'authorization':"046ccxxxxxxxxxxxxxxx20e9301",
'x-api-key':"NRMxxxxxxxxxxxxxxxxxH768rxsDMlo",
'cache-control':"no-cache",
}
response =requests.request("PUT", url,data=payload, headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/call/campaign/1xx",
"method": "PUT",
"headers": {
"authorization":"046ccxxxxxxxxxxxxxxxx0e9301",
"x-api-key":"NRMPGExxxxxxxxxxxxxxx0iT4iVH768rxsDMlo",
"cache-control":"no-cache",
},
"data": "{\n \"status\": \"stop\"\n}"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/call/campaign/123",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "PUT",
CURLOPT_POSTFIELDS =>"{\n \"status\":\"stop\"\n}",
CURLOPT_HTTPHEADER =>array(
"authorization:04xxxxxxxxxxx9301",
"cache-control:no-cache",
"x-api-key:NRxxxxxxxxxxxxxxxxxxxMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
{
"status":"pause"
}
Sample Response
Success - 200
{
"message": "Campaign pausedsuccessfully!"
}
Campaign Add Number
/{channel} /v1/account/call/campaign/add-numbers
API to add number in a campaign whose status is either in progress or pending.
Notes - sivr_call_ids in response is the set of call ids generated by product and used for all retry attempts of a call.
Example
Python :
import requests
url ="https://kpi.knowlarity.com/test/v1/account/call/campaign/add-numbers/"
payload = "{\n\t\"order_id\":178,\n\t\"phone_numbers\":\"+9170xxxx0689\"\n}"
headers = {
'authorization':"046ccxxxxxxxxxxxxxx67cf20e9301",
'x-api-key':"NRMxxxxxxxxxxxxxxxxxxxxH768rxsDMlo",
'content-type':"application/json"
}
response =requests.request("POST", url,data=payload, headers=headers)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/test/v1/account/call/campaign/add-numbers/",
"method": "POST",
"headers": {
"authorization":"046cc3f4-xxxxxxxxxxxxxxxxxx67cf20e9301",
"x-api-key":"NRMPxxxxxxxxxxxxxxxxxxxiT48rxsDMlo",
"content-type":"application/json"
},
"processData": false,
"data": "{\n\t\"order_id\":178,\n\t\"phone_numbers\":\"+917xxxxxx0689\"\n}"
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/test/v1/account/call/campaign/add-numbers/",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "POST",
CURLOPT_POSTFIELDS =>"{\n\t\"order_id\":178,\n\t\"phone_numbers\":\"+9170xxxxx0689\"\n}",
CURLOPT_HTTPHEADER =>array(
"authorization:046ccxxxxxxxxxxxxxxx-067cf20e9301",
"content-type:application/json",
"x-api-key:NRMPxxxxxxxxxxxxxxxx4iVH768rxsDMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
{
"order_id": 0,
"additional_number":"+91XXXXXXXX;+91XXXXXXXX"
}
Sample Response
{
"dnd_count": "0",
"message": "call addedsuccessfully"
"sivr_call_ids":[]
}
Tasks API
SuperReceptionist’s first aim is
to help businesses so that they
never lose a lead. We understand
how important every lead is and
we have a simple solution to
deal with the problem of missing
out on leads - generating
Follow-up Tasks for any missed
or deferred calls using the
Tasks API.
This API is especially useful to
capture leads for the calls
received during a missed call
campaign. Once the list of
callers has been identified via
call logs API, the Tasks API
allows the calls to be assigned
to agents with specific
due-dates.
This also means that agents can
schedule reminders for follow-up
calls to customers, thus plan
their work more efficiently.
Inputs like creation time, due
date, status etc. are highly
useful in analyzing
agent-performances and in
planning for high call volumes.
Contacts API
An important aspect of any
contact centre solution is the
information capturing mechanism
or the CRM. Using Contact APIs,
the developer can store and
retrieve customer details.
Results can be filtered using
attributes like status, phone
number, email address etc. You
can also assign a status to the
customers, edit their details
etc.
You can also customize your
searches. For eg. Finding out
how many calls someone with the
status ‘Hot’ made in the last
month, all you would need to do
is query all ‘Hot’ leads using
Contacts API and then use
Call-log APIs to get the logs of
those callers.
Call API
Call APIs are used to make outbound calls. These APIs can be used in two ways:
2. Running outbound campaign to multiple numbers at the same time (K-Broadcast)
While making multiple calls, the developer can do a plethora of customizations. Some of them are:
-
- defining call timings,
- setting priority while running multiple campaigns,
- scheduling the time,
- starting, pausing or stopping a campaign,
- adding phone numbers to a live campaign,
- selecting the number of concurrent calls to be made by the system
- defining the nature of a campaign - Transactional or Promotional - based on regulatory permitting limitations.**
- Getting a list of ongoing campaigns with their real-time status.
In short, call API helps you
save manual intervention and
organize communication for you
like never before.
**Please be noted that
Transactional campaigns are not
allowed by default due to legal
restrictions set by TRAI. If you
wish to avail this feature,
please get in touch with our
support team to help you get the
required clearance.
Notifications API
Notification APIs allow your
SuperReceptionist number to
receive notifications about any
live calls. Using this API,
developers can build highly
verbose applications (eg. two
users connected in a call can be
notified about the status of the
call).
The API uses a streaming API
that generates various events
(refer table below) which can be
monitored by developers. Each
event has a different call
status (eg.
ORIGINATE_AGENT_CALL, which
means the call has been
originated from the
SuperReceptionist web panel to
the agent’s number).
The developer can also set
specific actions for each of
these events (eg. For all HANGUP
statuses, the developer can send
a "Thank You" message).
This API facilitates the
development of an interactive
application, thereby leads to
improvement in user experience
and better relationship with
customers.
Get Agents List
/{channel}/v1/account/agent
Fetches list of agents for a given SR Account.
Request body
Header:
x-api-key:USERNAME:APPLICATION ACCESS KEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
Sample Response
Success 200:
[
{
"agent_status": "Available",
"call_groups": [],
"callcenter_role": "owner",
"first_name": "prashanth",
"id": "6xx793",
"last_name": "N"
},
{
"agent_status": "Logged Out",
"call_groups": [],
"callcenter_role": "agent",
"first_name": "Shivam",
"id": "7xx283",
"last_name": ""
}]
Get Agent Detail
/{channel}/v1/account/agent/ {id}
This API call fetches the details of an agent.
Request body
Header:
x-api-key:USERNAME:APPLICATION ACCESS KEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
Sample Response
Success 200:
{
"agent_status": "Available",
"call_groups": [
"-"
],
"callcenter_role": "owner",
"first_name": "prashanth",
"id": "615793",
"last_name": "N"
}
Get Task List
/{channel}/v1/account/tasks
Get List of tasks associated with SR Account.
Example
Javascript
var http = require("https");
var options = {
"method": "GET",
"hostname":"kpi.knowlarity.com",
"port": null,
"path":"/Basic/v1/account/tasks",
"headers": {
"channel": "Basic",
"x-api-key":"NRMPGxxxxxxxxxx7sa5xxxxxH768rxsDMlo",
"authorization":"046ccxxxxxxxxxx7sa5xxxxx0e9301",
"content-type":"application/json",
"cache-control":"no-cache",
}
};
var req =http.request(options, function(res) {
var chunks = [];
res.on("data", function(chunk) {
chunks.push(chunk);
});
res.on("end", function() {
var body =Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
Python
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/tasks"
payload = ""
headers = {
'channel': "Basic",
'x-api-key':"NRMPGEBxxxxxxxxxx7sa5xxxxx68rxsDMlo",
'authorization':"046cxxxxxxxxxx7sa5xxxxxcf20e9301",
'content-type':"application/json",
'cache-control':"no-cache",
}
response =requests.request("GET", url,data=payload, headers=headers)
print(response.text)
PHP
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/tasks",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_POSTFIELDS =>"",
CURLOPT_HTTPHEADER =>array(
"authorization:046cc3xxxxxxxxxx7sa5xxxxx7cf20e9301",
"cache-control:no-cache",
"channel: Basic",
"content-type:application/json",
"x-api-key:NRMPGEBxxxxxxxxxx7sa5xxxxxVH768rxsDMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization:USERNAME:SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
Sample Response
Success 200:
{
"meta": {
"limit": 1000,
"next": "",
"offset": "0",
"previous": "",
"total_count": "11"
},
"objects": [
{
"agent_id": "",
"call_missed_dt":"2016-06-17 16:18:21+00:00",
"callrecord_uuid":"0a4b6122-a48d-4d17-b40d-f4d9b267c5b9",
"completed_dt": "$None",
"completed_via": "",
"duedate": "",
"contact_id": "",
"created_by": "internal",
"created_dt": "2016-06-1716:18:21+00:00",
"id": 4369999,
"is_completed": false,
"modified_dt": "2016-06-1716:18:21+00:00",
"phone": "+261206350631",
"type": "missedcall"
}
]
}
Get Task Detail
/{channel}/v1/account/tasks/ {id}
Fetch a specific Task under an account
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/tasks/4591040"
payload = ""
headers = {
'channel': "Basic",
'x-api-key':"NRMPGxxxxxxxxxx7sa5xxxxxxsDMlo",
'authorization':"046cxxxxxxxxxx7sa5xxxxx0e9301",
'content-type':"application/json",
'cache-control':"no-cache",
}
response =requests.request("GET", url,data=payload, headers=headers)
print(response.text)
Javascript :
var http = require("https");
var options = {
"method": "GET",
"hostname":"kpi.knowlarity.com",
"port": null,
"path":"/Basic/v1/account/tasks/4591040",
"headers": {
"channel": "Basic",
"x-api-key":"NRMPGEBxxxxxxxxxx7sa5xxxxxVH768rxsDMlo",
"authorization":"046cc3xxxxxxxxxx7sa5xxxxx20e9301",
"content-type":"application/json",
"cache-control":"no-cache",
}
};
var req =http.request(options, function(res) {
var chunks = [];
res.on("data", function(chunk) {
chunks.push(chunk);
});
res.on("end", function() {
var body =Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/tasks/4591040",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_POSTFIELDS =>"",
CURLOPT_HTTPHEADER =>array(
"authorization:046cc3f4xxxxxxxxxx7sa5xxxxxf20e9301",
"cache-control:no-cache",
"channel: Basic",
"content-type:application/json",
"x-api-key:NRMPGEB9xxxxxxxxxx7sa5xxxxxH768rxsDMlo"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization:USERNAME:SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
Sample Response
Success 200:
{
"agent_id": "",
"call_missed_dt": "2016-06-1716:18:21+00:00",
"callrecord_uuid":"0a4b6122-a48d-4d17-b40d-f4d9b267c5b9",
"completed_dt": "$None",
"completed_via": "",
"duedate": "",
"contact_id": "",
"created_by": "internal",
"created_dt": "2016-06-1716:18:21+00:00",
"id": 4369999,
"is_completed": false,
"modified_dt": "2016-06-1716:18:21+00:00",
"phone": "+261206350631",
"type": "missedcall"
}
Make Outbound Call - (PSTN/WhatsApp)
https://kpi.knowlarity.com/{ channel} /v1/account/call/makecall
Establish a call between two
numbers (Agent and Customer).
The first call is placed to
agent number, and it is then
connects with the customer. In
the event where an agent misses
the call, no call is placed to
the customer number.
Note -
- To use the Make Call API, you need to register your SupreReceptionist number for receiving notifications from our Streaming API. On how to do this, please refer the Notifications API section on this page.
- If you are getting message that 'Agent Number not register with SR account' then check in your SR account -> settings -> plan settings, whether you have enabled 'Allowed agents Only', if yes then add the agent number there.
- caller_id field is optional.
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
Request Body:
{
"k_number":"+919069118xxx",
"agent_number":"+919069118xxx",
"customer_number":"+918861037xxx"
}
Additional Fields (for WhatsApp)
| Field | Type | Required | Description |
|---|---|---|---|
channel |
String | Required for WhatsApp, Optional for PSTN | Set to Whatsapp for WhatsApp Voice. |
call_permission_request |
Boolean string | Required for WhatsApp, Optional for PSTN | true or false — whether to request calling permission as part of the flow. |
Sample Response
Success: 200 OK
{
"success": {
"status": "success",
"message": "Callsuccessfully placed"
}
}
Error:
{
"error": {
"message": "Call Failed!Number 9876543210 in Do Not Callregistry."
}
}
or
{
"error": {
"message": "Invalid APIKey for this SR number"}
}
or
{
"error": {
"message": "Sent call permission request to customer. Please try calling after sometime"}
}
OTP Call - (PSTN/WhatsApp)
https://kpi.knowlarity.com/Basic/v1/account/otpcall
Triggers an OTP (one-time password) voice call over the WhatsApp channel using your Voice Console / Super Receptionist configuration. Use your SR auth key and API key in the headers.
Query parameters
| Parameter | Data Type | Required | Description |
|---|---|---|---|
ivr_id |
String | Yes | IVR or flow identifier (e.g. 100xxxxxxx). |
k_number |
String | Yes | Knowlarity / business number in E.164, URL-encoded (e.g. %2B91xxxxxxxxxx). |
customer_number |
String | Yes | Customer callee in E.164, URL-encoded. |
channel |
String | Required for WhatsApp, Optional for PSTN | Set to Whatsapp for WhatsApp Voice. |
call_permission_request |
Boolean string | Required for WhatsApp, Optional for PSTN | true or false — whether to request calling permission as part of the flow. |
Headers
| Header | Value |
|---|---|
x-api-key |
Your application access key |
Authorization |
Your SR API key |
Sample curl
curl --request GET \ --url "https://kpi.knowlarity.com/Basic/v1/account/otpcall?ivr_id=100xxxxxxx&k_number=%2B91xxxxxxxxxx&customer_number=%2B91xxxxxxxxxx&channel=Whatsapp&call_permission_request=true" \ --header "x-api-key: APPLICATION_ACCESSKEY" \ --header "Authorization: SR_API_KEY"
Sample Response (200 OK)
{
"success": {
"call_id": "abcd1234-5678-efgh-9012-ijklmnopqrst",
"message": "OTP call initiated successfully",
"status": "initiated"
}
}
Error Response (400)
{
"error": {
"message": "Not allowed to send call permission request."
}
}
or
{
"error": {
"message": "Sent call permission request to customer. Please try calling after sometime"
}
}
Enable/Disable Notifications
https://kpi.knowlarity.com/{ channel} /v1/account/notifications
Enable/Disable an Existing registered integration.
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/notifications"
payload = "\n{\n\"knowlarity_number\":\"+91906xxx1811\",\n\"enable\": \"enable\"\n}\n"
headers = {
'channel': "Basic",
'x-api-key':"mxoX4520Ih5xxxxxxxxxx7sa5xxxxx5QdC79PP",
'authorization':"84239xxxxxxxxxx7sa5xxxxx66beb27a027",
'content-type':"application/json",
'cache-control':"no-cache",
}
response =requests.request("PUT", url,data=payload, headers=headers)
print(response.text)
Javascript :
var http = require("https");
var options = {
"method": "PUT",
"hostname":"kpi.knowlarity.com",
"port": null,
"path":"/Basic/v1/account/notifications",
"headers": {
"channel": "Basic",
"x-api-key":"mxoX4520Ih5xxxxxxxxxxx7sa5xxxxxQdC79PP",
"authorization":"XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX",
"content-type":"application/json",
"cache-control":"no-cache",
}
};
var req =http.request(options, function(res) {
var chunks = [];
res.on("data", function(chunk) {
chunks.push(chunk);
});
res.on("end", function() {
var body =Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write(JSON.stringify({ knowlarity_number:'+91906xxx41811', enable:'enable' }));
req.end();
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/notifications",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "PUT",
CURLOPT_POSTFIELDS =>"\n{\n\"knowlarity_number\":\"+9190xxxx811\",\n\"enable\": \"enable\"\n}\n",
CURLOPT_HTTPHEADER =>array(
"authorization:8423xxxxxxxxxx7sa5xxxxxb27a027",
"cache-control:no-cache",
"channel: Basic",
"content-type:application/json",
"x-api-key:mxoX4520xxxxxxxxxx7sa5xxxxxQdC79PP"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
{
"knowlarity_number":"+919069118xxx",
"enable": "enable"
}
Sample Response
Success: 200
{
"message": "Successfullyenabled."
}
or
{
"message": "Successfullydisabled."
}
Error: 401 Unauthorized
{
"message": "Client name,authorization or knowlarity number iswrong.
}
Register for Notifications
https://kpi.knowlarity.com/{ channel} /v1/account/notifications
Register your SuperReceptionist number to start receiving live call notifications (Streaming API) for all incoming and outgoing calls.
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/notifications"
payload = "\n{\n\"knowlarity_number\": [\n \"+91XXXXXXXXXX\"\n ]\n}"
headers = {
'channel': "Basic",
'x-api-key':"mxoX452xxxxxxxxxxxxx7Jsa5xxxxx9PP",
'authorization':"842393ddxxxxxxxxxx7Jsa5xxxxx6beb27a027",
'content-type':"application/json",
'cache-control':"no-cache",
}
response =requests.request("POST", url,data=payload, headers=headers)
print(response.text)
Javascript :
var http = require("https");
var options = {
"method": "POST",
"hostname":"kpi.knowlarity.com",
"port": null,
"path":"/Basic/v1/account/notifications",
"headers": {
"channel": "Basic",
"x-api-key":"mxoX4520Ih5xxxxxxxxxx7Jsa5xxxxxZAq67Jsa5QdC79PP",
"authorization":"842393xxxxxxxxxx7Jsa5xxxxx9504-066beb27a027",
"content-type":"application/json",
"cache-control":"no-cache",
}
};
var req =http.request(options, function(res) {
var chunks = [];
res.on("data", function(chunk) {
chunks.push(chunk);
});
res.on("end", function() {
var body =Buffer.concat(chunks);
console.log(body.toString());
});
});
req.write(JSON.stringify({ knowlarity_number: ['+9190xxxx1811' ] }));
req.end();
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/notifications",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "POST",
CURLOPT_POSTFIELDS =>"\n{\n\"knowlarity_number\": [\n \"+9190xxxx1811\"\n ]\n}",
CURLOPT_HTTPHEADER =>array(
"authorization:842393xxxxxxxxxx7Jsa5xxxxx-066beb27a027",
"cache-control:no-cache",
"channel: Basic",
"content-type:application/json",
"x-api-key:mxoX4520Ixxxxxxxxxx7sa5xxxxxjCZAq67Jsa5QdC79PP"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
Request Body (raw JSON)
{
"knowlarity_number":["+91906911XXXX"]
}
Sample Response
Success: 200
{
"message": "Successfullyregistered."
}
Error: 400: bad request
{
"error": {
"knowlarity_number": "The knowlaritynumber(+91XXXXXXXXXX) or API key isinvalid."
}
}
Notifications (Streaming API)
https://konnect.knowlarity.com:8100/update-stream/ {SR_API_KEY}/konnect
Summary: Receive live call notifications for your registered SuperReceptionist number. Please see event descriptions above.
Computer-Telephony Integration (CTI)
SuperReceptionist provides CTI APIs for seamlessly integrating our cloud telephony with other applications. These APIs adds a lot to the agent's ability to respond to callers efficiently. At a minimum, these telephony events can be consumed to show relevant information on the agent's workstation whenever a call is delivered to the agent via telephone. A typical CTI application manages the event flow that is generated by the telephony API during the life cycle of a call. This typically proceeds along the following sequence:
| Term | Meaning |
|---|---|
| Agent | SuperReceptionist account owner or their employee(s) who will receive incoming calls to the SuperReceptionist number or make outbound calls to customers. |
| Customer | SuperReceptionist account owner's customers who are calling the SuperReceptionist number or receiving calls from it. |
| Events/Notifications | For each incoming/outgoing call, SuperReceptionist will generate notifications to inform what is happening with the call. These notifications can be used to display browser popups for incoming calls with the caller details, create call logs in the CRM etc. |
The event data is in JSON format and has the following fields.
| Field | Description |
|---|---|
| call_direction | Type of the call. It will be Inbound or Outbound. |
| business_call_type |
The value can be:
|
| agent_number | Agent's number. |
| call_recording | An URL to the audio file which contains the conversation between customer and agent. This URL will be available in bridge call for the event type 'HANGUP'. |
| uuid | It is an UUID number to uniquely identify the call. |
| customer_number | Your customer's phone number. For event type AGENT_CALL and AGENT_ANSWER, this field value will be null. |
| knowlarity_number | Your knowlarity number. |
| k_number | Your knowlarity number (deprecated). |
| event |
Type of the event. It can
be:
|
| application, called, k_api_key | Optional fields, should be ignored. |
CDR event data:
{
"business_call_type":"Unanswered",
"agent_number":"+91XXXXXXXXXX",
"call_recording":null,
, "call_type":null,
"uuid":"40eec284206dtf6d2d0e503c9877f9",
"customer_number":"+91XXXXXXXXXX",
"knowlarity_number":"+91XXXXXXXXXX",
"event_type":"ORIGINATE",
"called":"81XXXXXXXX"
}
Call Detail Record (CDR) event is generated at the end of a call after the agent/customer hangs up. Event fields are different from the actual telephony events and they described are below.
| Field | Description |
|---|---|
| Call_Type | "Incoming" or "Outgoing" |
| call_duration | Number of seconds from call launching to hangup |
| caller_id | Phone number of the agent(Outgoing) or customer (Incoming) |
| destination | Phone number of the customer(Outgoing) or agent (Incoming) |
| start_time | Start time of the telephone call |
| end_time | End time of the telephone call |
| dispnumber | SR Number or Virtual number purchased from Knowlarity |
| resource_url | Call recording link if there is bridged conversation |
| timezone_offset | The additional offset used to calculate UTC |
| uuid | It is an UUID number to uniquely identify the call. |
| type | CDR |
| business_call_type |
The values can be:
|
An example of CDR data can be like:
{
"dispnumber" :"+91XXXXXXXXXX",
"business_call_type" :"Phone",
"caller_id" :"+91XXXXXXXXXX",
"Call_Type" : "Incoming",
"start_time" :"2015-11-20 11:50:18+05:30",
"uuid" :"129ac15d-d8b4-499e-92e1-83317d1745df",
"call_duration" : 29,
"destination" :"+91XXXXXXXXXX",
"end_time" : "2015-11-2011:51:37.868542+05:30",
"resource_url" :"http://kservices.knowlarity.com/kstorage/read?uuid=6cd3bc78-3181-4e7d-aacf-daac580601a9_0_1_r.mp3&server_ip=124.7.51.154&base_dir=recording",
"type" : "CDR",
"timezone_offset" :"+0530"
}
Note: Please observe that for general events keyword for type is "event_type" and for CDR it is just "type".
Example
Python :
import requests
importsys
import traceback
while True:
try:
r =requests.get('https://konnect.knowlarity.com:8100/update-stream/{SR_API_KEY}/konnect',stream=True)
printr.status_code
if r.status_code== 200:
print'Connection Open'
for line inr.iter_lines():
if line:
printline
else:
printr.status_code, r.text
break
exceptKeyboardInterrupt:
sys.exit()
except:
traceback.format_exc()
print 'ConnectionClosed'
continue
Javascript :
URL ="https://konnect.knowlarity.com:8100/update-stream/{SR_API_KEY}/konnect"
source = newEventSource(URL);
source.onmessage = function(event) {
var data =JSON.parse(event.data)
console.log('Received anevent .......');
console.log(data);
}
Curl :
curl --get'https://konnect.knowlarity.com:8100/update-stream/{SR_API_KEY}/konnect'--verbose
Request body
Path Parameter: SR_API_KEY NoBody Required.
Sample Response
Stream events data in Json Format:
List Registrations
https://kpi.knowlarity.com/{ channel} /v1/account/notifications
List of SuperReceptionist number registered for notifications.
Example
Python :
import requests
importjson
url ="https://kpi.knowlarity.com/Basic/v1/account/notifications"
payload = ""
headers = {
'channel': "Basic",
'x-api-key':"mxoX452xxxxxxxxxx7sa5xxxxx7Jsa5QdC79PP",
'authorization':"XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX",
'content-type':"application/json",
'cache-control':"no-cache",
}
response =requests.request("GET", url,data=payload, headers=headers)
json_data =response.json()
#print(response.text)
Javascript :
var http = require("https");
var options = {
"method": "GET",
"hostname":"kpi.knowlarity.com",
"port": null,
"path":"/Basic/v1/account/notifications",
"headers": {
"channel": "Basic",
"x-api-key":"mxoX4520Ixxxxxxxxxx7sa5xxxxxq67Jsa5QdC79PP",
"authorization":"XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX",
"content-type":"application/json",
"cache-control":"no-cache",
}
};
var req =http.request(options, function(res) {
var chunks = [];
res.on("data", function(chunk) {
chunks.push(chunk);
});
res.on("end", function() {
var body =Buffer.concat(chunks);
console.log(body.toString());
});
});
req.end();
PHP :
$curl = curl_init();
curl_setopt_array($curl,array(
CURLOPT_URL =>"https://kpi.knowlarity.com/Basic/v1/account/notifications",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_POSTFIELDS =>"",
CURLOPT_HTTPHEADER =>array(
"authorization:842393xxxxxxxxxx7sa5xxxxx66beb27a027",
"cache-control:no-cache",
"channel: Basic",
"content-type:application/json",
"x-api-key:mxoX4520xxxxxxxxxx7sa5xxxxx67Jsa5QdC79PP"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
echo$response;
curl_close($curl);
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel:Basic,Advance,Premium,Enterprise
Request Body (raw JSON)
No Body required.
Query Params:
knowlarity_number: Filterresults using knowlarity number.
enabled: Filter results usingTrue or False.
Sample Response
Response 200:
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 1
},
"objects": [
{
"app_api_key": "",
"app_data": "{"username":"admin","password":"xxxxxxxx"}",
"app_type": {
"id": x,
"name": "SUGXXXCRM",
"resource_uri":"/api/v1/applications/x"
},
"app_url":"http://10.60.8.57/suitecrm/service/v4_1/rest.php",
"date_updated":"2015-08-06T12:33:56",
"enable": false,
"expired": false,
"id": xxx,
"k_api_key":"15e4xxxxxxxxxxxx1e4-bead-22000aaca33c",
"k_number":"+9190xxxxxxx780",
"k_number_cc": "IN",
"konnect_api_client":null,
"product": "SR",
"resource_uri":"/api/v1/integrations/xxx",
"user": {
"id": xx,
"resource_uri":"/api/v1/users/xx",
"username": "SR"
}
},]
}
Get Detailed Call Log
/{channel} /v1/account/call/get-detailed-call-log
Get Detailed Call Log API
Filters
| Parameter | Data Type | Description |
|---|---|---|
| uuid | String | DB id of the Call log |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/call/get-detailed-call-log?uuid={}"
payload = {}
headers = {
'authorization':"XXXXXX-XXXX-XXXX-XXXXXXXXX",
'x-api-key':"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
'Content-Type':"application/json"
}
response =requests.request("GET", url,headers=headers, data=payload)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/call/get-detailed-call-log?uuid={}",
"method": "GET",
"headers": {
"authorization":"XXXXXXX-XXXX-XXXX-XXXXXXX",
"x-api-key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"Content-Type":"application/json" }
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/call/get-detailed-call-log?uuid={}",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_FOLLOWLOCATION =>true,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "GET",
CURLOPT_HTTPHEADER =>array(
"authorization:XXXXXX-XXXX-XXXX-XXXXXXXXXX",
"x-api-key:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"Content-Type:application/json"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel: Basic
Sample Response
{
"message": {
"id": 0,
"unique_id": "1b6bb713-87e0-4fa6-XXXXX-XXXXXXXXXXX",
"caller": "+91803XXXXX30",
"called": "+91979XXXXX69",
"hangup_cause": 900,
"fs": "blrnextrafs88",
"priority": 7,
"ivr_refnum": 10000XXXXX,
"fs_chan_info": "sofia/80353XXXXX/09795XXXXX/",
"call_type": "outgoing",
"did_number": null,
"ref_uuid": null,
"start_time": "2023-08-16T13:38:06",
"end_time": "2023-08-16T13:38:32",
"pickup_time": "2023-08-16T13:38:18",
"hangup_time": "2023-08-16T13:38:32",
"posting_time": "2023-08-16T13:38:33",
"order_time": "2023-08-16T13:38:05",
"caller_in_fs": null,
"attempt_number": 1,
"events": {
"CALLERID_SYS": "+91979XXXXX69",
"execCtr": 0,
"direction": "_outgoing",
"SESSION_KNUMBER": "+91803XXXXX30",
"is_nginx_active": true,
"CUR_DEBUG_STAT": false,
"hungup_LegA": true,
"SESSION_ID_1_SYS": "1b6bb713-87e0-4fa6-XXXXX-XXXXXXXXXXX_0",
"hangup_time": "2023-08-16 13:38:31.922176",
"SESSION_ID_SYS": "1b6bb713-87e0-4fa6-XXXXX-XXXXXXXXXXX_0",
"exception_dict_sys": [],
"IVR_DISP_NUM_SYS": "+91803XXXXX30",
"ExceptionNode": "0002",
"answered": true,
"dtmf_1": "9",
"ACTION_ID_SYS": "1139",
"INCOMING_SYS": false,
"REF_NUM_SYS": "10000XXXXX",
"goto_system": {},
"preprocess_fs": "blrnextrafs98",
"start_time": "2023-08-16 13:38:06.394696",
"pickup_time": "2023-08-16 13:38:18.138337",
"CURPROCESS_SYS": "_run",
"app_params1": "None",
"app_params0": "+91979XXXXX69",
"runtime_debug_dict_sys": {},
"display_number": "+91803XXXXX30",
"INCALL_ANSWERED_SYS": true,
"client_meta_id": "14101XXXXX_XXXXX",
"IVR_FLOW": true,
"hangup_cause": 900,
"CUR_ACTION_ID": "1139",
"call_exec_status": true,
"total_exception_count": {},
"New_Hangup_Cause": "ANSWERED",
"caller": "+91803XXXXX30",
"SITE_LOCATION_SYS": "BANGALORE_NEXTRA",
"called": "+91979XXXXX69",
"unique_id": "1b6bb713-87e0-4fa6-XXXXX-XXXXXXXXXXX",
"group_to_publish": "jio_nextra",
"mydictionary_system": {
"key1": "value1",
"key2": {
"nested_key1": "nested_value1",
"nested_key2": "nested_value2"
},
"key3": [1, 2, 3, 4]
},
"pre_debug_dict_sys": {},
},
},
},
Get Call Log Records for New UI
/{channel} /v1/account/sr/calllog
Get Call Log Records for New UI API
Filters
| Parameter | Data Type | Description |
|---|---|---|
| start_time__gt | String | start_time Date range is limited to 3 months only. |
| start_time__lt | String | end_time Date range is limited to 3 months only. |
| limit | Integer | Maximum limit that can be passed is 200. If limit parameter is not passed in the payload: Default Limit is set to 20. |
| get_total | Boolean | For total count (boolean) - default is set to False. |
| campaign_id | String | For campaign id. For example : [1111,2222,3333,4444,5555] |
| solution_type | String | To select all solution type. For example : ["all","IBD","OBD","C2C","IBD_CC","sequential","predictive"] |
| action | String | For call action. |
| agent_number | String | For agent numbers. |
| agent_device | String | For calling mode. |
| agent_status | String | For agent status. |
| customer_status | String | For customer status. |
| disposition | String | For disposition. |
| duration__gt | Integer | For call duration. |
| duration__lt | Integer | For call duration. |
| call_status | String | For call status. |
| offset | Number | Count of records to be skip. Default value is 0. |
| customer__contains | String | For customer numbers |
Example
Python :
import requests
url ="https://kpi.knowlarity.com/Basic/v1/account/sr/calllog"
payload = json.dumps({
'start_time__gt': "2023-11-07 00:00:00",
'start_time__lt': "2023-12-06 13:26:19",
'limit': 10,
'offset': 10,
'customer__contains': "+9197957XXXXX",
}
headers = {
'Authorization':"XXXXXX-XXXX-XXXX-XXXXXXXXX",
'x-api-key':"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
'Content-Type':"application/json"
}
response =requests.request("POST", url,headers=headers, data=payload)
print(response.text)
Javascript :
var settings = {
"async": true,
"crossDomain": true,
"url":"https://kpi.knowlarity.com/Basic/v1/account/sr/calllog",
"method": "POST",
"headers": {
"authorization":"XXXXXXX-XXXX-XXXX-XXXXXXX",
"x-api-key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"Content-Type":"application/json"
},
"data": JSON.stringify({
"start_time__gt":"2023-11-07 00:00:00",
"start_time__lt":"2023-12-06 13:26:19"
"limit":10
'offset': 10,
'customer__contains': "+9197957XXXXX",
}
}
$.ajax(settings).done(function(response) {
console.log(response);
});
PHP :
"https://kpi.knowlarity.com/Basic/v1/account/sr/calllog",
CURLOPT_RETURNTRANSFER=> true,
CURLOPT_ENCODING =>"",
CURLOPT_MAXREDIRS =>10,
CURLOPT_TIMEOUT =>30,
CURLOPT_FOLLOWLOCATION =>true,
CURLOPT_HTTP_VERSION=> CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST=> "POST",
CURLOPT_POSTFIELDS =>{"'{"}
"start_time__gt:2023-11-07 00:00:00",
"start_time__lt:2023-12-06 13:26:19"
"limit:10"
'offset': 10,
'customer__contains': "+9197957XXXXX",
{"}'"},
CURLOPT_HTTPHEADER =>array(
"authorization:XXXXXX-XXXX-XXXX-XXXXXXXXXX",
"x-api-key:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"Content-Type:application/json"
),
));
$response =curl_exec($curl);
$err =curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" .$err;
} else {
echo $response;
}
Request body
Header:
x-api-key: APPLICATION ACCESSKEY
Authorization: SR_API_KEY
content-type :application/json
Path:
channel: Basic
Sample Response
{
"meta": {
"total_count": null,
"next": "forward##6568a83955bdd35f095e01e3##2023-11-30 15:20:00.365000__9a8684b8d6be5364e8bbb52395e115b390ef69c67a91c2c8db0c48c6dd85a9a6",
"limit": 10,
"previous": ""
},
"objects": [
{
"ref_call_uuid": "",
"destination": "Abandoned",
....
},
....
]
}
1. Introduction
WhatsApp Voice enables end-customers to initiate and receive calls via WhatsApp, creating a unified messaging and voice experience. Gupshup facilitates this capability through SIP (Session Initiation Protocol) integrations.
This guide provides the complete technical specifications for implementing WhatsApp Voice calls — both inbound (user-initiated) and outbound (agent-initiated) — through the Gupshup gateway.
2. Prerequisites
Before beginning the integration, ensure the following are in place:
| Requirement | Details |
|---|---|
| WABA Number | Active WhatsApp phone number configured on Gupshup (Console) |
| Enabling WA Voice | To be done by the Gupshup Team |
2.1 Client to provide SIP Details to Gupshup (For UIC)
| Item | Owner |
|---|---|
| SIP Endpoint (IP:Port) where inbound calls should be sent. See details below | Customer |
| WABA Number where WA Voice needs to be enabled | Customer |
| Sub-field | Mandatory | Type | Default |
|---|---|---|---|
host |
Yes | string | — |
port |
Yes | string | — |
sip_auth_username |
No | string | Blank |
sip_auth_password |
No | string | Blank |
force_tcp |
No | boolean | FALSE |
user |
Yes | string | — |
- host — The IP address or hostname of the server.
- port — The communication port (typically 5060 for UDP/TCP or 5061 for TLS).
- sip_auth_username — The credential used for SIP authentication.
- sip_auth_password — The password associated with the SIP user.
- force_tcp — If set to
true, forces the connection to use the TCP protocol. - user — This is the destination to which we will forward the call request. ex:
sip:<user@host:port>.
2.2 Gupshup to provide SIP details to Client (For BIC)
Your dialer must direct the SIP INVITE to:
sip:{{customer_number}}@wavoicetls.knowlarity.com:5072
2.3 Required Custom Headers (X-Headers)
To authenticate and route outbound calls through the Gupshup gateway, your dialer must include the following custom SIP headers in the initial INVITE:
| Header Name | Description | Placeholder |
|---|---|---|
X-waba_number |
Your unique WABA identification number | {{waba_number}} |
X-waba_password |
Your secure API/SIP password | {{waba_password}} |
3. Integration Checklist
Use this checklist to track your integration progress:
| # | Action | Owner |
|---|---|---|
| 1 | Provide WABA Number for WA Voice enablement | Customer |
| 2 | Provide SIP Endpoint for inbound calls - UIC → What You Need to Provide | Customer |
| 3 | Gupshup provides SIP Endpoint for outbound calls - BIC → Call Request Format | Gupshup |
| 4 | Configure Customer SIP endpoint for inbound calling (UIC) | Gupshup |
| 5 | Configure Gupshup SIP endpoint for outbound calling (BIC) → Example SIP INVITE | Customer |
| 6 | Whitelist IPs & domains in firewall → Network & Firewall Configuration | Customer |
| 7 | Open SIP (5072) and RTP (30000–40000) ports → Network & Firewall Configuration | Customer |
| 8 | Verify codec compatibility (Opus / G.711) → Media & RTP Requirements | Both |
| 9 | Test inbound calling end-to-end | Both |
| 10 | Test outbound calling end-to-end | Both |
| 11 | Test outbound calling with permissions flow | Both |
| 12 | Sign-off inbound calling | Customer |
| 13 | Sign-off outbound calling | Customer |
4. Network & Firewall Configuration
The following ports and addresses must be whitelisted in your firewall to allow SIP signalling and RTP media to flow between Gupshup and your dialer infrastructure.
4.1 Ports
| Protocol | Port(s) | Transport | Purpose |
|---|---|---|---|
| SIP Signalling | 5072 |
UDP (primary), TCP (optional) | Call setup / teardown |
| RTP Media | 30000–40000 |
UDP | Audio streams |
4.2 IP / Domain Whitelist — India
| Type | Value |
|---|---|
| IP Address | 35.154.159.246 |
| IP Address | 13.248.195.10 |
| Domain | wavoicetls.knowlarity.com |
Important: Ensure both outbound and inbound traffic to/from these addresses is permitted. Any blocking of SIP or RTP traffic will result in call failures or one-way audio.
5. Media & RTP Requirements
| Parameter | Value |
|---|---|
| Primary Codec | Opus/48000 (rtpmap:102 opus/48000/2) |
| Fallback Codec | PCMA/8000 (G.711) |
| Packetization Time | 20 ms |
| DTMF | rtpmap:126 telephone-event/8000 (RFC 4733) |
| Opus fmtp | maxaveragebitrate=20000; maxplaybackrate=16000; minptime=20; sprop-maxcapturerate=16000; useinbandfec=1 |
Sample SDP (Opus)
m=audio 34804 RTP/AVP 102 101 a=rtpmap:102 opus/48000/2 a=fmtp:102 useinbandfec=1; maxaveragebitrate=20000; maxplaybackrate=16000; sprop-maxcapturerate=16000; ptime=20; minptime=10; maxptime=40 a=rtpmap:101 telephone-event/48000 a=fmtp:101 0-15 a=ptime:20
6. SIP Configuration — User-Initiated (Inbound)
When a WhatsApp user initiates a call to your WABA number, Gupshup receives the call from the WhatsApp infrastructure and forwards it to your configured SIP endpoint as a standard SIP INVITE.
6.1 How It Works
- The WhatsApp user dials your WABA number from the WhatsApp app.
- The call is routed to Gupshup.
- Gupshup sends a SIP INVITE to your dialer's SIP endpoint.
- Your dialer rings the appropriate agent and answers the call.
- Audio flows over RTP between Gupshup and your dialer.
- Either party can terminate the call with a BYE.
6.2 Key Headers in Inbound INVITE
| Header | Description |
|---|---|
From |
The WhatsApp user's phone number (E.164 format) |
To |
The agent extension or routing destination on your dialer |
6.3 What You Need to Provide
| Item | Owner |
|---|---|
| SIP Endpoint (IP:Port) where inbound calls should be sent | Customer |
| WABA Number where WA Voice needs to be enabled | Customer |
| Sub-field | Mandatory | Type | Default |
|---|---|---|---|
host |
Yes | string | — |
port |
Yes | string | — |
sip_auth_username |
No | string | Blank |
sip_auth_password |
No | string | Blank |
force_tcp |
No | boolean | false |
- host — The IP address or hostname of the server.
- port — The communication port (typically 5060 for UDP/TCP or 5061 for TLS).
- sip_auth_username — The credential used for SIP authentication.
- sip_auth_password — The password associated with the SIP user.
- force_tcp — If set to
true, forces the connection to use the TCP protocol.
7. SIP Configuration — Business-Initiated (Outbound)
For outbound calls (agent-to-user), your dialer initiates a SIP INVITE toward the Gupshup gateway, which then routes the call to the WhatsApp user.
7.1 Call Request Format
Your dialer must direct the SIP INVITE to:
sip:{{customer_number}}@wavoicetls.knowlarity.com:5072
7.2 Required Custom Headers (X-Headers)
To authenticate and route outbound calls through the Gupshup gateway, your dialer must include the following custom SIP headers in the initial INVITE:
| Header Name | Description | Placeholder |
|---|---|---|
X-waba_number |
Your unique WABA identification number | {{waba_number}} |
X-waba_password |
Your secure API/SIP password | {{waba_password}} |
7.3 Example SIP INVITE
INVITE sip:{{customer_number}}@wavoicetls.knowlarity.com:5072 SIP/2.0
Via: SIP/2.0/UDP your-source-ip:port
From: <sip:{{waba_number}}@your-domain.com>;tag=12345
To: <sip:{{customer_number}}@wavoicetls.knowlarity.com>
X-waba_number: 91XXXXXXXXXX
X-waba_password: your_secure_password
Content-Type: application/sdp
8. Call Flow Diagrams
8.1 UIC Call Flow (User-Initiated)
The SIP message sequence for an inbound WhatsApp Voice call:
8.2 BIC Call Flow (Business-Initiated / Agent-Initiated)
The SIP message sequence for an outbound WhatsApp Voice call:
9. SIP Message Examples
9.1 BIC INVITE (Dialer → Gupshup)
INVITE sip:919XXXXXXXXX@wavoicetls.knowlarity.com:5072 SIP/2.0 Via: SIP/2.0/UDP <dialer-ip>:5090;report;branch=z9hG4bKxxxxxxx Max-Forwards: 69 From: "1001" <sip:1001@<dialer-ip>>;tag=xxxxxxx To: <sip:919XXXXXXXXX@wavoicetls.knowlarity.com:5072> Call-ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx CSeq: 105664876 INVITE Content-Type: application/sdp X-waba_number: 55XXXXXXXXXX X-waba_password: <your_secure_password>
9.2 UIC INVITE (Gupshup → Dialer)
INVITE sip:99xxxxxxxx@<dialer-ip>;transport=tcp SIP/2.0
Via: SIP/2.0/TCP 13.248.195.10:5072;rport;branch=z9hG4bK3tH8K4rK7Qp6j
Max-Forwards: 68
From: <sip:+9190xxxxxxxx@13.248.195.10>;tag=15BHc70UK50Xe
To: <sip:99xxxxxxxx@<dialer-ip>;transport=tcp>
Call-ID: 81xxxxxxxxxxxxxxxxxxxxxxxxxxx
CSeq: 113185150 INVITE
Contact: <sip:mod_sofia@13.248.195.10:5072;transport=tcp>
User-Agent: Gupshup-gs_sip/1.0
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE,
INFO, UPDATE, REGISTER, REFER, NOTIFY,
PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Type: application/sdp
Content-Disposition: session
X-FB-External-Domain: wa.meta.vc
x-wa-meta-wacid: wacid.IhggQUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
x-wa-meta-country-code: IN
X-WV-FROM: +9190xxxxxxxx
X-WV-TO: +9198xxxxxxxx
X-WV-CALLID: outgoing:wacid.IhggQUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-FS-Support: update_display,send_info
Remote-Party-ID: <sip:+9190xxxxxxxx@13.248.195.10>;party=calling;screen=yes;privacy=off
The inbound flow then follows the standard sequence: 100 Trying → 180 Ringing → 200 OK → ACK → RTP Audio → BYE → 200 OK.
10. Call Permissions
Before making an outbound call to a WhatsApp user, you must verify that the user has granted call permission. This is an enforced requirement.
10.1 Permission Flow
10.2 Key Notes
- Call permissions should be maintained at the CRM/LCM layer.
- It is not necessary to check permissions in real-time. Permissions can be checked in advance and stored in the CRM.
- Currently there is no batch API for checking call permissions.
- If there are no permissions, the system will return a
403SIP response (see Error Handling section).
10.3 End-to-End Outbound Integration Flow (with Permissions)
11. Error Handling & SIP Cause Codes
11.1 No Call Permission (403)
When a user has not granted call permission, a 403 Forbidden will be returned:
SIP/2.0 403 No Approved Call Permission Found
Action: Do not retry. Send a permission request to the user via Messaging API.
11.2 No Answer / No Internet (CANCEL)
When the WhatsApp user does not answer or is offline:
Reason: Q.850;cause=19;text="NO_ANSWER"
Action: Handle as a normal no-answer scenario. Retry later or follow your CRM's call-back logic.
11.3 Media Timeout (BYE with cause 500)
When the WhatsApp client terminates due to no media being received:
Reason: SIP;cause=500;text="WhatsApp client terminated the call due to not receiving any media for a long time."
Action: Verify that RTP media ports are open and that audio is flowing in both directions. Check firewall/NAT configuration.
11.4 Incompatible Destination (Q.850 cause=88)
Reason: Q.850;cause=88;text="INCOMPATIBLE_DESTINATION"
Action: Verify codec compatibility and SDP parameters.
12. Recordings & DTMF
12.1 Call Recording
- Recordings are done at the Customer's Dialer/Recorder infrastructure.
- Gupshup can also perform recording and provide the recording URL to the Customer.
- Each recording is mapped with a unique
Call-ID.
12.2 DTMF
- Gupshup supports in-band DTMF.
- DTMF tones are carried within the RTP media stream, not via SIP INFO messages.
- DTMF mapping:
rtpmap:101 telephone-event/48000withfmtp:101 0-15.
13. Frequently Asked Questions
General
Q: What is WhatsApp Voice calling?
A: WhatsApp Voice calling allows end-users to make and receive voice calls over WhatsApp. Gupshup acts as a SIP gateway between the WhatsApp infrastructure and your contact centre dialer.
Q: What codecs are supported?
A: The primary codec is Opus/48000. As a fallback, G.711 (PCMA/8000, PCMU/8000) is also supported.
Q: Are WhatsApp Voice calls regulated by TRAI (India)?
A: Currently, WhatsApp calls are not under TRAI guidelines. However, WhatsApp calls cannot be intermixed with PSTN calls.
Q: What happens if a PSTN call is made to a WABA number?
A: The telco treats the call as a normal PSTN call. It will be terminated to the dialer where the PSTN number is configured, and the dialer's calling logic will apply.
Q: Is there a limit on concurrent calls?
A: Yes, CPS (Calls Per Second) limits and concurrent call limits apply. Contact Gupshup for the specific limits applicable to your WABA.
SIP & Network
Q: What ports need to be open?
A: SIP signalling: UDP 5072 (TCP 5072 optional). RTP media: UDP 30000–40000.
Q: Which IPs/domains do I need to whitelist?
A: For India: 35.154.159.246, 13.248.195.10, and wavoicetls.knowlarity.com.
Q: How does DTMF work?
A: In-band DTMF is used. DTMF tones are carried within the RTP media stream (RFC 4733), not as separate SIP INFO messages.
Q: What happens if media ports are blocked?
A: If RTP ports (30000–40000) are blocked, you may experience one-way audio or the call may be terminated after a timeout with a cause=500 SIP error.
TLS / Security
Q: Is TLS supported for SIP signalling?
A: TLS is used on the upstream leg for SIP signalling. For the Gupshup-to-Customer leg, consult with Gupshup about enabling TLS/SRTP on your SIP trunk.
Q: Can SRTP be used for media encryption?
A: Yes, SRTP is supported. Recording can also be done over SRTP. Contact Gupshup to configure SRTP for your SIP trunk.
Call Permissions
Q: Do I need to check call permissions before every outbound call?
A: Not necessarily in real-time. Permissions can be checked in advance and cached in your CRM. Calls should only be placed to users who have already granted permission.
Q: What happens if I call a user without permission?
A: A 403 Forbidden SIP response will be returned indicating no approved call permission was found. This error is non-retryable.
Q: Is there a batch API for checking permissions?
A: Currently, there is no batch API. Permissions must be checked per-user.
Call Transfer & Routing
Q: Can calls be transferred to external numbers?
A: WhatsApp calls cannot be intermixed with PSTN calls. External number transfer is not supported in the standard flow.
Q: How is call routing handled?
A: Call routing is handled by the Customer's dialer. Gupshup passes custom header information in the SIP headers that can be used by the dialer for routing decisions.
Q: How can I pass metadata to the agent desktop?
A: Gupshup includes custom SIP headers (e.g., caller ID, display name) in the INVITE. Your dialer can extract these headers and display relevant metadata on the agent desktop.
Recordings
Q: Who handles call recording?
A: By default, recording is done at the Customer's Dialer/Recorder infrastructure. Gupshup can also perform the recording and provide a recording URL (at an additional cost).
Q: How are recordings identified?
A: Each recording is mapped using the unique Call-ID header present in every SIP session.
Chapter 1 — Quick Start Guide
This chapter walks you through setting up a working Voice AI agent connected to Knowlarity Voice Streaming. By the end you will have a live phone call being handled by your WebSocket server.
Prerequisites
- Knowlarity account with Voice Streaming enabled on your SR number
- Python 3.10 or later
- ngrok (free tier) — required for a public WSS URL during development
- API keys for Deepgram (STT), OpenAI (LLM), and Cartesia (TTS)
IMPORTANT: Voice Streaming must be explicitly enabled on your SR number. Contact your Knowlarity account manager before proceeding.
Setup Steps
Step 1 — Configure the IVR Stream Node
In Knowlarity IVR Studio, add a Stream Node to your IVR flow and set the following fields:
| Field | Value | Notes |
|---|---|---|
wss-url | wss://your-server.com/voice | Must use WSS. Use ngrok during development. |
sampling-rate | 16k | 16,000 Hz — compatible with all major AI services. |
metadata | leave default | Delivered as the first message on connect. |
Step 2 — Install dependencies
pip install fastapi uvicorn[standard] deepgram-sdk openai httpx python-dotenv
Step 3 — Configure environment variables
Create a .env file in your project directory:
DEEPGRAM_API_KEY=your_deepgram_key OPENAI_API_KEY=your_openai_key CARTESIA_API_KEY=your_cartesia_key CARTESIA_VOICE_ID=your_voice_uuid GREETING=Hello! How can I help you today? SYSTEM_PROMPT=You are a helpful voice assistant. Keep responses short. TRANSFER_NUMBER=+91XXXXXXXXXX AUDIO_CHUNK_MS=100
Step 4 — Start the server
uvicorn server:app --host 0.0.0.0 --port 8000
Step 5 — Expose via ngrok
In a second terminal:
ngrok http 8000
Copy the HTTPS URL from ngrok output and construct your WSS endpoint:
wss://abc123.ngrok-free.app/voice
Update the wss-url field in your IVR Stream Node with this value.
NOTE: The ngrok URL changes every time ngrok restarts on the free tier. For production, deploy on a fixed domain with a valid SSL certificate.
Step 6 — Make a test call
Dial the phone number linked to your SR number. You should see real-time log output:
[KNOWLARITY ] callid = abc123 [KNOWLARITY ] virtual_number = +91XXXXXXXXXX [KNOWLARITY ] customer_number = +91XXXXXXXXXX [KNOWLARITY ] call_type = inbound [KNOWLARITY ] Audio packet received | size=640 bytes [DEEPGRAM ] Transcript (final) | text="hello" [OPENAI ] Sentence | text="Hi there! How can I help?" [KNOWLARITY ] Chunk 1 sent | b64_size=4328 chars
Connection Flow
CRITICAL: Your server MUST send a playAudio event within a few seconds of Knowlarity connecting, or the stream will be terminated. Always send a greeting immediately on connect — before waiting for the caller to speak.
The expected connection sequence:
- Knowlarity opens a WSS connection to your endpoint.
- Knowlarity sends a metadata text frame with call details.
- Your server sends a greeting via
playAudioimmediately. - Knowlarity begins streaming the caller's audio as binary PCM frames.
- Your server processes speech and sends responses as
playAudioevents. - If the caller speaks while the bot is talking, your server sends
killAudioto interrupt.
Chapter 2 — Protocol Reference
This chapter provides a complete technical specification of the Knowlarity Voice Streaming WebSocket protocol, including all message formats and supported events.
Connection
| Property | Value |
|---|---|
| Protocol | WSS (Secure WebSocket) — plain WS is not accepted |
| Direction | Knowlarity connects to your server (you are the server) |
| Endpoint | Any path you choose, e.g. /voice |
| Concurrency | One WebSocket connection per active call |
Metadata Frame
The very first message Knowlarity sends after connecting is a text frame containing call metadata. All subsequent messages are binary audio frames.
{
'callid': '6ccf0a28-XXXX-XXXX-XXXXX-XXXXXXXXXXX',
'virtual_number': '+91XXXXXXXXXX',
'customer_number': '+91XXXXXXXXXX',
'call_type': 'inbound'
}
| Field | Type | Description |
|---|---|---|
callid | string | Unique identifier for this call. Use as your session key. |
virtual_number | string | The Knowlarity SR/virtual number that was dialled. |
customer_number | string | The caller's phone number in E.164 format. |
call_type | string | Type of call (e.g. inbound). |
PARSING NOTE: The metadata is delivered as a JSON-encoded string wrapping a Python-style single-quoted dict. Parse with json.loads() first, then ast.literal_eval() if the result is a string rather than a dict.
Incoming Audio Stream
After the metadata frame, Knowlarity streams the caller's audio continuously as binary WebSocket frames.
| Property | Value |
|---|---|
| Encoding | Linear PCM, 16-bit signed little-endian (pcm_s16le / linear16) |
| Channels | Mono (1 channel) |
| Sample rate | As configured in Stream Node: 8k / 16k / 24k / 32k / 48k Hz |
| Frame size | Typically 640 bytes (20 ms at 16 kHz) |
Outgoing Events
Your server controls the call by sending JSON text frames to Knowlarity.
playAudio
Play audio to the caller. Knowlarity queues events and plays them sequentially.
{
"type": "playAudio",
"data": {
"audioContentType": "wav",
"audioContent": "<base64-encoded WAV>"
}
}
LATENCY TIP: Send audio as multiple small playAudio events (e.g. 100 ms each) rather than one large payload. Knowlarity plays them back-to-back with no gap, and the caller hears audio as soon as the first chunk arrives.
killAudio
Stop the currently playing audio and clear all queued playAudio events. Used for barge-in.
{ "type": "killAudio" }
transfer
Transfer the call to a phone number.
{
"type": "transfer",
"data": { "destination": "+91XXXXXXXXXX" }
}
disconnect
Terminate the stream. The IVR continues to the next node after the Stream Node.
{ "type": "disconnect" }
playAudio — Audio Format Requirements
| Property | Required value |
|---|---|
| Container | WAV |
| Encoding | 16-bit PCM (pcm_s16le) |
| Channels | Mono (1 channel) |
| Sample rate | Must match the sampling-rate configured in the Stream Node |
| Wrapping | Base64-encoded, passed as the audioContent field |
Sampling Rate Reference
| Config value | Sample rate | Notes |
|---|---|---|
8k | 8,000 Hz | Narrowband telephony quality. Lowest bandwidth. |
16k | 16,000 Hz | Recommended. Wideband quality. Supported by all major STT/TTS services. |
24k | 24,000 Hz | High quality. Supported by Cartesia and Deepgram. |
32k | 32,000 Hz | Very high quality. Higher bandwidth requirement. |
48k | 48,000 Hz | Studio quality. Rarely required for telephony. |
Chapter 3 — Voice AI Integration Guide
This chapter covers how to build a production-quality Voice AI agent on top of Knowlarity Voice Streaming, including architecture, latency optimisation, and implementation patterns for the full STT → LLM → TTS pipeline.
Reference Architecture
Every component in the pipeline streams its output directly into the next stage — no buffering, no waiting for a complete response.
| # | Stage | Component | Output |
|---|---|---|---|
| 1 | Caller speaks | Knowlarity Stream Node | PCM audio streamed to WSS server |
| 2 | Speech to Text | Deepgram nova-2 (streaming) | Transcript (~200–400 ms) |
| 3 | Language Model | OpenAI gpt-4o-mini (streaming) | Response, sentence by sentence |
| 4 | Text to Speech | Cartesia sonic (SSE streaming) | PCM audio chunks (~300 ms first) |
| 5 | Audio playback | Knowlarity playAudio events | Caller hears response |
Recommended Services
| Function | Recommended service | Why |
|---|---|---|
| STT | Deepgram nova-2 | Streaming WebSocket API, low latency, high accuracy for telephony |
| LLM | OpenAI gpt-4o-mini | Fast, cost-effective, supports token streaming |
| TTS | Cartesia sonic-english | SSE streaming, very low time-to-first-audio, natural voice |
Time to First Audio (TTFA)
| Stage | Typical latency |
|---|---|
| Deepgram final transcript after speech ends | ~200–400 ms |
| OpenAI first sentence tokens | ~200–400 ms |
| Cartesia first SSE audio chunk | ~300–400 ms |
| Network and processing overhead | ~50–100 ms |
| Total — TTFA | ~800 ms – 1.2 s |
| Barge-in (interim transcript → killAudio) | ~300 ms |
Why stream at every layer?
Each layer must stream its output directly into the next — never wait for a complete response:
| Layer | Buffered approach (avoid) | Streaming approach (use) |
|---|---|---|
| STT | Record full utterance, then transcribe | Deepgram live: transcript in ~200 ms after speech ends |
| LLM | Wait for complete response (~800 ms+) | OpenAI stream=True: flush to TTS on each sentence |
| TTS | Wait for full audio file | Cartesia /tts/sse: chunks stream as generated |
| Playback | One large WAV payload | 100 ms WAV chunks: caller hears audio immediately |
Implementation Patterns
Pattern 1 — Send a greeting immediately on connect
Knowlarity will close the stream if your server does not send audio back within a few seconds. Generate and stream a greeting via TTS as soon as the WebSocket connects.
# On WebSocket connect — before any user speech: metadata = await websocket.receive_text() await stream_tts(call_id, 'Hello! How can I help you?', websocket)
Pattern 2 — Sentence-by-sentence LLM → TTS
Stream tokens from the LLM and flush to TTS at each sentence boundary. This starts audio playback before the LLM has finished the full response.
sentence_buf = ''
async for chunk in openai_stream:
token = chunk.choices[0].delta.content or ''
sentence_buf += token
if sentence_buf.rstrip().endswith(('.', '!', '?')) and len(sentence_buf) > 8:
await stream_tts(call_id, sentence_buf.strip(), websocket)
sentence_buf = ''
Pattern 3 — Stream TTS in 100 ms chunks
Use Cartesia's /tts/sse endpoint to receive raw PCM as it is generated. Buffer into 100 ms pieces, wrap in a WAV header, and send as playAudio events immediately.
# 100 ms of audio at 16 kHz 16-bit mono = 3,200 bytes
chunk_size = 16000 * 2 * 100 // 1000 # 3200 bytes
async for sse_line in cartesia_sse_stream:
pcm_buf.extend(base64.b64decode(sse_line['data']))
while len(pcm_buf) >= chunk_size:
wav = pcm_to_wav(pcm_buf[:chunk_size])
del pcm_buf[:chunk_size]
await websocket.send_text(json.dumps({
'type': 'playAudio',
'data': {'audioContentType': 'wav',
'audioContent': base64.b64encode(wav).decode()}
}))
Pattern 4 — Barge-in via interim transcripts
Trigger barge-in on Deepgram interim transcripts — the moment the caller starts speaking, not after they finish (~300 ms barge-in latency).
# Set barge_in_event when user starts speaking (interim transcript):
def on_transcript(_self, result, **_kwargs):
if result.is_final:
loop.call_soon_threadsafe(barge_in_event.clear)
asyncio.run_coroutine_threadsafe(queue.put(transcript), loop)
else:
loop.call_soon_threadsafe(barge_in_event.set)
# In AI pipeline — race response against barge-in:
done, _ = await asyncio.wait(
{response_task, get_task, barge_task},
return_when=asyncio.FIRST_COMPLETED
)
if barge_task in done and not response_task.done():
response_task.cancel()
await websocket.send_text(json.dumps({'type': 'killAudio'}))
Pattern 5 — Transfer to human agent via OpenAI function calling
Define a transfer_to_agent tool and pass it to OpenAI. The model decides when to transfer based on conversation context — no keyword matching required. Set TRANSFER_NUMBER in your environment to enable this feature.
TOOLS = [{
'type': 'function',
'function': {
'name': 'transfer_to_agent',
'description': 'Transfer to a human agent when the caller requests one.',
'parameters': {'type': 'object', 'properties': {}, 'required': []},
}
}] if TRANSFER_NUMBER else []
# After stream completes, check for tool call:
if finish_reason == 'tool_calls' and tool_name == 'transfer_to_agent':
await stream_tts(call_id, 'Transferring you now.', websocket)
await websocket.send_text(json.dumps({
'type': 'transfer', 'data': {'destination': TRANSFER_NUMBER}
}))
Conversation History
Maintain a conversation history list for the duration of the call and pass it with every LLM request. This allows the bot to reference earlier turns.
messages = [{'role': 'system', 'content': SYSTEM_PROMPT}]
# On each turn:
messages.append({'role': 'user', 'content': transcript})
messages.append({'role': 'assistant', 'content': full_reply})
Deepgram & Cartesia Configuration
Deepgram Configuration
LiveOptions(
model='nova-2',
language='en', # or 'hi' for Hindi
encoding='linear16',
sample_rate=16000, # match Stream Node sampling-rate
channels=1,
interim_results=True, # required for barge-in detection
)
Cartesia SSE vs REST
REST /tts/bytes | SSE /tts/sse (Recommended) | |
|---|---|---|
| Output | Full WAV file when generation completes | Raw PCM chunks as they are generated |
| Latency | High — wait for complete audio (1–2 s) | Low — first chunk in ~300 ms |
| Format | container: wav | container: raw, encoding: pcm_s16le |
| Use when | Not recommended for real-time calls | All real-time voice responses |
Chapter 4 — Troubleshooting Guide
This chapter covers the most common issues encountered when integrating with Knowlarity Voice Streaming, their root causes, and step-by-step resolutions.
Pre-flight Checklist
- Voice Streaming is enabled on your SR number
- Your server is running and reachable over a public WSS URL
- The
wss-urlin the IVR Stream Node matches your current server URL - The
sampling-ratein the Stream Node matches the sample rate in your code - All API keys in
.envare valid and not expired - No other process is occupying your server port
Common Issues
Issue 1 — Call disconnects immediately after connecting
Symptom: The server logs show ‘Connected’ but the call drops within 1–2 seconds.
Cause: No audio was sent back to Knowlarity within the connection timeout window.
Resolution: Send a greeting playAudio event immediately on connect:
# Immediately after receiving metadata: await stream_tts(call_id, 'Hello! How can I help you?', websocket)
IMPORTANT: This is the most common integration mistake. Never wait for the caller to speak before sending your first playAudio event.
Issue 2 — Metadata parse error
Symptom: Server logs ‘Failed to parse metadata’ with a JSON decode error.
Cause: The metadata frame uses Python-style single-quoted keys/values.
Resolution:
import ast, json
parsed = json.loads(raw_metadata)
if isinstance(parsed, dict):
metadata = parsed
elif isinstance(parsed, str):
metadata = ast.literal_eval(parsed)
else:
metadata = {}
Issue 3 — Server port already in use
Symptom: uvicorn fails to start with ‘address already in use’ error.
Cause: A previous server instance is still running on that port.
Resolution:
# macOS / Linux: kill -9 $(lsof -ti :8000) # Windows: netstat -ano | findstr :8000 taskkill /PID <pid> /F
Issue 4 — Caller hears silence
Symptom: The connection works and logs show activity, but the caller hears no audio.
Cause: WAV not in correct format, sample rate mismatch, or incorrect base64 encoding.
Resolution: Verify your WAV output:
import wave, io
with wave.open(io.BytesIO(your_wav_bytes)) as wf:
print('channels:', wf.getnchannels()) # must be 1
print('bit depth:', wf.getsampwidth()) # must be 2 (16-bit)
print('sample rate:', wf.getframerate()) # must match Stream Node
Issue 5 — High response latency (2–4 seconds)
Symptom: The bot responds but there is a long delay before the caller hears anything.
Cause:
- Using Cartesia
/tts/bytes(waits for the full audio file) instead of/tts/sse - Sending the entire LLM response to TTS instead of sentence-by-sentence
- Sending one large
playAudioWAV instead of small chunks
Resolution:
- Use Cartesia
/tts/ssefor streaming TTS output - Use OpenAI
stream=Trueand flush to TTS at each sentence boundary (. ! ?) - Send audio as 100 ms WAV chunks via sequential
playAudioevents
Issue 6 — Deepgram connection timeout
Symptom: Deepgram closes the connection with error code 1011.
Cause: No audio was forwarded to Deepgram within its timeout window.
Resolution: Ensure every binary frame from Knowlarity is forwarded to Deepgram:
if data.get('bytes'):
dg_connection.send(data['bytes'])
Issue 7 — ngrok URL changed, server unreachable
Symptom: Previously working integration stops receiving calls with no server-side activity.
Cause: ngrok free tier generates a new URL on each restart. The IVR Stream Node still points to the old URL.
Resolution:
- Run
ngrok http 8000to get the new URL. - In IVR Studio, update the
wss-urlfield in the Stream Node. - Save the IVR flow.
TIP: For production deployments, use a fixed domain with a valid SSL certificate to avoid this issue entirely.
Issue 8 — WebSocket connection refused (403 or 404)
Symptom: Knowlarity cannot connect — HTTP 403 or 404 response.
Cause:
- 404: The endpoint path in
wss-urldoes not match the server's WebSocket route - 403: A stale server process is running with different routes
Resolution:
- Confirm the path in
wss-urlexactly matches the@app.websocket()route in your server - Stop all processes on the port and restart the server cleanly
Log Reference & Support
All log lines follow this structure:
TIMESTAMP [call_id=X] [COMPONENT] message
| Component | What it covers |
|---|---|
KNOWLARITY | Connection events, metadata, incoming audio packets, outgoing audio chunks |
DEEPGRAM | Interim and final transcripts, connection errors |
OPENAI | Stream requests, sentence flushes, tool calls, completion |
CARTESIA | TTS stream requests, SSE chunks received, stream summary |
Getting Support
If the issue persists after following this guide:
- Collect the full server log from the failing call
- Note the
call_id— it correlates with the Knowlarity CDR - Contact Knowlarity developer support with the logs and your integration details