Developer API
A REST API that converts music files, links and text into Jam Jam's songbook format (chords, lyrics, structure) or into portable exports (PDF, MIDI, MusicXML...). Same engine as the app, usable from your own scripts and agents.
Supported formats
The full, current list, with exact limits and what this server actually serves, is always at GET /formats. In short:
Input
- Audio & video files
- PDF (chords, lyrics, sheet music, tab, scanned songbook)
- Images (chords, lyrics, sheet music, tab)
- Plain text, ChordPro, OnSong
- Links & web search (page-link, web-search)
- MusicXML, MIDI
- JamSong, mixed .zip, songbook (pivot)
Output
- Songbook (JSON pivot, always available)
- PDF (chords, lyrics, sheet music, tab, grid)
- PNG, HTML, plain text, ChordPro
- chords-lab / chords-csv, key + BPM
- MusicXML, MIDI (Premium)
- Synced lyrics: .lrc, .srt
- Karaoke video (.mp4), backing audio, JamSong
Getting an API key
Create a free Jam Jam account, then open Settings, API keys in the app (mobile or web) and create a key. It starts with jj_live_ and is shown once: copy it right away. Up to 5 keys per account, revocable at any time.
Manage my API keysQuotas
Same counter as exporting from the notebook in the app: 10 conversions per rolling week on a free account, 500 per month on Premium. Anonymous calls (no key, no session) are limited to 3 per 24 hours. The exact balance is in GET /me/usage and in the X-Quota-* headers of every response that consumes quota.
How it works
Conversion is asynchronous: you submit a job, it queues, runs, and you fetch the result once done. Track it either by polling GET /jobs/{id} (respect Retry-After) or by opening a Server-Sent Events stream at GET /jobs/{id}/events.
Examples
List the formats this server serves
curl https://jam-jam.org/api/v1/formats Convert a file to PDF
curl -X POST https://jam-jam.org/api/v1/jobs \
-H "Authorization: Bearer jj_live_xxxxxxxxxxxxxxxx" \
-F [email protected] \
-F inputFormat=pdf-songbook \
-F output=pdf-songbook Convert a URL to a songbook
curl -X POST https://jam-jam.org/api/v1/jobs \
-H "Authorization: Bearer jj_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/tabs/wonderwall", "output": "songbook"}' Follow progress (SSE or polling)
# Server-Sent Events
curl -N -H "Authorization: Bearer jj_live_xxxxxxxxxxxxxxxx" \
https://jam-jam.org/api/v1/jobs/jb_123/events
# Polling
curl -H "Authorization: Bearer jj_live_xxxxxxxxxxxxxxxx" \
https://jam-jam.org/api/v1/jobs/jb_123 Download the result
curl -H "Authorization: Bearer jj_live_xxxxxxxxxxxxxxxx" \
-OJ https://jam-jam.org/api/v1/jobs/jb_123/result Python (requests)
import time
import requests
API = "https://jam-jam.org/api/v1"
HEADERS = {"Authorization": "Bearer jj_live_xxxxxxxxxxxxxxxx"}
# 1. Discover formats
formats = requests.get(f"{API}/formats").json()
# 2. Submit a conversion
resp = requests.post(
f"{API}/jobs",
headers=HEADERS,
json={"url": "https://example.com/tabs/wonderwall", "output": "songbook"},
)
resp.raise_for_status()
job = resp.json()
# 3. Poll until done (or use GET /jobs/{id}/events for SSE)
while job["phase"] not in ("done", "failed", "cancelled"):
time.sleep(job.get("etaS", 2))
job = requests.get(f"{API}/jobs/{job['id']}", headers=HEADERS).json()
# 4. Fetch the result
if job["phase"] == "done":
songbook = requests.get(f"{API}/jobs/{job['id']}/result/songbook", headers=HEADERS).json()
print(songbook["songs"][0]["title"])
else:
print("failed:", job.get("problem")) Errors
Every error, on every route, is an application/problem+json object (RFC 9457) with a stable code field a client can branch on: quota-exhausted, rate-limited, unsupported-pair, not-found... The full catalogue is in the OpenAPI schema (components.schemas.Problem).
Retention
Uploaded files and generated results are deleted 24 hours after the job is created. Nothing is kept longer, including failed jobs. Fetching a result past that window returns 410 Gone.
For AI agents
Read GET /openapi.json first: it documents the recommended call sequence (discover formats, submit, track, fetch), authentication and quotas in an x-agent-guide block meant to be parsed by a model. llms.txt on this site lists each conversion capability as its own entry.
MCP server
An official Model Context Protocol server, generated from this same OpenAPI spec, exposes the API as five tools: list_formats, convert_file, convert_text, get_job and get_usage. It handles polling, quota errors and file results for you, so an assistant like Claude Desktop, Claude Code or Cursor can convert a file without you writing any HTTP code.
Install
npx @jam-jam/convert-mcp Configuration (Claude Desktop, Claude Code, Cursor)
{
"mcpServers": {
"jam-convert": {
"command": "npx",
"args": ["-y", "@jam-jam/convert-mcp"],
"env": { "JAM_JAM_API_KEY": "jj_live_xxxxxxxxxxxxxxxx" }
}
}
} Tools
- list_formats: input and output formats served, with limits
- convert_file: local file path or base64 content in, downloaded result out
- convert_text: pasted text or ChordPro in, no file needed
- get_job: job status by id (phase, progress, artifacts)
- get_usage: the calling identity's quota balance
Open-source credits
This API stands on real open-source engines. Used honestly, credited by name:
- MuseScore 4 (GPL-3.0) : Notation import/render, sheet music PDF
- Audiveris (AGPL-3.0) : Optical Music Recognition (scanned sheet music)
- Tesseract OCR (Apache-2.0) : Text recognition in scanned pages and photos
- faster-whisper (MIT) : Speech-to-text for lyrics from audio
- Basic Pitch (Apache-2.0) : Note and melody detection from audio
- FluidSynth (LGPL-2.1) : Backing-track rendering from MIDI (SoundFont synthesis)
- FFmpeg (LGPL-2.1 / GPL-2.0) : Audio and video encoding, format conversion
- Chromium (BSD-3-Clause) : Headless rendering of sheet music and chord sheets to PDF