<aside> ℹ️ Note: this document is subject to change and may be updated periodically as development and testing of the functionality progresses. Updates will be highlighted in the Changelog below this message.

Changelog

</aside>

This document outlines a proposed procedure to upload an audio file to the Voyc platform. There are 2 HTTP calls that need to be made in order to successfully upload audio.

<aside> ℹ️ Note: the below needs to happen for each audio file. We do not support bulk uploads.

</aside>

Steps:

  1. POST request to Voyc API to supply the conversation metadata and retrieve secure S3 upload token.
  2. Upload an audio file directly to S3

<aside> ⚠️ In the examples below <url> should be replaced with the base url specific to your organisation. Please contact Voyc support if you are unsure.

The base url can be seen from the login page. In https://app.voyc.ai/login the base url is api.app.voyc.ai.

</aside>

Step 1 - POST request to Voyc API

Endpoint: https://<url>/api/v2/workspace/{organisation_id}/conversation/upload_data/

Request Type: POSTAuthorization: Bearer Token (See ‘Generating an Authorization Token’ below)

Request Headers:

import requests

# session to be created once
session = requests.Session()
session.headers.update(
    {
        "Content-type": "application/json",
        "Authorization": f"Bearer <token>", # See below on generation a token
    }
)

# upload on a per audio basis
url = (
    f"https://<url>/api/v2/workspace/<organisation_id>/"
    "conversation/upload_data/"
)
session.post(url, json=<request data>) # See below on json format
const token = "<your_token>";
const organisation_id = "<your_organisation_id>";
const requestData = {}; // Replace with the actual JSON request data in the appropriate format

const headers = new Headers();
headers.set("Content-type", "application/json");
headers.set("Authorization", `Bearer ${token}`);

const url = `https://<url>/api/v2/workspace/${organisation_id}/conversation/upload_data/`;

fetch(url, {
  method: "POST",
  headers: headers,
  body: JSON.stringify(requestData),
  mode: "cors",
})
  .then((res) => res.json())
  .then((data) => console.log(data))
  .catch((error) => console.error("Request error:", error.message))
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
public class VoycApi
{
    private readonly HttpClient _client;
    public VoycApi()
    {
        _client = new HttpClient();
        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    }
    public async Task<JObject> PostToVoycAPI(string organisationId, string token, JObject requestData)
    {
        string url = $"https://<url>/api/v2/workspace/{organisationId}/conversation/upload_data/";
        _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        var response = await _client.PostAsync(url, new StringContent(requestData.ToString(), Encoding.UTF8, "application/json"));
        if (response.IsSuccessStatusCode)
        {
            var content = await response.Content.ReadAsStringAsync();
            return JObject.Parse(content);
        }
        else
        {
            throw new Exception($"Error: {response.StatusCode}");
        }
    }
}

Request Data:

This will contain the necessary metadata attributed to the audio conversation being uploaded.

There are reserved keywords that hold specific meaning within the Voyc system:

Keyword Value
channel_id • id of the channel to upload to
• required ⚠
call_date • The date that the audio conversation took place
• required ⚠
YYYY-MM-DD
• ISO 8601 format
call_time • The time of day that the audio conversation took place
• required ⚠
hh:mm:ss
• ISO 8601 format
agent • The agent associated with the audio conversation
• required ⚠
direction • Whether the audio conversation was inbound, outbound or internal
• not required
language • The language the conversation is in
• not required
speakers • The number of speakers
• not required
• defaults to 2 if not supplied