Theme
Voice Isolator
Remove background noise from audio and optionally restore speech with Sidon. Upload a file, poll its job, then download the processed audio. Processing continues after the upload request finishes.
Authentication
Use a server-side developer API key with Voice Isolator → Access, permission ID audio_isolation. Access grants audio_isolation:read and audio_isolation:write. Restricted keys need this permission added explicitly. See API keys.
| Credential | Route prefix | Purpose |
|---|---|---|
| Developer API key | /v1/voice-isolations | Server integrations documented here |
| User access JWT | /api/v1/voice-isolations | VoiceLab dashboard |
Jobs belong to the account. A permitted key can retrieve jobs created by another key or by the dashboard on that account. Other accounts cannot access them.
Isolate audio
Submit an asynchronous audio isolation job.
Requires audio_isolation:write.
Headers and fields
| Header | Required | Value |
|---|---|---|
Authorization | yes | Bearer <VOICELAB_API_KEY> |
Idempotency-Key | yes | UUID generated once per logical upload; reuse for retries |
Content-Type | yes | Multipart boundary generated by your HTTP client |
| Multipart field | Required | Value |
|---|---|---|
file | yes | One audio file |
title | no | Up to 512 UTF-8 bytes; default Isolated audio |
speech_restoration | no | Text true or false; default false |
restoration_model | no | sidon; valid only when restoration is true |
Denoising always runs. Enabling restoration runs Sidon afterwards. New jobs do not accept lavasr. An unavailable restoration stage returns an error rather than silently changing the requested processing.
The same idempotency key and content return the original job without another credit hold. Changing audio, title, or processing options with that key returns 409. Keys are scoped per developer API key, separately from dashboard uploads.
Limits
| Limit | Value |
|---|---|
| Single upload | 300 MiB, or 314,572,800 bytes |
| Batch upload | 1–4 files, 300 MiB combined |
| Minimum decoded duration | 0.5 seconds per file |
| Maximum recording duration | No separate duration limit; decode resource budgets and execution timeouts still apply |
| Input | Exactly one audio stream; common MP3, WAV, M4A, AAC, OGG, WebM, FLAC and AIFF inputs |
The API inspects and decodes the audio. A supported filename extension alone does not establish validity. Multipart metadata has a separate small allowance. Capacity limits can return 429; respect Retry-After.
Request examples
These examples run on your server. Set VOICELAB_API_KEY in the environment. Let the client generate the multipart boundary. Retain the generated UUID if you retry the upload.
bash
request_key=$(uuidgen)
curl --fail-with-body -i 'https://api.voicelab.uz/v1/voice-isolations' \
-H "Authorization: Bearer $VOICELAB_API_KEY" \
-H "Idempotency-Key: $request_key" \
-F 'file=@speech.mp3' \
-F 'title=Interview' \
-F 'speech_restoration=true'python
import os
import uuid
import requests
request_key = str(uuid.uuid4())
with open("speech.mp3", "rb") as audio:
response = requests.post(
"https://api.voicelab.uz/v1/voice-isolations",
headers={
"Authorization": f"Bearer {os.environ['VOICELAB_API_KEY']}",
"Idempotency-Key": request_key,
},
files={"file": ("speech.mp3", audio, "audio/mpeg")},
data={"title": "Interview", "speech_restoration": "true"},
timeout=900,
)
response.raise_for_status()
print(response.json()["id"])ts
import { readFile } from "node:fs/promises";
import { randomUUID } from "node:crypto";
const requestKey = randomUUID();
const form = new FormData();
form.append("file", new Blob([new Uint8Array(await readFile("speech.mp3"))]), "speech.mp3");
form.append("title", "Interview");
form.append("speech_restoration", "true");
const response = await fetch("https://api.voicelab.uz/v1/voice-isolations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VOICELAB_API_KEY}`,
"Idempotency-Key": requestKey,
},
body: form,
signal: AbortSignal.timeout(900_000),
});
if (!response.ok) throw new Error(`Upload failed: ${response.status}`);
console.log((await response.json()).id);Response and polling
Returns 202 Accepted, Location: /v1/voice-isolations/{id}, and Retry-After: 3. A replay returns the existing job with its current status. Example fields, with a hypothetical quote of 120 credits for one minute:
json
{
"id": "iso_550e8400-e29b-41d4-a716-446655440000",
"title": "Interview",
"status": "queued",
"duration_ms": 60000,
"credits": 120,
"audio_available": false,
"audio_format": "mp3",
"speech_restoration": true,
"restoration_model": "sidon",
"created_at": "2026-09-08T10:00:00Z",
"updated_at": "2026-09-08T10:00:00Z",
"request_id": "req_example"
}credits is the reserved quote. The configured rate determines the amount; this example is not a fixed tariff.
| Field | Meaning |
|---|---|
status | queued, running, completed, or failed |
processing_stage | When present: noise_reduction, speech_restoration, or finalizing |
audio_available | A retained processed master is available; this alone does not mean MP3 is ready |
audio_status | Default MP3 preparation: queued, running, completed, or failed, when present |
audio_url | Temporary MP3 download URL once preparation completes |
error_code | Safe failure code when the job fails |
completed_at | Processing completion timestamp, when present |
original_filename, original_content_type, original_available | Retained upload metadata |
original_audio_url, input_audio_url, denoised_audio_url | Detail-only signed links for available original, normalized input, and denoised audio |
output_sample_rate | Output sample rate; does not establish job completion |
batch_id, batch_index | Batch membership and upload order |
Poll detail every three seconds while the job is queued/running. When status=completed, keep polling while MP3 preparation is queued/running. Download when audio_status=completed and audio_url exists. Stop on job failure or MP3 conversion failure and handle that state explicitly. There are no completion webhooks.
Batch isolation
Submit one to four files atomically.
Requires audio_isolation:write and a UUID Idempotency-Key. Send repeated files parts with the same optional speech_restoration and restoration_model fields as a single upload. Processing options apply to every file; filenames become job titles.
bash
request_key=$(uuidgen)
curl --fail-with-body 'https://api.voicelab.uz/v1/voice-isolations/batch' \
-H "Authorization: Bearer $VOICELAB_API_KEY" \
-H "Idempotency-Key: $request_key" \
-F 'files=@first.mp3' \
-F 'files=@second.wav' \
-F 'speech_restoration=true'Returns 202 with an isb_… batch id and jobs in data, preserving batch_index. Validation and credit reservation are atomic: an invalid or unaffordable batch admits no jobs. Preserve file order, filenames, bytes and options on retry. Poll each child job by ID; there is no separate batch polling route.
List isolations
List the account's visible isolation history.
Requires audio_isolation:read. Optional limit defaults to 20 and accepts 1–50. Pass the returned opaque next_cursor as cursor for the next page.
bash
curl --fail-with-body 'https://api.voicelab.uz/v1/voice-isolations?limit=20' \
-H "Authorization: Bearer $VOICELAB_API_KEY"Returns 200 with data containing jobs in descending creation order and optional next_cursor. History includes all job states. List responses omit signed audio URLs; request detail for playback or downloads.
Get an isolation
Read job state and renew available audio URLs.
Requires audio_isolation:read. Returns 200 with the job. Unknown jobs and jobs belonging to another account return 404.
bash
curl --fail-with-body 'https://api.voicelab.uz/v1/voice-isolations/iso_REPLACE_ME' \
-H "Authorization: Bearer $VOICELAB_API_KEY"Signed audio URLs expire after ten minutes. Fetch detail again for fresh URLs. Download the returned storage URL without forwarding your API key. Store the job ID for future access rather than relying on an old URL.
Hide an isolation
Hide a job from history without erasing its audio.
Requires audio_isolation:write. Returns 204 No Content on success. Hiding does not cancel processing, refund completed work, or delete stored files. Original uploads, normalized inputs, denoised/restored audio and exports are retained indefinitely, including hidden jobs.
bash
curl --fail-with-body -X DELETE 'https://api.voicelab.uz/v1/voice-isolations/iso_REPLACE_ME' \
-H "Authorization: Bearer $VOICELAB_API_KEY"Create an export
Prepare a download in the requested format.
Requires audio_isolation:write. Send {"format":"flac"}. Supported values are mp3, wav, flac, ogg, and original for the untouched upload. Processed exports require an available final master; otherwise the API returns 409 audio_not_ready. The original upload can be available before processing completes.
bash
curl --fail-with-body -X POST 'https://api.voicelab.uz/v1/voice-isolations/iso_REPLACE_ME/exports' \
-H "Authorization: Bearer $VOICELAB_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"format":"flac"}'Queued/running exports return 202 with Retry-After: 2. Completed or failed exports return 200; inspect status. Exports reuse stored audio, do not rerun inference, and do not charge additional credits.
Get an export
Poll an export or retrieve its current download URL.
Requires audio_isolation:read. A read-only key can retrieve existing exports; requesting a new conversion requires write permission. Poll queued/running conversions every two seconds.
bash
curl --fail-with-body 'https://api.voicelab.uz/v1/voice-isolations/iso_REPLACE_ME/exports/flac' \
-H "Authorization: Bearer $VOICELAB_API_KEY"Example completed response:
json
{
"job_id": "iso_550e8400-e29b-41d4-a716-446655440000",
"format": "flac",
"status": "completed",
"filename": "Interview.flac",
"audio_url": "https://storage.example.com/audio.flac?signature=EXAMPLE"
}The example URL is a placeholder. Use the actual audio_url without an Authorization header.
Billing and errors
Credits are reserved at admission, rounded up per file at the configured per-minute rate, and debited once when processing succeeds. Terminal processing failures release the hold. Sidon restoration and exports have no separate surcharge. MP3 readiness is separate from successful inference and billing. See pricing.
A key's credit limit includes its recorded billable usage and pending isolation reservations. Revoking a key prevents new access but does not cancel accepted jobs. Usage is attributed to the submitting key under voice_enhancer in analytics.
| HTTP status | Meaning |
|---|---|
400 | Missing/invalid UUID, malformed multipart or export JSON, invalid pagination |
401 | Invalid, expired, disabled or revoked API key |
403 | Missing scope or denied source IP |
402 | Insufficient credits or api_key_credit_limit |
404 | Feature unavailable, unknown job or another account's job |
409 | Conflicting idempotent retry or audio_not_ready |
413 | Upload exceeds the size limit |
422 | Invalid audio, processing options or export format |
429 | Upload or job capacity exceeded |
503 | Processing service or requested restoration stage unavailable |
Honor Retry-After for capacity failures. Retry transient upload failures with the original idempotency key and identical content. Do not retry authorization or validation failures unchanged. Keep request_id for support. See errors and limits.