Nech.PL APIs · api.nech.pl/audio/v1 · Getting Started
Stem-aware audio analysis as simple HTTP calls — emotion (valence/arousal), a ~35-dim feature stack, per-sample role, loop grading, onsets/tempo, render-ready waveform & spectrogram (FFT-as-a-service), BS.1770 loudness, and naming. Upload a clip, get JSON. Identical audio is cached server-side, so repeats are free.
Your key carries scope api:* — full access to every Nech.PL API, present and future. Only /healthz is public; the interactive docs & spec need an api:docs scope, which your api:* key already covers.
Both are bearer-gated — open them with your key (e.g. a browser extension that sends Authorization: Bearer, or curl -H). Generate a client in any language from the spec.
B=https://api.nech.pl/audio/v1 # is it up? (no key needed) curl $B/healthz # who am I? curl -H "Authorization: Bearer $KEY" $B/me # analyse a clip curl -H "Authorization: Bearer $KEY" \ -F file=@track.wav $B/analyze/emotion
| Method & path | Returns |
|---|---|
| POST /analyze/emotion | valence/arousal + top emotions |
| POST /features | ~35-dim feature stack (spectral, MFCC, chroma/key, rhythm) |
| POST /analyze/samples | per-sample EDA + measured role (percs/bass/melodic/tops/atmos) |
| POST /analyze | emotion + features + sample role in one call |
| POST /grade | mechanical loop quality: 0–1 + S/A/B/C/D tier + flags |
| POST /onsets | onset times + tempo + onset rate |
| POST /waveform | [min,max] peaks + 0–1 RMS envelope (audio-reactive visuals) |
| POST /spectrum | downsampled spectrogram, bands×frames 0–1 (FFT-as-a-service) |
| POST /loudness | BS.1770 LUFS + sample/true peak + gain-to-target (−14/−9) |
| POST /naming | convention-compliant sample name from the measured role |
| POST /sources | fetch a URL's audio (yt-dlp) → 44.1k WAV, as a job → 202 {job_id}. ✨ the front door of the YouTube→emotion pipeline |
| GET /jobs/{id} · DELETE | poll an async job (status/progress/result) · cancel it |
| GET /artifacts/{cid}/{name} | download a stored artifact (fetched source WAV; later stems/loops). Range-capable |
| POST /separate | 503 stem separation — GPU runner pending; code against it now |
| GET /healthz | public: liveness probe (no token) |
| GET /docs · /openapi.json | interactive docs · spec — need an api:docs scope (your api:* token covers it) |
Hand the API a URL — YouTube, SoundCloud, Bandcamp, any http(s) yt-dlp supports — and read its mood. /sources fetches + transcodes to WAV as a background job; poll /jobs/{id}, grab the artifact, run /analyze/emotion. Re-fetching the same URL is instant (cached server-side).
B=https://api.nech.pl/audio/v1 ; H="Authorization: Bearer $KEY" # 1 · fetch a URL's audio as a job -> 202 { job_id } JID=$(curl -s -H "$H" -H "Content-Type: application/json" \ -d '{"url":"https://youtu.be/<id>"}' $B/sources | jq -r .job_id) # 2 · poll until done -> { content_id, artifact_ref } REF=$(curl -s -H "$H" $B/jobs/$JID | jq -r .result.artifact_ref) # 3 · download the WAV 4 · read its emotion curl -s -H "$H" $B/artifacts/$REF -o src.wav curl -s -H "$H" -F file=@src.wav $B/analyze/emotion | jq .emotion # -> { valence: 0.62, arousal: 0.78, top: ["energetic","uplifting", …] }
Same pipeline in TypeScript with @nech/api: submitSource → getJob (poll) → fetch artifact → analyzeEmotion. Heavier engines (/separate stems, loops) follow the same job shape.
The official client is generated from the OpenAPI spec, so it never drifts. Install from the private registry (needs your npm read token), then import the per-API subpath — runs on Node 18+, Vercel Functions and the Edge.
# .npmrc @nech:registry=https://npm.nech.pl/ //npm.nech.pl/:_authToken=${NECH_NPM_TOKEN} $ npm i @nech/api
import { AudioApi, Configuration } from "@nech/api/audio"; const audio = new AudioApi(new Configuration({ basePath: "https://api.nech.pl/audio/v1", accessToken: process.env.NECH_TOKEN!, })); const clip = await fetch(trackUrl).then(r => r.blob()); const mood = await audio.analyzeEmotion({ file: clip }); // { emotion: { valence, arousal, … } } const spec = await audio.spectrum({ file: clip, bands: 64, frames: 200 });
This is hand-built by ParVagues for the hydra-live-hexa Studio. Anything weird, a number that looks off, an endpoint you wish existed — just shout. Fast iterations, that's the point.
Welcome aboard. ⛵