V 2.0

Call Disposition Analysis

Call Disposition Analysis API

Description

The Call Disposition Analysis API provides endpoints for analyzing call dispositions and agent statistics in a call center environment. This API allows users to retrieve detailed information about call outcomes, agent performance, and various metrics related to call dispositions.

Key features:

  1. Analyze call dispositions across different parameters
  2. Retrieve agent-specific performance statistics
  3. Apply filters to narrow down data analysis
  4. Support for various breakdown options (e.g., by call type, campaign, agent)

The API uses Elasticsearch for efficient data retrieval and aggregation, ensuring fast and accurate results even with large datasets.

Error Codes

The API uses the following error codes from the SarvErrors module:

Error Code Message Description
1502 Invalid filter value The filter value provided is not valid

These error codes are used consistently across all endpoints in the API to provide clear and specific feedback on various error conditions that may occur during API calls.

Call Stats

{{brand}}/api/v2/callDispositionAnalysis/stats

Endpoint

Description

The POST /stats/ endpoint is a sophisticated API interface designed for comprehensive call disposition analytics. It provides organizations with powerful data retrieval and analysis capabilities for call center performance tracking. This endpoint allows users to extract granular insights about call outcomes, enabling data-driven decision-making in contact center operations.

Key Features

Detailed Endpoint Specification

1. Authentication Parameters

Parameter Type Required Description
s string Conditional Session ID for authentication
userId string Conditional User identifier for authentication
token string Conditional Authentication token

Authentication Rules:

2. Request Configuration Parameters

Parameter Type Optional Description
analysisby string Yes Breakdown field for analysis (e.g., "callType", "campId")
filter object Yes Advanced data filtering options

3. Filter Options

Filter Key Purpose Value Type Example
date Time-based filtering Timestamp range Start and end timestamps
campId Campaign-specific filtering Campaign ID Specific campaign metrics
ivrArr IVR-based filtering IVR Identifier Interactive Voice Response analysis
did Direct Inward Dialing filter DID Number Specific phone number analysis
callStatus Call outcome filtering Status value Completed, Missed, etc.
callType Call classification Type value Inbound, Outbound

4. Response Structure

Key Type Description
status string Request processing status
code number HTTP status code
data.clDispoData array Call disposition records
key string Disposition identifier
doc_count number Total matching records
dispoCount.value number Aggregated disposition count

Technical Specifications

Error Handling

Use Cases

  1. Performance tracking

  2. Call center analytics

  3. Campaign effectiveness measurement

  4. Disposition trend analysis

Best Practices

Call Stats

var axios = require('axios');
var data = '{"s":"{{ssid1}}"}';

var config = {
 method: 'post',
 url: '{{brand}}/api/v2/callDispositionAnalysis/stats',
 headers: { 
'Content-Length': ''
 },
 data : data
};

axios(config)
.then(function (response) {
 console.log(JSON.stringify(response.data));
})
.catch(function (error) {
 console.log(error);
});
setUrl('{{brand}}/api/v2/callDispositionAnalysis/stats');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
 'follow_redirects' => TRUE
));
$request->setHeader(array(
 'Content-Length' => ''
));
$request->setBody('{"s":"{{ssid1}}"}');
try {
 $response = $request->send();
 if ($response->getStatus() == 200) {
echo $response->getBody();
 }
 else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
 }
}
catch(HTTP_Request2_Exception $e) {
 echo 'Error: ' . $e->getMessage();
}
import http.client

conn = http.client.HTTPSConnection("{{brand}}")
payload = "{\"s\":\"{{ssid1}}\"}"
headers = {
 'Content-Length': ''
}
conn.request("POST", "/api/v2/callDispositionAnalysis/stats", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
var client = new RestClient("{{brand}}/api/v2/callDispositionAnalysis/stats");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
var body = @"{" + "\n" +
@"    ""s"":""{{ssid1}}""" + "\n" +
@"" + "\n" +
@"}";
request.AddParameter("text/plain", body,  ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
curl --location -g --request POST '{{brand}}/api/v2/callDispositionAnalysis/stats' \
--data-raw '{
    "s":"{{ssid1}}"

}'
var request = http.Request('POST', Uri.parse('{{brand}}/api/v2/callDispositionAnalysis/stats'));
request.body = '''{\n    "s":"{{ssid1}}"\n\n}''';

http.StreamedResponse response = await request.send();

if (response.statusCode == 200) {
   print(await response.stream.bytesToString());
}
else {
   print(response.reasonPhrase);
}
package main

import (
   "fmt"
   "strings"
   "net/http"
   "io/ioutil"
)

func main() {

   url := "%7B%7Bbrand%7D%7D/api/v2/callDispositionAnalysis/stats"
   method := "POST"

   payload := strings.NewReader(`{
    "s":"{{ssid1}}"

}`)

   client := &http.Client {
   }
   req, err := http.NewRequest(method, url, payload)

   if err != nil {
      fmt.Println(err)
      return
   }
   res, err := client.Do(req)
   if err != nil {
      fmt.Println(err)
      return
   }
   defer res.Body.Close()

   body, err := ioutil.ReadAll(res.Body)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(string(body))
}
POST /api/v2/callDispositionAnalysis/stats HTTP/1.1
Host: {{brand}}
Content-Length: 24

{
    "s":"{{ssid1}}"

}
OkHttpClient client = new OkHttpClient().newBuilder()
   .build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType, "{\n    \"s\":\"{{ssid1}}\"\n\n}");
Request request = new Request.Builder()
   .url("{{brand}}/api/v2/callDispositionAnalysis/stats")
   .method("POST", body)
   .addHeader("Content-Length", "")
   .build();
Response response = client.newCall(request).execute();
var myHeaders = new Headers();
myHeaders.append("Content-Length", "");

var raw = "{\n    \"s\":\"{{ssid1}}\"\n\n}";

var requestOptions = {
   method: 'POST',
   headers: myHeaders,
   body: raw,
   redirect: 'follow'
};

fetch("{{brand}}/api/v2/callDispositionAnalysis/stats", requestOptions)
   .then(response => response.text())
   .then(result => console.log(result))
   .catch(error => console.log('error', error));
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
   curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
   curl_easy_setopt(curl, CURLOPT_URL, "%7B%7Bbrand%7D%7D/api/v2/callDispositionAnalysis/stats");
   curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
   curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
   struct curl_slist *headers = NULL;
   headers = curl_slist_append(headers, "Content-Length: ");
   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
   const char *data = "{\n    \"s\":\"{{ssid1}}\"\n\n}";
   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
   res = curl_easy_perform(curl);
}
curl_easy_cleanup(curl);
#import 

dispatch_semaphore_t sema = dispatch_semaphore_create(0);

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"%7B%7Bbrand%7D%7D/api/v2/callDispositionAnalysis/stats"]
   cachePolicy:NSURLRequestUseProtocolCachePolicy
   timeoutInterval:10.0];
NSDictionary *headers = @{
   @"Content-Length": @""
};

[request setAllHTTPHeaderFields:headers];
NSData *postData = [[NSData alloc] initWithData:[@"{\n    \"s\":\"{{ssid1}}\"\n\n}" dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postData];

[request setHTTPMethod:@"POST"];

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
   if (error) {
      NSLog(@"%@", error);
      dispatch_semaphore_signal(sema);
   } else {
      NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
      NSError *parseError = nil;
      NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
      NSLog(@"%@",responseDictionary);
      dispatch_semaphore_signal(sema);
   }
}];
[dataTask resume];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
open Lwt
open Cohttp
open Cohttp_lwt_unix

let postData = ref "{\n    \"s\":\"{{ssid1}}\"\n\n}";;

let reqBody = 
   let uri = Uri.of_string "%7B%7Bbrand%7D%7D/api/v2/callDispositionAnalysis/stats" in
   let headers = Header.init ()
      |> fun h -> Header.add h "Content-Length" ""
   in
   let body = Cohttp_lwt.Body.of_string !postData in

   Client.call ~headers ~body `POST uri >>= fun (_resp, body) ->
   body |> Cohttp_lwt.Body.to_string >|= fun body -> body

let () =
   let respBody = Lwt_main.run reqBody in
   print_endline (respBody)
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Length", "")

$body = "{`n    `"s`":`"{{ssid1}}`"`n`n}"

$response = Invoke-RestMethod '{{brand}}/api/v2/callDispositionAnalysis/stats' -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Json
require "uri"
require "net/http"

url = URI("{{brand}}/api/v2/callDispositionAnalysis/stats")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Length"] = ""
request.body = "{\n    \"s\":\"{{ssid1}}\"\n\n}"

response = http.request(request)
puts response.read_body
printf '{
    "s":"{{ssid1}}"

}'| http  --follow --timeout 3600 POST '{{brand}}/api/v2/callDispositionAnalysis/stats' \
 Content-Length:
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

var semaphore = DispatchSemaphore (value: 0)

let parameters = "{\n    \"s\":\"{{ssid1}}\"\n\n}"
let postData = parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "{{brand}}/api/v2/callDispositionAnalysis/stats")!,timeoutInterval: Double.infinity)
request.addValue("", forHTTPHeaderField: "Content-Length")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in 
   guard let data = data else {
      print(String(describing: error))
      semaphore.signal()
      return
   }
   print(String(data: data, encoding: .utf8)!)
   semaphore.signal()
}

task.resume()
semaphore.wait()

Example Response

 [{"key":"Date"
"value":"Thu
 28 Nov 2024 12:36:52 GMT"}
{"key":"Content-Type"
"value":"application\/json; charset=utf-8"}
{"key":"Content-Length"
"value":"62"}
{"key":"Connection"
"value":"keep-alive"}
{"key":"Access-Control-Allow-Origin"
"value":"*"}
{"key":"Access-Control-Allow-Methods"
"value":"POST
 GET
 OPTIONS
 PATCH
 DELETE"}
{"key":"Access-Control-Allow-Headers"
"value":"X-Requested-With
content-type"}
{"key":"Access-Control-Allow-Credentials"
"value":"true"}
{"key":"Vary"
"value":"Origin"}
{"key":"ETag"
"value":"W\/\"3e-TwBGyQMfRf+WmNeeEv6YcZdunOQ\""}
{"key":"Strict-Transport-Security"
"value":"max-age=31536000; includeSubDomains"}]
 {
    "status": "error",
    "message": "Invalid credentials",
    "code": 1011
}