# Agent images

Agent images let you define custom Dockerfile bodies for [Buildkite hosted agents](/docs/agent/buildkite-hosted). Each agent image is associated with a cluster and is built on top of a Buildkite-managed base image.

This API is available to organizations with Buildkite hosted agents enabled. If Buildkite hosted agents are not enabled for your organization, every endpoint returns `404 Not Found`. When they are enabled but the target cluster is not a hosted cluster, [list](#list-agent-images) requests return an empty list, [get](#get-an-agent-image) and [delete](#delete-an-agent-image) requests return `404 Not Found`, and [create](#create-an-agent-image) requests return `422 Unprocessable Entity`.

## Agent image data model



| `id` | ID of the agent image (the Namespace profile ID) |
| --- | --- |
| `name` | Name of the agent image |
| `status` | Build status of the agent image. Possible values: `BUILDING`, `READY`, `FAILED` |
| `image_ref` | The fully qualified image URL once the agent image has been built. `null` while the image is still building |
| `version` | Version number of the agent image |
| `last_build_error` | Error message from the most recent failed build, or `null` if no error |
| `dockerfile` | The user-supplied Dockerfile body (without the `FROM` instruction). This is the content you would submit in a [create](#create-an-agent-image) request |
| `base_image` | The Buildkite-managed base image `FROM` line prepended to every agent image Dockerfile |
| `composed_dockerfile` | The full Dockerfile sent to the image builder: `base_image` followed by `dockerfile` |
| `url` | Canonical API URL of the agent image |
| `web_url` | URL of the agent image on Buildkite |
| `cluster_url` | API URL of the cluster the agent image belongs to |



## List agent images

Returns the list of a cluster's agent images, sorted alphabetically by name. Non-hosted clusters return an empty list.

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

```json
[
  {
    "id": "abc123def4567",
    "name": "my-custom-image",
    "status": "READY",
    "image_ref": "registry.example.com/your-org/buildkite/abc123def4567:v1",
    "version": 1,
    "last_build_error": null,
    "dockerfile": "RUN apt-get update && apt-get install -y curl",
    "base_image": "FROM docker.io/buildkite/hosted-agent-base:ubuntu-v1.0.1@sha256:f1378abd34fccb2b7b661aaf3b06394509a4f7b5bb8c2f8ad431e7eaa1cabc9c",
    "composed_dockerfile": "FROM docker.io/buildkite/hosted-agent-base:ubuntu-v1.0.1@sha256:f1378abd34fccb2b7b661aaf3b06394509a4f7b5bb8c2f8ad431e7eaa1cabc9c\nRUN apt-get update && apt-get install -y curl",
    "url": "https://api.buildkite.com/v2/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf/agent-images/abc123def4567",
    "web_url": "https://buildkite.com/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf/agent_images/abc123def4567",
    "cluster_url": "https://api.buildkite.com/v2/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf"
  }
]
```

Required scope: `read_clusters`

Success response: `200 OK`

## Get an agent image

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

```json
{
  "id": "abc123def4567",
  "name": "my-custom-image",
  "status": "READY",
  "image_ref": "registry.example.com/your-org/buildkite/abc123def4567:v1",
  "version": 1,
  "last_build_error": null,
  "dockerfile": "RUN apt-get update && apt-get install -y curl",
  "base_image": "FROM docker.io/buildkite/hosted-agent-base:ubuntu-v1.0.1@sha256:f1378abd34fccb2b7b661aaf3b06394509a4f7b5bb8c2f8ad431e7eaa1cabc9c",
  "composed_dockerfile": "FROM docker.io/buildkite/hosted-agent-base:ubuntu-v1.0.1@sha256:f1378abd34fccb2b7b661aaf3b06394509a4f7b5bb8c2f8ad431e7eaa1cabc9c\nRUN apt-get update && apt-get install -y curl",
  "url": "https://api.buildkite.com/v2/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf/agent-images/abc123def4567",
  "web_url": "https://buildkite.com/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf/agent_images/abc123def4567",
  "cluster_url": "https://api.buildkite.com/v2/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf"
}
```

Required scope: `read_clusters`

Success response: `200 OK`

## Create an agent image

Buildkite manages the base image for all hosted agent images. Submit only the Dockerfile body — the instructions to layer on top of the base image. Do not include a `FROM` instruction; Buildkite prepends the managed base image automatically.

Image builds are asynchronous. The response returns immediately with `status: "BUILDING"`. Poll [get an agent image](#get-an-agent-image) until `status` is `READY` or `FAILED`.

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X POST "https://api.buildkite.com/v2/organizations/{org.slug}/clusters/{cluster.id}/agent-images" \
  -H "Content-Type: application/json" \
  -d '{ "name": "my-custom-image", "dockerfile": "RUN apt-get update && apt-get install -y curl" }'
```

```json
{
  "id": "abc123def4567",
  "name": "my-custom-image",
  "status": "BUILDING",
  "image_ref": null,
  "version": 1,
  "last_build_error": null,
  "dockerfile": "RUN apt-get update && apt-get install -y curl",
  "base_image": "FROM docker.io/buildkite/hosted-agent-base:ubuntu-v1.0.1@sha256:f1378abd34fccb2b7b661aaf3b06394509a4f7b5bb8c2f8ad431e7eaa1cabc9c",
  "composed_dockerfile": "FROM docker.io/buildkite/hosted-agent-base:ubuntu-v1.0.1@sha256:f1378abd34fccb2b7b661aaf3b06394509a4f7b5bb8c2f8ad431e7eaa1cabc9c\nRUN apt-get update && apt-get install -y curl",
  "url": "https://api.buildkite.com/v2/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf/agent-images/abc123def4567",
  "web_url": "https://buildkite.com/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf/agent_images/abc123def4567",
  "cluster_url": "https://api.buildkite.com/v2/organizations/acme-inc/clusters/42f1a7da-812d-4430-93d8-1cc7c33a6bcf"
}
```

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



| `name` | Name for the agent image. Must be unique within the cluster. _Example:_ `"my-custom-image"` |
| --- | --- |
| `dockerfile` | Dockerfile body to layer on top of the Buildkite-managed base image. Must be a string and must not contain a `FROM` instruction. Pass an empty string (`""`) to build an image with no additional layers. _Example:_ `"RUN apt-get update &amp;&amp; apt-get install -y curl"` |



Required scope: `write_clusters`

Success response: `201 Created`

Error responses:



| `409 Conflict` | `{ "message": "an agent image named \"my-custom-image\" already exists in this cluster" }` |
| --- | --- |
| `422 Unprocessable Entity` | `{ "message": "Reason for failure" }` |



## Delete an agent image

Deleting an agent image that is currently assigned to one or more queues returns `409 Conflict`. Reassign those queues to a different agent image before deleting.

```bash
curl -H "Authorization: Bearer $TOKEN" \
  -X DELETE "https://api.buildkite.com/v2/organizations/{org.slug}/clusters/{cluster.id}/agent-images/{id}"
```

Required scope: `write_clusters`

Success response: `204 No Content`

Error responses:



| `404 Not Found` | `{ "message": "No agent image found with the given ID." }` |
| --- | --- |
| `409 Conflict` | `{ "message": "this agent image is in use by one or more queues; reassign those queues before deleting it" }` |


