CleanvoiceDocs
JavaScript SDK

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-sdk
pnpm add @cleanvoice/cleanvoice-sdk
yarn add @cleanvoice/cleanvoice-sdk
bun add @cleanvoice/cleanvoice-sdk

Initialization

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

ParameterTypeDescription
fileInputstringURL or local file path to the audio or video file
configProcessingConfigProcessing options (see below)
optionsobjectAdditional 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 locally

client.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

TypeFormats
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.