# Trigger and manage builds

> Trigger and manage builds - Start an image build, track its status, cancel it, and interpret build
> errors.

This Markdown file sits beside the HTML page at the same path (with a `.md` suffix). It summarizes the topic and lists links for tools and LLM context.

Companion generated at `2026-09-30T19:40:40.962003+00:00` (UTC).

## Primary page

- [Trigger and manage builds](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md): Full documentation for this topic (Markdown sidecar).

## Sections on this page

- [Endpoints](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#endpoints): In-page section heading.
- [Trigger a build](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#trigger-a-build): In-page section heading.
- [Preconditions](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#preconditions): In-page section heading.
- [Build statuses](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#build-statuses): In-page section heading.
- [Track a build](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#track-a-build): In-page section heading.
- [List builds](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#list-builds): In-page section heading.
- [Rebuild after a code change](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#rebuild): In-page section heading.
- [Cancel a build](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#cancel-a-build): In-page section heading.
- [Build results](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#build-results): In-page section heading.
- [Build before you deploy or lock](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#gates): In-page section heading.
- [Error reference](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#error-reference): In-page section heading.
- [Next steps](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-operations.html.md#next-steps): In-page section heading.

## Related documentation

- [Workload API](https://docs.datarobot.com/en/docs/workload-api/index.html.md): Linked from this page.
- [Build artifacts](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/index.html.md): Linked from this page.
- [Build artifacts from source code](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/index.html.md): Linked from this page.
- [Build an image from source code](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-from-code.html.md): Linked from this page.
- [Build logs](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-logs.html.md): Linked from this page.
- [Sharing and access control](https://docs.datarobot.com/en/docs/workload-api/operate-workloads/sharing-access-control.html.md): Linked from this page.
- [Tutorial: Build a Workload from source](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/tutorial-build-from-code.html.md): Linked from this page.
- [Create Workloads](https://docs.datarobot.com/en/docs/workload-api/create-workloads/index.html.md): Linked from this page.

## Documentation content

> [!NOTE] Premium feature
> The Workload API is a premium feature. Contact your DataRobot representative or administrator for information on enabling the feature.

Once an artifact has an `imageBuildConfig` and a `codeRef`, you trigger builds against it. A build takes your uploaded source, produces a container image, pushes it to DataRobot's registry, and writes the resulting `imageUri` back onto the artifact.

This page covers running builds. For configuring what gets built, see [Build an image from source code](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-from-code.html.md).

## Endpoints

Builds are always scoped to an artifact; there is no top-level builds collection, because a build's output is written directly onto that artifact's container—tracking or cancelling a build only makes sense in the context of the artifact it belongs to.

| Verb | Path | Success | Required role |
| --- | --- | --- | --- |
| POST | /artifacts/{artifact_id}/builds | 202 | Editor |
| GET | /artifacts/{artifact_id}/builds | 200 | Consumer |
| GET | /artifacts/{artifact_id}/builds/{build_id} | 200 | Consumer |
| DELETE | /artifacts/{artifact_id}/builds/{build_id} | 204 | Editor |

Build output is not served by the Workload API. It is exported as OpenTelemetry logs and read from `GET /api/v2/otel/artifact/{artifactId}/logs/` —see [Build logs](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-logs.html.md).

> [!NOTE] Insufficient permissions return404, not403
> All four endpoints return `404 Artifact not found` when you lack access to the artifact, so that the API does not reveal whether an artifact you cannot see exists. A `404` on an ID you believe is correct usually means a missing role rather than a missing artifact—see [Sharing and access control](https://docs.datarobot.com/en/docs/workload-api/operate-workloads/sharing-access-control.html.md).

## Trigger a build

Trigger a build directly through the REST API, or with the CLI, which can optionally block until the build reaches a terminal state.

**cURL:**
```
curl -s -X POST "${DATAROBOT_ENDPOINT}/artifacts/${ARTIFACT_ID}/builds" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" | tee /tmp/build.json

export BUILD_ID=$(jq -r '.buildIds[0]' /tmp/build.json)
```

**CLI:**
```
# Inside a directory linked with dr artifact code init, the ID is optional
dr artifact build create ${ARTIFACT_ID}

# Or block until the build reaches a terminal state
dr artifact build create ${ARTIFACT_ID} --wait
```


> [!NOTE] The trigger takes no request body
> `POST /artifacts/{id}/builds` reads everything it needs from the artifact. Any body you send is ignored—there are no build parameters to pass at trigger time.

The response is `202` with the IDs of the builds that were started:

```
{ "buildIds": ["68f0d4aa11bb22cc33dd44ee"] }
```

`buildIds` always contains exactly one ID today, because only one container per artifact may build from source. Use that ID for the status and cancel calls, and to filter the build's logs.

### Preconditions

A trigger that fails these checks returns `422` and starts nothing:

| Requirement | Error when unmet |
| --- | --- |
| The artifact is in draft status | Builds may only be triggered for draft artifacts. |
| The artifact type is service, agent, or mcp | Image builds apply only to service-type, agent-type, or mcp-type artifacts that use codeRef. |
| Exactly one container defines imageBuildConfig | Multi-container image builds are not supported: only one container may define imageBuildConfig. Provide a pre-built imageUri for secondary containers. |
| The artifact has a codeRef | No codeRef with catalog identifiers found on this artifact; nothing to build. |
| The catalog version contains at least one file | No files listed for catalog <catalogId> version <catalogVersionId>; cannot build image |
| No competing update is in flight | Concurrent modification detected; please retry. |

## Build statuses

A build progresses through the following statuses, with `BUILT` frequently mistaken for a completed, deployable image.

| Status | Meaning |
| --- | --- |
| PENDING | The build has been accepted and is queued. |
| IN_PROGRESS | Source is being fetched, unpacked, or built. |
| BUILT | The image has been built and is being pushed and finalized. Not yet usable. |
| COMPLETED | Terminal. The image exists in the registry. The artifact is updated to use it a moment later; the build's imageApplied field reports when. |
| FAILED | Terminal. The build did not produce an image. |
| CANCELLED | Terminal. The build was stopped before finishing. |
| UNKNOWN | The current state could not be determined. Transient; retry the status call. |

> [!NOTE] Statuses are uppercase
> Build statuses are uppercase ( `COMPLETED`), while artifact statuses ( `draft`, `locked`) and Workload statuses ( `running`) are lowercase. Comparisons in scripts must match the exact casing.

Status only ever moves forward:

```
flowchart LR
    P["PENDING"] --> I["IN_PROGRESS"]
    I --> B["BUILT"]
    B --> C["COMPLETED"]
    I --> F["FAILED"]
    B --> F
    P --> X["CANCELLED"]
    I --> X
    B --> X
```

`COMPLETED`, `FAILED`, and `CANCELLED` are terminal and never change afterwards.

> [!WARNING] BUILTdoes not mean the image is ready
> `BUILT` means the image was produced but the build job has not finished pushing and cleaning up. Only `COMPLETED` writes `imageUri` onto the artifact. Wait for `COMPLETED` before deploying, and treat `BUILT` as still in flight.

## Track a build

Check a build's status the same two ways as triggering it: a direct API call, or the CLI, which can also poll on your behalf with `--wait`.

**cURL:**
```
curl -s "${DATAROBOT_ENDPOINT}/artifacts/${ARTIFACT_ID}/builds/${BUILD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" | jq '{id, status}'
```

Poll until the status is terminal:

```
until curl -s "${DATAROBOT_ENDPOINT}/artifacts/${ARTIFACT_ID}/builds/${BUILD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
  | jq -e -r '.status | test("COMPLETED|FAILED|CANCELLED")' >/dev/null; do
  sleep 10
done
```

**CLI:**
```
dr artifact build get ${ARTIFACT_ID} ${BUILD_ID}
```

Or let `dr artifact build create --wait` poll for you when you trigger the build.


A single build reads as:

```
{
  "id": "68f0d4aa11bb22cc33dd44ee",
  "name": "my-agent image build",
  "artifactId": "68f0c1a2b3d4e5f607182930",
  "status": "COMPLETED",
  "createdAt": "2026-08-20T10:15:00Z",
  "updatedAt": "2026-08-20T10:19:42Z",
  "creator": { "id": "...", "username": "...", "email": "..." }
}
```

| Field | Description |
| --- | --- |
| id | Build ID. Also the tag of the resulting image. |
| name | Auto-generated as <artifact name> image build. |
| artifactId | The artifact this build belongs to. |
| status | One of the values in Build statuses. Defaults to UNKNOWN. |
| createdAt / updatedAt | Timestamps in UTC. |
| creator | The user who triggered the build. |
| failureReason | Populated when status is FAILED, null otherwise. A short, phase-level description (for example, that the build failed while fetching its build context)—faster to check than build logs, but coarser; the logs still carry the underlying error. |

### List builds

Retrieve the artifact's build history in a single paginated call, newest first.

```
curl -s "${DATAROBOT_ENDPOINT}/artifacts/${ARTIFACT_ID}/builds?limit=20" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}"
```

Builds are returned newest first in the standard paginated envelope ( `totalCount`, `count`, `next`, `previous`, `data`). The only query parameters are `offset` (default `0`) and `limit` (default `10`, maximum `100`). There is no filtering, sorting, or search.

> [!NOTE] Poll the single-build endpoint, not the list
> `GET /builds/{build_id}` refreshes the status from the builder as part of the request. The list endpoint serves stored records and does not refresh. Both converge, because a background process keeps stored statuses current. Poll the single-build endpoint from a script that watches for completion.

## Rebuild after a code change

Sync the new code, then trigger another build. There is no need to cancel the previous one first: triggering a build stops any earlier build for the same source, and the new build gets its own ID and its own image tag. Builds are never deduplicated—every trigger produces a new build.

If a rebuild fails, the artifact keeps the `imageUri` from the last successful build, so anything already deployed keeps running and the image stays deployable. The failure is visible in the build status, not by the image disappearing.

Each container also exposes a read-only `imageOutdated` flag: `true` when the container has an `imageUri` but the most recent build is still running or has failed. The flag tracks build activity, not `codeRef` drift—patching a newer `codeRef` without triggering a build leaves `imageOutdated` at `false` even though the deployed image no longer matches the current source; it only flips once a build against that source is actually running. A cancelled build does not mark the image outdated either, since keeping the previous image is the intended outcome of a cancel. The flag is derived, never stored, and is ignored if you send it back.

## Cancel a build

Cancelling stops an in-progress build without affecting the artifact's current image.

```
curl -s -X DELETE "${DATAROBOT_ENDPOINT}/artifacts/${ARTIFACT_ID}/builds/${BUILD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}"
```

`DELETE` is the cancel operation—there is no separate cancel endpoint. It returns `204` and:

- stops the running build;
- makes a best-effort attempt to remove the build's image from the registry, so a cancelled or in-progress build doesn't leave a partial image behind;
- removes the build from the artifact's build list;
- clears the build pointer from the container spec.

Cancelling does not revert `imageUri`. An image from an earlier successful build stays attached to the artifact and remains deployable. Deleting the same build twice returns `404`.

## Build results

When a build reaches `COMPLETED`, the platform updates the container in the artifact spec:

```
"build": {
  "artifactImageBuildId": "68f0d4aa11bb22cc33dd44ee",
  "status": "COMPLETED",
  "createdAt": "2026-08-20T10:15:00Z"
}
```

and sets `imageUri` on the container. The image tag is the build ID, so an artifact's image always traces back to the build that produced it. The `build` block is managed by the platform; it is ignored if you send it.

## Build before you deploy or lock

Both deploying and locking require a real, completed build. The relevant errors are:

| Situation | HTTP | Message |
| --- | --- | --- |
| Deploying an artifact whose codeRef was never set | 422 | Cannot deploy artifact: imageBuildConfig is set but codeRef is missing. Upload source code and PATCH the codeRef before deploying. |
| Deploying before a build completes | 422 | Cannot deploy artifact: imageBuildConfig is set but imageUri is not populated. Trigger and complete an image build before deploying. |
| Locking without a codeRef | 422 | Cannot lock artifact: imageBuildConfig is set but codeRef is missing. Upload source code and PATCH the codeRef before locking. |
| Locking before a build completes | 422 | Cannot lock artifact: imageBuildConfig is set but imageUri is not populated. Trigger and complete an image build before locking. |
| Locking an artifact whose imageUri did not come from a build | 422 | Cannot lock artifact: container '<name>' imageUri is not the product of a completed image build. Trigger and complete an image build before locking. |
| Creating a Workload with an inline artifact that uses imageBuildConfig | 422 | Container '<name>': an inline artifact cannot use imageBuildConfig&mdash;the image must be built before deploying. Create the artifact first, sync your code, trigger a build, and then create the workload with artifactId. |

> [!NOTE] Source-built artifacts cannot be deployed inline
> `POST /workloads` accepts an inline `artifact` or an `artifactId`. Build-from-source artifacts must exist first, so always create the artifact, sync, build, and then deploy by `artifactId`.

## Error reference

The following table maps the HTTP status codes the build endpoints return to their cause and the corrective action.

| HTTP | Cause | What to do |
| --- | --- | --- |
| 403 | The ENABLE_WORKLOAD_API_CODE feature is not enabled for your user. Message: Please enable access to Workload API Code Features for current user to set codeRef for container. | Ask your administrator to enable the feature. |
| 404 | The artifact or build does not exist, or you lack a role on the artifact. | Confirm the ID; confirm you have at least the consumer role. |
| 422 | A precondition failed, the Dockerfile was not found, the project runtime could not be detected, or the execution environment cannot resolve a base image. | The message names the fix. See Preconditions and Supported project types. |
| 422 | One or more uploaded file names are not valid build context entries. Message begins Image build service rejected the build: the following source file name(s) are not valid build context entries and must be renamed or removed: and names each file with a reason. | Rename or remove the named files, re-sync, and rebuild. Names cannot be blank, start with /, contain .. or empty path segments, or be absolute Windows paths. |
| 502 | The build service or the Dockerfile storage backend returned an error. Messages: Image build service error (HTTP <n>) or Dockerfile storage failed: <detail>. | Retry. If it persists, contact DataRobot support with the artifact ID and timestamp. |
| 503 | A DataRobot service needed to submit the build is temporarily unavailable. Message: A DataRobot service needed to submit the build is temporarily unavailable, please retry in a few minutes. | Retry in a few minutes. |

A build that is accepted ( `202`) and then fails asynchronously reports `FAILED` rather than an HTTP error. Use [Build logs](https://docs.datarobot.com/en/docs/workload-api/build-artifacts/build-from-code/build-logs.html.md) to find out why.

## Next steps

Triggering and tracking a build is one stage in the source-to-Workload flow; the following resources cover diagnosing a failure, configuring what gets built, and deploying the result.

| Goal | Go here |
| --- | --- |
| Read build output and diagnose a failure | Build logs |
| Configure the source and the Dockerfile | Build an image from source code |
| Run the full flow once | Tutorial: Build a Workload from source |
| Deploy the built artifact | Create Workloads |
