Guida

Masterizzare audio tramite API: curl, Python, Node, batch e MCP

L’API di Jam Jam masterizza un file audio sul server con le stesse regolazioni dello strumento gratuito del browser. Carichi un file, scegli un preset o invii le tue regolazioni, segui il lavoro e scarichi un WAV. Questa guida mostra l’intero percorso in curl, Python e Node, l’elaborazione in batch, la gestione degli errori e il server MCP per gli assistenti.

Masterizza un brano →

Strumento consigliato · Mastering audio gratuito, nel tuo browser

Cosa fa l’API

La famiglia /mastering dell’API REST di Jam Jam elabora un file audio con un preset: bilancia il tono, calma le sibilanti, regola l’ampiezza stereo e porta il livello a un obiettivo di volume (streaming, Apple Music, Deezer, podcast o club), con le regolazioni dello strumento web su jam-jam.org/app/mastering. Il contratto OpenAPI 3.1 è su jam-jam.org/api/v1/openapi.json e il riferimento su jam-jam.org/developers. Un file pesa al massimo 200 MB e dura al massimo 10 minuti, mono o stereo (oltre due canali si usano i primi due), e viene elaborato a 48 kHz. L’uscita è un WAV a 16 bit (wav-pcm16, predefinito) o a 32 bit in virgola mobile (wav-f32); l’API non offre i 24 bit. Il file sorgente viene cancellato appena decodificato e il risultato è conservato 24 ore. Un’elaborazione sul server è riproducibile (stesso file, stesse regolazioni, stessa engineVersion), ma non è garantita identica bit per bit all’esportazione del browser.

Masterizza un brano →

Ottenere una chiave e verificare il tuo accesso

Crea un account su jam-jam.org, apri Impostazioni poi Chiavi API (jam-jam.org/app/prefs/api-keys) e crea una chiave con gli ambiti mastering:read e mastering:write. La chiave inizia con jj_live_, viene mostrata una sola volta e un account può averne cinque. Conservala nella variabile d’ambiente JAM_JAM_API_KEY, mai in un repository né su una riga di comando condivisa. L’elaborazione di un file tramite API (POST /mastering/jobs) è aperta a ogni account: 3 elaborazioni per settimana ISO con un account gratuito, sullo stesso contatore dello strumento web, senza tetto con Premium. Leggere il contratto e elencare o salvare preset è aperto a ogni account.

Leggere il contratto in tempo reale

GET /mastering/capabilities non richiede chiave. Restituisce la versione del motore, l’intervallo e il passo di ogni regolazione, gli obiettivi di volume, i preset integrati e i limiti, e con una chiave aggiunge renderAllowed e il saldo del tuo contatore. Leggilo invece di scrivere i limiti nel codice. Cinque preset integrati sono in sola lettura e si usano come preset=builtin:<id>: builtin:balanced, builtin:warm, builtin:bright, builtin:punchy e builtin:crushed. Puoi anche salvare fino a 50 preset tuoi (nome di 60 caratteri al massimo) con POST /mastering/presets e richiamarli per identificatore.

Leggere il contratto (nessuna chiave richiesta)

curl https://jam-jam.org/api/v1/mastering/capabilities

Elaborare un file con curl

Il percorso è quello di ogni lavoro di Jam Jam: un POST che risponde 202, interrogazioni fino alla fine, poi il download. L’intestazione Idempotency-Key (da 16 a 80 caratteri tra A-Z, a-z, 0-9, _ e -) è obbligatoria a ogni scrittura: ripetere la stessa chiave con lo stesso corpo restituisce lo stesso lavoro senza un secondo addebito. Il lavoro passa per queued, decoding, analyzing e rendering, poi termina come done, failed, cancelled o expired; una volta finito riporta un report con il volume integrato (LUFS) e il picco reale (dBTP) prima e dopo. Un account ha al massimo un’elaborazione attiva e tre in attesa. Il repository di esempi include gli stessi passi come script numerati, da curl/09-mastering-capabilities.sh a curl/14-mastering-delete.sh.

Elaborare con un preset integrato, seguire il lavoro, scaricare il WAV

# 1. Upload the file with a built-in preset (Idempotency-Key is required)
curl -X POST https://jam-jam.org/api/v1/mastering/jobs \
  -H "Authorization: Bearer $JAM_JAM_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -F [email protected] -F preset=builtin:warm -F format=wav-pcm16
# The 202 answer carries the job "id": JOB_ID=<that id>

# 2. Follow the job, honouring Retry-After, until "status" is "done"
curl https://jam-jam.org/api/v1/mastering/jobs/$JOB_ID \
  -H "Authorization: Bearer $JAM_JAM_API_KEY"

# 3. Download the mastered WAV
curl -o mix-master.wav https://jam-jam.org/api/v1/mastering/jobs/$JOB_ID/result \
  -H "Authorization: Bearer $JAM_JAM_API_KEY"

Python e Node

Questi due frammenti condensano python/mastering_lib.py e javascript/mastering-lib.mjs dal repository di esempi github.com/titouannwtt/jam-jam-api-examples (licenza MIT): Python 3.10 o successivo con requests, Node 20 o successivo senza dipendenze. Gli script completi aggiungono un messaggio leggibile per ogni codice HTTP e si lanciano con python mastering.py master mix.wav --preset builtin:warm oppure node mastering.mjs master mix.wav --preset builtin:warm.

Python (3.10 o successivo, requests)

import os, time, uuid, requests

API = "https://jam-jam.org/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['JAM_JAM_API_KEY']}"}
FINAL = ("done", "failed", "cancelled", "expired")

# 1. Upload the file with a built-in preset. Idempotency-Key is required.
with open("mix.wav", "rb") as audio:
    res = requests.post(
        f"{API}/mastering/jobs",
        headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
        data={"preset": "builtin:warm", "format": "wav-pcm16"},
        files={"file": ("mix.wav", audio)},
    )
res.raise_for_status()
job = res.json()

# 2. Poll, waiting as long as the server asks.
while job["status"] not in FINAL:
    time.sleep(int(res.headers.get("Retry-After") or 2))
    res = requests.get(f"{API}/mastering/jobs/{job['id']}", headers=HEADERS)
    res.raise_for_status()
    job = res.json()
if job["status"] != "done":
    raise SystemExit(f"mastering {job['status']}: {job.get('error')}")

before, after = job["report"]["before"], job["report"]["after"]
print(f"LUFS {before['integratedLufs']} -> {after['integratedLufs']}")

# 3. Download the mastered WAV.
audio = requests.get(f"{API}/mastering/jobs/{job['id']}/result", headers=HEADERS)
audio.raise_for_status()
with open("mix-master.wav", "wb") as out:
    out.write(audio.content)

Node (20 o successivo, senza dipendenze)

import { openAsBlob } from 'node:fs';
import { writeFile } from 'node:fs/promises';

const API = 'https://jam-jam.org/api/v1';
const headers = { Authorization: `Bearer ${process.env.JAM_JAM_API_KEY}` };
const FINAL = ['done', 'failed', 'cancelled', 'expired'];

// 1. Upload the file with a built-in preset. Idempotency-Key is required.
const body = new FormData();
body.append('file', await openAsBlob('mix.wav'), 'mix.wav');
body.append('preset', 'builtin:warm');
body.append('format', 'wav-pcm16');
let res = await fetch(`${API}/mastering/jobs`, {
  method: 'POST',
  headers: { ...headers, 'Idempotency-Key': crypto.randomUUID() },
  body,
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
let job = await res.json();

// 2. Poll, waiting as long as the server asks.
while (!FINAL.includes(job.status)) {
  await new Promise((r) => setTimeout(r, (Number(res.headers.get('retry-after')) || 2) * 1000));
  res = await fetch(`${API}/mastering/jobs/${job.id}`, { headers });
  if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
  job = await res.json();
}
if (job.status !== 'done') throw new Error(`mastering ${job.status}: ${JSON.stringify(job.error)}`);

const { before, after } = job.report;
console.log(`LUFS ${before.integratedLufs} -> ${after.integratedLufs}`);

// 3. Download the mastered WAV.
res = await fetch(`${API}/mastering/jobs/${job.id}/result`, { headers });
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
await writeFile('mix-master.wav', Buffer.from(await res.arrayBuffer()));

Le tue regolazioni

Al posto di un preset, invia le regolazioni in JSON nel campo settings: esattamente uno dei due, preset o settings. Il formato (MasteringSettingsV1) contiene otto moduli, ciascuno con un value e un indicatore enabled, un obiettivo di volume (streaming, apple, deezer, podcast o club) e normalize. Le regolazioni del tono sono in decibel e le altre in percentuale, fino a 150; un valore fuori dall’intervallo o dal passo risponde 422 invalid-settings con una voce per problema. Per riutilizzare un insieme di regolazioni, salvalo con POST /mastering/presets e passa il suo identificatore in preset. Le regolazioni vengono copiate al caricamento: modificare il preset dopo non cambia un lavoro già avviato.

Inviare le tue regolazioni

{
  "modules": {
    "autoEq":   { "value": 50, "enabled": true },
    "lows":     { "value": 2, "enabled": true },
    "mids":     { "value": -0.5, "enabled": true },
    "highs":    { "value": -1.5, "enabled": true },
    "deEss":    { "value": 40, "enabled": true },
    "width":    { "value": 10, "enabled": true },
    "loudness": { "value": 45, "enabled": true },
    "destruct": { "value": 0, "enabled": false }
  },
  "target": "streaming",
  "normalize": false
}

Inviare le tue regolazioni

curl -X POST https://jam-jam.org/api/v1/mastering/jobs \
  -H "Authorization: Bearer $JAM_JAM_API_KEY" -H "Idempotency-Key: $(uuidgen)" \
  -F [email protected] -F "settings=<samples/mastering-settings.json" -F format=wav-pcm16

Masterizzare un’intera cartella in batch

Il repository contiene due script batch, python/mastering_batch.py e javascript/mastering-batch.mjs, che masterizzano una cartella con un preset, un file dopo l’altro. Tre scelte vale la pena riprendere. I file partono uno alla volta, perché un account accetta un’elaborazione attiva e tre in attesa. Un file il cui nome-master.wav esiste già viene saltato, così puoi rilanciare dopo un’interruzione. Davanti a un 429 con attesa breve (cinque minuti al massimo) lo script aspetta Retry-After e ripete lo stesso file con la stessa chiave di idempotenza, e si ferma davanti a un 403 o a un 429 lungo, perché i file successivi fallirebbero allo stesso modo.

Masterizzare una cartella, un file alla volta

python mastering_batch.py ~/Music/mixes --preset builtin:balanced --out masters
node mastering-batch.mjs ~/Music/mixes --preset builtin:balanced --out masters

Errori e quote

Ogni errore è un application/problem+json con un code stabile da verificare, e le risposte di elaborazione portano le intestazioni X-Mastering-Quota-Limit, X-Mastering-Quota-Remaining e X-Mastering-Quota-Reset. Gli account Premium non hanno un tetto di elaborazioni. Con un account gratuito, un 429 con il codice quota-exhausted segnala che le elaborazioni della settimana sono esaurite; ogni altro 429 segnala un limite di frequenza o una coda occupata. Un’elaborazione fallita o annullata non viene conteggiata. L’elaborazione di un file tramite API (POST /mastering/jobs) è aperta a ogni account: 3 elaborazioni per settimana ISO con un account gratuito, sullo stesso contatore dello strumento web, senza tetto con Premium. Leggere il contratto e elencare o salvare preset è aperto a ogni account.

Errori del mastering e cosa fare
StatoCodiceSignificato
401Chiave assente o non valida.
403insufficient-scopeLa chiave non ha l’ambito mastering:read o mastering:write.
403premium-requiredL’elaborazione non è aperta al tuo piano (vedi renderAllowed in GET /mastering/capabilities).
409not-readyRisultato richiesto prima della fine dell’elaborazione.
410expiredLe 24 ore sono passate: rielabora.
413, 415, 422File troppo grande, formato non supportato, audio oltre 10 minuti o regolazioni non valide (leggi errors[]).
429rate-limitedTroppe richieste, oppure un’elaborazione già in corso e tre in attesa (client-quota), o coda piena (queue-full): attendi Retry-After secondi e non andare in loop.

Il server MCP per gli assistenti

Il server MCP ufficiale @jam-jam/convert-mcp offre il Mastering a Claude Desktop, Claude Code, Cursor e agli altri client Model Context Protocol, e mostra solo gli strumenti consentiti dagli ambiti della tua chiave. Sei strumenti coprono il Mastering: jj_mastering_capabilities (senza ambito), jj_list_mastering_presets, jj_create_mastering_preset, jj_master_audio, jj_mastering_get_job e jj_mastering_cancel_job. jj_master_audio carica un file locale con un preset o con regolazioni in linea e, con maxWaitMs, attende e scarica il risultato. Puoi poi chiedere al tuo assistente di masterizzare un file con il preset warm e di dirti il volume prima e dopo. Metti la chiave nell’ambiente, mai su una riga di comando.

Configurazione di un client MCP

{
  "mcpServers": {
    "jam-jam": {
      "command": "npx",
      "args": ["-y", "@jam-jam/convert-mcp"],
      "env": { "JAM_JAM_API_KEY": "jj_live_..." }
    }
  }
}

Per capire cosa fanno le regolazioni e che volume puntare a raggiungere, leggi la nostra guida per masterizzare un brano gratis.

Domande frequenti sull’API di mastering

L’API di mastering di Jam Jam è gratuita?

Sì. Con un account gratuito, POST /mastering/jobs elabora 3 file per settimana ISO, sullo stesso contatore dello strumento web; un’elaborazione fallita o annullata viene restituita. Premium toglie il tetto. Leggere il contratto in tempo reale e gestire i tuoi preset non costa nulla.

Quali sono i limiti dei file?

Al massimo 200 MB e 10 minuti, mono o stereo. Il risultato è un WAV a 48 kHz, a 16 bit, a 24 bit o a 32 bit in virgola mobile, conservato 24 ore.

Il risultato è identico a quello del browser?

È riproducibile sul server (stesso file, stesse regolazioni, stessa engineVersion) ma non è garantito identico bit per bit all’esportazione del browser. Le regolazioni sono le stesse.

Posso inviare più file contemporaneamente?

Un account ha un’elaborazione attiva e tre in attesa. Per una cartella, invia i file uno alla volta con gli script batch del repository di esempi.

Come si usa con un assistente IA?

Con il server MCP @jam-jam/convert-mcp: lo strumento jj_master_audio masterizza un file locale e jj_mastering_get_job legge il volume prima e dopo.

Lo stesso motore si prova gratis nel tuo browser, con il file che resta sul tuo dispositivo.