Guia

Masterizar áudio por uma API: curl, Python, Node, lote e MCP

A API do Jam Jam masteriza um arquivo de áudio no servidor com os mesmos ajustes da ferramenta gratuita do navegador. Você envia um arquivo, escolhe uma predefinição ou manda seus próprios ajustes, acompanha o trabalho e baixa um WAV. Este guia mostra o caminho completo em curl, Python e Node, o processamento em lote, o tratamento de erros e o servidor MCP para assistentes.

Masterizar uma música →

Ferramenta relacionada · Masterização de áudio grátis, no seu navegador

O que a API faz

A família /mastering da API REST do Jam Jam processa um arquivo de áudio com uma predefinição: equilibra o tom, acalma as sibilantes, ajusta a largura estéreo e leva o nível a um alvo de volume (streaming, Apple Music, Deezer, podcast ou club), com os ajustes da ferramenta web em jam-jam.org/app/mastering. O contrato OpenAPI 3.1 está em jam-jam.org/api/v1/openapi.json e a referência em jam-jam.org/developers. Um arquivo tem no máximo 200 MB e 10 minutos, mono ou estéreo (acima de dois canais, usam-se os dois primeiros), e é processado a 48 kHz. A saída é um WAV de 16 bits (wav-pcm16, o padrão) ou de 32 bits em ponto flutuante (wav-f32); a API não oferece 24 bits. O arquivo de origem é apagado assim que é decodificado e o resultado é guardado por 24 horas. Um processamento no servidor é reproduzível (mesmo arquivo, mesmos ajustes, mesma engineVersion), mas não é garantido idêntico bit a bit à exportação do navegador.

Masterizar uma música →

Obter uma chave e verificar seu acesso

Crie uma conta em jam-jam.org, abra Configurações e depois Chaves de API (jam-jam.org/app/prefs/api-keys) e crie uma chave com os escopos mastering:read e mastering:write. A chave começa com jj_live_, é mostrada uma única vez, e uma conta pode ter cinco. Guarde-a na variável de ambiente JAM_JAM_API_KEY, nunca em um repositório nem em uma linha de comando compartilhada. O processamento de um arquivo pela API (POST /mastering/jobs) está aberto a qualquer conta: 3 processamentos por semana ISO com uma conta gratuita, no mesmo contador da ferramenta web, e sem teto com Premium. Ler o contrato e listar ou salvar predefinições também está aberto a qualquer conta.

Ler o contrato em tempo real

GET /mastering/capabilities não precisa de chave. Ele devolve a versão do motor, a faixa e o passo de cada ajuste, os alvos de volume, as predefinições integradas e os limites, e com uma chave acrescenta renderAllowed e o saldo do seu contador. Leia-o em vez de fixar os limites no código. Cinco predefinições integradas são somente leitura e se usam como preset=builtin:<id>: builtin:balanced, builtin:warm, builtin:bright, builtin:punchy e builtin:crushed. Você também pode salvar até 50 predefinições suas (nome de no máximo 60 caracteres) com POST /mastering/presets e chamá-las pelo identificador.

Ler o contrato (sem chave)

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

Processar um arquivo com curl

O fluxo é o de todo trabalho do Jam Jam: um POST que responde 202, consultas até o fim e depois o download. O cabeçalho Idempotency-Key (16 a 80 caracteres entre A-Z, a-z, 0-9, _ e -) é obrigatório em toda escrita: repetir a mesma chave com o mesmo corpo devolve o mesmo trabalho sem uma segunda cobrança. O trabalho passa por queued, decoding, analyzing e rendering, e termina como done, failed, cancelled ou expired; depois de concluído traz um report com o volume integrado (LUFS) e o pico real (dBTP) antes e depois. Uma conta tem no máximo um processamento ativo e três em espera. O repositório de exemplos traz os mesmos passos como scripts numerados, de curl/09-mastering-capabilities.sh a curl/14-mastering-delete.sh.

Processar com uma predefinição integrada, acompanhar o trabalho e baixar o 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

Estes dois trechos condensam python/mastering_lib.py e javascript/mastering-lib.mjs do repositório de exemplos github.com/titouannwtt/jam-jam-api-examples (licença MIT): Python 3.10 ou superior com requests, Node 20 ou superior sem dependências. Os scripts completos acrescentam uma mensagem legível para cada código HTTP e rodam com python mastering.py master mix.wav --preset builtin:warm ou node mastering.mjs master mix.wav --preset builtin:warm.

Python (3.10 ou superior, 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 ou superior, sem dependências)

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

Seus próprios ajustes

Em vez de uma predefinição, envie os ajustes em JSON no campo settings: exatamente um dos dois, preset ou settings. O formato (MasteringSettingsV1) contém oito módulos, cada um com um value e um indicador enabled, um alvo de volume (streaming, apple, deezer, podcast ou club) e normalize. Os ajustes de tom são em decibéis e os demais em porcentagem, até 150; um valor fora da faixa ou do passo responde 422 invalid-settings com uma entrada por problema. Para reutilizar um conjunto de ajustes, salve-o com POST /mastering/presets e passe o identificador em preset. Os ajustes são copiados no envio: alterar a predefinição depois não muda um trabalho já iniciado.

Enviar seus próprios ajustes

{
  "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
}

Enviar seus próprios ajustes

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

Masterizar uma pasta inteira em lote

O repositório contém dois scripts de lote, python/mastering_batch.py e javascript/mastering-batch.mjs, que masterizam uma pasta com uma predefinição, um arquivo depois do outro. Três escolhas valem ser copiadas. Os arquivos são enviados um por vez, porque uma conta aceita um processamento ativo e três em espera. Um arquivo cujo nome-master.wav já existe é ignorado, então você pode reiniciar após uma interrupção. Diante de um 429 com espera curta (cinco minutos no máximo), o script aguarda Retry-After e reenvia o mesmo arquivo com a mesma chave de idempotência, e para diante de um 403 ou de um 429 longo, porque os arquivos seguintes falhariam do mesmo jeito.

Masterizar uma pasta, um arquivo por vez

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

Erros e cotas

Todo erro é um application/problem+json com um code estável que você pode testar, e as respostas de processamento trazem os cabeçalhos X-Mastering-Quota-Limit, X-Mastering-Quota-Remaining e X-Mastering-Quota-Reset. As contas Premium não têm teto de processamentos. Numa conta gratuita, um 429 com o código quota-exhausted indica que os processamentos da semana se esgotaram; qualquer outro 429 indica limite de taxa ou fila ocupada. Um processamento que falha ou é cancelado não é contado. O processamento de um arquivo pela API (POST /mastering/jobs) está aberto a qualquer conta: 3 processamentos por semana ISO com uma conta gratuita, no mesmo contador da ferramenta web, e sem teto com Premium. Ler o contrato e listar ou salvar predefinições também está aberto a qualquer conta.

Erros da masterização e o que fazer
StatusCódigoSignificado
401Chave ausente ou inválida.
403insufficient-scopeA chave não tem o escopo mastering:read ou mastering:write.
403premium-requiredO processamento não está aberto ao seu plano (veja renderAllowed em GET /mastering/capabilities).
409not-readyResultado pedido antes do fim do processamento.
410expiredAs 24 horas passaram: processe de novo.
413, 415, 422Arquivo grande demais, formato não suportado, áudio acima de 10 minutos ou ajustes inválidos (leia errors[]).
429rate-limitedRequisições demais, ou um processamento já em andamento e três na espera (client-quota), ou fila cheia (queue-full): espere Retry-After segundos e não entre em loop.

O servidor MCP para assistentes

O servidor MCP oficial @jam-jam/convert-mcp oferece o Mastering ao Claude Desktop, ao Claude Code, ao Cursor e a outros clientes do Model Context Protocol, e só mostra as ferramentas que os escopos da sua chave permitem. Seis ferramentas cobrem o Mastering: jj_mastering_capabilities (sem escopo), jj_list_mastering_presets, jj_create_mastering_preset, jj_master_audio, jj_mastering_get_job e jj_mastering_cancel_job. jj_master_audio envia um arquivo local com uma predefinição ou ajustes em linha e, com maxWaitMs, espera e baixa o resultado. Depois você pode pedir ao seu assistente que masterize um arquivo com a predefinição warm e diga o volume antes e depois. Coloque a chave no ambiente, nunca em uma linha de comando.

Configuração de um cliente MCP

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

Para entender o que os ajustes fazem e que volume buscar, leia nosso guia para masterizar uma música de graça.

Perguntas frequentes sobre a API de masterização

A API de masterização do Jam Jam é gratuita?

Sim. Com uma conta gratuita, POST /mastering/jobs processa 3 arquivos por semana ISO, no mesmo contador da ferramenta web; um processamento que falha ou é cancelado é devolvido. Premium remove o teto. Ler o contrato em tempo real e gerenciar suas predefinições não custa nada.

Quais são os limites de arquivo?

No máximo 200 MB e 10 minutos, mono ou estéreo. O resultado é um WAV de 48 kHz, de 16 bits, de 24 bits ou de 32 bits em ponto flutuante, guardado por 24 horas.

O resultado é idêntico ao do navegador?

É reproduzível no servidor (mesmo arquivo, mesmos ajustes, mesma engineVersion), mas não é garantido idêntico bit a bit à exportação do navegador. Os ajustes são os mesmos.

Posso enviar vários arquivos ao mesmo tempo?

Uma conta tem um processamento ativo e três em espera. Para uma pasta, envie os arquivos um por vez com os scripts de lote do repositório de exemplos.

Como usar com um assistente de IA?

Com o servidor MCP @jam-jam/convert-mcp: a ferramenta jj_master_audio masteriza um arquivo local e jj_mastering_get_job lê o volume antes e depois.

O mesmo motor pode ser testado de graça no seu navegador, com o arquivo ficando no seu dispositivo.