JavaScript SDK
Official JavaScript and TypeScript SDK for the Cleanvoice API.
The official Cleanvoice JavaScript SDK works in Node.js and is fully typed with TypeScript. It handles authentication, polling, and provides a clean async/await interface.
Installation
npm install @cleanvoice/cleanvoice-sdkpnpm add @cleanvoice/cleanvoice-sdkyarn add @cleanvoice/cleanvoice-sdkbun add @cleanvoice/cleanvoice-sdkInitialization
import { Cleanvoice } from '@cleanvoice/cleanvoice-sdk';
// Recommended: reads CLEANVOICE_API_KEY from the environment
const client = Cleanvoice.fromEnv();
// Or pass the key explicitly
const client = new Cleanvoice({ apiKey: process.env.CLEANVOICE_API_KEY });client.process()
Submit a file and wait for the result. This is the recommended method for most use cases. Blocks until the job finishes and returns a ProcessResult.
const result = await client.process(fileInput, config?, options?);Parameters
| Parameter | Type | Description |
|---|---|---|
fileInput | string | URL or local file path to the audio or video file |
config | ProcessingConfig | Processing options (see below) |
options | object | Additional request options |
ProcessingConfig
interface ProcessingConfig {
fillers?: boolean; // Remove filler words ("um", "uh", etc.)
stutters?: boolean; // Remove repeated word fragments
long_silences?: boolean; // Trim long pauses
mouth_sounds?: boolean; // Remove clicks and lip smacks
breath?: boolean | string; // true, 'legacy', or 'natural'
remove_noise?: boolean; // Reduce background noise
normalize?: boolean; // Normalize loudness
autoeq?: boolean; // Legacy EQ option; prefer studio_sound
studio_sound?: string | boolean; // true or advanced 'nightly'
mute_lufs?: number; // Enable LUFS targeting (set threshold)
target_lufs?: number; // Target LUFS level (e.g. -16)
export_format?: 'auto' | 'mp3' | 'wav' | 'flac' | 'm4a'; // Audio-only; video keeps original container
transcription?: boolean; // Return a transcript
summarize?: boolean; // Generate summary and chapters (auto-enables transcription)
social_content?: boolean; // Generate social media copy (auto-enables summarize)
signed_url?: string; // Pre-signed PUT URL for your own storage
video?: boolean; // Process as video; SDK auto-detects common video files
merge?: boolean; // Multi-track only; merge all tracks into one output
audio_for_edl?: boolean; // Video workflows only; extra EDL/NLE audio output
}social_content: true automatically enables summarize. summarize: true automatically enables transcription.
Return value — ProcessResult
interface ProcessResult {
audio: {
url: string; // Remote URL for the cleaned audio
localPath?: string; // Set after download()
statistics: {
FILLER_SOUND?: number;
// ...other stats
};
download(outputPath?: string): Promise<string>; // Save to file, returns saved path
};
media: { // Same shape as audio, used for video output
url: string;
};
isVideo: boolean;
transcript?: {
text: string;
summary?: string;
chapters?: Chapter[];
};
}Example
import { Cleanvoice } from '@cleanvoice/cleanvoice-sdk';
const client = Cleanvoice.fromEnv();
const result = await client.process(
'https://example.com/episode.mp3',
{
fillers: true,
long_silences: true,
mouth_sounds: true,
remove_noise: true,
normalize: true,
}
);
console.log('Cleaned audio:', result.audio.url);
await result.audio.download('cleaned.mp3'); // save locallyclient.processAndDownload()
Convenience method that calls process() and immediately downloads the result. Returns a [result, savedPath] tuple.
const [result, savedPath] = await client.processAndDownload(
'https://example.com/episode.mp3',
'cleaned.mp3',
{ fillers: true, normalize: true }
);
console.log('Saved to:', savedPath);client.createEdit()
Submit a job without waiting for completion. Returns the editId for later polling.
const editId = await client.createEdit(
'https://example.com/episode.mp3',
{
fillers: true,
long_silences: true,
}
);
console.log('Edit ID:', editId);client.getEdit()
Retrieve the current status and result of a previously created edit.
const edit = await client.getEdit('edit_abc123');
console.log(edit.status); // 'PENDING' | 'STARTED' | 'SUCCESS' | 'FAILURE' | 'RETRY'
if (edit.status === 'SUCCESS') {
console.log('Download URL:', edit.result.audio.url);
}Polling manually
async function waitForEdit(editId: string) {
while (true) {
const edit = await client.getEdit(editId);
if (edit.status === 'SUCCESS') return edit;
if (edit.status === 'FAILURE') throw new Error('Edit failed');
await new Promise((resolve) => setTimeout(resolve, 5000));
}
}client.uploadFile()
Upload a local file and receive a URL you can pass to process() or createEdit().
const url = await client.uploadFile('/path/to/episode.mp3');
console.log('Uploaded:', url);client.downloadFile()
Download a file from a URL to a local path.
const savedPath = await client.downloadFile(
'https://example.com/cleaned.mp3',
'output.mp3' // optional output path
);client.checkAuth()
Verify your API key and retrieve account information including remaining credits.
const account = await client.checkAuth();
console.log(account);Error handling
import { Cleanvoice, ApiError } from '@cleanvoice/cleanvoice-sdk';
try {
const result = await client.process('episode.mp3', { fillers: true });
} catch (err) {
if (err instanceof ApiError) {
console.error('API error:', err.message, err.status);
} else {
throw err;
}
}TypeScript support
The SDK ships with full TypeScript definitions. All config options and response types are exported:
import { Cleanvoice, ProcessingConfig, ProcessResult } from '@cleanvoice/cleanvoice-sdk';
const config: ProcessingConfig = {
fillers: true,
normalize: true,
export_format: 'wav',
};
const result: ProcessResult = await client.process(url, config);Supported formats
| Type | Formats |
|---|---|
| Audio | .wav, .mp3, .ogg, .flac, .m4a, .aiff, .aac, .opus |
| Video | .mp4, .mov, .webm, .avi, .mkv |
Usage in Next.js
// app/api/clean/route.ts
import { NextResponse } from 'next/server';
import { Cleanvoice } from '@cleanvoice/cleanvoice-sdk';
const client = Cleanvoice.fromEnv();
export async function POST(req: Request) {
const { url } = await req.json();
const editId = await client.createEdit(url, {
fillers: true,
long_silences: true,
});
return NextResponse.json({ editId });
}Never expose your API key in client-side code (browser bundles, React components without server boundaries, etc.). Always call Cleanvoice from server-side code only.