# djSet

> 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/dj/set`

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; 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: `render_dj_set`.

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

## Example

```sh
curl -sS "https://api.map.audio/v1/dj/set" \
  -H "Authorization: Bearer $MAP_API_KEY" \
  -H "Map-Version: 2026-11-01" \
  -H "Prefer: wait=30" \
  -H "Content-Type: application/json" \
  -d '{"set":{"queue":[{"presetPath":"pam:factory/acid-sprinkle","bars":16},{"presetPath":"pam:factory/teknochonic","variationIndex":1,"bars":16,"transition":{"preset":"blend","bars":8}},{"presetPath":"pam:factory/breakbeatrcool","variationIndex":2,"bars":16,"transition":{"preset":"drop"}}],"tempo":{"bpm":124}},"seed":42}'
```

### Request: Three presets at 124 BPM: an 8-bar blend, then a drop

```json
{
  "set": {
    "queue": [
      {
        "presetPath": "pam:factory/acid-sprinkle",
        "bars": 16
      },
      {
        "presetPath": "pam:factory/teknochonic",
        "variationIndex": 1,
        "bars": 16,
        "transition": {
          "preset": "blend",
          "bars": 8
        }
      },
      {
        "presetPath": "pam:factory/breakbeatrcool",
        "variationIndex": 2,
        "bars": 16,
        "transition": {
          "preset": "drop"
        }
      }
    ],
    "tempo": {
      "bpm": 124
    }
  },
  "seed": 42
}
```

### 200: Finished

```json
{
  "object": "job",
  "id": "job_01M6BPRFPCH9EBPY7B6JKM7CE1",
  "operation": "djSet",
  "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": 92.903,
    "renderMinutes": 1.548
  },
  "result": {
    "outputs": [
      {
        "role": "master",
        "name": null,
        "cell": null,
        "file": "file_01M6BPRMNR7PYGFNA66BX2YJ8M",
        "sha256": "13d41d922519699fc14a7587130eceee7d0f149414350000578de1564866a0d4",
        "bytes": 26756108,
        "format": "wav",
        "sampleRate": 48000,
        "durationSeconds": 92.903,
        "url": "https://api.map.audio/v1/download/file_01M6BPRMNR7PYGFNA66BX2YJ8M?expires=1793545422&signature=GQ2GkmPjqXuxxBSSM4NKBCY7OjU7w3YSeZBrCoxxtbY",
        "expiresAt": "2026-11-01T15:03:42.000Z"
      }
    ],
    "seed": 42,
    "command": {
      "ok": true,
      "wavPath": "file_01M6BPRMNR7PYGFNA66BX2YJ8M",
      "sampleRate": 48000,
      "durationSeconds": 92.903,
      "seed": 42,
      "stems": [],
      "boundaries": [
        {
          "index": 1,
          "presetPath": "pam:factory/teknochonic",
          "variationIndex": 1,
          "anchorBar": 16,
          "windowBars": 8,
          "mode": "mix",
          "locked": false
        },
        {
          "index": 2,
          "presetPath": "pam:factory/breakbeatrcool",
          "variationIndex": 2,
          "anchorBar": 32,
          "windowBars": 0,
          "mode": "auto",
          "locked": false
        }
      ],
      "bpm": 124,
      "timeSig": [
        4,
        4
      ],
      "bars": 48
    },
    "provenance": {
      "object": "provenance",
      "id": "prov_01M6BPRVA8ZC7F7J737SQ0EPN2",
      "jobId": "job_01M6BPRFPCH9EBPY7B6JKM7CE1",
      "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/acid-sprinkle",
          "sha256": "eee63255e1350ec8f03f098656befcc3c1c1c23c0bd7933f93fee84071f9279d"
        },
        {
          "ref": "pam:factory/teknochonic",
          "variation": 2,
          "sha256": "a2e6645b2108343284008cd4ef4b8356ab1f4c47dbd9da63a785d893b31a9266"
        },
        {
          "ref": "pam:factory/breakbeatrcool",
          "variation": 3,
          "sha256": "92916c116f9e0a17fd8217a67a98b57063efc8554de0e66b8398053dda7e3296"
        }
      ],
      "packs": [],
      "userFiles": [],
      "inputs": [],
      "outputs": [
        {
          "file": "file_01M6BPRMNR7PYGFNA66BX2YJ8M",
          "sha256": "13d41d922519699fc14a7587130eceee7d0f149414350000578de1564866a0d4"
        }
      ],
      "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:LEVZHpOHj8BMGZgJh-_Y7SmKbqDlBDR8LqY-XelU6GYK8lntZqg3rRK4b3BH8cy25bK0iWzOXFXmkiGHEYue7A"
    }
  },
  "error": null,
  "usage": {
    "renderMinutes": 1.548,
    "audioSeconds": 92.903,
    "computeMs": 6273
  },
  "metadata": {},
  "urls": {
    "self": "https://api.map.audio/v1/jobs/job_01M6BPRFPCH9EBPY7B6JKM7CE1",
    "events": "https://api.map.audio/v1/jobs/job_01M6BPRFPCH9EBPY7B6JKM7CE1/events",
    "cancel": "https://api.map.audio/v1/jobs/job_01M6BPRFPCH9EBPY7B6JKM7CE1/cancel"
  }
}
```

### 202: Queued

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

### 400: Set cannot render as sent

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

## Errors

- [`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)
- [`terms_required`](https://map.audio/developers/music-api/errors#terms_required)
- [`concurrency_limit`](https://map.audio/developers/music-api/errors#concurrency_limit)
- [`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)
- [`insufficient_credits`](https://map.audio/developers/music-api/errors#insufficient_credits)
- [`render_too_long`](https://map.audio/developers/music-api/errors#render_too_long)
- [`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)
- [`dj_invalid_set`](https://map.audio/developers/music-api/errors#dj_invalid_set)
- [`dj_offline_unsupported`](https://map.audio/developers/music-api/errors#dj_offline_unsupported)
- [`dj_preset_missing`](https://map.audio/developers/music-api/errors#dj_preset_missing)
- [`dj_unknown_transition_preset`](https://map.audio/developers/music-api/errors#dj_unknown_transition_preset)
