# createRender

> Part of the MAP Audio Music API docs. Index of every page: https://map.audio/developers/music-api/llms.txt. OpenAPI document: https://map.audio/developers/music-api/openapi.json.

`POST https://api.map.audio/v1/renders`

Render presets or a plan to audio

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; otherwise the answer is `202` with the job. Send `Idempotency-Key` to retry safely: the same key and body return the same result for 24 hours. MCP tool: `create_render`.

## 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. |

## Example

```sh
curl -sS "https://api.map.audio/v1/renders" \
  -H "Authorization: Bearer $MAP_API_KEY" \
  -H "Map-Version: 2026-11-01" \
  -H "Prefer: wait=30" \
  -H "Content-Type: application/json" \
  -d '{"source":{"preset":"pam:factory/313-disco"},"bars":8,"seed":42}'
```

### Request: Eight bars of 313 Disco as WAV, with a fixed seed

```json
{
  "source": {
    "preset": "pam:factory/313-disco"
  },
  "bars": 8,
  "seed": 42
}
```

### Request: Four of Cal's variation slots in one job, as FLAC

```json
{
  "source": {
    "preset": "pam:factory/cal"
  },
  "bars": 8,
  "variations": {
    "kind": "slots",
    "slots": [
      1,
      2,
      3,
      4
    ]
  },
  "format": {
    "container": "flac"
  }
}
```

### Request: Four takes of Totes Rando, each from its own seed

```json
{
  "source": {
    "preset": "pam:factory/totes-rando"
  },
  "bars": 4,
  "variations": {
    "kind": "seeds",
    "count": 4
  },
  "seed": 7
}
```

### Request: Sixteen bars of a variation with one stem per cell

```json
{
  "source": {
    "preset": "pam:factory/breakbeatrcool",
    "variation": 2
  },
  "bars": 16,
  "stems": true,
  "seed": 42
}
```

### Request: Three points on a morph from Acid Sprinkle toward Teknochonic

```json
{
  "source": {
    "preset": "pam:factory/acid-sprinkle"
  },
  "bars": 8,
  "variations": {
    "kind": "morph",
    "to": {
      "preset": "pam:factory/teknochonic"
    },
    "at": [
      0.25,
      0.5,
      0.75
    ]
  }
}
```

### Request: 30- and 15-second cutdowns for an ad, as 256 kbit/s MP3

```json
{
  "source": {
    "preset": "pam:factory/thaw"
  },
  "items": [
    {
      "name": "spot-30",
      "cutdown": {
        "seconds": 30
      }
    },
    {
      "name": "spot-15",
      "cutdown": {
        "seconds": 15
      }
    }
  ],
  "format": {
    "container": "mp3",
    "bitrate": 256
  }
}
```

### Request: Render four seeds and keep the one nearest -14 LUFS

```json
{
  "source": {
    "preset": "pam:factory/junglistic"
  },
  "bars": 8,
  "quality": "standard",
  "search": {
    "candidates": 4,
    "return": 1,
    "targetLufs": -14
  }
}
```

### Request: Two minutes, with a 4-bar preview published first

```json
{
  "source": {
    "preset": "pam:factory/corduroy"
  },
  "seconds": 120,
  "preview": {
    "bars": 4
  },
  "seed": 11
}
```

### Request: Render a stored plan

```json
{
  "plan": "plan_01M6BPRCC4FTKB29RFYD2JDKJQ",
  "format": {
    "container": "mp3"
  }
}
```

### 200: Succeeded: 16 s of 313 Disco

```json
{
  "object": "job",
  "id": "job_01M6BPRE186QHP9QPYGDX5NNFP",
  "operation": "renders.create",
  "status": "succeeded",
  "livemode": false,
  "sequence": 3,
  "progress": 1,
  "queuePosition": null,
  "createdAt": "2026-11-01T14:03:31.512Z",
  "startedAt": "2026-11-01T14:03:33.104Z",
  "finishedAt": "2026-11-01T14:03:41.877Z",
  "estimate": {
    "audioSeconds": 16,
    "renderMinutes": 0.267
  },
  "result": {
    "outputs": [
      {
        "role": "master",
        "name": null,
        "cell": null,
        "file": "file_01M6BPRK0M34NBP2XKJ1RMX1TQ",
        "sha256": "5a3485b7a3221be5f7ead6ab953cbc198988a7246158215b32bb937acbd3852b",
        "bytes": 4608044,
        "format": "wav",
        "sampleRate": 48000,
        "durationSeconds": 16,
        "url": "https://api.map.audio/v1/download/file_01M6BPRK0M34NBP2XKJ1RMX1TQ?expires=1793545422&signature=yaoMrgCHcK9T8MaVnCVtXZc4Ym0FWWM8P-0feZDMObk",
        "expiresAt": "2026-11-01T15:03:42.000Z"
      }
    ],
    "seed": 42,
    "command": {
      "ok": true,
      "wavPath": "file_01M6BPRK0M34NBP2XKJ1RMX1TQ",
      "sampleRate": 48000,
      "channels": 2,
      "durationSeconds": 16,
      "seed": 42,
      "stems": [],
      "stemTap": "post_cell_pre_master",
      "latencySamples": 0,
      "missingSamples": []
    },
    "spec": {
      "source": {
        "preset": "pam:factory/313-disco"
      },
      "plan": null,
      "bars": 8,
      "seconds": null,
      "tail": 0,
      "seed": 42,
      "stems": false,
      "sampleRate": 48000,
      "format": {
        "container": "wav"
      },
      "quality": "draft",
      "tempo": 120
    },
    "provenance": {
      "object": "provenance",
      "id": "prov_01M6BPRVA8ZC7F7J737SQ0EPN2",
      "jobId": "job_01M6BPRE186QHP9QPYGDX5NNFP",
      "createdAt": "2026-11-01T14:03:41.877Z",
      "engine": {
        "product": "pam",
        "version": null,
        "runtime": "native-linux-x86_64",
        "image": "registry.cloudflare.com/c7c2e61448617e81ced650f444fb6787/pam-render@sha256:5c5ffe3fabc103e277280fbd65a08988d31361f00fe7857e36f603d67bcec42d"
      },
      "seed": 42,
      "presets": [
        {
          "ref": "pam:factory/313-disco",
          "sha256": "3afbf5dea1003b2d17385955017785a57d74c65f77f97b58cf5d7cec9794ca1c"
        }
      ],
      "packs": [],
      "userFiles": [],
      "inputs": [],
      "outputs": [
        {
          "file": "file_01M6BPRK0M34NBP2XKJ1RMX1TQ",
          "sha256": "5a3485b7a3221be5f7ead6ab953cbc198988a7246158215b32bb937acbd3852b"
        }
      ],
      "planner": null,
      "contracts": {
        "api": "2026-11-01",
        "pam.cli": 1
      },
      "aiModels": [],
      "audioByModel": false,
      "license": {
        "id": "lic_api_prototype_test",
        "commercialUse": false,
        "attribution": true
      },
      "kid": "6c2f0a9d4b7e1358",
      "signature": "ed25519:jsfkW3eF1r4kChqccp6AKLTvjTK5Re8acrEusqigz7MDUu6uZhsJXVnuQEl6EsErDgVYNXOkos9d0mMyt2CVCg"
    }
  },
  "error": null,
  "usage": {
    "renderMinutes": 0.267,
    "audioSeconds": 16,
    "computeMs": 6273
  },
  "metadata": {},
  "urls": {
    "self": "https://api.map.audio/v1/jobs/job_01M6BPRE186QHP9QPYGDX5NNFP",
    "events": "https://api.map.audio/v1/jobs/job_01M6BPRE186QHP9QPYGDX5NNFP/events",
    "cancel": "https://api.map.audio/v1/jobs/job_01M6BPRE186QHP9QPYGDX5NNFP/cancel"
  }
}
```

### 202: Queued

```json
{
  "object": "job",
  "id": "job_01M6BPRE186QHP9QPYGDX5NNFP",
  "operation": "renders.create",
  "status": "queued",
  "livemode": false,
  "sequence": 1,
  "progress": 0,
  "queuePosition": null,
  "createdAt": "2026-11-01T14:03:31.512Z",
  "startedAt": null,
  "finishedAt": null,
  "estimate": {
    "audioSeconds": 16,
    "renderMinutes": 0.267
  },
  "result": null,
  "error": null,
  "usage": null,
  "metadata": {},
  "urls": {
    "self": "https://api.map.audio/v1/jobs/job_01M6BPRE186QHP9QPYGDX5NNFP",
    "events": "https://api.map.audio/v1/jobs/job_01M6BPRE186QHP9QPYGDX5NNFP/events",
    "cancel": "https://api.map.audio/v1/jobs/job_01M6BPRE186QHP9QPYGDX5NNFP/cancel"
  }
}
```

### 400: Render too long

```json
{
  "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

```json
{
  "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

```json
{
  "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.

## Errors

- [`terms_required`](https://map.audio/developers/music-api/errors#terms_required)
- [`preset_not_found`](https://map.audio/developers/music-api/errors#preset_not_found)
- [`preset_not_served`](https://map.audio/developers/music-api/errors#preset_not_served)
- [`variation_not_found`](https://map.audio/developers/music-api/errors#variation_not_found)
- [`quality_unavailable`](https://map.audio/developers/music-api/errors#quality_unavailable)
- [`render_too_long`](https://map.audio/developers/music-api/errors#render_too_long)
- [`not_found`](https://map.audio/developers/music-api/errors#not_found)
- [`concurrency_limit`](https://map.audio/developers/music-api/errors#concurrency_limit)
- [`insufficient_credits`](https://map.audio/developers/music-api/errors#insufficient_credits)
- [`idempotency_key_reused`](https://map.audio/developers/music-api/errors#idempotency_key_reused)
- [`idempotency_in_flight`](https://map.audio/developers/music-api/errors#idempotency_in_flight)
- [`queue_unavailable`](https://map.audio/developers/music-api/errors#queue_unavailable)
- [`invalid_request`](https://map.audio/developers/music-api/errors#invalid_request)
- [`unsupported_media_type`](https://map.audio/developers/music-api/errors#unsupported_media_type)
- [`payload_too_large`](https://map.audio/developers/music-api/errors#payload_too_large)
