Annotations API

An annotation is a snippet of Markdown uploaded by your agent during the execution of a build's job. Annotations are created using the buildkite-agent annotate command from within a job.

Annotation data model

id ID of the annotation
context The "context" specified when annotating the build. Only one annotation per build may have any given context value.
style The style of the annotation. Can be success, info, warning, or error.
scope The scope of the annotation. Either build or job.
job_id The ID of the job associated with the annotation, or null for build-scoped annotations
priority The priority of the annotation (1 to 10). Higher values are shown first. Default is 3.
body_html Rendered HTML of the annotation's body. The List annotations for a build endpoint omits this field when the request includes omit_body=true.
created_at When the annotation was first created
updated_at When the annotation was last added to or replaced

List annotations for a build

Returns a paginated list of a build's annotations.

curl -H "Authorization: Bearer $TOKEN" \
  -X GET "https://api.buildkite.com/v2/organizations/{org.slug}/pipelines/{pipeline.slug}/builds/{build.number}/annotations"

Note that this URL requires using a build number (for example, 3), not a build ID (for example, 01908131-7d9f-495e-a17b-80ed31276810).

Learn more about the difference between these concepts in Build number vs build ID.

[
  {
    "id": "de0d4ab5-6360-467a-a34b-e5ef5db5320d",
    "context": "default",
    "style": "info",
    "scope": "build",
    "job_id": null,
    "priority": 3,
    "body_html": "<h1>My Markdown Heading</h1>\n<img src=\"artifact://indy.png\" alt=\"Belongs in a museum\" height=250 />",
    "created_at": "2019-04-09T18:07:15.775Z",
    "updated_at": "2019-08-06T20:58:49.396Z"
  },
  {
    "id": "5b3ceff6-78cb-4fe9-88ae-51be5f145977",
    "context": "coverage",
    "style": "info",
    "scope": "build",
    "job_id": null,
    "priority": 3,
    "body_html": "Read the <a href=\"artifact://coverage/index.html\">uploaded coverage report</a>",
    "created_at": "2019-04-09T18:07:16.320Z",
    "updated_at": "2019-04-09T18:07:16.320Z"
  }
]

Optional query string parameters:

scope Filters annotations by scope. The build value returns build-scoped annotations and is the default. The job value returns job-scoped annotations. The all value returns both.

Example: scope=all

omit_body Omits the body_html field from each annotation in the response when set to true. Use this parameter to fetch annotation metadata without response bodies. The default is false.

Example: omit_body=true

Required scope: read_builds

Success response: 200 OK

Create an annotation on a build

Creates an annotation on a build.

curl -H "Authorization: Bearer $TOKEN" \
  -X POST "https://api.buildkite.com/v2/organizations/{org.slug}/pipelines/{pipeline.slug}/builds/{build.number}/annotations" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hello world!",
    "style": "info",
    "priority": 5,
    "context": "greeting"
  }'

Note that this URL requires using a build number (for example, 3), not a build ID (for example, 01908131-7d9f-495e-a17b-80ed31276810).

Learn more about the difference between these concepts in Build number vs build ID.

{
  "id": "018b8d10-6b5b-4df2-b0ff-dfa2af566050",
  "context": "greeting",
  "style": "info",
  "scope": "build",
  "job_id": null,
  "priority": 5,
  "body_html": "<p>Hello world!</p>\n",
  "created_at": "2023-11-01T22:45:45.435Z",
  "updated_at": "2023-11-01T22:45:45.435Z"
}

Required request body properties:

body The annotation's body, as HTML or Markdown.

Example: "My annotation here"

Optional request body properties:

style The style of the annotation. Can be success, info, warning, or error.

Example: "info"

priority The priority of the annotation (1 to 10). Annotations with a priority of 10 are shown first, while annotations with a priority of 1 are shown last. When this option is not specified, annotations have a default priority of 3.

Example: 5

context A string value by which to identify the annotation on the build. This is useful when appending to an existing annotation. Only one annotation per build may have any given context value.

Example: "coverage"

append Whether to append the given body onto the annotation with the same context.

Example: true

Required scope: write_builds

Success response: 201 Created

Delete an annotation on a build

Deletes an annotation on a build.

curl -H "Authorization: Bearer $TOKEN" \
  -X DELETE "https://api.buildkite.com/v2/organizations/{org.slug}/pipelines/{pipeline.slug}/builds/{build.number}/annotations/{annotation.uuid}"

Required scope: write_builds

Success response: 204 No Content

List annotations for a job

Returns a paginated list of a job's annotations.

curl -H "Authorization: Bearer $TOKEN" \
  -X GET "https://api.buildkite.com/v2/organizations/{org.slug}/jobs/{job.id}/annotations"

You can also use the build-scoped route if you have the pipeline slug and build number:

curl -H "Authorization: Bearer $TOKEN" \
  -X GET "https://api.buildkite.com/v2/organizations/{org.slug}/pipelines/{pipeline.slug}/builds/{build.number}/jobs/{job.id}/annotations"
[
  {
    "id": "a7c5b1d2-4f3e-4a1b-9c8d-6e2f1a3b4c5d",
    "context": "test-results",
    "style": "success",
    "scope": "job",
    "job_id": "01234567-89ab-4cde-8f01-23456789abcd",
    "priority": 3,
    "body_html": "<p>All 42 tests passed</p>\n",
    "created_at": "2024-01-15T10:30:00.000Z",
    "updated_at": "2024-01-15T10:30:00.000Z"
  }
]

Required scope: read_builds

Success response: 200 OK

Create an annotation on a job

Creates an annotation scoped to a specific job in a build. Job-scoped annotations use the same parameters as build-scoped annotations. However, the scope is automatically set to job.

curl -H "Authorization: Bearer $TOKEN" \
  -X POST "https://api.buildkite.com/v2/organizations/{org.slug}/jobs/{job.id}/annotations" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Test results: 42 passed",
    "style": "success",
    "context": "test-results"
  }'

You can also use the build-scoped route if you have the pipeline slug and build number:

curl -H "Authorization: Bearer $TOKEN" \
  -X POST "https://api.buildkite.com/v2/organizations/{org.slug}/pipelines/{pipeline.slug}/builds/{build.number}/jobs/{job.id}/annotations" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Test results: 42 passed",
    "style": "success",
    "context": "test-results"
  }'
{
  "id": "a7c5b1d2-4f3e-4a1b-9c8d-6e2f1a3b4c5d",
  "context": "test-results",
  "style": "success",
  "scope": "job",
  "job_id": "01234567-89ab-4cde-8f01-23456789abcd",
  "priority": 3,
  "body_html": "<p>Test results: 42 passed</p>\n",
  "created_at": "2024-01-15T10:30:00.000Z",
  "updated_at": "2024-01-15T10:30:00.000Z"
}

Required request body properties:

body The annotation's body, as HTML or Markdown.

Example: "My annotation here"

Optional request body properties:

style The style of the annotation. Can be success, info, warning, or error.

Example: "info"

priority The priority of the annotation (1 to 10). Annotations with a priority of 10 are shown first, while annotations with a priority of 1 are shown last. When this option is not specified, annotations have a default priority of 3.

Example: 5

context A string value by which to identify the annotation on the job. This is useful when appending to an existing annotation. Only one annotation per job may have any given context value.

Example: "coverage"

append Whether to append the given body onto the annotation with the same context.

Example: true

Required scope: write_builds

Success response: 201 Created

Delete an annotation on a job

Deletes an annotation on a job.

curl -H "Authorization: Bearer $TOKEN" \
  -X DELETE "https://api.buildkite.com/v2/organizations/{org.slug}/jobs/{job.id}/annotations/{annotation.uuid}"

You can also use the build-scoped route if you have the pipeline slug and build number:

curl -H "Authorization: Bearer $TOKEN" \
  -X DELETE "https://api.buildkite.com/v2/organizations/{org.slug}/pipelines/{pipeline.slug}/builds/{build.number}/jobs/{job.id}/annotations/{annotation.uuid}"

Required scope: write_builds

Success response: 204 No Content