Skip to main content

roark_rs/apis/
call_analysis_api.rs

1/*
2 * Roark Analytics API
3 *
4 * # Roark Analytics API - Voice AI Analytics Platform  The Roark Analytics API provides comprehensive monitoring, evaluation, and analytics capabilities for voice AI agents. This API allows developers to seamlessly integrate with the Roark platform to track call quality, analyze agent performance, and extract insights from voice interactions.  ## Key Features  - **Real-time Call Analysis**: Upload and analyze voice call recordings with AI-powered insights - **Sentiment Analysis**: Extract emotional tone, key phrases, and sentiment scores across 64+ emotions - **Agent Performance Evaluation**: Create custom evaluation jobs with configurable metrics and scoring - **Platform Integrations**: Native support for VAPI and Retell AI with webhook-based data ingestion - **Custom Analytics**: Build custom analytics pipelines with flexible data models and properties  ## Authentication  All API endpoints require Bearer token authentication. Include your API token in the Authorization header:  ``` Authorization: Bearer YOUR_API_TOKEN ```  ## Rate Limiting  The API implements rate limiting to ensure service stability. Rate limit headers are included in responses.  ## Error Handling  The API uses standard HTTP status codes and returns structured error responses with detailed error information including error types, codes, and human-readable messages.  ## Rust Code Generation  This OpenAPI specification has been optimized for Rust code generation with: - Snake_case field naming conventions - Proper nullable field handling with Option<T> - Comprehensive documentation for generated code - Type-safe enum definitions - Structured error handling
5 *
6 * The version of the OpenAPI document: 1.0.0
7 * Contact: support@roark.ai
8 * Generated by: https://openapi-generator.tech
9 */
10
11
12use reqwest;
13use serde::{Deserialize, Serialize, de::Error as _};
14use crate::{apis::ResponseContent, models};
15use super::{Error, configuration, ContentType};
16
17
18/// struct for typed errors of method [`create_call_analysis_job`]
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(untagged)]
21pub enum CreateCallAnalysisJobError {
22    Status400(models::ErrorResponse),
23    Status401(models::ErrorResponse),
24    Status403(models::ErrorResponse),
25    Status429(models::ErrorResponse),
26    Status500(models::ErrorResponse),
27    UnknownValue(serde_json::Value),
28}
29
30/// struct for typed errors of method [`get_call_analysis_job`]
31#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(untagged)]
33pub enum GetCallAnalysisJobError {
34    Status401(models::ErrorResponse),
35    Status403(models::ErrorResponse),
36    Status404(models::ErrorResponse),
37    Status429(models::ErrorResponse),
38    Status500(models::ErrorResponse),
39    UnknownValue(serde_json::Value),
40}
41
42
43/// Upload a call recording and create an analysis job to extract insights, transcripts, and metadata from the audio.
44pub async fn create_call_analysis_job(configuration: &configuration::Configuration, call_analysis_create_request: models::CallAnalysisCreateRequest) -> Result<models::CreateCallAnalysisJob201Response, Error<CreateCallAnalysisJobError>> {
45    // add a prefix to parameters to efficiently prevent name collisions
46    let p_call_analysis_create_request = call_analysis_create_request;
47
48    let uri_str = format!("{}/v1/call-analysis", configuration.base_path);
49    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
50
51    if let Some(ref user_agent) = configuration.user_agent {
52        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
53    }
54    if let Some(ref token) = configuration.bearer_access_token {
55        req_builder = req_builder.bearer_auth(token.to_owned());
56    };
57    req_builder = req_builder.json(&p_call_analysis_create_request);
58
59    let req = req_builder.build()?;
60    let resp = configuration.client.execute(req).await?;
61
62    let status = resp.status();
63    let content_type = resp
64        .headers()
65        .get("content-type")
66        .and_then(|v| v.to_str().ok())
67        .unwrap_or("application/octet-stream");
68    let content_type = super::ContentType::from(content_type);
69
70    if !status.is_client_error() && !status.is_server_error() {
71        let content = resp.text().await?;
72        match content_type {
73            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
74            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::CreateCallAnalysisJob201Response`"))),
75            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::CreateCallAnalysisJob201Response`")))),
76        }
77    } else {
78        let content = resp.text().await?;
79        let entity: Option<CreateCallAnalysisJobError> = serde_json::from_str(&content).ok();
80        Err(Error::ResponseError(ResponseContent { status, content, entity }))
81    }
82}
83
84/// Retrieve the status and results of a call analysis job by its unique identifier.
85pub async fn get_call_analysis_job(configuration: &configuration::Configuration, job_id: &str) -> Result<models::CreateCallAnalysisJob201Response, Error<GetCallAnalysisJobError>> {
86    // add a prefix to parameters to efficiently prevent name collisions
87    let p_job_id = job_id;
88
89    let uri_str = format!("{}/v1/call-analysis/{job_id}", configuration.base_path, job_id=crate::apis::urlencode(p_job_id));
90    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
91
92    if let Some(ref user_agent) = configuration.user_agent {
93        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
94    }
95    if let Some(ref token) = configuration.bearer_access_token {
96        req_builder = req_builder.bearer_auth(token.to_owned());
97    };
98
99    let req = req_builder.build()?;
100    let resp = configuration.client.execute(req).await?;
101
102    let status = resp.status();
103    let content_type = resp
104        .headers()
105        .get("content-type")
106        .and_then(|v| v.to_str().ok())
107        .unwrap_or("application/octet-stream");
108    let content_type = super::ContentType::from(content_type);
109
110    if !status.is_client_error() && !status.is_server_error() {
111        let content = resp.text().await?;
112        match content_type {
113            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
114            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::CreateCallAnalysisJob201Response`"))),
115            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::CreateCallAnalysisJob201Response`")))),
116        }
117    } else {
118        let content = resp.text().await?;
119        let entity: Option<GetCallAnalysisJobError> = serde_json::from_str(&content).ok();
120        Err(Error::ResponseError(ResponseContent { status, content, entity }))
121    }
122}
123