Complete Workflow Examples
End-to-end code examples in multiple languages
This guide provides complete, copy-pasteable examples for the full ComsWise workflow:
- Upload Audio: Get a signed URL and upload your file.
- Create Call: Register the call for processing.
- Poll for Results: Wait for the transcript to be ready.
- Retrieve Data: Download the final transcript and summary.
The API supports two ways to associate calls:
- Grouping ID (Recommended): Use an external ID (like a Ticket ID or CRM Lead ID) to automatically group related calls.
- Phone Numbers: Explicitly provide
fromandtonumbers if you don't have a grouping ID.
Method 1: Using Grouping ID (Recommended)
Use groupingId to thread conversations automatically.
import requests
import time
import json
import os
import sys
import uuid
from datetime import datetime, timezone
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.comswise.in/v1"
FILE_PATH = "call_recording.wav"
headers = {"Authorization": f"Bearer {API_KEY}"}
def main():
try:
# 1. Get Presigned Upload URL
print("Requesting upload URL...")
req_payload = {
"fileName": os.path.basename(FILE_PATH),
"contentType": "audio/wav"
}
resp = requests.post(f"{BASE_URL}/upload/request", json=req_payload, headers=headers)
resp.raise_for_status()
upload_data = resp.json()
upload_url = upload_data["uploadUrl"]
file_key = upload_data["fileKey"]
# 2. Upload File
print(f"Uploading {FILE_PATH}...")
with open(FILE_PATH, 'rb') as f:
upload_resp = requests.put(upload_url, data=f, headers={"Content-Type": "audio/wav"})
upload_resp.raise_for_status()
# 3. Create Call
print("Creating call record...")
# Note: Provide your own internal unique ID for the call
external_call_id = f"call-{uuid.uuid4()}"
current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
call_payload = {
"callId": external_call_id,
"direction": "inbound",
"groupingId": "ticket-12345", # Use groupingId for conversation threading
"startTime": current_time,
"recordingUrl": file_key
}
create_resp = requests.post(f"{BASE_URL}/calls/create", json=call_payload, headers=headers)
create_resp.raise_for_status()
call_id = create_resp.json()["id"]
print(f"Call created! ID: {call_id}")
# 4. Poll for Result
print("Waiting for processing...")
while True:
status_resp = requests.get(f"{BASE_URL}/calls/{call_id}", headers=headers)
status_resp.raise_for_status()
call_data = status_resp.json()
transcript = call_data.get("transcript")
if transcript and transcript["status"] == "ready":
print("\nProcessing Complete!")
print(f"Summary: {call_data.get('executiveSummary')}")
print(f"Download Transcript: {transcript['transcriptUrl']}")
break
elif transcript and transcript["status"] == "failed":
print("Processing Failed.")
print(f"Error: {transcript.get('error')}")
break
time.sleep(5)
except requests.exceptions.HTTPError as err:
print(f"\n[API Error]: {err}")
if err.response is not None:
print(f"Server Response: {err.response.text}")
sys.exit(1)
except Exception as e:
print(f"\n[Unexpected Error]: {e}")
sys.exit(1)
if __name__ == "__main__":
main()using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
private static readonly HttpClient client = new HttpClient();
private const string ApiKey = "YOUR_API_KEY";
private const string BaseUrl = "https://api.comswise.in/v1";
static async Task Main(string[] args)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ApiKey);
string filePath = "call_recording.wav";
try
{
// 1. Get Presigned Upload URL
Console.WriteLine("Requesting upload URL...");
var uploadReq = new { fileName = Path.GetFileName(filePath), contentType = "audio/wav" };
var uploadResp = await PostJsonAsync($"{BaseUrl}/upload/request", uploadReq);
string uploadUrl = uploadResp.GetProperty("uploadUrl").GetString();
string fileKey = uploadResp.GetProperty("fileKey").GetString();
// 2. Upload File
Console.WriteLine("Uploading file...");
using (var fileStream = File.OpenRead(filePath))
{
var content = new StreamContent(fileStream);
content.Headers.ContentType = new MediaTypeHeaderValue("audio/wav");
var putResp = await client.PutAsync(uploadUrl, content);
putResp.EnsureSuccessStatusCode();
}
// 3. Create Call
Console.WriteLine("Creating call...");
// Note: Provide your own internal unique ID for the call
string externalCallId = $"call-{Guid.NewGuid()}";
string currentTime = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
var callReq = new
{
callId = externalCallId,
direction = "inbound",
groupingId = "ticket-12345",
startTime = currentTime,
recordingUrl = fileKey
};
var createResp = await PostJsonAsync($"{BaseUrl}/calls/create", callReq);
string callId = createResp.GetProperty("id").GetString();
Console.WriteLine($"Call Created: {callId}");
// 4. Poll for Completion
while (true)
{
await Task.Delay(5000);
var statusResp = await GetJsonAsync($"{BaseUrl}/calls/{callId}");
if (statusResp.TryGetProperty("transcript", out var transcript))
{
string status = transcript.GetProperty("status").GetString();
if (status == "ready")
{
Console.WriteLine("\nDone!");
Console.WriteLine($"Transcript URL: {transcript.GetProperty("transcriptUrl").GetString()}");
break;
}
else if (status == "failed")
{
Console.WriteLine("\nProcessing Failed.");
if (transcript.TryGetProperty("error", out var error))
Console.WriteLine($"Error: {error.GetString()}");
break;
}
}
}
}
catch (HttpRequestException e)
{
Console.WriteLine($"\n[API Error]: {e.Message}");
// Note: In .NET 5+ use e.StatusCode to inspect 409 etc.
}
catch (Exception e)
{
Console.WriteLine($"\n[Error]: {e.Message}");
}
}
private static async Task<JsonElement> PostJsonAsync(string url, object data)
{
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
if (!response.IsSuccessStatusCode)
{
var errorContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Server Error ({response.StatusCode}): {errorContent}");
response.EnsureSuccessStatusCode(); // Re-throw
}
var respString = await response.Content.ReadAsStringAsync();
return JsonDocument.Parse(respString).RootElement;
}
private static async Task<JsonElement> GetJsonAsync(string url)
{
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var respString = await response.Content.ReadAsStringAsync();
return JsonDocument.Parse(respString).RootElement;
}
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.util.UUID;
import java.time.Instant;
import org.json.JSONObject;
public class ComsWiseClient {
private static final String API_KEY = "YOUR_API_KEY";
private static final String BASE_URL = "https://api.comswise.in/v1";
private static final HttpClient client = HttpClient.newHttpClient();
public static void main(String[] args) {
try {
// 1. Get Presigned URL
JSONObject uploadReq = new JSONObject()
.put("fileName", "call.wav")
.put("contentType", "audio/wav");
HttpRequest req1 = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/upload/request"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(uploadReq.toString()))
.build();
HttpResponse<String> resp1 = client.send(req1, HttpResponse.BodyHandlers.ofString());
if (resp1.statusCode() >= 400) {
throw new RuntimeException("Upload Request Failed: " + resp1.body());
}
JSONObject uploadResp = new JSONObject(resp1.body());
String uploadUrl = uploadResp.getString("uploadUrl");
String fileKey = uploadResp.getString("fileKey");
// 2. Upload File
System.out.println("Uploading...");
HttpRequest req2 = HttpRequest.newBuilder()
.uri(URI.create(uploadUrl))
.header("Content-Type", "audio/wav")
.PUT(HttpRequest.BodyPublishers.ofFile(Path.of("call.wav")))
.build();
HttpResponse<String> resp2 = client.send(req2, HttpResponse.BodyHandlers.ofString());
if (resp2.statusCode() >= 400) throw new RuntimeException("R2 Upload Failed");
// 3. Create Call
// Note: Provide your own internal unique ID for the call
String externalCallId = "call-" + UUID.randomUUID().toString();
String currentTime = Instant.now().toString();
JSONObject callReq = new JSONObject()
.put("callId", externalCallId)
.put("direction", "inbound")
.put("groupingId", "ticket-12345")
.put("startTime", currentTime)
.put("recordingUrl", fileKey);
HttpRequest req3 = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/calls/create"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(callReq.toString()))
.build();
HttpResponse<String> resp3 = client.send(req3, HttpResponse.BodyHandlers.ofString());
if (resp3.statusCode() >= 400) {
// For example, 409 Conflict
throw new RuntimeException("Create Call Failed (" + resp3.statusCode() + "): " + resp3.body());
}
JSONObject createResp = new JSONObject(resp3.body());
String callId = createResp.getString("id");
System.out.println("Call ID: " + callId);
} catch (Exception e) {
System.err.println("[Error] " + e.getMessage());
}
}
}# 1. Get Upload URL
UPLOAD_RESP=$(curl -s -X POST "https://api.comswise.in/v1/upload/request" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"fileName": "call.wav", "contentType": "audio/wav"}')
# Check for error (simple check)
if echo "$UPLOAD_RESP" | grep -q "detail"; then
echo "Error: $UPLOAD_RESP"
exit 1
fi
UPLOAD_URL=$(echo $UPLOAD_RESP | jq -r .uploadUrl)
FILE_KEY=$(echo $UPLOAD_RESP | jq -r .fileKey)
# 2. Upload File
curl -s -X PUT "$UPLOAD_URL" \
-H "Content-Type: audio/wav" \
--data-binary @call.wav
# 3. Create Call
# Note: Provide your own internal unique ID for the call
CALL_UUID=$(uuidgen) # Requires 'uuidgen' to be installed (e.g., on macOS/Linux)
CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
CALL_RESP=$(curl -s -X POST "https://api.comswise.in/v1/calls/create" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"callId\": \"call-$CALL_UUID\",
\"direction\": \"inbound\",
\"groupingId\": \"ticket-12345\",
\"startTime\": \"$CURRENT_TIME\",
\"recordingUrl\": \"$FILE_KEY\"
}")
# Check for success
if echo "$CALL_RESP" | grep -q "id"; then
ID=$(echo $CALL_RESP | jq -r .id)
echo "Created Call: $ID"
else
echo "Failed: $CALL_RESP"
fi
# 4. Check Status (Manual)
# You would typically poll this endpoint in a loop until status is 'ready' or 'failed'
echo "Polling for status (manual check):"
curl -s "https://api.comswise.in/v1/calls/$ID" \
-H "Authorization: Bearer $API_KEY" | jq .Method 2: Using Phone Numbers
Use from and to numbers if you don't have a system ID.
import requests
import time
import json
import os
import sys
import uuid
from datetime import datetime, timezone
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.comswise.in/v1"
FILE_PATH = "call_recording.wav"
headers = {"Authorization": f"Bearer {API_KEY}"}
def main():
try:
# 1. Get Presigned Upload URL
print("Requesting upload URL...")
req_payload = {
"fileName": os.path.basename(FILE_PATH),
"contentType": "audio/wav"
}
resp = requests.post(f"{BASE_URL}/upload/request", json=req_payload, headers=headers)
resp.raise_for_status()
upload_data = resp.json()
upload_url = upload_data["uploadUrl"]
file_key = upload_data["fileKey"]
# 2. Upload File
print(f"Uploading {FILE_PATH}...")
with open(FILE_PATH, 'rb') as f:
upload_resp = requests.put(upload_url, data=f, headers={"Content-Type": "audio/wav"})
upload_resp.raise_for_status()
# 3. Create Call with Phone Numbers
print("Creating call record...")
# Note: Provide your own internal unique ID for the call
external_call_id = f"call-{uuid.uuid4()}"
current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
call_payload = {
"callId": external_call_id,
"direction": "inbound",
"from": "+919999999999",
"to": "+918888888888",
"startTime": current_time,
"recordingUrl": file_key
}
create_resp = requests.post(f"{BASE_URL}/calls/create", json=call_payload, headers=headers)
create_resp.raise_for_status()
call_id = create_resp.json()["id"]
print(f"Call created! ID: {call_id}")
# 4. Poll for Result
print("Waiting for processing...")
while True:
status_resp = requests.get(f"{BASE_URL}/calls/{call_id}", headers=headers)
status_resp.raise_for_status()
call_data = status_resp.json()
transcript = call_data.get("transcript")
if transcript and transcript["status"] == "ready":
print("\nProcessing Complete!")
print(f"Summary: {call_data.get('executiveSummary')}")
print(f"Download Transcript: {transcript['transcriptUrl']}")
break
elif transcript and transcript["status"] == "failed":
print("Processing Failed.")
print(f"Error: {transcript.get('error')}")
break
time.sleep(5)
except requests.exceptions.HTTPError as err:
print(f"\n[API Error]: {err}")
if err.response is not None:
print(f"Server Response: {err.response.text}")
sys.exit(1)
except Exception as e:
print(f"\n[Unexpected Error]: {e}")
sys.exit(1)
if __name__ == "__main__":
main()using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
private static readonly HttpClient client = new HttpClient();
private const string ApiKey = "YOUR_API_KEY";
private const string BaseUrl = "https://api.comswise.in/v1";
static async Task Main(string[] args)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ApiKey);
string filePath = "call_recording.wav";
try
{
// 1. Get Presigned Upload URL
Console.WriteLine("Requesting upload URL...");
var uploadReq = new { fileName = Path.GetFileName(filePath), contentType = "audio/wav" };
var uploadResp = await PostJsonAsync($"{BaseUrl}/upload/request", uploadReq);
string uploadUrl = uploadResp.GetProperty("uploadUrl").GetString();
string fileKey = uploadResp.GetProperty("fileKey").GetString();
// 2. Upload File
Console.WriteLine("Uploading file...");
using (var fileStream = File.OpenRead(filePath))
{
var content = new StreamContent(fileStream);
content.Headers.ContentType = new MediaTypeHeaderValue("audio/wav");
var putResp = await client.PutAsync(uploadUrl, content);
putResp.EnsureSuccessStatusCode();
}
// 3. Create Call
Console.WriteLine("Creating call...");
// Note: Provide your own internal unique ID for the call
string externalCallId = $"call-{Guid.NewGuid()}";
string currentTime = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
var callReq = new
{
callId = externalCallId,
direction = "inbound",
from = "+919999999999",
to = "+918888888888",
startTime = currentTime,
recordingUrl = fileKey
};
var createResp = await PostJsonAsync($"{BaseUrl}/calls/create", callReq);
string callId = createResp.GetProperty("id").GetString();
Console.WriteLine($"Call Created: {callId}");
// 4. Poll for Completion
while (true)
{
await Task.Delay(5000);
var statusResp = await GetJsonAsync($"{BaseUrl}/calls/{callId}");
if (statusResp.TryGetProperty("transcript", out var transcript))
{
string status = transcript.GetProperty("status").GetString();
if (status == "ready")
{
Console.WriteLine("\nDone!");
Console.WriteLine($"Transcript URL: {transcript.GetProperty("transcriptUrl").GetString()}");
break;
}
else if (status == "failed")
{
Console.WriteLine("\nProcessing Failed.");
if (transcript.TryGetProperty("error", out var error))
Console.WriteLine($"Error: {error.GetString()}");
break;
}
}
}
}
catch (HttpRequestException e)
{
Console.WriteLine($"\n[API Error]: {e.Message}");
}
catch (Exception e)
{
Console.WriteLine($"\n[Error]: {e.Message}");
}
}
private static async Task<JsonElement> PostJsonAsync(string url, object data)
{
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
if (!response.IsSuccessStatusCode)
{
var errorContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Server Error ({response.StatusCode}): {errorContent}");
response.EnsureSuccessStatusCode();
}
var respString = await response.Content.ReadAsStringAsync();
return JsonDocument.Parse(respString).RootElement;
}
private static async Task<JsonElement> GetJsonAsync(string url)
{
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
var respString = await response.Content.ReadAsStringAsync();
return JsonDocument.Parse(respString).RootElement;
}
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.util.UUID;
import java.time.Instant;
import org.json.JSONObject;
public class ComsWiseClient {
private static final String API_KEY = "YOUR_API_KEY";
private static final String BASE_URL = "https://api.comswise.in/v1";
private static final HttpClient client = HttpClient.newHttpClient();
public static void main(String[] args) {
try {
// 1. Get Presigned URL
JSONObject uploadReq = new JSONObject()
.put("fileName", "call.wav")
.put("contentType", "audio/wav");
HttpRequest req1 = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/upload/request"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(uploadReq.toString()))
.build();
HttpResponse<String> resp1 = client.send(req1, HttpResponse.BodyHandlers.ofString());
if (resp1.statusCode() >= 400) {
throw new RuntimeException("Upload Request Failed: " + resp1.body());
}
JSONObject uploadResp = new JSONObject(resp1.body());
String uploadUrl = uploadResp.getString("uploadUrl");
String fileKey = uploadResp.getString("fileKey");
// 2. Upload File
System.out.println("Uploading...");
HttpRequest req2 = HttpRequest.newBuilder()
.uri(URI.create(uploadUrl))
.header("Content-Type", "audio/wav")
.PUT(HttpRequest.BodyPublishers.ofFile(Path.of("call.wav")))
.build();
HttpResponse<String> resp2 = client.send(req2, HttpResponse.BodyHandlers.ofString());
if (resp2.statusCode() >= 400) throw new RuntimeException("R2 Upload Failed");
// 3. Create Call
// Note: Provide your own internal unique ID for the call
String externalCallId = "call-" + UUID.randomUUID().toString();
String currentTime = Instant.now().toString();
JSONObject callReq = new JSONObject()
.put("callId", externalCallId)
.put("direction", "inbound")
.put("from", "+919999999999")
.put("to", "+918888888888")
.put("startTime", currentTime)
.put("recordingUrl", fileKey);
HttpRequest req3 = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/calls/create"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(callReq.toString()))
.build();
HttpResponse<String> resp3 = client.send(req3, HttpResponse.BodyHandlers.ofString());
if (resp3.statusCode() >= 400) {
throw new RuntimeException("Create Call Failed (" + resp3.statusCode() + "): " + resp3.body());
}
JSONObject createResp = new JSONObject(resp3.body());
String callId = createResp.getString("id");
System.out.println("Call ID: " + callId);
} catch (Exception e) {
System.err.println("[Error] " + e.getMessage());
}
}
}# 1. Get Upload URL
UPLOAD_RESP=$(curl -s -X POST "https://api.comswise.in/v1/upload/request" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"fileName": "call.wav", "contentType": "audio/wav"}')
# Check for error
if echo "$UPLOAD_RESP" | grep -q "detail"; then
echo "Error: $UPLOAD_RESP"
exit 1
fi
UPLOAD_URL=$(echo $UPLOAD_RESP | jq -r .uploadUrl)
FILE_KEY=$(echo $UPLOAD_RESP | jq -r .fileKey)
# 2. Upload File
curl -s -X PUT "$UPLOAD_URL" \
-H "Content-Type: audio/wav" \
--data-binary @call.wav
# 3. Create Call
# Generate dynamic UUID for callId (Requires uuidgen)
CALL_UUID=$(uuidgen) # Replace with your internal UNIQUE call ID
CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
CALL_RESP=$(curl -s -X POST "https://api.comswise.in/v1/calls/create" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"callId\": \"call-$CALL_UUID\",
\"direction\": \"inbound\",
\"from\": \"+919999999999\",
\"to\": \"+918888888888\",
\"startTime\": \"$CURRENT_TIME\",
\"recordingUrl\": \"$FILE_KEY\"
}")
# Check for success
if echo "$CALL_RESP" | grep -q "id"; then
ID=$(echo $CALL_RESP | jq -r .id)
echo "Created Call: $ID"
# 4. Check Status (Manual)
echo "Checking Status..."
curl -s "https://api.comswise.in/v1/calls/$ID" \
-H "Authorization: Bearer $API_KEY"
else
echo "Failed: $CALL_RESP"
fi