Jam Jam

org.jam-jamPublished by jam-jam.orgv0.3.1Updated Oct 30, 2026

Turn audio, PDF, photos and text into chord sheets and manage your Jam Jam songbook with AI.

The publisher's own server: convert.express

Overview

AI-generated overview

Jam Jam converts audio, PDFs, photos and text into chord sheets and lets an assistant manage a Jam Jam songbook, playlists, stems and mastering.

What you can do
  • Check account allowances and list the input/output formats the API currently serves
  • Convert a local file or pasted text into chord sheets, PDF, MIDI and other formats, then poll the job
  • Read and write the private notebook: list, get, create, update and delete songs and playlists
  • Browse public profiles, published songs and playlists, and the account's own followers and following
  • Separate audio into stems, analyse chords and lyrics, detect AI-generated music, and render mastering presets
When to use it
Useful when you want an assistant to turn recordings, lead sheets or lyric text into chord sheets, or to file, edit and organise songs and playlists in a Jam Jam notebook. Also fits audio work such as stem separation, chord/lyric alignment, AI-music detection and mastering.
Requirements
Runs as a local stdio process (npm package) on a desktop machine. Needs a Jam Jam account and an API key supplied in the JAM_JAM_API_KEY environment variable, created in the account's API key settings. Network access to the Jam Jam API is required.
Before you install
The API key is a secret with access to the account's private notebook and quotas. Many tools write or delete data: songs and playlists can be created, updated, deleted or published publicly, and jobs cancelled. Uploaded audio and files are sent to the Jam Jam servers, and conversions, separations, analyses and mastering consume metered quotas.

Installation

In SourceWeft

  1. Open Jam Jam in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Tools

42

jj_check_usage

Check quotas and what this key may do

Returns, in one call, what the calling Jam Jam identity is allowed to do and how much of each allowance is left. THREE INDEPENDENT COUNTERS, they never borrow from one another: `conversion` (10 per week on a free account, 500 per calendar month on Premium, 3 per 24h anonymous), `read` (2000 per UTC day free, 20000 Premium, spent by the notebook and social listing tools) and `write` (200 per UTC day free, 5000 Premium, spent by the notebook writing tools). Stem separation and AI music detection keep their own counters, read with jj_stems_capabilities and jj_ai_music_availability. `scopes` lists the permissions of the API key in use. Call this before a batch, and after a quota error to learn when it resets. Costs nothing itself.

Takes no parameters.

jj_list_formats

List conversion formats

Lists the input and output formats actually served by the Jam Jam API right now (GET /formats), with their limits (maxBytes, maxPages, maxDurationS) and whether they require an account or Premium. Call this FIRST, before jj_convert_file or jj_convert_text, to know which output ids are valid for a given input. Pass "input" to get the exact list of possible outputs for that one input format. Needs no API key.

Parametersinputlocale

jj_convert_file

Convert a local file

Uploads a local file (path, or base64 content) to the Jam Jam API, waits for the conversion to finish, and returns the result: embedded text for small text formats (ChordPro, .lrc, .lab...), or a local file path for binary formats (PDF, MIDI, MP4...). Call jj_list_formats first to find valid "output" ids for your input. Consumes one unit of the conversion quota (10/week free, 500/month Premium, see jj_check_usage), which is a different counter from notebook reads and writes.

ParameterspathoutputrequireddeliveroptionsfilenamemaxWaitMsinputFormatcontentBase64

jj_convert_text

Convert pasted text or ChordPro

Sends plain text or ChordPro (pasted lyrics and chords, no file) to the Jam Jam API, waits for the conversion to finish, and returns the result: embedded text for small text formats, or a local file path for binary formats (PDF, MIDI...). Call jj_list_formats first to find valid "output" ids. Consumes one unit of the conversion quota.

ParameterstextrequiredoutputrequireddeliveroptionsmaxWaitMsinputFormat

jj_get_job

Get a conversion job status

Fetches the current state of a conversion job by id: phase (queued/running/done/failed/cancelled), per-step progress, and the list of artifacts once done. Use this to check on a job after jj_convert_file or jj_convert_text stopped waiting for it.

Parametersidrequired

jj_list_songs

List my notebook songs

Lists the songs in the calling account's PRIVATE Jam Jam notebook, page by page, oldest update first. fields="summary" (default) gives id, title, artist, key, capo, bpm, playlistIds and updatedAt; fields="full" adds the complete pivot payload (chords, lyrics, sections) and lowers the page cap to 25. Use the returned nextCursor to get the next page, and stop when it is null. Consumes one unit of the daily READ quota (2000/day free, 20000 Premium), never a conversion.

ParameterslimitcursorfieldsupdatedSince

jj_get_song

Get one notebook song

Returns one song of the calling account's notebook in full: the summary fields AND `song`, the canonical pivot payload (sections, lines, chords with their offsets, lyrics, detectedKey, metadata). That payload is exactly what jj_create_song and jj_update_song accept, so reading then writing back is a copy, not a translation. An unknown id and an id belonging to another account both return the same not-found error.

ParameterssongIdrequired

jj_list_playlists

List my notebook playlists

Lists the playlists of the calling account's notebook. Playlists are FLAT and allow multi-membership: `songIds` is the ORDERED list of song ids, and one song can appear in several playlists. Same cursor pagination and same updatedSince incremental filter as jj_list_songs. Consumes one unit of the daily read quota.

ParameterslimitcursorupdatedSince

jj_get_playlist

Get one notebook playlist and its songs

Returns one playlist of the calling account's notebook with its songs in summary form, in playlist order, paginated by the same opaque cursor. A song the playlist still references but that has since been deleted from the notebook is simply skipped.

ParameterslimitcursorplaylistIdrequired

jj_create_song

Add a song to my notebook

Adds a song to the calling account's PRIVATE notebook. `song` is the canonical pivot payload: exactly the object returned by jj_get_song (`song`) or by a conversion whose output is "songbook", so converting then filing is a copy with no transformation. The id is DERIVED, never random: `song.id` if given, otherwise an "artist-title" slug. That means posting the same song twice REPLACES it instead of creating a duplicate, and it is also how you rewrite a song wholesale (read it with jj_get_song, edit the payload, post it back with its id). Adding NEVER publishes anything on the public profile. Consumes one unit of the daily WRITE quota (200/day free, 5000 Premium).

ParameterssongrequiredpublishplaylistIds

jj_update_song

Change a notebook song

Changes some fields of one song of the calling account's notebook. Only the fields you pass move; a field set to null erases its value. `key` is the DISPLAYED key ("G", "Am"). `playlistIds` is the complete target membership, so it is idempotent. `publish: true` puts the song on the account's public profile and requires `publishDeclaration` the first time, plus a public username; `publish: false` removes it and has no conditions. Publishing is a deliberate act by the account holder: never publish unless they asked. To rewrite lyrics, chords or structure, use jj_create_song with the song's id instead.

ParametersbpmkeycapotitleartistsongIdrequiredifMatchpublishplaylistIdspublishDeclaration

jj_delete_song

Delete a notebook song

Deletes a song from the calling account's notebook. Idempotent: deleting twice succeeds twice, and an unknown id succeeds too (saying "no such song" would leak whether it exists in someone else's notebook). Side effects are the same as deleting in the app: the song leaves all its playlists, its published copy disappears from the profile, and accounts that had imported it are notified. This cannot be undone from the API: confirm with the person before calling it.

ParameterssongIdrequired

jj_create_playlist

Create a notebook playlist

Creates a playlist in the calling account's notebook. Playlists are flat and allow multi-membership: a song can be in several of them. `songIds` is the ordered content and every id must be a live song of this account. Consumes one unit of the daily write quota.

ParametersnamerequiredsongIdscoverEmoji

jj_update_playlist

Rename, re-cover or reorder a playlist

Changes one or more fields of a playlist: `name`, `coverEmoji` (null removes it), and `songIds`, which REPLACES the whole content and its order. Only the fields you pass move. To reorder, read the playlist with jj_get_playlist first and send the full list back in the new order.

ParametersnameifMatchsongIdscoverEmojiplaylistIdrequired

jj_delete_playlist

Delete a notebook playlist

Deletes a playlist, and ONLY the playlist: its songs stay in the notebook and in their other playlists. Idempotent, and an unknown id succeeds too. If the playlist was published on the profile, that published copy disappears.

ParametersplaylistIdrequired

jj_get_profile

Get a public profile card

Returns the profile card of a Jam Jam account designated by its public @handle, seen from the calling account: display name, bio, avatar, visibility (public/private), follower and following counts, and `relation` (none / following / follower / mutual / requested / self). A PRIVATE account the caller does not follow returns a closed card without bio or counts. An unknown handle returns not-found. Jam Jam is a host: this never ranks or recommends anyone, and never exposes somebody else's audience figures.

Parametershandlerequired

jj_list_profile_songs

List songs published by an account

Lists the songs an account has chosen to publish on its profile, newest first, with cursor pagination. `hasAudio` and `audioPlayable` are only ever true between accounts that follow each other MUTUALLY: without that link the very existence of a backing track is withheld, and no endpoint serves audio at all. A private account you do not follow refuses the call; an unknown handle returns not-found. Consumes one unit of the daily read quota.

Parameterslimitcursorhandlerequired

jj_list_profile_playlists

List playlists published by an account

Lists the playlists an account has published on its profile. Same visibility rules as jj_list_profile_songs. `songCount` already counts only what the caller is allowed to see: a published playlist hides the songs its author did not publish.

Parameterslimitcursorhandlerequired

jj_list_followers

List the accounts that follow me

Lists the calling account's own followers, newest first. status="requested" lists the follow requests it has not accepted yet. Only the caller's own relations are readable; reading somebody else's followers is not offered by this API.

Parameterslimitcursorstatus

jj_list_following

List the accounts I follow

Lists the accounts the calling account follows, newest first. status="requested" lists the requests it has sent to private accounts and that are still pending. Following and un-following are done in the Jam Jam application, never by API.

Parameterslimitcursorstatus

jj_stems_capabilities

Stem separation: availability, limits and quota

Reports whether stem separation is available right now (GET /stem-tool/capabilities), the models this account may use ("fast" and "quality"), the file formats ("mp3", "flac"), the maximum duration and upload size, how long results are kept, and the remaining quota with its reset time (`quota.fast` and `quota.quality`, `resetsAt` in epoch milliseconds, UTC). Call it before jj_stems_separate. Costs no quota (only the read rate limit, 240 per minute). An API key must belong to a Premium account.

Takes no parameters.

jj_stems_separate

Separate a song into stems

Uploads a local audio file (path, or base64 content) and starts its separation into vocals + instrumental (stems=2) or vocals + drums + bass + other (stems=4) (POST /stem-tool/jobs). Asynchronous and slow (minutes, up to hours for a long file): by default this returns at once with the job, then follow it with jj_stems_get_job and fetch the files with jj_stems_get_file; pass maxWaitMs to wait for a short file instead. Needs the stems:write scope and an API key from a Premium account (403 otherwise). Limits on Premium: a file of at most 1 h 30 and under 2 GB (5 minutes and 100 MB without Premium). Quotas, in UTC days and calendar months, with one pair of counters per model: "fast" 10 jobs/day and 100/month (10800 s of audio/day, 54000 s/month), "quality" 2 jobs/day and 10/month (5400 s/day, 18000 s/month). Only one separation can run at a time per account. A 429 states when the counter resets; a 413 means the file is too large or too long. Stems come as MP3 320 kb/s by default, or as FLAC 24-bit with format="flac" (lossless, about 4 times larger). Check jj_stems_capabilities first.

ParameterspathmodelstemsformatfilenamemaxWaitMscontentBase64

jj_stems_get_job

Get a stem separation status

Fetches the state of one of your separations by id (GET /stem-tool/jobs/{id}): state (uploading, queued, running, saving, done, failed, cancelled, expired), queue position, processed seconds against duration, time estimates, and, once done, the names of the stems available. A job unknown or belonging to another account answers the same 404. Costs no quota (read rate limit, 240 per minute): poll no faster than every few seconds.

Parametersidrequired

jj_stems_list_jobs

List recent stem separations

Lists your recent separations, newest first, 30 per page (GET /stem-tool/jobs). Use it to find a job id again, or to see whether one is still running before starting another (only one can run at a time). Pass the returned "next" as "before" for the next page. Costs no quota (read rate limit).

Parametersbefore

jj_stems_get_file

Get a separated stem

Fetches one result file of a finished separation (GET /stem-tool/jobs/{id}/files/{name}): a stem (vocals, instrumental, drums, bass, other, depending on the number of stems chosen; .mp3, or .flac when the job has format "flac") or all of them as stems.zip. By default the file is downloaded and its local path is returned; with download=false only the signed link is returned, valid for about 60 seconds. Files are kept 24 hours after the separation (410 afterwards); the job must be in state "done" (409 otherwise). Costs no quota (read rate limit).

Parametersidrequirednamerequireddownload

jj_stems_cancel_job

Cancel a stem separation

Cancels one of your own separations that is still uploading, queued or running (DELETE /stem-tool/jobs/{id}). Needs the stems:write scope. Only call it when the user asked to stop that separation. Costs no quota. An unknown id, or a job of another account, answers 404.

Parametersidrequired

jj_audio_analyze

Queue an audio file for chord and lyrics analysis

Uploads a local audio file (path, or base64 content) to the Jam Jam server queue so that its chords and lyrics are analysed, then automatically aligned, for a song of YOUR notebook (POST /audio). Same queue as the Jam Jam app. "songId" must already exist in the caller's notebook (see jj_list_songs), otherwise 404. Needs an account and the audio:write scope. It returns at once with a job: follow it with jj_queue_get_job. Idempotent per (account, song, file content): sending the same file again returns the same job with reused=true and consumes nothing. Quota: counter "audio-analysis", 15 analyses per ISO week on a free account (resets Monday 00:00 UTC), no limit on Premium; at most 50 jobs may wait per account. Errors: 413 file too large, 415 not audio, 429 quota or queue full.

ParameterspathsongIdrequiredfilenamecontentBase64

jj_queue_list

List the audio analysis queue

Lists the caller's audio analysis jobs in three groups (GET /queue): "active" (running), "queued" (waiting, with "rank" = real service order) and "done" (finished, failed or cancelled in the last 7 days). Needs an account and the queue:read scope. Costs no quota.

Takes no parameters.

jj_queue_get_job

Get an audio analysis job

Fetches one job of the caller's audio queue by id (GET /queue/{id}): status (queued, active, done, failed, cancelled), stage (analyze, align), per-step status, progress and rank. An unknown id and a job of another account answer the same 404. Needs the queue:read scope. Costs no quota.

Parametersidrequired

jj_queue_cancel_job

Cancel an audio analysis job

Cancels one job of the caller's own audio queue (DELETE /queue/{id}). The unit is refunded ONLY if the analysis had not completed yet; during alignment, the analysis already delivered is kept, without refund. 409 when the job can no longer be cancelled. Needs the audio:write scope. Only call it when the user asked to stop that job.

Parametersidrequired

jj_ai_music_availability

AI music detection: availability, limits and quota

Reports whether the AI music detection is available (GET /ai-music/availability): upload size and duration limits, whether links are accepted, and the remaining daily and monthly quota with exact reset times (`quota.daily.resetsAt`, `quota.monthly.resetsAt`, epoch milliseconds, UTC). Quotas: visitor 2/day and 5/month, free account 5/day and 50/month, Premium 30/day and 300/month, shared between website, app and API keys; failures and cancellations are refunded. Call it before jj_ai_music_analyze and after a 429. Costs nothing.

Takes no parameters.

jj_ai_music_analyze

Analyse a track for AI music signals

Starts an AI music detection (POST /ai-music/jobs) on a local audio file (path, or base64 content: 100 MB and 600 seconds at most), OR on exactly one link: "url" (Spotify track link), "spotifyTrackId", "isrc" or "audioUrl" (direct audio link; YouTube is not supported; a Spotify or ISRC source may only provide an excerpt, see result.primary.audioSource). Links only work when jj_ai_music_availability reports links=true. Asynchronous: returns at once with a job (pass maxWaitMs to wait), then follow it with jj_ai_music_get_job. One unfinished analysis per account at a time (409), results kept 90 days, no audio kept. Needs the audio:write scope. Consumes one unit of the ai-music counter (free 5/day and 50/month, Premium 30/day and 300/month, UTC; failures refunded); a 429 states when it resets, a 413 means the file is too large or too long. The report is an aggregated index of signals, not a probability and not proof of origin: present it as such.

ParametersurlisrcpathaudioUrlfilenamemaxWaitMscontentBase64spotifyTrackId

jj_ai_music_current

Find my current AI music analysis

Returns the caller's current or most recent AI music analysis, or null when there is none (GET /ai-music/jobs). Use it to find the id of a running analysis, since only one unfinished analysis per account can exist. Needs the queue:read scope. Costs no quota.

Takes no parameters.

jj_ai_music_get_job

Get an AI music analysis and its report

Fetches one AI music analysis by id (GET /ai-music/jobs/{id}): state (uploading, queued, running, cancelling, done, failed, cancelled), progress, queue position and, once done, the report in "result" (score 0 to 100, verdict signals-detected / few-signals / inconclusive, per-detector windows, and for the v3 report the classification human / processed-ai / pure-ai). The report is an aggregated index of signals, not a probability and not proof of origin: present it as such. A job of another account answers 404. Needs the queue:read scope. Costs no quota.

Parametersidrequired

jj_ai_music_history

List my AI music analyses of the last 90 days

Lists the caller's own analyses of the last 90 days, newest first, 30 per page (GET /ai-music/history): source label (file name or link), dates, state and report, never any audio. Needs an account and the queue:read scope. Pass the returned "nextBefore" as "before" for the next page. Costs no quota.

Parametersbefore

jj_ai_music_cancel_job

Cancel an AI music analysis

Cancels the caller's own AI music analysis and deletes its temporary files (DELETE /ai-music/jobs/{id}). The quota unit is refunded. Needs the audio:write scope. Only call it when the user asked to stop that analysis.

Parametersidrequired

jj_mastering_capabilities

Mastering: limits, setting ranges, targets and render quota

Reports the live contract of the Mastering engine (GET /mastering/capabilities): for each of the eight modules the unit, range, step, neutral and initial value, the loudness targets, the built-in presets (builtin:balanced, ... with their full settings, a good starting point for a new preset), the limits (200 MB, 10 minutes, 50 presets of 60 characters), the validation tolerance, whether THIS account may render through the API (`renderAllowed`: any account with mastering:write) and the render quota balance. Call it before jj_create_mastering_preset or jj_master_audio with inline settings. Needs no scope and costs nothing.

Takes no parameters.

jj_list_mastering_presets

List Mastering presets

Lists the Mastering presets saved on the account, newest first (GET /mastering/presets), with their full settings, plus the ids of the read-only built-in presets (builtin:balanced, ...) which are valid as the `preset` of jj_master_audio. No pagination: an account keeps 50 presets at most. Open to any account, free or Premium. Counts one unit of the daily read quota.

Takes no parameters.

jj_create_mastering_preset

Create a Mastering preset

Saves a named Mastering preset on the account (POST /mastering/presets): a name of 1 to 60 characters, unique among the account presets, and the settings (all eight modules with value and enabled, a loudness target, normalize). Each value must be within its range and on its step: read them with jj_mastering_capabilities, or copy the settings of a built-in preset and change a few values. The API answers 422 with the path of every rejected field when the settings are invalid, 409 when the name is taken or the 50-preset cap is reached. Open to any account, free or Premium. Counts one unit of the daily write quota. Only call it when the user asked to save a preset.

Parametersnamerequiredsettingsrequired

jj_master_audio

Master an audio file with a preset

Uploads a local audio file (path, or base64 content) and renders it with a Mastering preset on the server (POST /mastering/jobs): the same engine as the Jam Jam web tool. Pass EXACTLY ONE of `preset` (a preset id from jj_list_mastering_presets, or builtin:<id>) and `settings` (inline settings, see jj_create_mastering_preset). The result is a 48 kHz WAV (`format` wav-pcm16 by default, wav-pcm24, or wav-f32). Asynchronous: by default this returns at once with the job, then follow it with jj_mastering_get_job; pass maxWaitMs to wait, and a render that finishes in time is downloaded in the same call (`file`). Open to any account (3 renders per ISO week for a free account, 429 quota-exhausted beyond; unlimited for Premium) and needs the mastering:write scope. Limits: a file of at most 200 MB and 10 minutes, one or two channels; one render runs and three wait per account. The render consumes the Mastering render counter (shared with the Jam Jam app), counted at submission; a failed or cancelled render is refunded. Results are kept 24 hours. Only call it when the user asked to master that file.

ParameterspathformatpresetfilenamesettingsmaxWaitMscontentBase64

jj_mastering_get_job

Get a Mastering render status

Fetches one of your renders by id (GET /mastering/jobs/{id}): status (queued, decoding, analyzing, rendering, done, failed, cancelled, expired), progress, queue position, a copy of the settings used and, once done, the loudness measures before and after (`report`) and the sha256 of the result. With download=true on a finished render, the mastered WAV (GET /mastering/jobs/{id}/result, free to repeat) is downloaded to a local file and its path returned. A render unknown or belonging to another account answers the same 404; results are kept 24 hours (410 afterwards). Costs no quota (read rate limit): poll no faster than every few seconds.

Parametersidrequireddownload

jj_mastering_cancel_job

Cancel a Mastering render

Cancels one of your own renders and deletes its files (DELETE /mastering/jobs/{id}). The render quota already consumed is refunded when the render was not finished. Needs the mastering:write scope. Only call it when the user asked to stop that render. An unknown id, or a render of another account, answers 404.

Parametersidrequired

Version history

3
  1. v0.3.1LatestOct 30, 2026
  2. v0.2.2Oct 19, 2026
  3. v0.2.1Oct 15, 2026

Score

65% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts

    Declare a GitHub repository with a README, or serve resource_documentation in the OAuth protected-resource metadata.

  • License10 pts

    Declare a license in the repository or the registry entry.

Other Convert integrations