Authentication
All requests require BUILDKITE_API_TOKEN. The token is read-only for most
operations; a read-write token is needed to trigger retries.
# Check for token
if [ -z "$BUILDKITE_API_TOKEN" ]; then
echo "Set BUILDKITE_API_TOKEN before proceeding."
exit 1
fi
BK_AUTH="Authorization: Bearer $BUILDKITE_API_TOKEN"
ORG="elastic"
PIPELINE="kibana-pull-request"
BASE="https://api.buildkite.com/v2"
If the token is missing, ask the user to export it:
You can create a token at https://buildkite.com/user/api-access-tokens (scope: read_builds, read_artifacts).
URL takes priority
If the user provides a Buildkite URL, always extract the build number from that URL and fetch it directly. Never fall back to "latest build for the PR" when the user has given an explicit URL.
Pattern: https://buildkite.com/elastic/kibana-pull-request/builds/<BUILD_NUMBER>[/...]
Extract <BUILD_NUMBER> and use it immediately. Do not query by PR number instead.
Fetch build by number
BUILD_NUMBER=<number>
curl -sf -H "$BK_AUTH" \
"$BASE/organizations/$ORG/pipelines/$PIPELINE/builds/$BUILD_NUMBER" \
| jq '{number,state,branch,commit,created_at,web_url,jobs:[.jobs[]|{id,name,state,exit_status,web_url}]}'
To get a build number from a Buildkite URL like
https://buildkite.com/elastic/kibana-pull-request/builds/414685, extract 414685.
Fetch latest build for a PR
The API returns builds newest-first, so .[0] is always the most recent build.
PR=<number>
curl -sf -H "$BK_AUTH" \
"$BASE/organizations/$ORG/pipelines/$PIPELINE/builds?pull_request_id=$PR&per_page=1" \
| jq '.[0] | {number,state,branch,web_url,jobs:[.jobs[]|{id,name,state,exit_status}]}'
When the user reports a failure without a URL, use the state filter to fetch only failed
builds directly — no page-size guessing needed:
curl -sf -H "$BK_AUTH" \
"$BASE/organizations/$ORG/pipelines/$PIPELINE/builds?pull_request_id=$PR&state[]=failed&state[]=failing&per_page=1" \
| jq '.[0] | {number,state,branch,web_url,jobs:[.jobs[]|{id,name,state,exit_status}]}'
Valid state values include: running, passed, failing, failed, canceled, finished
(where finished matches passed, failed, blocked, canceled).
Also supports arrays: state[]=failed&state[]=failing.
Fetch job log
Once you have a build number and job ID:
BUILD_NUMBER=<number>
JOB_ID=<uuid>
curl -sf -H "$BK_AUTH" \
"$BASE/organizations/$ORG/pipelines/$PIPELINE/builds/$BUILD_NUMBER/jobs/$JOB_ID/log" \
| jq -r '.content'
Logs can be large. Pipe through tail -n 200 or search with grep/rg for
relevant sections:
... | jq -r '.content' | grep -A 5 -i "error\|fail\|FAIL\|exception"
Workflow: diagnose a failing build
- Get build overview (fetch build by number or PR, see above).
- Identify failed jobs: filter
jobswherestate == "failed". - Fetch log for each failed job and search for the first error/failure.
- Summarise: report job name, exit code, and the key error lines.
For large logs, focus on the last 200–500 lines plus any lines matching
error, FAIL, AssertionError, TypeError, or ✖.
Workflow: understand job definition for PR build
- Analyse .buildkite/pipelines/pull_request/base.yml
- Analyse any relevant yml files in the folder
List and download artifacts
BUILD_NUMBER=<number>
# List artifacts for the build
curl -sf -H "$BK_AUTH" \
"$BASE/organizations/$ORG/pipelines/$PIPELINE/builds/$BUILD_NUMBER/artifacts" \
| jq '.[] | {id,filename,file_size,download_url}'
# Download a specific artifact
ARTIFACT_ID=<uuid>
curl -sL -H "$BK_AUTH" \
"$BASE/organizations/$ORG/pipelines/$PIPELINE/builds/$BUILD_NUMBER/artifacts/$ARTIFACT_ID/download" \
-o <filename>
Artifacts for a single job:
JOB_ID=<uuid>
curl -sf -H "$BK_AUTH" \
"$BASE/organizations/$ORG/pipelines/$PIPELINE/builds/$BUILD_NUMBER/jobs/$JOB_ID/artifacts" \
| jq '.[] | {id,filename,file_size,download_url}'
Other pipelines
Kibana has multiple pipelines. Common slugs:
| Pipeline | Slug |
|---|---|
| PR | kibana-pull-request |
| On-merge | kibana-on-merge |
| Flaky test runner | kibana-flaky-test-suite-runner |
Substitute the PIPELINE variable as needed.