https://api.echonova.aiDevelopers
Sound Cleaning quickstart
Clean a recording of up to 10 minutes in one call, read the cleaned file link and its cost, tune the cleaner, then list your past jobs.
Sound Cleaning removes low rumble, compresses the dynamics, evens out the loudness and caps the peaks of a recording. This tutorial cleans a short file with one synchronous call, reads the link to the cleaned file, then tunes the cleaner and lists your past jobs.
What you need
- An API key. See Get an API key. If the key restricts services, it needs Access on Sound Cleaning.
- The base URL. See Base URL.
- Credits on the workspace. The charge is taken before cleaning starts. See Credits.
- An audio file of 10 minutes or less and 150 MB or less, in MP3, WAV, FLAC or OGG/Opus.
Steps
Step 1: Clean a file
Send the file as the file part of a multipart/form-data request to
POST https://api.echonova.ai/v1/sound-cleaning. The call waits for the cleaner and
returns the result in the response. There is no asynchronous endpoint.
curl -X POST "https://api.echonova.ai/v1/sound-cleaning" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@noisy.wav;type=audio/wav"import requests
with open("noisy.wav", "rb") as audio:
response = requests.post(
"https://api.echonova.ai/v1/sound-cleaning",
headers={"Authorization": "Bearer YOUR_API_KEY"},
files={"file": ("noisy.wav", audio, "audio/wav")},
)
print(response.json())import { readFile } from 'node:fs/promises';
const formData = new FormData();
formData.append('file', new Blob([await readFile('noisy.wav')], { type: 'audio/wav' }), 'noisy.wav');
const response = await fetch('https://api.echonova.ai/v1/sound-cleaning', {
method: 'POST',
headers: { Authorization: 'Bearer YOUR_API_KEY' },
body: formData,
});
console.log(await response.json());The API checks the Content-Type of the file part and the file extension,
and the two must agree. Use audio/mpeg with .mp3, audio/wav with
.wav, audio/flac with .flac, and audio/ogg or audio/opus with
.ogg or .opus. Set the type explicitly as the samples do.
Step 2: Read the result
A successful call returns HTTP 200 and the standard envelope. The result is
in data:
{
"success": true,
"statusCode": 200,
"errorMessage": null,
"data": {
"id": "66e3f2a1c9d4b8a1f0e12345",
"status": "completed",
"fileName": "noisy.wav",
"outputUrl": "https://storage.example.com/cleaned/66e3f2a1c9d4b8a1f0e12345.wav?signature=abc",
"durationSeconds": 12,
"creditsConsumed": 207,
"metrics": {
"sampleRate": 48000,
"integratedLufs": -16.1,
"truePeakDbfs": -1
},
"createdAt": "2026-10-11T10:21:04.512Z"
}
}| Field | Type | What it holds |
|---|---|---|
id |
string | The job id. Read it again from GET /v1/sound-cleaning/jobs/{jobId}. |
status |
string | completed on a successful call. |
fileName |
string | The name of the file you uploaded. |
outputUrl |
string | A time-limited link to the cleaned WAV. Download it, or read the job again for a fresh link. |
durationSeconds |
number or absent | The length of the audio, rounded to whole seconds. The charge uses the unrounded length: 12.4 s costs 207. |
creditsConsumed |
number | The credits charged, a whole number. |
options |
object or absent | The tuning values you sent. Absent when you sent none. |
metrics |
object or absent | What the cleaner measured on the result: sampleRate, integratedLufs and truePeakDbfs, when it reports. |
error |
string or absent | The reason, on a job that failed. |
createdAt |
string | When the job was created, in ISO 8601. |
The cleaned file is always a WAV. The link expires, so download the file when you get it, or fetch the job again later for a new link.
Step 3: Tune the cleaner
Eight optional form fields change how the cleaner works. Leave them out and
the cleaner uses its defaults. A value outside its range is rejected with
400.
| Field | Meaning | Range | Default |
|---|---|---|---|
cutoffFreq |
High-pass cutoff in Hz | 20 to 300 | 90 |
qFactor |
High-pass smoothness | 0.1 to 5 | 0.707 |
targetLufs |
Target loudness in LUFS | -30 to -6 | -16 |
truePeakDbfs |
Peak ceiling in dBFS | -6 to 0 | -1 |
compThreshDb |
Compressor threshold in dBFS | -30 to 0 | -3.8 |
compRatio |
Compressor ratio | 1 to 20 | 4 |
compAttackMs |
Compressor attack in milliseconds | 0.1 to 100 | 5 |
compReleaseMs |
Compressor release in milliseconds | 1 to 1000 | 50 |
curl -X POST "https://api.echonova.ai/v1/sound-cleaning" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@noisy.wav;type=audio/wav" \
-F "targetLufs=-18" \
-F "cutoffFreq=120"Step 4: List your jobs
GET https://api.echonova.ai/v1/sound-cleaning/jobs returns the API jobs of your
workspace, newest first, 20 per page. Add offset and limit (1 to 100) to page.
GET https://api.echonova.ai/v1/sound-cleaning/jobs/{jobId} returns one job with a
fresh outputUrl.
curl "https://api.echonova.ai/v1/sound-cleaning/jobs?offset=0&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"Any key in the workspace with Sound Cleaning access sees these jobs, whichever key created them. Jobs made in the portal are not listed here.
What happens next
- The price is 1,000 credits per minute of audio, charged per second, with a minimum of 1 second. The API measures the decoded audio, not the file header, so a file of 12.4 seconds costs 207 credits (206.67, rounded to a whole credit). See Credits.
- The workspace is charged before cleaning starts and refunded if cleaning
fails. The key's own usage counter is checked against its Credit Limit
first; a call that would pass the limit is rejected with
429and nothing is charged. - Every call creates a job, so the work stays listed under your key.
Limits
| Limit | Value | Applies to |
|---|---|---|
| Audio duration | 10 minutes | POST /v1/sound-cleaning |
| File size | 150 MB | POST /v1/sound-cleaning |
| Formats | MP3, WAV, FLAC, OGG/Opus | POST /v1/sound-cleaning |
limit query parameter |
1 to 100, default 20 | GET /v1/sound-cleaning/jobs |
offset query parameter |
0 or more, default 0 | GET /v1/sound-cleaning/jobs |
| Requests per key | See Rate limits | Every endpoint |
Troubleshooting
400 File is required
The request had no part named file. Check the field name and that the
request is multipart/form-data.
400 Unsupported audio format. Sound cleaning accepts MP3, WAV, FLAC or OGG/Opus.
The file extension or its Content-Type is not one of the four formats, or
the two do not match. A .wav file sent as audio/mpeg is refused.
400 Audio exceeds the 10-minute limit.
The audio is longer than 10 minutes. Cut it into pieces of 10 minutes or less and send each one.
400 targetLufs must not be greater than -6
A tuning field is outside its range in the table in Step 3; the message names
the field and the bound. A form field that is not one of the eight, such as
volume, is refused with property volume should not exist.
413 File too large
The upload is over 150 MB. The request is cut off before the file is read.
503 Sound cleaning is temporarily unavailable. Please try again.
The cleaner could not be reached. The charge is refunded. Retry once.
404 Clean Job not found
The jobId does not exist, or it belongs to another workspace or was made in the portal.
403 This API key does not have access to Sound Cleaning services
The key restricts services and Sound Cleaning is not among them. Edit the key in the portal and turn Sound Cleaning on. Keys that have no service restriction can use it already.
402 Insufficient subscription balance
The workspace cannot cover the charge. Nothing ran.
FAQ
Can I clean a file longer than 10 minutes?
Not through the API today. Cut it into pieces of 10 minutes or less and send each one.
Is there an asynchronous endpoint?
No. The cleaner answers in the same call, so the endpoint is synchronous only.