# Separations

Create a separation, follow its status, download its stems and delete it.

## Create

`POST /separations` Create a separation

| Parameter        | In    | Type                     | Description                                                                            |
| ---------------- | ----- | ------------------------ | -------------------------------------------------------------------------------------- |
| `stems` required | query | string\[]                | Stem ids from the catalog, repeated as `stems=a&stems=b`                               |
| `formats`        | query | string\[]                | File formats to deliver each stem in, repeated like `stems`                            |
| `name`           | query | string                   | The file's name, for the list and the download file names                              |
| `bytes`          | query | integer                  | Size in bytes of a file to upload separately instead of sending it as the request body |
| `body` required  | body  | application/octet-stream | MP3, WAV, FLAC, M4A, Ogg or Opus audio                                                 |

Response

```json
{
  "id": "sep_8f3kq2",
  "name": "Halfway Home",
  "created_at": "2026-11-12T14:04:05.000Z",
  "expires_at": "2026-11-12T15:20:05.000Z",
  "status": "queued",
  "charge": 70
}
```

```bash
curl "https://api.disband.io/v1/separations" \
  --url-query stems=vocals \
  --url-query stems=instrumental.drums \
  --url-query formats=mp3 \
  --url-query "name=Halfway Home" \
  -H "Authorization: Bearer $DISBAND_KEY" \
  --data-binary @song.mp3
```

* The request body is the audio file, at most 95 MB, with a `Content-Length` header. Larger files use a [reserved upload](https://disband.io/docs/large-files).
* Supported formats: WAV, FLAC, MP3, AAC and ALAC (`.m4a`), Ogg Vorbis and Opus, mono or stereo. The format is detected from the file's content, so `Content-Type` is not required.
* The price depends on the file's length and the requested stems, not on `formats`. See [Credits](https://disband.io/docs/credits).
* Returns `202 Accepted` with a `Location` header and the separation. The credits are charged at this point and refunded if the separation fails on our side.

## Status

`GET /separations/{id}` Get a separation

| Parameter     | In     | Type   | Description                                                                           |
| ------------- | ------ | ------ | ------------------------------------------------------------------------------------- |
| `prefer`      | header | string | `wait=N` holds the response until the next status change, at most N seconds, up to 60 |
| `id` required | path   | string | Separation id                                                                         |

Response

```json
{
  "id": "sep_8f3kq2",
  "name": "Halfway Home",
  "created_at": "2026-11-12T14:04:05.000Z",
  "expires_at": "2026-11-12T15:05:12.000Z",
  "status": "ready",
  "charge": 70,
  "duration": 210.4,
  "stems": {
    "vocals": {
      "mp3": {
        "url": "https://api.disband.io/v1/separations/sep_8f3kq2/stems/vocals/mp3",
        "bytes": 5262000
      }
    },
    "instrumental.drums": {
      "silent": true
    }
  }
}
```

| Status       | Meaning                                                                                 |
| ------------ | --------------------------------------------------------------------------------------- |
| `uploading`  | A [reserved upload](https://disband.io/docs/large-files) is waiting for its file        |
| `queued`     | Waiting for a GPU                                                                       |
| `separating` | Running on a GPU                                                                        |
| `ready`      | Done, with `duration` and `stems`                                                       |
| `failed`     | Ended with a `problem`, see [Errors](https://disband.io/docs/errors#failed-separations) |

With `Prefer: wait=N`, the response is held until the status changes, for at most N seconds and no more than 60 seconds, and includes `Preference-Applied`. Repeat the request until the status is `ready` or `failed`. No polling interval is needed. Ready and failed separations return immediately.

`GET /separations` List separations

Response

```json
[
  {
    "id": "sep_8f3kq2",
    "name": "Halfway Home",
    "created_at": "2026-11-12T14:04:05.000Z",
    "expires_at": "2026-11-12T15:05:12.000Z",
    "status": "ready",
    "charge": 70,
    "duration": 210.4,
    "stems": {
      "vocals": {
        "mp3": {
          "url": "https://api.disband.io/v1/separations/sep_8f3kq2/stems/vocals/mp3",
          "bytes": 5262000
        }
      },
      "instrumental.drums": {
        "silent": true
      }
    }
  }
]
```

Lists the account's separations, newest first, until they expire or are deleted.

## Stems

A ready separation maps each requested stem to one file per format, each with its `url` and size in `bytes`, as in the response under [Status](#status).

A stem with no audio in the song is returned as `{"silent": true}` without files. It is charged like any other stem. See [Silent stems](https://disband.io/docs/stems#silent-stems).

## Download

`GET /separations/{id}/stems/{stem}/{format}` Download a stem

| Parameter         | In   | Type   | Description                                     |
| ----------------- | ---- | ------ | ----------------------------------------------- |
| `id` required     | path | string | Separation id                                   |
| `stem` required   | path | string | Stem id from the catalog                        |
| `format` required | path | string | `wav` or `mp3`, one of the separation's formats |

* Requires the same key. WAV files are 16-bit, 44.1 kHz stereo. MP3 files are about 200 kbps VBR, 44.1 kHz stereo.
* The file name is the separation's `name` and the stem, for example `Halfway Home - Vocals.mp3`.
* Byte ranges are supported, so interrupted downloads can resume.
* Downloads don't delete anything and can be repeated until the separation expires.

## Delete

`DELETE /separations/{id}` Delete a separation

| Parameter     | In   | Type   | Description   |
| ------------- | ---- | ------ | ------------- |
| `id` required | path | string | Separation id |

Deletes the separation and its files and returns `204`. Deleting a `queued` separation refunds its charge, deleting a `separating` one stops it and keeps its charge. Otherwise the files are deleted at `expires_at`, one hour after the separation is ready or fails.
