/api
Live · self-serve keysAudio analysis as an API.
Most teams script ffmpeg for loudness checks, or ship audio to a cloud they don’t control. AudioLab puts loudness, voice quality, and signal analysis behind one key, and it can run right in the browser, so the audio never has to leave the user’s device.
Drop your own file in the playground below and see the exact JSON response in seconds. No signup, nothing uploaded.
The same job, three ways. The difference is who hosts the audio, how many tools you wire together, and who maintains it.
Scripting ffmpeg yourself
Free, but you build and babysit the pipeline. It only does loudness, there is no voice or signal layer, and it lives in your infra.
A cloud audio API
Capable, but every file is uploaded to a server you do not control, usually US-hosted, and most vendors do exactly one thing.
AudioLab
One key for loudness, voice, and signal. It can run client-side, so the audio can stay on the user device. EU-hosted, DSP verified against reference tools.
Concrete numbers, not vibes. One file in, structured JSON out. Pick the lab that fits the problem.
MixLab
loudness + dynamicsIntegrated LUFS, true-peak, loudness range, crest factor, stereo correlation, and a tonal-balance spectrum.
Know if a track hits −14 LUFS, clips, or has a boomy low-end, before it ships.
VoiceLab
speech qualitySpeech/silence ratio, pacing, signal-to-noise, room echo, sibilance and clipping risk.
Catch a noisy, echoey, or clipped voice take automatically.
SignalLab
index + tagsContent type, tags, clipping and silence regions, brightness and dynamics buckets, file metadata.
Tag and triage a whole library: what is it, is it clean, where is the silence.
LUFS-QC every episode before publish, without uploading unreleased audio.
Loudness and clarity QC on generated speech, right in your pipeline.
Embed analysis without building or hosting the DSP yourself.
Show creators their loudness and dynamics before they submit.
Don’t take the loudness numbers on faith. Here is the engine run against the canonical
EBU Tech 3341/3342 and ITU-R BS.1770-4 reference signals, checked against the standard’s own
tolerances. Reproduce it: node scripts/loudness-benchmark.mjs.
- Integrated loudness 3341-1
Stereo 1 kHz sine at −23 dBFS → −23.0 LUFS (absolute calibration)
-22.99 LUFStarget -23 · ±0.1 LUPass - Integrated loudness 3341-2
Stereo 1 kHz sine at −33 dBFS → −33.0 LUFS (linearity)
-32.99 LUFStarget -33 · ±0.1 LUPass - Integrated loudness gate-abs
Silence → −23 dBFS tone → silence: −70 LUFS absolute gate excludes silence → −23.0 LUFS
-23.04 LUFStarget -23 · ±0.1 LUPass - Integrated loudness gate-rel
−23 dBFS then −40 dBFS: −10 LU relative gate drops the quiet block → −23.0 LUFS
-23.06 LUFStarget -23 · ±0.1 LUPass - True peak tp-997
997 Hz sine at 0 dBFS → true peak 0.0 dBTP (BS.1770-4 true-peak)
0 dBTPtarget 0 · +0.2 / −0.4 dBPass
Extended observations
- Loudness range 3342-1
−20 dBFS and −30 dBFS blocks → loudness range ≈ 10 LU (EBU 3342)
10 LUtarget 10 · ±1 LUPass - True peak tp-isp
12 kHz 0 dBFS, π/4 phase: samples sit at −3.0 dBFS, testing inter-sample peak detection (true peak should rise above sample peak)
-1.07 dBTPtarget 0 · +0.2 / −0.4 dBInfo
We measure what we claim. Per-task accuracy (scene, pitch, beat) and server-side research benchmarks aren’t claimed until the same kind of harness backs them.
This is the API, running client-side. Drop a file, switch endpoints, and copy a request that returns the exact JSON you see. Nothing uploads; your file stays in the browser.
This playground runs the identical engine client-side, so the response below is exactly what the hosted API returns. Your file never leaves the browser. The hosted API is live with self-serve keys at audiolab.tools/v1/*.
curl https://audiolab.tools/v1/mixlab/analyze \
-H "Authorization: Bearer $AUDIOLAB_KEY" \
-F file=@track.wavLoudness, dynamics, spectrum
From nothing to a real response in under two minutes. No account required to see the shape.
Drop a file
Use the playground above. It runs the engine in your browser, no key, no upload.
Open the playground 02Copy the request
Grab the cURL, JavaScript, or Python snippet, already shaped to the response you just saw.
Grab the snippet 03Add your key
Add your Bearer key and POST to audiolab.tools/v1/* (the same JSON you just saw). Self-serve keys with a free tier, live now.
Get a keycurl https://audiolab.tools/v1/mixlab/analyze \
-H "Authorization: Bearer $AUDIOLAB_KEY" \
-F file=@track.wav Each takes a multipart audio file and returns structured JSON. Full schemas live in the OpenAPI spec.
- POST
/v1/mixlab/analyzeLoudness (BS.1770-4), true-peak, dynamics, stereo image, and a tonal-balance spectrum.
- POST
/v1/voicelab/qaSpeech quality: clarity, pacing, filler/silence ratio, room echo, SNR, and clipping risk.
- POST
/v1/signallab/indexA metadata index: content type, tags, clipping/silence regions, brightness, and dynamics buckets.
- GET
/v1/jobs/:idPoll a long-running job. Most analyses complete in under a second and return inline.
Every field each endpoint returns, mirrored 1:1 from the engine types via the OpenAPI contract, so this reference can’t drift from what the API actually sends.
MixLab: analyze POST /v1/mixlab/analyze 29 fields
| Field | Type | Notes |
|---|---|---|
| durationSec* | number | |
| sampleRate* | integer | |
| channels* | integer | |
| integratedLufs* | number | Integrated loudness (LUFS), BS.1770-4. |
| shortTermLufsMax | number | |
| loudnessRange | number | LRA (LU). |
| truePeakDb* | number | True peak (dBTP). |
| peakDb | number | |
| rmsDb | number | |
| crestFactorDb | number | |
| stereoWidth | number | |
| midSideRatio | number | |
| stereoCorrelation | number | |
| monoCompatible | boolean | |
| spectralCentroidHz | number | |
| spectralRolloffHz | number | |
| spectralFlatness | number | |
| lowEndDensity | number | |
| bandEnergy | Band | |
| harshness.score | number | |
| harshness.label | string | Low | Medium | High |
| harshness.band | string | |
| muddiness.score | number | |
| muddiness.label | string | Low | Medium | High |
| spectrum.freqs | number[] | |
| spectrum.mags | number[] | |
| waveform | number[] | Downsampled waveform peaks. |
| shortTermLufs | number[] | |
| fileName | string |
MixLab: check-target POST /v1/mixlab/check-target 10 fields
| Field | Type | Notes |
|---|---|---|
| pass* | boolean | True only if both LUFS within ±0.5 LU of target and true-peak ≤ target+0.5 dB. |
| target.lufs | number | Target integrated loudness (LUFS). |
| target.tp | number | Target maximum true-peak (dBTP). |
| target.label | string | Human-readable target name (e.g. "Spotify"). |
| measurements.integratedLufs | number | |
| measurements.truePeakDb | number | |
| measurements.lufsDelta | number | measured - target. |
| measurements.tpDelta | number | measured - target. |
| issues* | object[] | |
| ffmpegFix | string | ffmpeg loudnorm one-liner to fix when failing; null when passing. |
MixLab: timeseries POST /v1/mixlab/timeseries 8 fields
| Field | Type | Notes |
|---|---|---|
| durationSec* | number | |
| sampleRate | integer | |
| loudnessOverTime* | SeriesArray | |
| waveformOverTime* | SeriesArray | |
| summary.integratedLufs | number | |
| summary.shortTermLufsMax | number | |
| summary.loudnessRange | number | |
| summary.truePeakDb | number |
MixLab: spectrum POST /v1/mixlab/spectrum 8 fields
| Field | Type | Notes |
|---|---|---|
| sampleRate* | integer | |
| spectralCentroidHz | number | |
| spectralRolloffHz | number | |
| spectralFlatness | number | |
| bandEnergy* | Band | |
| spectrum.freqs | number[] | |
| spectrum.mags | number[] | |
| spectrum.count | integer |
VoiceLab: qa POST /v1/voicelab/qa 25 fields
| Field | Type | Notes |
|---|---|---|
| durationSec* | number | |
| sampleRate* | integer | |
| speechSec | number | |
| silenceSec | number | |
| speechRatio* | number | |
| segments | VoiceSegment[] | |
| estimatedSyllableRate | number | |
| speakingRateLabel | string | Slow | Normal | Fast | Variable |
| pacingVariance | number | |
| longSilences | number | |
| burstiness | number | |
| peakDb | number | |
| averageSpeechRms | number | |
| averageSpeechRmsDb | number | |
| noiseFloorDb | number | |
| signalToNoiseDb | number | |
| clipping.count | integer | |
| clipping.severity | string | None | Low | Medium | High |
| brightness | number | |
| roomEchoScore | number | |
| roomEchoLabel | string | Dry | Tight | Live | Reverberant |
| sibilanceRisk | string | Low | Medium | High |
| rmsEnvelope | number[] | |
| voicedMask | boolean[] | |
| fileName | string |
VoiceLab: segments POST /v1/voicelab/segments 6 fields
| Field | Type | Notes |
|---|---|---|
| durationSec* | number | |
| speechSec | number | |
| silenceSec | number | |
| speechRatio* | number | 0..1 fraction of audio that is voiced. |
| longSilences | number | Count of unusually long silences (e.g. potential dead air). |
| segments* | SpeechSegment[] |
SignalLab: index POST /v1/signallab/index 25 fields
| Field | Type | Notes |
|---|---|---|
| fileName* | string | |
| fileSizeKb | number | |
| format | string | |
| durationSec* | number | |
| sampleRate* | integer | |
| channels* | integer | |
| bitDepthGuess | string | |
| peakDb | number | |
| rmsDb | number | |
| noiseFloorDb | number | |
| dcOffset | number | |
| hasClipping | boolean | |
| clippingRegions | integer | |
| silenceRegions | integer | |
| silenceTotalSec | number | |
| contentTypeGuess* | string | voice | music | mixed | noise | silence |
| contentConfidence | number | |
| brightnessBucket | string | Dark | Balanced | Bright | Very bright |
| dynamicsBucket | string | Flat | Compressed | Modern | Dynamic |
| dominantBand | string | |
| monophonicProbability | number | |
| regions | TimelineRegion[] | |
| energyEnvelope | number[] | |
| centroidEnvelope | number[] | |
| tags | string[] |
Shared types Band · VoiceSegment · TimelineRegion · SeriesArray · SpeechSegment
| sub | number | |
| bass | number | |
| lowMid | number | |
| mid | number | |
| highMid | number | |
| presence | number | |
| air | number |
| startSec | number | |
| endSec | number | |
| meanRms | number |
| startSec | number | |
| endSec | number | |
| kind | string | voice | silence | music | noise | clipping |
| confidence | number |
| intervalSec | number | Seconds between samples. |
| count | integer | Number of samples. |
| samples | number[] | |
| unit | string | Unit of measurement (e.g. "LUFS", "peak (-1..1)"). |
| startSec | number | |
| endSec | number | |
| durationSec | number | |
| meanRmsDb | number | Mean RMS of the segment in dBFS. |
* required · generated from the OpenAPI spec (public/openapi.yaml)
The hosted API will use a bearer key in the Authorization
header, issued from your dashboard. Keys and billing open once VAT registration clears. Until then the
playground needs no key, and your audio never leaves the browser.
Authorization: Bearer al_live_xxx issued from the dashboard · preview
AudioLab ships an MCP server + a Claude Code plugin so any AI agent (Claude Code, Claude Desktop, Cursor) can analyze audio (eight tools, one install), plus AI-native docs so an agent can read the engine without scraping marketing.
Add to Claude →
- analyze_loudness · check_target
- analyze_voice · get_spectrum
- + 4 more · A/B compare
Eight tools over MCP. One command in Claude Code wires up the skill + server; bring an API key.
llms.txt
An LLM-readable map of the engine, API, and labs. The convention agents look for first.
CLAUDE.md
Drop it in your repo so your agent knows how to reach AudioLab, with the honest preview scope baked in.
Building on audio? Get a key.
The hosted API is live at audiolab.tools/v1/*. Self-serve keys with a free tier, live now. Add it to Claude or any agent in one page, or call the REST API directly. Building something bigger? Email partners@audiolab.tools.