Examples read the key from MAP_API_KEY and pin the version with Map-Version. Their ids have the shape real ones have, such as job_01M6BPRE186QHP9QPYGDX5NNFP: put in the ids from your own answers. Every operation is also published on its own as Markdown, linked from its entry.
Account
The account behind a credential: plan, render-minutes, usage, terms, access requests, API keys and billing. Keys and billing need a map.audio sign-in on MAP Audio's own pages (map.audio/music).
Who this credential belongs to: the Music API account's status, the terms version it accepted, its tier's limits and this month's render-minutes. Call it first. currentTerms is the version POST /v1/account/terms takes (every request that starts work needs it), and credits.remaining is what jobs can still draw. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
{
"error": {
"type": "entitlement",
"code": "not_invited",
"message": "This map.audio account (customer 8f14e45f-ceea-467a-9575-62f3b1a6c2d0) has no Music API access yet. Request access at https://map.audio/music, or POST /v1/access-requests with this token.",
"param": null,
"details": {
"customerId": "8f14e45f-ceea-467a-9575-62f3b1a6c2d0",
"emailConfirmed": true,
"accessRequest": null,
"requestAccessUrl": "https://map.audio/music"
},
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_invited",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The account., 403 No Music API access yet, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Accept the terms that every request starting work needs: renders, commands, plans, arrangements, uploads and checkout. Send the version from currentTerms in GET /v1/account; an invited account becomes active. The terms are on map.audio/music, where you can also accept them signed in. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
{
"error": {
"type": "invalid_request",
"code": "terms_version_mismatch",
"message": "accept must be \"2026-11-01-prototype\", the current terms version; got \"2026-10-01\".",
"param": "accept",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#terms_version_mismatch",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The account, now active., 400 Wrong terms version, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Ask MAP Audio for Music API access as the signed-in map.audio account behind the access token. Use it when a call answers 403 not_invited: send the same token, with a line about what you will build and a website if you like. One request per account; sending again updates the fields you send (null clears one), keeps the ones you leave out, and answers 200. MAP Audio emails the account when access is ready, and map.audio/music does the same signed in. An API key cannot call this route, and it never answers not_invited. Free.
Auth: Authorization: Bearer with a map.audio access token; an API key is refused.
Not an MCP tool: An MCP session already has Music API access; an account without it requests access signed in at map.audio/music.
createAccessRequest body
Field
Type
Required
Description
useCase
string or null
no
What you want to build with the API, in a sentence or two. null clears a saved one; leaving it out keeps it. At most 1000 characters.
website
string or null
no
A public https URL for you or your product: a host name, not an IP address, localhost or a URL with credentials. null clears a saved one; leaving it out keeps it. At most 200 characters. Matches ^https://.
curl
curl -sS "https://api.map.audio/v1/access-requests" \
-H "Authorization: Bearer $MAP_ACCESS_TOKEN" \
-H "Map-Version: 2026-11-01" \
-H "Content-Type: application/json" \
-d '{"useCase":"A game that scores every level with new loops from PAM presets.","website":"https://example.com"}'
Request: A short note about the project
{
"useCase": "A game that scores every level with new loops from PAM presets.",
"website": "https://example.com"
}
200: Updated
{
"object": "access_request",
"id": "areq_01M6BPS09M7WAVD3A2N3JPJE0X",
"status": "pending",
"email": "dev@example.com",
"useCase": "A game that scores every level with new loops from PAM presets.",
"website": "https://example.com",
"createdAt": "2026-11-01T13:40:12.007Z",
"updatedAt": "2026-11-01T14:05:51.630Z"
}
201: Created
{
"object": "access_request",
"id": "areq_01M6BPS09M7WAVD3A2N3JPJE0X",
"status": "pending",
"email": "dev@example.com",
"useCase": "A game that scores every level with new loops from PAM presets.",
"website": "https://example.com",
"createdAt": "2026-11-01T13:40:12.007Z",
"updatedAt": "2026-11-01T13:40:12.007Z"
}
403: Access requests need a sign-in
{
"error": {
"type": "entitlement",
"code": "access_request_needs_sign_in",
"message": "An API key cannot request access: every key belongs to an account that has it already. Sign in at https://map.audio/music with the map.audio account that needs access, and request it there.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#access_request_needs_sign_in",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
409: Already has access
{
"error": {
"type": "conflict",
"code": "already_has_access",
"message": "This map.audio account already has Music API access, so there is nothing to request. Call the API with this token, or create API keys at https://map.audio/music.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#already_has_access",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The request, updated., 201 The request, created., 403 Access requests need a sign-in, 409 Already has access, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Meter totals for the account per API key and meter: render-minutes, rendered audio seconds, compute time, and the free commands' own meters. from and to are UTC days, at most a year apart and at most 90 days back, as usage is kept that long. Requests made with a map.audio sign-in have keyId: null. Free; GET /v1/credits shows what is left to spend.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Per-key meter totals are for dashboards and audits; get_credits shows the render-minutes an agent can still spend.
getUsage parameters
Name
In
Type
Required
Description
from
query
string
no
First UTC day, YYYY-MM-DD, at most 90 days back. Default: the first of this month.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "from must be a date as YYYY-MM-DD; got \"yesterday\".",
"param": "from",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Usage., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
What jobs can still spend this month: the tier's allowance, render-minutes used, render-minutes running jobs hold, credits bought, and remaining, which the next job draws on. A job reserves its estimate when it is admitted and settles at its outputs' real length. Free. Buy render-minutes or a paid tier at map.audio/music.
Auth: Authorization: Bearer with an API key or a map.audio access token.
{
"error": {
"type": "authentication",
"code": "authentication_failed",
"message": "That API key is not valid or was revoked.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#authentication_failed",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Credits., 401 Authentication failed, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "\"cursor\" is not a parameter of GET /v1/api-keys; it takes none.",
"param": "cursor",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Keys., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Create an API key; its secret is in this response only, so store it now. Needs a map.audio sign-in on MAP Audio's own pages (map.audio/music), not an API key or another app's token, so a leaked key cannot mint more. mode picks the sk_test_ or sk_live_ prefix: both modes spend the same render-minutes and see the same jobs and files. An account holds at most 10 active keys. Send acceptTerms to accept the terms in the same call. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: API keys are created, listed and revoked signed in at map.audio/music, so a connected app never holds or handles credentials.
createApiKey body
Field
Type
Required
Description
name
string
no
A label you choose, to tell keys apart. At most 80 characters.
mode
"test" | "live"
no
test or live. Both draw on the same render-minutes; the prefix separates Idempotency-Key namespaces and marks test renders' provenance. Default "test".
acceptTerms
string
no
The prototype terms version being accepted, required until the account has accepted it.
{
"error": {
"type": "entitlement",
"code": "oauth_required",
"message": "Only the account owner, signed in at https://map.audio/music, can create or revoke API keys. This request used an API key.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#oauth_required",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
403: Key limit reached
{
"error": {
"type": "entitlement",
"code": "too_many_keys",
"message": "An account may hold 10 active keys; revoke one (DELETE /v1/api-keys/{id}) first.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#too_many_keys",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 201 The key, with its secret., 403 Needs the account owner's sign-in; Key limit reached, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Revoke a key at once: requests with it answer 401 from then on, and webhook endpoints whose secret it last set are disabled with it. Needs a map.audio sign-in on MAP Audio's own pages (map.audio/music), so a leaked key cannot revoke the others. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: API keys are created, listed and revoked signed in at map.audio/music, so a connected app never holds or handles credentials.
revokeApiKey parameters
Name
In
Type
Required
Description
id
path
string
yes
An API key id (key_…), from GET /v1/api-keys; not the secret. Matches ^key_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No API key with that id; GET /v1/api-keys lists this account's keys.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The key, revoked., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Open a Stripe Checkout page to subscribe to a paid tier or to buy render-minutes; the tier or credits apply once Stripe confirms the payment. Send tier or renderMinutes, not both. Needs a map.audio sign-in on MAP Audio's own pages, as map.audio/music uses; an API key or another app cannot buy. Answers with a URL for a person to open in a browser.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Spends money on a Stripe page a person completes in a browser; only MAP Audio's own pages may open one.
createBillingCheckout body
Field
Type
Required
Description
tier
"creator" | "pro" | "app"
no
A paid tier to subscribe to.
renderMinutes
integer
no
Whole render-minutes of pay-as-you-go credit to buy. From 334 to 100000.
consent
object
no
The buyer's analytics and advertising choice on map.audio, which the purchase's analytics and ad reports follow. Without it, both count as denied.
{
"error": {
"type": "conflict",
"code": "subscription_exists",
"message": "This account already subscribes to a plan; change or cancel it from the billing portal (POST /v1/billing/portal).",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#subscription_exists",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 A Stripe Checkout page., 409 Already subscribed, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Open the Stripe billing portal, where a subscriber changes plan or card, cancels and reads invoices. Needs a map.audio sign-in on MAP Audio's own pages. It does not wait on the terms, so a subscription can always be cancelled.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Spends money on a Stripe page a person completes in a browser; only MAP Audio's own pages may open one.
{
"error": {
"type": "conflict",
"code": "billing_not_available",
"message": "Nothing has been bought on this account yet, so it has no billing portal; buy with POST /v1/billing/checkout.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#billing_not_available",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The billing portal., 409 No billing account yet, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Search the factory presets the engine renders, by words in their names, descriptions, categories and tags, by category and by tempo. Each preset's ref (pam:factory/<slug>) is what renders, plans, arrangements and DJ sets take, and variations lists its slots. Free. Next: POST /v1/renders with source.preset set to a ref.
Auth: Authorization: Bearer with an API key or a map.audio access token.
MCP tool: search_presets
listPresets parameters
Name
In
Type
Required
Description
q
query
string
no
Words that must each start a word of a preset's name, description, category, subcategory, author or tags. At most 200 characters.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "limit must be a whole number from 1 to 100; got \"500\".",
"param": "limit",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Matching presets., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
{
"error": {
"type": "not_found",
"code": "preset_not_found",
"message": "No factory preset 313-discoo; list them with GET /v1/presets.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#preset_not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The preset., 404 No such preset, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
The drum-synth engines POST /v1/synth/drum plays, each with its controls: label, unit and range. Set controls by label in that route's param (Tune=55,Decay=1.5); percent controls take 0 to 100. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
{
"error": {
"type": "rate_limit",
"code": "rate_limited",
"message": "This API key sent more than 120 requests in a minute, the limit for each key; retry after 10 s.",
"param": null,
"retryable": true,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#rate_limited",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Engines., 429 Rate limited, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
What a DJ set's transitions can use: the transition presets a render knows, the modes and curves a transition takes, the longest window in bars, and the DJ set schema's definitions. Read it before writing a set for POST /v1/arrangements or POST /v1/dj/set. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
200: Factory transitions (definitions cut to DjTransition's plain fields)
{
"object": "transition_presets",
"presets": [
"drop",
"rise",
"break",
"blend",
"sweep",
"fill"
],
"modes": [
"auto",
"param",
"mix",
"seq",
"all",
"swap",
"chop"
],
"curves": [
"linear",
"ease",
"exp",
"log"
],
"maxBars": 32,
"schema": "https://map.audio/schemas/pam/dj-set.schema.json",
"definitions": {
"DjTransition": {
"type": "object",
"additionalProperties": false,
"description": "Resolved in order: the preset's spec, spec merged over it one level deep per section, then bars, mode and curve as the DJ view's Length, Mode and Curve rows apply them.",
"properties": {
"preset": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"description": "A transition preset id: drop, rise, break, blend, sweep, fill, or one the user saved."
},
"bars": {
"type": "number",
"minimum": 0,
"maximum": 32
},
"mode": {
"enum": [
"auto",
"param",
"mix",
"seq",
"all",
"swap",
"chop"
]
},
"curve": {
"enum": [
"linear",
"ease",
"exp",
"log"
]
}
}
}
}
}
401: Authentication failed
{
"error": {
"type": "authentication",
"code": "authentication_failed",
"message": "Send an API key or a map.audio access token as `Authorization: Bearer …`.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#authentication_failed",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Transitions., 401 Authentication failed, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
{
"error": {
"type": "unavailable",
"code": "internal_error",
"message": "Something went wrong on our side; nothing was charged.",
"param": null,
"retryable": true,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#internal_error",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 OpenAPI 3.1., 500 Internal error, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Turn a short prompt into an editable render plan, or store one you wrote. The rules planner matches the prompt's words and tempo against the catalogue, with no AI model, and returns its ranked candidates and a spec; caller stores your own spec once every reference checks out. Plans are free and never change: edit a spec and send it back as a caller plan. Next: POST /v1/renders with plan set to the plan's id.
Auth: Authorization: Bearer with an API key or a map.audio access token.
MCP tool: create_plan
createPlan body
Field
Type
Required
Description
planner
"rules" | "caller"
no
rules plans from prompt and constraints; caller stores the spec you send. Default "rules".
prompt
string
no
What you want, in a few words: genre, mood, instruments, a tempo such as 128 bpm, or "variations". At most 500 characters.
spec
object
no
spec.product
"pam"
no
Default "pam".
spec.base
object
yes
A factory preset, and optionally one of its variation slots.
spec.base.preset
string
yes
A factory preset pam:factory/<slug>, or its bare slug. At most 200 characters.
spec.base.variation
integer
no
A variation slot of the preset, numbered from 1; GET /v1/presets/{id} lists the slots it has. Default: its base state. From 1 to 16.
spec.tempo
number
no
Render at this tempo instead of the preset's, in BPM. From 20 to 400.
spec.morph
object
no
spec.morph.to
object
yes
A factory preset, and optionally one of its variation slots.
spec.morph.at
number
no
Morph position: 0 is the start, 1 the target; values outside 0..1 extrapolate along the same line. From -1 to 2. Default 0.5.
spec.morph.curve
"linear" | "ease" | "exp" | "log"
no
How the morph position eases, as a live Glide shapes its window. Default "ease".
spec.morph.pattern
"dissolve" | "wipe" | "cells"
no
Stage the cells' patterns at at as a Steps transition does; without it the patterns stay the start's below 1.
spec.morph.patternSeed
integer
no
Draws each step of a dissolve, so the same seed gives the same steps. From 0 to 4294967295.
spec.blend
array of object
no
2 to 16 items.
spec.blend[].preset
string
yes
A factory preset pam:factory/<slug>, or its bare slug. At most 200 characters.
spec.blend[].variation
integer
no
The preset's variation slot to blend; default: its base state. From 1 to 16.
spec.blend[].weight
number
yes
More than 0.
spec.envelopes
array of object
no
State envelopes ({delta, options?}) applied in order before rendering: the same envelopes POST /v1/state takes. 0 to 64 items.
spec.arrangement
object
no
loop renders bars of the base; variations renders each listed slot.
spec.arrangement.kind
"loop" | "variations"
yes
spec.arrangement.bars
integer
no
From 1 to 64.
spec.arrangement.variations
array of integer
no
0 to 16 items.
seed
integer
no
Breaks ties between equally good presets; the same seed and prompt give the same plan. From 0 to 4294967295. Default 0.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "Give a prompt, or constraints with a tempo or category, to plan from.",
"param": "prompt",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 201 The plan., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
A stored plan: its spec, the candidates the rules planner ranked, and the presets it names. Plans never change; render one with POST /v1/renders and plan. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
MCP tool: get_plan
getPlan parameters
Name
In
Type
Required
Description
id
path
string
yes
A plan id (plan_…), from POST /v1/plans. Matches ^plan_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No plan with that id; plans come from POST /v1/plans, which returns the id.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The plan., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Render a factory preset or a stored plan as one job, with one output or many: a length in bars or seconds, a variation, stems, a sample rate, WAV, FLAC or MP3, and a seed (the job reports the seed it used; sending it again renders the same audio). variations renders several slots, seeds, morph positions or a blend; items names outputs of their own lengths or cutdowns; quality: standard renders candidate seeds, measures each and keeps the best. Costs render-minutes: each output's length in minutes, at least 0.1 an output, shown in estimate before it runs. Answers 202 with the queued job unless Prefer: wait covers it; its outputs are in result.outputs once it succeeds.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: create_render
createRender body
Field
Type
Required
Description
source
object
no
The preset to render; give source or plan.
source.preset
string
yes
A factory preset pam:factory/<slug>, or its bare slug. At most 200 characters.
source.variation
integer
no
A variation slot of the preset, numbered from 1; GET /v1/presets/{id} lists the slots it has. Default: its base state. From 1 to 16.
plan
string
no
A stored plan's id (plan_…), instead of source. Matches ^plan_.
bars
integer
no
Length in bars of the preset's time signature, at its tempo (or the plan's). Default 4; give bars or seconds. From 1 to 64.
seconds
number
no
Length in seconds, instead of bars. More than 0, up to 300.
tail
number
no
Seconds of effect tail after the transport stops, added to the length. From 0 to 30. Default 0.
seed
integer
no
Seed for everything random in the render; 0 draws one, which the job reports, and sending that seed again renders the same audio. From 0 to 4294967295. Default 0.
stems
boolean
no
Also write one stem per cell, captured after cell effects and before the master chain, encoded like the master. Default false.
sampleRate
22050 | 32000 | 44100 | 48000
no
Output sample rate in Hz. Default 48000.
format
object
no
Container and MP3 bitrate for every output; WAV unless you ask.
format.container
"wav" | "flac" | "mp3"
no
Default "wav".
format.bitrate
96 | 112 | 128 | 160 | 192 | 224 | 256 | 320
no
MP3 only, kbit/s. At 22050 Hz the most is 160, which is then the default. Default 320.
quality
"draft" | "standard" | "elite"
no
standard renders search.candidates seeds, measures each and returns the best that pass the limit gate; elite is refused until a curated archive exists. Default "draft".
search
object
no
Only with quality standard.
search.candidates
integer
no
From 2 to 8. Default 4.
search.return
integer
no
From 1 to 4. Default 1.
search.targetLufs
number
no
From -40 to -6.
variations
object, kind slots, seeds, morph, blend
no
Several outputs from one job: slots renders variation slots, seeds takes from derived seeds, morph renders positions between the source and to, blend renders a weighted blend of presets.
variations.slots
array of integer
no
With kind slots. 1 to 16 items.
variations.count
integer
yes
With kind seeds. From 2 to 8.
variations.to
object
yes
With kind morph. A factory preset, and optionally one of its variation slots.
variations.to.preset
string
yes
With kind morph. A factory preset pam:factory/<slug>, or its bare slug. At most 200 characters.
variations.to.variation
integer
no
With kind morph. A variation slot of the preset, numbered from 1; GET /v1/presets/{id} lists the slots it has. Default: its base state. From 1 to 16.
variations.at
array of number
yes
With kind morph. 2 to 8 items.
variations.curve
"linear" | "ease" | "exp" | "log"
no
With kind morph.
variations.pattern
"dissolve" | "wipe" | "cells"
no
With kind morph.
variations.patternSeed
integer
no
With kind morph. From 0 to 4294967295.
variations.presets
array of object
yes
With kind blend. 2 to 16 items.
variations.presets[].preset
string
yes
With kind blend. A factory preset pam:factory/<slug>, or its bare slug. At most 200 characters.
variations.presets[].variation
integer
no
With kind blend. The preset's variation slot to blend; default: its base state. From 1 to 16.
variations.presets[].weight
number
yes
With kind blend. More than 0.
items
array of object
no
Named outputs of their own lengths: a variation for some bars, or a cutdown fitted to seconds across the preset's variations. 1 to 8 items.
items[].name
string
yes
Matches ^[A-Za-z0-9_-]{1,40}$.
items[].variation
integer
no
From 1 to 16.
items[].bars
integer
no
From 1 to 64.
items[].cutdown
object
no
Fits the preset to this length across its variations. An item with a cutdown takes no variation or bars.
items[].cutdown.seconds
number
yes
From 5 to 300.
preview
object
no
A short render published first, as a job.preview event. A job that succeeds pays for its render or its preview, whichever is longer; if it fails or is cancelled, the preview is still charged at its own length.
preview.bars
integer
no
From 1 to 8. Default 4.
metadata
map of string
no
Up to 20 string pairs stored with the job and returned with it. At most 20 entries.
{
"error": {
"type": "invalid_request",
"code": "render_too_long",
"message": "This render is about 310 s (seconds 300 plus tail 10 s); a render may be at most 300 s.",
"param": "seconds",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#render_too_long",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
402: Not enough render-minutes
{
"error": {
"type": "entitlement",
"code": "insufficient_credits",
"message": "This job needs 0.267 render-minutes and 0.012 remain this month; make it shorter, or buy render-minutes at https://map.audio/music.",
"param": null,
"details": {
"needed": 0.267,
"remaining": 0.012
},
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#insufficient_credits",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
403: Terms not accepted
{
"error": {
"type": "entitlement",
"code": "terms_required",
"message": "This account has not accepted the prototype terms (2026-11-01-prototype), which work needs. Read and accept them at https://map.audio/music, or send POST /v1/account/terms with {\"accept\": \"2026-11-01-prototype\"} (over MCP, the accept_terms tool).",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#terms_required",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job, when it ends within `Prefer: wait`., 202 The queued job; poll `urls.self`, stream `urls.events`, or wait for a webhook., 400 Render too long, 402 Not enough render-minutes, 403 Terms not accepted, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Plan a render without rendering. cutdown fits one preset (from source or a stored plan) to a length in seconds as a DJ set over its variations; set checks a DJ set you wrote: references, variations, lengths and transitions. The answer is the set in preset references, its tempo and length, and each item's start in bars and seconds. It costs nothing; render the set with POST /v1/dj/set, or a cutdown as an item of POST /v1/renders.
Auth: Authorization: Bearer with an API key or a map.audio access token.
MCP tool: create_arrangement
createArrangement body
Field
Type
Required
Description
source
object
no
The preset a cutdown fits; give source or plan.
source.preset
string
yes
A factory preset pam:factory/<slug>, or its bare slug. At most 200 characters.
source.variation
integer
no
A variation slot of the preset, numbered from 1; GET /v1/presets/{id} lists the slots it has. Default: its base state. From 1 to 16.
plan
string
no
A stored plan whose base preset and tempo a cutdown fits. Matches ^plan_.
cutdown
object
no
Fit the preset to about this many seconds, as an opening, a main section and an ending over its variations.
cutdown.seconds
number
yes
From 5 to 300.
set
object
no
A DJ set to check: queue lists its items in play order, each naming a factory preset (presetPath), its variation (variationIndex, counted from 0), its length in bars and the transition into it. GET /v1/transition-presets lists the transitions and the set schema's definitions.
{
"error": {
"type": "invalid_request",
"code": "dj_unknown_transition_preset",
"message": "Unknown transition preset swoosh; GET /v1/transition-presets lists the ones a render can use.",
"param": "set.queue[1].transition.preset",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#dj_unknown_transition_preset",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The arrangement., 400 Unknown transition preset, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
PAM's engine commands as endpoints: audio analysis and editing, preset renders, effects, mastering, headless state, DJ sets, patterns and drum synthesis. Body fields use the same names as the commands' MCP arguments.
Measure audio this account holds, such as a render's master: loudness (BS.1770), true peak, spectrum, stereo image, tempo, key, sections and defects. Send file ids from a job's result.outputs; the measurements come back in result.command, under files when you send more than one. Run it on a render before you keep or deliver it, or to compare seeds. Free: it counts in GET /v1/usage, never in render-minutes. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: audio_analyze
audioAnalyze body
Field
Type
Required
Description
files
array of string
yes
Ids (file_…) of WAV or FLAC audio this account holds, at most 16. 1 to 16 items.
peaks
boolean
no
Include the existing 48-bin RMS envelope.
pitch
boolean
no
Estimate mono pitch and confidence.
class
boolean
no
Classify the mono sample and report measured features.
spectrum
boolean
no
Long-term third-octave spectrum of mid and side, and each band's energy share (sub, low, lowMid, mid, highMid, air), relative to the file's total energy from 20 Hz to 20 kHz.
stereo
boolean
no
Side minus mid and L/R correlation per band, and the mono fold-down's loudness difference.
hpss
boolean
no
Harmonic, percussive and residual energy shares from the Transient card's spectral split (HpssCore, FIRM).
sections
boolean
no
Section boundaries from Foote novelty over third-octave features, with each section's loudness and true peak.
transients
boolean
no
Transient times from the sampler's transient detector.
beats
boolean
no
Tempo in BPM, its confidence and the first downbeat, from the DJ view's beat tracker; a tempo in the file name ("loop 92 BPM.wav") fixes the octave.
musicalKey
boolean
no
Musical key ("A minor") with its Camelot code and confidence, from the DJ view's key estimate.
levels
boolean
no
Level statistics: RMS, PLR (true peak minus integrated), PSR (3 s true peak minus short-term loudness, median and lowest), the loudest momentary and short-term loudness, block crest and level swing.
validity
boolean
no
File defects: non-finite samples with the first frame and channel, subnormals, DC offset, clipped samples, where sound starts and ends, and the level of the last 100 ms.
timbre
boolean
no
Timbre: spectral centroid, spread, skewness, kurtosis and 95% rolloff in Hz, flatness and crest in dB (median and 90th percentile over the frames within 60 dB of the loudest) across 20 Hz-20 kHz and per broad band, MFCCs 1-13 (mean and standard deviation) and each pitch class's share of the power (chroma, C first).
compare
string
no
Compare with a reference file at the same rate, such as a render's input, lined up by latency: the null raw, after one best gain and after the best linear filter, the largest and RMS sample difference, the residual per broad band, gain and coherence per third octave, the envelope change per band, and MFCC and chroma distances. The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
latency
integer
no
Frames the file lags the compare reference by, such as a render's latencySamples. From -8388608 to 8388608. Default 0.
thd
number
no
A steady tone's distortion at this frequency in Hz, over the whole file: harmonics in dBc, THD, THD+N, the even harmonics' share and the worst spur. From 1 to 192000.
imd
string
no
A steady twin tone's intermodulation, its two frequencies in Hz as 19000,20000: the difference tone and all products against the pair.
window
number
no
Adds a per-window series of spectrum, stereo and hpss values, this many seconds a window, at most 256 windows. From 0.5 to 3600.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No file with that id; GET /v1/files lists this account's files.",
"param": "files[0]",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Normalize loudness and verify a true-peak ceiling.
Bring a file to a loudness target under a true-peak ceiling, for a platform's delivery spec (-14 LUFS and -1 dBTP unless you send others). Writes a new WAV and reports the loudness it reached; the source file stays as it was. Free: it counts in GET /v1/usage, never in render-minutes. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: audio_normalize
audioNormalize body
Field
Type
Required
Description
file
string
yes
The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
lufs
number
no
Target integrated LUFS; achieved loudness is reported if the peak ceiling prevents the target. From -60 to 0. Default -14.
tp
number
no
Maximum measured true peak in dBTP. From -24 to 0. Default -1.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 410 File no longer stored, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Render varispeed pitch shifting using the browser repitch core.
Shift a file's pitch by varispeed, as a turntable does: tempo and length move with the pitch, so 12 semitones down plays at half speed. Writes a new WAV. Free: it counts in GET /v1/usage, never in render-minutes. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: audio_repitch
audioRepitch body
Field
Type
Required
Description
file
string
yes
The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
semitones
number
no
Varispeed pitch shift; duration changes. From -24 to 24. Default 0.
cents
number
no
Additional pitch shift in cents. From -100 to 100. Default 0.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "semitones must be at most 24; got 30.",
"param": "semitones",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Trim a sample by time using the shared sample-edit core.
Cut a file to a time range in seconds, such as a loop's first bars or a hit without its lead-in. Writes a new WAV. Free: it counts in GET /v1/usage, never in render-minutes. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: audio_trim
audioTrim body
Field
Type
Required
Description
file
string
yes
The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
start
number
no
Trim start in seconds. From 0 to 86400. Default 0.
end
number
no
Trim end in seconds; absent uses file end. From 0 to 86400.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "end (2 s) must be after start (4 s).",
"param": "end",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Apply sample gain using the shared sample-edit core.
Raise or lower a file's level by a number of decibels; samples past full scale clip. For a loudness target, POST /v1/audio/normalize measures and sets the level for you. Free: it counts in GET /v1/usage, never in render-minutes. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: audio_gain
audioGain body
Field
Type
Required
Description
file
string
yes
The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
db
number
yes
Gain in decibels; samples exceeding full scale clip in the output WAV. From -96 to 48.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Reverse a sample using the shared sample-edit core.
Play a file backwards, for reverse cymbals, risers and transitions. Writes a new WAV. Free: it counts in GET /v1/usage, never in render-minutes. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: audio_reverse
audioReverse body
Field
Type
Required
Description
file
string
yes
The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No file with that id; GET /v1/files lists this account's files.",
"param": "file",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
The engine's own render command: one factory preset to one WAV, with optional stems and an input file that the preset's External cells play. POST /v1/renders is the render API for everything else (FLAC and MP3, variation and seed batches, cutdowns, quality search, previews); use this route for an input file or the exact pam preset render options. It costs render-minutes for the audio it renders: its length in minutes, at least 0.1 a render. Answers 202 with the queued job: poll GET /v1/jobs/{id}, stream GET /v1/jobs/{id}/events, or send Prefer: wait=N (at most 60 s) to get the finished job in this response.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: preset_render
presetRender body
Field
Type
Required
Description
preset
string
yes
A factory preset reference, pam:factory/<slug> or the bare slug; GET /v1/presets lists them. At most 200 characters.
seconds
number
no
Render length in seconds; mutually exclusive with bars. Defaults to the input duration for fx and audio master. From 0.001 to 300.
bars
integer
no
Length in bars (1..64): pattern generation uses four beats and defaults to 1; preset rendering uses the preset time signature and defaults to 4. From 1 to 64.
sampleRate
integer
no
Output sample rate. From 22050 to 48000. Default 48000.
tail
number
no
Additional effect tail in seconds after transport stops. From 0 to 30. Default 0.
seed
integer
no
Reproducible seed; zero draws a random seed. From 0 to 4294967295. Default 0.
variation
integer
no
Preset variation, numbered from 1. From 1 to 16.
stems
boolean
no
Write each cell stem alongside the master in one render pass.
input
string
no
Audio played into the engine's input, through the PAM cells whose source is External. Without seconds or bars the render lasts as long as the input, plus tail. The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "entitlement",
"code": "insufficient_credits",
"message": "This job needs 0.267 render-minutes and 0.012 remain this month; make it shorter, or buy render-minutes at https://map.audio/music.",
"param": null,
"details": {
"needed": 0.267,
"remaining": 0.012
},
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#insufficient_credits",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The queued job; poll `urls.self` or stream `urls.events`., 402 Not enough render-minutes, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Remix an Ableton Live set, Bitwig project, DAWproject or FL Studio project into a PAM preset built from its own samples, MIDI and sections.
Turn an uploaded DAW project (Ableton Live, Bitwig, DAWproject or FL Studio) into a PAM preset built from its own samples, MIDI and sections, returned as a .zip that holds the preset and its samples. Free: it counts in GET /v1/usage, never in render-minutes. Answers 202 with the queued job: poll GET /v1/jobs/{id}, stream GET /v1/jobs/{id}/events, or send Prefer: wait=N (at most 60 s) to get the finished job in this response. Needs uploads, which stay off until the decoder and project-reader fuzzers have run; until then it answers 403 uploads_disabled.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: project_remix
projectRemix body
Field
Type
Required
Description
project
string
yes
The id (file_…) of an uploaded DAW project or zipped project folder. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
seed
integer
no
Seed for the remix variations; absent or zero derives one from the project, so the same project remixes the same way as a drop into PAM. From 0 to 4294967295. Default 0.
name
string
no
Preset name; absent uses the project file name followed by Remix.
faithful
boolean
no
Keep only the project's own sections; skip PAM's remix variations and song tail.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "entitlement",
"code": "uploads_disabled",
"message": "POST /v1/project/remix works on uploaded files, and uploads are not open yet. Nothing was charged.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#uploads_disabled",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The queued job; poll `urls.self` or stream `urls.events`., 403 Uploads not open yet, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Render a PAM cell effect chain over an audio file.
Run a file through PAM's cell effects: one cell's chain (delay, flanger, crusher, EQ and the rest of the cell rack), set as PAM parameters in chain. Without bars or seconds the render lasts as long as the file, plus tail. It costs render-minutes for the audio it renders: its length in minutes, at least 0.1 a render. Answers 202 with the queued job: poll GET /v1/jobs/{id}, stream GET /v1/jobs/{id}/events, or send Prefer: wait=N (at most 60 s) to get the finished job in this response.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: fx
fx body
Field
Type
Required
Description
file
string
yes
The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
seconds
number
no
Render length in seconds; mutually exclusive with bars. Defaults to the input duration for fx and audio master. From 0.001 to 300.
bars
integer
no
Length in bars (1..64): pattern generation uses four beats and defaults to 1; preset rendering uses the preset time signature and defaults to 4. From 1 to 64.
sampleRate
integer
no
Output sample rate. From 22050 to 48000. Default 48000.
tail
number
no
Additional effect tail in seconds after transport stops. From 0 to 30. Default 0.
seed
integer
no
Reproducible seed; zero draws a random seed. From 0 to 4294967295. Default 0.
chain
object
yes
A PAM state fragment as a JSON object: for fx, cell1_* settings, cell1_effectOrder and cells.1.effectConfig, or the same as {params, effectConfig, effectOrder} without the cell1_ prefix; master* settings for audio master.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "chain must be a JSON object; got a string.",
"param": "chain",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The queued job; poll `urls.self` or stream `urls.events`., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Render the PAM master effect chain over an audio file.
Run a file through PAM's master chain (EQ, compression, tape, clipping, limiting and the other master stages), set as master* parameters in chain. For loudness alone, POST /v1/audio/normalize is free. It costs render-minutes for the audio it renders: its length in minutes, at least 0.1 a render. Answers 202 with the queued job: poll GET /v1/jobs/{id}, stream GET /v1/jobs/{id}/events, or send Prefer: wait=N (at most 60 s) to get the finished job in this response.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: audio_master
audioMaster body
Field
Type
Required
Description
file
string
yes
The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
seconds
number
no
Render length in seconds; mutually exclusive with bars. Defaults to the input duration for fx and audio master. From 0.001 to 300.
bars
integer
no
Length in bars (1..64): pattern generation uses four beats and defaults to 1; preset rendering uses the preset time signature and defaults to 4. From 1 to 64.
sampleRate
integer
no
Output sample rate. From 22050 to 48000. Default 48000.
tail
number
no
Additional effect tail in seconds after transport stops. From 0 to 30. Default 0.
seed
integer
no
Reproducible seed; zero draws a random seed. From 0 to 4294967295. Default 0.
chain
object
yes
A PAM state fragment as a JSON object: for fx, cell1_* settings, cell1_effectOrder and cells.1.effectConfig, or the same as {params, effectConfig, effectOrder} without the cell1_ prefix; master* settings for audio master.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "conflict",
"code": "file_not_ready",
"message": "File file_01M6BPRK0M34NBP2XKJ1RMX1TQ is still being written by job_01M6BPRE186QHP9QPYGDX5NNFP; retry when that job succeeds.",
"param": "file",
"retryable": true,
"jobId": "job_01M6BPRE186QHP9QPYGDX5NNFP",
"docUrl": "https://map.audio/developers/music-api/errors#file_not_ready",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The queued job; poll `urls.self` or stream `urls.events`., 409 File not ready, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Apply state envelopes to Init, a preset or a point between two presets in the headless PAM engine, read the resulting state and optionally render it.
Run PAM's engine headless on a preset's state: apply envelopes (parameter changes), morph toward another preset or variation, or blend presets, then read the resulting state or render it. Without render it is free and answers at once; with render: true it renders like POST /v1/renders and also returns the session as a .preset file. Free without render; with render: true it costs render-minutes for the audio it renders. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll; with render: true it waits only as long as Prefer: wait asks.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: state
state body
Field
Type
Required
Description
preset
string
no
A factory preset reference, pam:factory/<slug> or the bare slug; GET /v1/presets lists them. At most 200 characters.
envelopes
object or array of any
no
State envelopes ({delta, options?}, or {directNodeOps, options?} without a delta) applied in order, as a JSON array or object.
keys
string
no
Top-level state keys to return, as a comma list or a JSON array; absent keys are listed in missingKeys.
tempo
number
no
Transport tempo in beats per minute before the envelopes apply. From 20 to 999.
playing
boolean
no
Start the transport before the envelopes apply.
variation
integer
no
Preset variation, numbered from 1. From 1 to 16.
morphTo
string
no
Preset to morph toward, from the preset argument or Init, at the position at gives. Below 1 the session stays the start's and only its parameters move; from 1 it is this preset's. A factory preset reference, pam:factory/<slug> or the bare slug; GET /v1/presets lists them. At most 200 characters.
toVariation
integer
no
Variation, numbered from 1, the morph moves toward: of the morphTo preset, or of the preset argument without morphTo. From 1 to 16.
at
number
no
Morph position: 0 is the start, 1 the target. Values outside 0..1 extrapolate along the same line, clamped to each parameter's range.
curve
"linear" | "ease" | "exp" | "log"
no
Shape applied to at between 0 and 1, as a live Glide shapes its window. Default "ease".
discrete
string
no
When parameters a Glide switches instead of moving (modes, selectors, timing) take the target's value: hold until 1, switch once at is above 0, or a threshold between 0 and 1. Default "hold".
pattern
"dissolve" | "wipe" | "cells"
no
Stage the cells' patterns at at as a Steps transition does: dissolve fades the start's steps out and the target's in through their probability, wipe sweeps a frontier through each pattern, cells hands patterns over cell by cell. Without it the patterns stay the start's below 1.
patternCurve
"linear" | "ease" | "exp" | "log"
no
Shape applied to at for pattern, as a live transition shapes its pattern stages. Default "linear".
patternSeed
integer
no
Decide each step a pattern dissolve scaled: a start-only step stays with probability 1 - p and a target-only step arrives with p, drawn from this seed, so the cells hold a concrete pattern. The same seed gives the same steps. From 0 to 4294967295.
relations
"off" | "stepped"
no
A live Glide's relations: stepped moves a drum synth's pitch through its semitones instead of switching it at the anchor. Default "off".
stagger
"off" | "cell" | "category"
no
A live Glide's cascade: parameters start moving group by group, by cell or by category, over the staggerSpread fraction of the window. Default "off".
staggerSpread
number
no
Fraction of the window a stagger cascade spreads its groups' starts over; 0 staggers nothing, as in a live transition. From 0 to 0.9. Default 0.
staggerOrder
"forward" | "reverse"
no
Order of a stagger cascade: forward starts the first cell or category first. Default "forward".
liveCap
boolean
no
Move only the 1,024 largest moves, as a live Glide does when more parameters differ; the others switch as discrete says.
blend
array of object
no
Presets to blend instead of a start and a target, each with a positive weight; weights are relative. 2 to 16 items.
blend[].preset
string
yes
A factory preset pam:factory/<slug>, or its bare slug. At most 200 characters.
blend[].variation
integer
no
The preset's variation slot to blend; default: its base state. From 1 to 16.
blend[].weight
number
yes
More than 0.
render
boolean
no
Render the session the envelopes leave to WAV, as preset render renders a preset.
seconds
number
no
Render length in seconds; mutually exclusive with bars. Defaults to the input duration for fx and audio master. From 0.001 to 300.
bars
integer
no
Length in bars (1..64): pattern generation uses four beats and defaults to 1; preset rendering uses the preset time signature and defaults to 4. From 1 to 64.
sampleRate
integer
no
Output sample rate. From 22050 to 48000. Default 48000.
tail
number
no
Additional effect tail in seconds after transport stops. From 0 to 30. Default 0.
seed
integer
no
Reproducible seed; zero draws a random seed. From 0 to 4294967295. Default 0.
stems
boolean
no
Write each cell stem alongside the master in one render pass.
input
string
no
Audio played into the engine's input, through the PAM cells whose source is External. Without seconds or bars the render lasts as long as the input, plus tail. The id (file_…) of WAV or FLAC audio this account holds: a render output, or an upload once uploads open. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
saveSlot
integer
no
Variation slot, numbered from 1, that holds the saved state; the other slots keep the session's bank. Defaults to the slot the session is on. From 1 to 8.
meta
object
no
Metadata for the preset a render saves, as a JSON object: name, author, description, category, tags and the other browser fields.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Render a DJ set of PAM presets to WAV, each boundary on its DJ view transition, without opening PAM.
Render a DJ set: factory presets in order, each boundary on its DJ-view transition (blend, drop, rise, break, sweep or fill), as one WAV. Check the set first with POST /v1/arrangements, which costs nothing and returns the boundaries; GET /v1/transition-presets lists the transitions. It costs render-minutes for the audio it renders: its length in minutes, at least 0.1 a render. Answers 202 with the queued job: poll GET /v1/jobs/{id}, stream GET /v1/jobs/{id}/events, or send Prefer: wait=N (at most 60 s) to get the finished job in this response.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
MCP tool: render_dj_set
djSet body
Field
Type
Required
Description
set
object
yes
The set to render. queue lists its items in play order: queue[0] plays first, and each item names a factory preset (presetPath, such as pam:factory/313-disco), its variation (variationIndex, counted from 0), its length in bars and the transition into it. stepBars, launchBars, defaultTransition and tempo set the defaults; without tempo.bpm the set runs at its first preset's tempo, and auto: false is refused because a render steps through the set itself. POST /v1/arrangements checks a set without rendering it; GET /v1/transition-presets lists the transition presets, modes and the set schema's definitions.
sampleRate
integer
no
Output sample rate. From 22050 to 48000. Default 48000.
tail
number
no
Additional effect tail in seconds after transport stops. From 0 to 30. Default 0.
seed
integer
no
Reproducible seed; zero draws a random seed. From 0 to 4294967295. Default 0.
stems
boolean
no
Write each cell stem alongside the master in one render pass.
metadata
map of string
no
Up to 20 string pairs stored with the job. At most 20 entries.
{
"error": {
"type": "invalid_request",
"code": "dj_offline_unsupported",
"message": "set.auto false waits for a hand to advance the set, and a render steps through it on its own; leave out auto or send true.",
"param": "set.auto",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#dj_offline_unsupported",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The queued job; poll `urls.self` or stream `urls.events`., 400 Set cannot render as sent, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Generate seeded genre patterns with the shared MIDI corpus; optionally write MIDI.
Generate seeded drum and bass patterns in a genre from PAM's MIDI corpus, returned as notes per cell and a MIDI file. It renders no audio, so it is free; render presets to audio with POST /v1/renders. Free: it counts in GET /v1/usage, never in render-minutes. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
Reproducible seed; zero draws a random seed. From 0 to 4294967295. Default 0.
bpm
number
no
MIDI tempo in beats per minute. From 20 to 400. Default 120.
bars
integer
no
Length in bars (1..64): pattern generation uses four beats and defaults to 1; preset rendering uses the preset time signature and defaults to 4. From 1 to 64.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "genre must be one of trap, drill, boombap, dnb, house, techno or idm; got \"polka\".",
"param": "genre",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Render procedural drum engines with named controls and timed triggers.
Synthesize drum hits with one of PAM's drum-synth engines (kick, snare, hats, 808 and more), set by named controls in real units, with trigger times for a pattern of hits. It is free; GET /v1/drum-engines lists the engines and their controls. Free: it counts in GET /v1/usage, never in render-minutes. Answers 200 with the finished job when it ends within Prefer: wait=N (30 s unless sent, at most 60), else 202 with the job to poll.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "duration must be at most 30; got 45.",
"param": "duration",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The finished job: `result.outputs` link each file it wrote and `result.command` is the engine's own result., 202 The job, still running when `Prefer: wait` ran out; poll `urls.self`., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
The account's jobs, newest first, optionally filtered by status and operation, with fresh download links on the outputs. Jobs from test and live keys are listed together. Job records are kept 90 days. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "status must be one of queued, running, succeeded, failed, cancelled or expired; got \"done\".",
"param": "status",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Jobs., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
A job as it stands: status, progress and estimate, and once it ends, its outputs with download links valid for an hour, the seed, the engine's own result, the provenance record and the render-minutes it was charged. Poll it after a 202, or read it when a webhook says the job ended. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
MCP tool: get_job
getJob parameters
Name
In
Type
Required
Description
id
path
string
yes
A job id (job_…), from the response that created the job or GET /v1/jobs. Matches ^job_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No job with that id; GET /v1/jobs lists this account's jobs.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The job., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Stop a queued or running job. A queued job ends cancelled at once and a running one when its engine stops; nothing is charged unless the job already published a preview. A job that already ended keeps its outcome. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
MCP tool: cancel_job
cancelJob parameters
Name
In
Type
Required
Description
id
path
string
yes
A job id (job_…), from the response that created the job or GET /v1/jobs. Matches ^job_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No job with that id; GET /v1/jobs lists this account's jobs.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The job., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Server-sent events for one job: job.queued, job.started, job.progress, job.preview and job.requeued, then job.succeeded, job.failed, job.cancelled or job.expired. Each event's data is JSON with jobId and createdAt; job.preview carries the preview's outputs, and job.failed the error. Reconnect with Last-Event-ID (or after) to miss nothing; a stream closes after 10 minutes or once the job has ended. A browser's EventSource cannot send Authorization, so read it with fetch. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: A server-sent event stream; MCP tools answer once, so poll get_job instead.
streamJobEvents parameters
Name
In
Type
Required
Description
id
path
string
yes
A job id (job_…), from the response that created the job or GET /v1/jobs. Matches ^job_[0-9A-HJKMNP-TV-Z]{26}$.
after
query
integer
no
Resume after this event id, as the Last-Event-ID header does. At least 0.
Last-Event-ID
header
string
no
The last event id received; the stream resumes after it. Matches ^\d{1,9}$.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No job with that id; GET /v1/jobs lists this account's jobs.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The event stream., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Render outputs and uploads the account holds, newest first: kind, status, size, SHA-256 and the job that wrote each. Outputs are kept 7 days on the free tier and longer on paid tiers. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "The cursor is not one this API issued; pass the nextCursor of the page before, unchanged.",
"param": "cursor",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Files., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
One file's metadata: kind, status, name, content type, size, SHA-256, the job that wrote it and when retention deletes it. For its bytes, GET /v1/files/{id}/content. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
MCP tool: get_file
getFile parameters
Name
In
Type
Required
Description
id
path
string
yes
A file id (file_…), from a job's result.outputs or GET /v1/files. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No file with that id; GET /v1/files lists this account's files.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The file., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Delete a file's bytes now, before retention would; its record stays with status deleted, and an output leaves its job's outputs. A file whose job is still running cannot be deleted yet. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Deleting a render cannot be undone, so it stays with your own code: DELETE /v1/files/{id} with an API key.
deleteFile parameters
Name
In
Type
Required
Description
id
path
string
yes
A file id (file_…), from a job's result.outputs or GET /v1/files. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "conflict",
"code": "file_not_ready",
"message": "File file_01M6BPRK0M34NBP2XKJ1RMX1TQ is still being written by job_01M6BPRE186QHP9QPYGDX5NNFP; retry when that job succeeds.",
"param": "id",
"retryable": true,
"jobId": "job_01M6BPRE186QHP9QPYGDX5NNFP",
"docUrl": "https://map.audio/developers/music-api/errors#file_not_ready",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The file, deleted., 409 File not ready, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Redirects (302) to a signed link for the file's bytes, valid for one hour; the link needs no Authorization header. Job outputs already carry such a link in url; use this route for a fresh one. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Answers with a redirect to raw bytes, which a tool result cannot carry; get_job lists each output with a signed download url.
getFileContent parameters
Name
In
Type
Required
Description
id
path
string
yes
A file id (file_…), from a job's result.outputs or GET /v1/files. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
Responses: 302 Redirect to the signed download link., 410 File no longer stored, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Start a multipart upload of an audio file or a DAW project, declared by kind, name, size and SHA-256. Send the parts with PUT /v1/uploads/{id}/parts/{part}, then POST /v1/uploads/{id}/complete. Uploads are off until the decoder and project-reader fuzzers have run, so today this answers 403 uploads_disabled. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Uploads send raw bytes in parts, which a JSON tool call cannot carry; uploads are also off until the decoder fuzzers have run.
createUpload body
Field
Type
Required
Description
kind
"audio" | "sample" | "project"
yes
sample is an alias of audio. Preset and project-folder uploads are not served yet.
{
"error": {
"type": "entitlement",
"code": "uploads_disabled",
"message": "File uploads are not open yet; render from factory presets (GET /v1/presets) and pass render outputs as files meanwhile.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#uploads_disabled",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 201 The upload., 403 Uploads not open yet, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Send one part of an upload as raw bytes with its exact Content-Length: every part but the last is partBytes long (16 MiB), the last holds the rest. Sending a part again replaces it. Uploads are off for now, so this answers 403 uploads_disabled. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Uploads send raw bytes in parts, which a JSON tool call cannot carry; uploads are also off until the decoder fuzzers have run.
putUploadPart parameters
Name
In
Type
Required
Description
id
path
string
yes
The upload's file id (file_…), from POST /v1/uploads. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "entitlement",
"code": "uploads_disabled",
"message": "File uploads are not open yet; render from factory presets (GET /v1/presets) and pass render outputs as files meanwhile.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#uploads_disabled",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The part, stored., 403 Uploads not open yet, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Close the upload and start its probe job: the render host checks the bytes against the declared SHA-256 and rewrites audio as a canonical WAV, after which the file is ready for commands. Answers with the probe job; completing again retries a probe that never started. Uploads are off for now, so this answers 403 uploads_disabled. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Send Prefer: wait=N (0 to 60) to receive the finished job when it ends within N seconds.
Send Idempotency-Key to retry safely: the same key and body return the same result for 24 hours.
Not an MCP tool: Uploads send raw bytes in parts, which a JSON tool call cannot carry; uploads are also off until the decoder fuzzers have run.
completeUpload parameters
Name
In
Type
Required
Description
id
path
string
yes
The upload's file id (file_…), from POST /v1/uploads. Matches ^file_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "entitlement",
"code": "uploads_disabled",
"message": "File uploads are not open yet; render from factory presets (GET /v1/presets) and pass render outputs as files meanwhile.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#uploads_disabled",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The probe job, finished., 202 The probe job, queued., 403 Uploads not open yet, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
The account's webhook endpoints, newest first, without their secrets. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Webhook endpoints hold signing secrets for your own server; set them up with an API key (POST /v1/webhook-endpoints) or with the account holder's map.audio sign-in.
{
"error": {
"type": "invalid_request",
"code": "invalid_request",
"message": "\"limit\" is not a parameter of GET /v1/webhook-endpoints; it takes none.",
"param": "limit",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#invalid_request",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 Endpoints., 400 Invalid request, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Subscribe a public HTTPS URL to job events: job.succeeded, job.failed and job.cancelled unless you list others, or * for every event. Each delivery is a signed Standard Webhooks POST (webhook-id, webhook-timestamp and webhook-signature headers: HMAC-SHA256 under the whsec_ secret, which is in this response only), retried with backoff for about 63 hours. An endpoint is disabled after three deliveries in a row run out of retries. Needs an API key or a map.audio sign-in on MAP Audio's own pages; an account has at most 10 endpoints. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Webhook endpoints hold signing secrets for your own server; set them up with an API key (POST /v1/webhook-endpoints) or with the account holder's map.audio sign-in.
createWebhookEndpoint body
Field
Type
Required
Description
url
string
yes
A public HTTPS URL with a host name; deliveries are POSTs to it. Matches ^https://.
events
array of "job.preview" | "job.succeeded" | "job.failed" | "job.cancelled" | "job.expired" | "webhook.test" or "*"
{
"error": {
"type": "entitlement",
"code": "too_many_endpoints",
"message": "An account may have 10 webhook endpoints; delete one with DELETE /v1/webhook-endpoints/{id} first (GET /v1/webhook-endpoints lists them).",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#too_many_endpoints",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 201 The endpoint, with its secret., 400 Invalid request, 403 Webhook endpoint limit reached, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Webhook endpoints hold signing secrets for your own server; set them up with an API key (POST /v1/webhook-endpoints) or with the account holder's map.audio sign-in.
deleteWebhookEndpoint parameters
Name
In
Type
Required
Description
id
path
string
yes
A webhook endpoint id (whep_…), from GET /v1/webhook-endpoints. Matches ^whep_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No webhook endpoint with that id; GET /v1/webhook-endpoints lists this account's endpoints.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The endpoint, deleted., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Issue a new whsec_ secret, in this response only. For 24 hours each delivery carries signatures under both the old and the new secret, so your server can switch without dropping one; rotating a disabled endpoint also enables it again. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Webhook endpoints hold signing secrets for your own server; set them up with an API key (POST /v1/webhook-endpoints) or with the account holder's map.audio sign-in.
rotateWebhookSecret parameters
Name
In
Type
Required
Description
id
path
string
yes
A webhook endpoint id (whep_…), from GET /v1/webhook-endpoints. Matches ^whep_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "conflict",
"code": "rotation_in_progress",
"message": "The previous secret stays valid until 2026-11-02T14:20:00.000Z; rotate again after that, or delete the endpoint and create a new one.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#rotation_in_progress",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The endpoint, with its new secret., 409 Secret rotation in progress, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
Queue a signed webhook.test event to the endpoint, to check that your server receives deliveries and verifies their signatures. Free.
Auth: Authorization: Bearer with an API key or a map.audio access token.
Not an MCP tool: Webhook endpoints hold signing secrets for your own server; set them up with an API key (POST /v1/webhook-endpoints) or with the account holder's map.audio sign-in.
testWebhookEndpoint parameters
Name
In
Type
Required
Description
id
path
string
yes
A webhook endpoint id (whep_…), from GET /v1/webhook-endpoints. Matches ^whep_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "conflict",
"code": "endpoint_disabled",
"message": "This endpoint is disabled, after repeated failed deliveries or because the key that set its secret was revoked; rotate its secret (POST /v1/webhook-endpoints/{id}/rotate-secret) to enable it again.",
"param": null,
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#endpoint_disabled",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 202 The queued event., 409 Webhook endpoint disabled, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
A render's signed provenance record: the engine image, seed, presets, inputs and outputs with their SHA-256, the licence the render was made under, and that no AI model made the audio. Public, so anyone holding a record id can check it: verify signature (Ed25519 over the record's JSON with sorted keys and without signature) with the key in GET /.well-known/jwks.json whose kid matches. Free.
Auth: none; this route is public.
Not an MCP tool: Public and unauthenticated: read it with a plain GET. get_job already returns each render's provenance record.
getProvenance parameters
Name
In
Type
Required
Description
id
path
string
yes
A provenance record id (prov_…), from a job's result.provenance.id. Matches ^prov_[0-9A-HJKMNP-TV-Z]{26}$.
{
"error": {
"type": "not_found",
"code": "not_found",
"message": "No provenance record with that id; a job's result.provenance.id names its record.",
"param": "id",
"retryable": false,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#not_found",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 The record., 404 Not found, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..
{
"error": {
"type": "unavailable",
"code": "internal_error",
"message": "Something went wrong on our side; nothing was charged.",
"param": null,
"retryable": true,
"jobId": null,
"docUrl": "https://map.audio/developers/music-api/errors#internal_error",
"requestId": "9a3f7c2e5b1d8f40-LHR"
}
}
Responses: 200 JWKS., 500 Internal error, default Any other error: `error.code` names it, `error.param` the field at fault, and `error.docUrl` its entry in the error catalogue..