> For the full page index, fetch https://echonova.ai/llms.txt

# Clean audio synchronously

Cleans an uploaded MP3, WAV, FLAC or OGG/Opus file of up to 10 minutes and 150MB in one call and returns the job with the cleaned file URL. Every tuning field is optional; an omitted one uses its default.

## Endpoint

`POST https://api.echonova.ai/v1/sound-cleaning`

## Authentication

Keys are created in the portal under Developers, sent as `Authorization: Bearer YOUR_API_KEY`. See [Get an API key](/docs/developers/get-an-api-key).

## Request

| Name          | In       | Type   | Required | Limits                  | Description                                                     |
| ------------- | -------- | ------ | -------- | ----------------------- | --------------------------------------------------------------- |
| file          | formData | file   | Yes      |                         | Audio file (mp3, wav, flac, ogg/opus). Up to 10 minutes, 150MB. |
| cutoffFreq    | formData | number | No       | 20 to 300, default 90   | High-pass cutoff in Hz                                          |
| qFactor       | formData | number | No       | 0.1 to 5, default 0.707 | High-pass smoothness                                            |
| targetLufs    | formData | number | No       | -30 to -6, default -16  | Target loudness in LUFS                                         |
| truePeakDbfs  | formData | number | No       | -6 to 0, default -1     | Peak ceiling in dBFS                                            |
| compThreshDb  | formData | number | No       | -30 to 0, default -3.8  | Compressor threshold in dBFS                                    |
| compRatio     | formData | number | No       | 1 to 20, default 4      | Compressor ratio                                                |
| compAttackMs  | formData | number | No       | 0.1 to 100, default 5   | Compressor attack in ms                                         |
| compReleaseMs | formData | number | No       | 1 to 1000, default 50   | Compressor release in ms                                        |

## Responses

| Status | Description           |
| ------ | --------------------- |
| 200    | OK                    |
| 400    | Bad Request           |
| 401    | Unauthorized          |
| 402    | Payment Required      |
| 403    | Forbidden             |
| 413    | Payload Too Large     |
| 429    | Too Many Requests     |
| 500    | Internal Server Error |
| 503    | Service Unavailable   |
| 504    | Gateway Timeout       |

## Response

A success answers 200 with the envelope `{ data, success, statusCode, errorMessage }`. The `data` fields:

| Field                  | Type    | Description                                                |
| ---------------------- | ------- | ---------------------------------------------------------- |
| id                     | string  | The job id.                                                |
| status                 | string  | pending, processing, completed or failed.                  |
| fileName               | string  | The name of the uploaded file.                             |
| outputUrl              | string  | Time-limited link to the cleaned WAV.                      |
| durationSeconds        | number  | Length of the audio in seconds.                            |
| creditsConsumed        | integer | Credits charged, a whole number.                           |
| options                | object  | The tuning values the job ran with.                        |
| options.cutoffFreq     | number  | High-pass cutoff in Hz.                                    |
| options.qFactor        | number  | High-pass smoothness.                                      |
| options.targetLufs     | number  | Target loudness in LUFS.                                   |
| options.truePeakDbfs   | number  | Peak ceiling in dBFS.                                      |
| options.compThreshDb   | number  | Compressor threshold in dBFS.                              |
| options.compRatio      | number  | Compressor ratio.                                          |
| options.compAttackMs   | number  | Compressor attack in ms.                                   |
| options.compReleaseMs  | number  | Compressor release in ms.                                  |
| metrics                | object  | Measurements of the cleaned file.                          |
| metrics.sampleRate     | number  | Sample rate of the cleaned file in Hz.                     |
| metrics.integratedLufs | number  | Measured loudness of the cleaned file in LUFS.             |
| metrics.truePeakDbfs   | number  | Measured peak of the cleaned file in dBFS.                 |
| error                  | string  | The reason the job failed. Absent unless status is failed. |
| createdAt              | string  | When the job was created, ISO 8601 in UTC.                 |

```json
{
  "data": {
    "id": "66e3f2a1c9d4b8a1f0e12345",
    "status": "completed",
    "fileName": "noisy.wav",
    "outputUrl": "https://storage.example.com/cleaned/66e3f2a1c9d4b8a1f0e12345.wav?signature=abc",
    "durationSeconds": 12,
    "creditsConsumed": 207,
    "options": {
      "cutoffFreq": 90,
      "qFactor": 0.707,
      "targetLufs": -16,
      "truePeakDbfs": -1,
      "compThreshDb": -3.8,
      "compRatio": 4,
      "compAttackMs": 5,
      "compReleaseMs": 50
    },
    "metrics": {
      "sampleRate": 48000,
      "integratedLufs": -16.1,
      "truePeakDbfs": -1
    },
    "error": "The audio could not be cleaned.",
    "createdAt": "2026-10-11T10:21:04.512Z"
  },
  "success": true,
  "statusCode": 200,
  "errorMessage": null
}
```

## Errors

| Status | errorMessage                                                                 | When                                                                                                                                                                                                                                                                                       | Fix                                                                               |
| ------ | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| 400    | Multipart: Boundary not found                                                | The Content-Type header says multipart/form-data but carries no boundary, usually because the client set the header by hand.                                                                                                                                                               | Remove the hand-written header and let the client set it with the boundary.       |
| 400    | Unexpected file field - <name>                                               | The form has a part with a field name other than file, or more than one part named file (only one file is accepted).                                                                                                                                                                       | Send exactly one file part, and name it file.                                     |
| 400    | File is required                                                             | The form has no file part, or the request was not multipart at all.                                                                                                                                                                                                                        | Send a multipart form with one part named file.                                   |
| 400    | Unsupported file type: <type>. Please upload an audio file.                  | The part's Content-Type does not start with audio/; <type> is what the client sent.                                                                                                                                                                                                        | Set the part's type, for example audio/wav or audio/mpeg.                         |
| 400    | Audio exceeds the 10-minute limit.                                           | The file's duration is over 10 minutes.                                                                                                                                                                                                                                                    | Split the recording into parts of 10 minutes or less.                             |
| 400    | Could not read the audio length. Try another file.                           | The file is empty or could not be decoded as audio.                                                                                                                                                                                                                                        | Check the file plays, or export it again in a common format.                      |
| 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.                                                                                                                                                                                            | Send MP3, WAV, FLAC or OGG/Opus with a matching extension and type.               |
| 400    | targetLufs must not be greater than -6                                       | A tuning field is outside its range; the message names the field and the bound.                                                                                                                                                                                                            | Stay inside the minimum and maximum listed for the field.                         |
| 400    | property <name> should not exist                                             | The body or query carries a field the endpoint does not define.                                                                                                                                                                                                                            | Remove the field.                                                                 |
| 401    | Unauthorized                                                                 | The Authorization header is missing or is not Bearer ek\_..., no key matches the token, or the key is deleted, disabled or its account is closed.                                                                                                                                          | Send Authorization: Bearer ek\_... with an enabled key.                           |
| 402    | Insufficient subscription balance                                            | The workspace balance cannot cover the charge for this call; nothing ran and nothing was charged.                                                                                                                                                                                          | Add credits to the workspace.                                                     |
| 403    | Subscription not found                                                       | The workspace that owns the key has no subscription.                                                                                                                                                                                                                                       | Check the workspace's plan in the portal.                                         |
| 403    | Subscription expired or inactive                                             | The subscription is in a state other than active or trial.                                                                                                                                                                                                                                 | Renew the subscription.                                                           |
| 403    | This API key does not have access to Sound Cleaning services                 | The key is restricted and Sound Cleaning is not among its services.                                                                                                                                                                                                                        | Edit the key and turn Sound Cleaning on, or use another key.                      |
| 413    | File too large                                                               | The upload is over 150 MB; the request is cut off before the file is read.                                                                                                                                                                                                                 | Re-encode at a lower bitrate or as mono.                                          |
| 429    | ThrottlerException: Too Many Requests                                        | The key made more than 100 requests to one endpoint in 60 seconds, or one IP address made more than 100 requests to one endpoint in 60 seconds (the IP limit is counted before the key is checked, so it can answer with no key at all); a Retry-After header carries the seconds to wait. | Wait Retry-After seconds, then retry.                                             |
| 429    | Monthly spending limit exhausted                                             | The call would take the key past its Credit Limit for this billing cycle; nothing ran and there is no Retry-After header.                                                                                                                                                                  | Raise or clear the limit on the key, or wait for the next cycle.                  |
| 500    | Something went wrong                                                         | An error the API did not classify.                                                                                                                                                                                                                                                         | Check the request, then retry after a short wait; contact support if it persists. |
| 503    | Audio processing is temporarily unavailable. Please try again.               | Too many uploads were being measured at once, or measuring timed out; nothing was charged.                                                                                                                                                                                                 | Retry after a short wait.                                                         |
| 503    | Sound cleaning is temporarily unavailable. Please try again.                 | The cleaner could not be reached; the charge is refunded.                                                                                                                                                                                                                                  | Retry once.                                                                       |
| 503    | Database unavailable                                                         | A transient outage inside the API.                                                                                                                                                                                                                                                         | Retry after a short wait.                                                         |
| 504    | Database timed out                                                           | A transient timeout inside the API.                                                                                                                                                                                                                                                        | Retry after a short wait.                                                         |

## Code samples

:::tabs

```bash title="cURL"
curl -X POST "https://api.echonova.ai/v1/sound-cleaning" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@audio.mp3;type=audio/mpeg" \
  -F "cutoffFreq=value" \
  -F "qFactor=value" \
  -F "targetLufs=value" \
  -F "truePeakDbfs=value" \
  -F "compThreshDb=value" \
  -F "compRatio=value" \
  -F "compAttackMs=value" \
  -F "compReleaseMs=value"
```

```python
import requests

response = requests.post(
    "https://api.echonova.ai/v1/sound-cleaning",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    files={"file": ("audio.mp3", open("audio.mp3", "rb"), "audio/mpeg")},
    data={"cutoffFreq": "value", "qFactor": "value", "targetLufs": "value", "truePeakDbfs": "value", "compThreshDb": "value", "compRatio": "value", "compAttackMs": "value", "compReleaseMs": "value"},
)
print(response.json())
```

```javascript
import { readFile } from 'node:fs/promises';

const formData = new FormData();
formData.append('file', new Blob([await readFile('audio.mp3')], { type: 'audio/mpeg' }), 'audio.mp3');
formData.append('cutoffFreq', 'value');
formData.append('qFactor', 'value');
formData.append('targetLufs', 'value');
formData.append('truePeakDbfs', 'value');
formData.append('compThreshDb', 'value');
formData.append('compRatio', 'value');
formData.append('compAttackMs', 'value');
formData.append('compReleaseMs', 'value');

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());
```

:::
