# Queue migrations

> 📘 Preview feature
> Queue migrations are in preview. [Contact Buildkite support](https://buildkite.com/support) to have this feature enabled for your organization.

A queue migration associates a queue key with a specific destination [queue](/docs/apis/rest-api/clusters/queues), tracking the proportion of that queue key's jobs routed to the destination using `routed_percent`. Creating a migration starts `routed_percent` at 0, and the create endpoint doesn't accept a value for it. Use the update endpoint to move `routed_percent` up or down after creation. Only one queue migration can exist for a queue key in your organization at a time.

## Queue migration data model



| `id` | ID of the queue migration |
| --- | --- |
| `source.queue_key` | Key of the queue being migrated |
| `destination.cluster_id` | ID of the cluster containing the destination queue |
| `destination.queue_id` | ID of the destination queue |
| `destination.queue_key` | Key of the destination queue |
| `routed_percent` | Percentage of the queue key's jobs currently routed to the destination queue. New queue migrations start at `0`. |
| `created_at` | When the queue migration was created |
| `updated_at` | When the queue migration was last updated |



## List queue migrations

Returns a cursor-paginated list of queue migrations. Organization administrators can view all queue migrations in the organization. Cluster maintainers can view migrations whose destination queues belong to clusters they maintain.

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X GET "https://api.buildkite.com/v2/organizations/{org.slug}/cluster-queue-migrations"
```

```json
{
  "items": [
    {
      "id": "0198f47a-9c1a-7db2-93aa-2b6f6a2e9d41",
      "source": {
        "queue_key": "default"
      },
      "destination": {
        "cluster_id": "42f1a7da-812d-4430-93d8-1cc7c33a6bcf",
        "queue_id": "01885682-55a7-44f5-84f3-0402fb452e66",
        "queue_key": "default"
      },
      "routed_percent": 70,
      "created_at": "2026-08-07T04:17:55.867Z",
      "updated_at": "2026-08-07T05:02:11.221Z"
    }
  ],
  "links": {
    "self": "https://api.buildkite.com/v2/organizations/acme-inc/cluster-queue-migrations?per_page=30",
    "next": "https://api.buildkite.com/v2/organizations/acme-inc/cluster-queue-migrations?per_page=30&after=eyJ1dWlkIjoiLi4uIn0"
  }
}
```

The response body contains the following pagination fields:

- `items`: The queue migrations on the current page.
- `links`: URLs for the current page and available `first`, `prev`, and `next` pages. Follow these URLs instead of constructing cursors. The response also includes these links in the HTTP `Link` header.

Optional query string parameters:



| `after` | Returns the next page after the supplied cursor. Cannot be combined with `before`. |
| --- | --- |
| `before` | Returns the previous page before the supplied cursor. Cannot be combined with `after`. |
| `per_page` | Number of results per page. Defaults to `30` and has a maximum of `100`. |



Required scope: `read_clusters`

Required permission: organization administrator privileges or cluster maintainer permissions for at least one cluster

Success response: `200 OK`

Error responses:



| `400 Bad Request` | The request supplies both cursor parameters, an invalid cursor, or a `per_page` value outside the supported range. |
| --- | --- |



## Get a queue migration

Organization administrators can retrieve any queue migration in the organization. Cluster maintainers can retrieve a migration if its destination queue belongs to a cluster they maintain.

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X GET "https://api.buildkite.com/v2/organizations/{org.slug}/cluster-queue-migrations/{migration.id}"
```

```json
{
  "id": "0198f47a-9c1a-7db2-93aa-2b6f6a2e9d41",
  "source": {
    "queue_key": "default"
  },
  "destination": {
    "cluster_id": "42f1a7da-812d-4430-93d8-1cc7c33a6bcf",
    "queue_id": "01885682-55a7-44f5-84f3-0402fb452e66",
    "queue_key": "default"
  },
  "routed_percent": 70,
  "created_at": "2026-08-07T04:17:55.867Z",
  "updated_at": "2026-08-07T05:02:11.221Z"
}
```

Required scope: `read_clusters`

Required permission: organization administrator privileges or cluster maintainer permissions for the destination cluster

Success response: `200 OK`

## Create a queue migration

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X POST "https://api.buildkite.com/v2/organizations/{org.slug}/cluster-queue-migrations" \
  -H "Content-Type: application/json" \
  -d '{ "cluster_id": "42f1a7da-812d-4430-93d8-1cc7c33a6bcf", "queue_key": "default" }'
```

```json
{
  "id": "0198f47a-9c1a-7db2-93aa-2b6f6a2e9d41",
  "source": {
    "queue_key": "default"
  },
  "destination": {
    "cluster_id": "42f1a7da-812d-4430-93d8-1cc7c33a6bcf",
    "queue_id": "01885682-55a7-44f5-84f3-0402fb452e66",
    "queue_key": "default"
  },
  "routed_percent": 0,
  "created_at": "2026-08-07T04:17:55.867Z",
  "updated_at": "2026-08-07T04:17:55.867Z"
}
```

Required [request body properties](/docs/api#request-body-properties):



| `cluster_id` | ID of the cluster containing the destination queue. _Example:_ `"42f1a7da-812d-4430-93d8-1cc7c33a6bcf"` |
| --- | --- |
| `queue_key` | Key of the destination queue within the specified cluster. _Example:_ `"default"` |



Required scope: `write_clusters`

Required permissions: organization administrator privileges (the `change_organization` permission) and permission to manage the destination cluster

Success response: `201 Created`

Error responses:



| `403 Forbidden` | The token does not have the required scope, or the user lacks organization administrator privileges or permission to manage the destination cluster. |
| --- | --- |
| `404 Not Found` | `{ "message": "No cluster found" }` if `cluster_id` doesn't resolve to a cluster in your organization, or `{ "message": "No cluster queue found" }` if `queue_key` doesn't resolve to a queue in that cluster |
| `409 Conflict` | `{ "message": "A migration for queue key `default` already exists" }` |
| `422 Unprocessable Entity` | `{ "message": "routed_percent cannot be set when creating a migration" }`, `{ "message": "cluster_id must be a valid UUID" }`, or `{ "message": "queue_key must be a string" }` |
| `503 Service Unavailable` | `{ "message": "This feature hasn't been enabled for your organization" }` |



## Update a queue migration

Changes the percentage of a queue key's jobs routed to the migration's destination queue. `routed_percent` can be moved up or down, and accepts any integer from 0 through 100.

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X PATCH "https://api.buildkite.com/v2/organizations/{org.slug}/cluster-queue-migrations/{migration.id}" \
  -H "Content-Type: application/json" \
  -d '{ "routed_percent": 70 }'
```

```json
{
  "id": "0198f47a-9c1a-7db2-93aa-2b6f6a2e9d41",
  "source": {
    "queue_key": "default"
  },
  "destination": {
    "cluster_id": "42f1a7da-812d-4430-93d8-1cc7c33a6bcf",
    "queue_id": "01885682-55a7-44f5-84f3-0402fb452e66",
    "queue_key": "default"
  },
  "routed_percent": 70,
  "created_at": "2026-08-07T04:17:55.867Z",
  "updated_at": "2026-08-07T05:02:11.221Z"
}
```

Required [request body properties](/docs/api#request-body-properties):



| `routed_percent` | The percentage of the queue key's jobs to route to the destination queue, as an integer from `0` through `100`. Can be higher or lower than the migration's current value. _Example:_ `70` |
| --- | --- |



Required scope: `write_clusters`

Required permission: organization administration, and permission to manage the destination cluster

Success response: `200 OK`

Error responses:



| `403 Forbidden` | The token does not have the required scope, or the user lacks organization administration or destination cluster management permission. |
| --- | --- |
| `404 Not Found` | `{ "message": "No cluster queue migration found" }` if the migration doesn't exist or belongs to another organization |
| `422 Unprocessable Entity` | `{ "message": "routed_percent is required" }`, `{ "message": "routed_percent must be an integer" }`, or `{ "message": "Validation failed: Routed percent must be greater than or equal to 0" }` (and similarly for values over 100) |
| `503 Service Unavailable` | `{ "message": "This feature hasn't been enabled for your organization" }` |


