Skip to content

Retrieve build logs

Premium feature

The Workload API is a premium feature. Contact your DataRobot representative or administrator for information on enabling the feature.

Every image build produces builder output—base image pulls, dependency resolution, each Dockerfile step, and the error that stopped it if it failed. Build logs are how you find out why a build reported FAILED, and how you watch a long build make progress.

The builder exports its output as OpenTelemetry logs, and you read them from the platform observability surface, keyed by artifact:

GET /api/v2/otel/artifact/{artifactId}/logs/

Note the singular artifact in the path—that segment is the OTel entity type, not the Workload API's /artifacts collection. The Workload API itself does not expose or proxy /otel/* routes.

Build logs cover the build. For logs from the container once it is running, see Monitor telemetry and health.

Retrieve a build log

Retrieve build output directly through the REST API, or with the CLI when the project directory is already linked.

# Every build the artifact has ever run
curl -s "${DATAROBOT_ENDPOINT}/otel/artifact/${ARTIFACT_ID}/logs/" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}"

# One build, filtered by its Workload API build ID
curl -s "${DATAROBOT_ENDPOINT}/otel/artifact/${ARTIFACT_ID}/logs/?searchKeys=external_build_id&searchValues=${BUILD_ID}" \
  -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}"
dr artifact build logs ${ARTIFACT_ID} ${BUILD_ID}

# Show warnings and errors only
dr artifact build logs ${ARTIFACT_ID} ${BUILD_ID} --level warn

Inside a directory linked with dr artifact code init, the artifact ID can be omitted.

The CLI prints one structured record per line and hides anything below info. Lower --level to debug to see everything.

The stream is scoped to the artifact, so without a filter it contains every build the artifact has run. external_build_id narrows it to one build:

Attribute Value
Service name artifact-<artifactId>—identifies the stream itself
external_build_id The Workload API build ID, stamped on every record of that build
log_source build_output for the builder's own output

The response is JSON, one object per log record:

{
  "count": 100,
  "next": "https://app.datarobot.com/api/v2/otel/artifact/68f0.../logs/?offset=100&limit=100",
  "previous": null,
  "data": [
    {
      "timestamp": "2026-08-18 09:14:22.481000+00:00",
      "level": "INFO",
      "message": "Step 6/12 : RUN uv sync --frozen"
    }
  ]
}

stacktrace, spanId, and traceId appear on records that carry them. count is the size of the page you were served, not the total number of records—page through with next until it is null.

Query parameters

The following table describes each supported parameter.

Parameter Description
searchKeys, searchValues Attribute filter, paired positionally. Both must be supplied and must be the same length—supplying one alone returns 400. Up to 10 pairs, each value at most 100 characters.
level Minimum level to return: debug, info, warn, warning, error, or critical. Defaults to debug. Lowercase only—level=INFO returns 400.
includes, excludes Substrings a record must contain, or must not contain. Up to 10 each.
startTime, endTime RFC 3339 bounds. startTime must be earlier than endTime.
offset, limit Pagination. offset defaults to 0; limit defaults to 100 and caps at 1000. next and previous in the response carry ready-made URLs.
spanId, traceId Restrict to records correlated with a specific OTel span or trace.

Query parameters are camelCase; attribute names are not

Like the rest of the public API, the parameters themselves are camelCase (searchKeys), and search_keys returns 400. The values you filter on are raw OTel attribute names, which are snake_case—external_build_id, log_source.

Logs are a snapshot, not a stream

The endpoint returns what has been exported at the moment you call it. There is no follow or websocket variant. To watch a build in progress, call it again:

while true; do
  clear
  curl -s "${DATAROBOT_ENDPOINT}/otel/artifact/${ARTIFACT_ID}/logs/?searchKeys=external_build_id&searchValues=${BUILD_ID}" \
    -H "Authorization: Bearer ${DATAROBOT_API_TOKEN}" \
    | jq -r '.data[] | "\(.timestamp) \(.level) \(.message)"'
  sleep 10
done

When logs are not available

An artifact with no matching records returns 200 with an empty data array rather than an error, so an empty result is not a failure:

Empty result What it means What to do
The build is PENDING or IN_PROGRESS Export lags the builder by a few seconds; early records may not have landed yet. Wait a few seconds and call again.
The build ended FAILED or CANCELLED immediately The build request was rejected before the builder started, so there is no builder output at all. Check the artifact's imageBuildConfig and codeRef, then retrigger. The error reference covers the common causes.
An older build returns nothing OTel retention is configured per organization and the records have aged out. See Monitoring concepts. Retrieve logs while a build is recent, before they age out.
external_build_id matches nothing but the unfiltered stream has records The build ID is wrong, or belongs to a different artifact. Confirm it with GET /artifacts/{artifact_id}/builds.

Error responses:

HTTP Meaning
400 An invalid query parameter—an uppercase level, searchKeys without searchValues, or mismatched list lengths. The message names the parameter.
404 The artifact does not exist, or you lack a role on it.

Availability

Build log export depends on the platform's OpenTelemetry observability stack. On installations where it is not present—including air-gapped installations—builds run normally, but the endpoint returns no records.

Diagnose a failed build

Read the log from the bottom: the last builder step before the error is nearly always the cause.

In the log Cause Fix
unknown instruction: ... A syntax error in your Dockerfile. Correct the Dockerfile, re-sync, and rebuild.
pull access denied, or a failure resolving the FROM image The base image does not exist or is not reachable from the build environment. Check the image reference. For a generated Dockerfile, check that the execution environment version resolves to a real image.
A dependency resolver error naming a package or version A dependency cannot be satisfied—a typo, a yanked release, or an incompatible version pin. Fix the dependency, regenerate the lockfile (uv lock or npm install), re-sync, and rebuild.
A compiler error (gcc, error: command ... failed) while installing a dependency The package builds from source and the base image has no C/C++ toolchain. Use a DataRobot-published execution environment, or a base image that includes build tools. See Known limitations of custom base images.
failed to execute build action, or a step failing without further detail A RUN step in your Dockerfile exited non-zero. Reproduce that step locally against the same base image.
The build fails with no builder output at all The build request was rejected before the builder started. See the error reference.

If a build succeeds but the container does not start, the problem is runtime rather than build: check the entrypoint, the port, and the readiness probe against Container requirements, then use Health and readiness.

Next steps

Reading build output is one part of managing the build lifecycle; the following resources cover the surrounding build operations and Dockerfile configuration.

Goal Go here
Retrigger, cancel, or track a build Trigger and manage builds
Change the base image or Dockerfile Build an image from source code
Inspect a running container Monitor telemetry and health