shell python typescript ruby

Introduction

Base url

https://api.cleanvoice.ai/v1
https://api.cleanvoice.ai/v1
https://api.cleanvoice.ai/v1
https://api.cleanvoice.ai/v1

Welcome to the Cleanvoice API 👋

With this API you can automatically submit files to be edited by Cleanvoice, access existing edits and export them to various formats.

This is a REST API that uses predictable resource names and verbs. Our API is versioned where breaking changes are released as incremental versions. We'll try our best not to release versions too often, and to reasonably support legacy versions.

Click here if you want access to the swagger docs

If you have any questions, please write to us at support@cleanvoice.ai. We'd love to hear from you!

— Cleanvoice team

Authentication

To authorize, use this code:

# With shell, you can just pass the correct header with each request
curl "https://api.cleanvoice.ai/v1/account" \
  -H "X-API-Key: **your_api_key_here**"
import requests

url = 'https://api.cleanvoice.ai/v1/account'
headers = {'X-API-Key': '**your_api_key_here**'}
requests.get(url, headers=headers)

require 'net/http'
require 'uri'

uri = URI.parse('https://api.cleanvoice.ai/v1/account')
header = { 'X-API-Key': '**your_api_key_here**' }

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Get.new(uri.request_uri, header)
response = http.request(request)
import axios from 'axios';

const url = 'https://api.cleanvoice.ai/v1/account';
const headers = {'X-API-Key': '**your_api_key_here**'};

axios.get(url, { headers })
    .then((response) => {
        console.log(response.data);
    })
    .catch((error) => {
        console.log(error);
    });

Make sure to replace **your_api_key_here** with your API key.

Cleanvoice uses API keys to allow access to the API. You can get your API key by logging in and going to settings

Cleanvoice expects the API key to be included in all API requests to the server in a header that looks like the following:

X-Api-Key: **your_api_key_here**

Uploads

To get started, you have to provide an media file. Check here for the currently supported audio files

There are two ways to upload your audio files(s):

Option 1: Upload via Public URL

You can directly use publicly available URLs to upload media files to Cleanvoice. This can be a publicly accessible URL hosted by yourselves or a third-party. The files will be automatically downloaded from the URL, so you don't need to explicitly upload them. For example, you can use a URL like "https://yourdomain.com/file.mp3". If you choose to use this option, you can proceed directly to the Edit Section

Option 2: Upload via File

If you choose the option to upload files, you will need to explicitly upload them to Cleanvoice servers. The files will be stored in our DigitalOcean S3 bucket.

After uploading, the API will return a link which you will need for starting a new edit. To upload files to our DigitalOcean S3 bucket, you will first need to request a signed URL by using the provided endpoints.

Step 1 - Get a Signed Url

curl -X 'POST' \
  'https://api.cleanvoice.ai/v1/upload?filename=audio.mp3' \
  -H 'X-API-Key: **your_api_key_here**' 
import requests

url = 'https://api.cleanvoice.ai/v1/upload?filename=audio.mp3'
headers = {'X-API-Key': '**your_api_key_here**'}
response = requests.post(url, headers=headers)
signed_url = response.json()['signedUrl']
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse('https://api.cleanvoice.ai/v1/upload?filename=audio.mp3')
header = { 'X-API-Key': '**your_api_key_here**' }

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, header)
response = http.request(request)
signed_url = JSON.parse(response.body)["signedUrl"]
import axios from 'axios';

const url = 'https://api.cleanvoice.ai/v1/upload?filename=audio.mp3';
const headers = {'X-API-Key': '**your_api_key_here**'};
const response = await axios.post(url, {headers});
const signed_url = response.data.signedUrl;

The above command returns JSON structured like this:

{
  "signedUrl": "https://cleanvoice.fra1.digitaloceanspaces.com/uploads/VW7rUX3_audio.mp3\?X-Amz-Algorithm..."
}

This endpoint returns a signed URL which can be used to make PUT requests to our S3 Digitalocean bucket. More information here: docs.digitalocean.com

Once the file is uploaded, this same url should be used as the files URL when creating the associated edit.

HTTP Request

POST https://api.cleanvoice.ai/v1/upload

Parameters

Parameter Description
filename (required) The filename and extension of the media file (e.g. my_media.mp3)

2. Upload your file with the Signed Url

curl -X PUT -T my_media.mp3 -L "https://signed-url..."
import requests

url = "https://signed-url..."
file = open("my_media.mp3", "rb")

requests.put(url, data=file)
import axios from 'axios';

const url = "https://signed-url...";
const file = new File(["my_media.mp3"], "my_media.mp3", {
  type: "audio/mp3"
});

axios.put(url, file)
  .then(response => {
    console.log(response.status);
  })
  .catch(error => {
    console.log(error);
  });
require 'uri'
require 'net/http'

signed_url = "https://signed-url..."
uri = URI(signed_url)
req = Net::HTTP::Put.new(uri)
req.body = File.read("my_media.mp3")
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
  http.request(req)
end

Simple upload to an DO S3 Bucket

Once you have a signed url, you have to upload the file there, and you do it as you would with any S3 bucket.

To upload a file to the signed URL you may use cURL like the example on the right.

Here you have more information about how to deal with Digitalocean S3 signed urls docs.digitalocean.com

Edits

Create a Edit

curl -X POST "https://api.cleanvoice.ai/v1/edits" \
  -H "X-API-Key: **your_api_key_here**" \
  -H "Content-Type: application/json" \
  -d '{
  "input": {
    "files": [
      "https://public.com/file.mp3"
    ],
    "config": {}
  }
}'

import requests
import json

file_url = "https://public.com/file.mp3_OR_Signed_URL"
api_key = "**your_api_key_here**"

data = {
    "input": {
        "files": [file_url],
        "config": {}
    }
}
headers = {
    "X-API-Key": api_key,
    "Content-Type": "application/json"
}

response = requests.post("https://api.cleanvoice.ai/v1/edits", json=data, headers=headers)
print(response.json())

import axios from 'axios';

const fileUrl = "https://public.com/file.mp3_OR_Signed_URL";
const apiKey = "**your_api_key_here**";

const data = {
    input: {
        files: [fileUrl],
        config: {}
    }
};
const headers = {
    "X-API-Key": apiKey,
    "Content-Type": "application/json"
};

axios.post("https://api.cleanvoice.ai/v1/edits", data, { headers })
    .then((response) => {
        console.log(response.data);
    })
    .catch((error) => {
        console.log(error);
    });

require 'net/http'
require 'json'

file_url = "https://public.com/file.mp3_OR_Signed_URL"
api_key = "**your_api_key_here**"

data = {
    input: {
        files: [file_url],
        config: {}
    }
}.to_json
headers = {
    "X-API-Key" => api_key,
    "Content-Type" => "application/json"
}

uri = URI("https://api.cleanvoice.ai/v1/edits")

response = Net::HTTP.post(uri, data, headers)
puts JSON.parse(response.body)


The above command returns JSON structured like this:

{
  "id": "9a14b8fe-3604-43e4-8c06-06a7491ae8fc"
}

This endpoint creates a new edit. After a edit is created, the system will proceed to automatically editing it. You can check if the editing process has finished by retrieving a edit.

Cleanvoice requires a public link to edit your audio, if this is not possible go back to the upload section. If you have allready uploaded your audio via our api, you can use the signed URL instead.

Note all uploads and edits are stored for 7 days only. If you require longer storage, write us.

The API can edit multi-track audio as well. Multi-track uploads are where every audio file contains a different speaker. To use it, just pass multiple files. Single-Track are where all the speakers are merged into a single file.

HTTP Request

POST https://api.cleanvoice.ai/v1/edits

Parameters

Input

Parameter Type Description
files Array (required) A list of URL-Strings containing Audio. For Single-Track, a single link is located in the array. Else Cleanvoice assumes it's a multi-track audio recording

Config

Parameter Type Description
send_mail Boolean Send an email to your account with the edited file(s). Default: False
timestamps_only Boolean Send only the JSON with the edits, without editing the audio file. (Faster Processing) Default: False
remove_noise Boolean Remove Background Noise Default: True
mastering Boolean Audio Mastering for Podcast Distribution. This converts it to optimized mp3 aswell. Default: False
export_edits Boolean Export the locations which cleanvoice would edit out. See JSON example. Default: False
ignore_music Boolean Don't edit voice over music and dont edit music out. Default: False
ignore_features List[String] Ignore features related to editing. Possible options: "STUTTERING", "FILLER_SOUND", "MOUTH_SOUND", "DEADAIR_LONG", "DEADAIR" Default: []

Retrieve a Edit

curl "https://api.cleanvoice.ai/v1/edits/<ID>" \
  -H "X-Api-Key: **your_api_key_here**"
import requests

url = "https://api.cleanvoice.ai/v1/edits/<ID>"
headers = {
    "X-Api-Key": "**your_api_key_here**"
}

response = requests.get(url, headers=headers)
print(response.json())

import axios from 'axios';

const url = "https://api.cleanvoice.ai/v1/edits/<ID>";
const headers = {
    "X-Api-Key": "**your_api_key_here**"
};

axios.get(url, { headers })
    .then((response) => {
        console.log(response.data);
    })
    .catch((error) => {
        console.log(error);
    });
require 'net/http'
require 'json'

url = "https://api.cleanvoice.ai/v1/edits/<ID>"
headers = {
    "X-Api-Key" => "**your_api_key_here**"
}
uri = URI(url)

response = Net::HTTP.get_response(uri, headers)
puts JSON.parse(response.body)

The above command returns JSON structured like this:

{
  "status": "SUCCESS",
  "result": {
    "download_url": "https://fra1.digitaloceanspaces.com/cleanvoice/uploads/clean_jyYweGY_audio.mp3?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=TNTLOTODENTEDRISPGU5%2F20220502%2Ffra1%2Fs3%2Faws4_request&X-Amz-Date=20220502T045843Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=29c01a115f73cb00b39fe631b5e41a5617e17fae7c9640afb373e0e8c5ab57a3",
    "edits": {
      "edits": [
        {
          "end": 11.86,
          "label": "DEADAIR",
          "start": 9.86
        },
        {
          "end": 16.38,
          "label": "FILLER_SOUND",
          "start": 15.53
        },
        {
          "end": 54.95,
          "label": "MOUTH_SOUND",
          "start": 53.95
        },
        {
          "end": 58.95,
          "label": "MOUTH_SOUND",
          "start": 56.95
        }

      ]
    },
    "statistics": {
      "DEADAIR": 1,
      "REPHRASE": 0,
      "WORD_DUB": 0,
      "LONG_PAUSE": 0,
      "STUTTERING": 0,
      "MOUTH_SOUND": 2,
      "FILLER_SOUND": 1,
      "NORMAL_PAUSE": 0,
      "PROLONGED_SOUND": 0,
      "ZOOM_DISTORTION": 0,
      "INVOLUTARY_PAUSE": 0
    },
    "id": "107b9579-583e-4585-bfa0-6a76cd15a4bb",
    "task_id": "9a14b8fe-3604-43e4-8c06-06a7491ae8fc",
    "filename": "jyYweGY_audio.mp3",
    "length": 5.899319449999999
  },
  "task_id": "9a14b8fe-3604-43e4-8c06-06a7491ae8fc"
}

This endpoint retrieves information about a specific edit. The results can be used in two ways.

HTTP Request

GET https://api.cleanvoice.ai/v1/edits/<ID>

Edits State Descriptions

Value Description
PENDING Waiting for execution or unknown edit ID
STARTED Edit has been started
SUCCESS Audio has been successfully edited
RETRY Task is being retried
FAILURE File failed to process

Files

We currently support the following fileformats: For certain formats, we can't return the original codec or audio quality.

fileformat Description Returned fileformat the same?
mp3 MPEG-1 Audio Layer-3
wav Waveform Audio File Format
flac Free Lossless Audio Codec
m4a MPEG-4 Audio

Languages

We support the following languages:

Code Language Support
EN English Full
DE German Full
RO Romanian Full
FR French Partial
NL Dutch Partial
BG Bulgarian (Bulgaria) Partial
AR Arabic (United Arab Emirates) Partial
tr-TR Turkish (Turkey) Partial

Note that, we don't work on the word level. We work on the phonetical level, therefore if theres a language which is similar to two languages which we have listed, it could work as well. Say German and English are supported, then Dutch should work as well.