ComsWise LogoComsWise

Complete Workflow Examples

End-to-end code examples in multiple languages

This guide provides complete, copy-pasteable examples for the full ComsWise workflow:

  1. Upload Audio: Get a signed URL and upload your file.
  2. Create Call: Register the call for processing.
  3. Poll for Results: Wait for the transcript to be ready.
  4. Retrieve Data: Download the final transcript and summary.

The API supports two ways to associate calls:

  1. Grouping ID (Recommended): Use an external ID (like a Ticket ID or CRM Lead ID) to automatically group related calls.
  2. Phone Numbers: Explicitly provide from and to numbers if you don't have a grouping ID.

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

On this page