This is documentation for the next version of Grafana documentation. For the latest stable release, go to the latest version.
Annotations API
Note
This API complies with the new Grafana API structure. To learn more refer to the New API structure in Grafana documentation.
The legacy Annotations API is still available, and removal will be announced well in advance to avoid disruptions. Refer to Migrate from the legacy Annotations API to learn more about how both APIs match, and how to migrate.
Annotations mark points or regions in time with text and tags. An annotation that has a dashboardUID belongs to that dashboard, and can also belong to a single panel. An annotation without a dashboardUID is an organization annotation, which you can show on any dashboard that uses the Grafana annotations data source.
Before you begin
This API is in alpha (v0alpha1) and might change. For more details about versioning, refer to
New API versioning.
Availability depends on where you run Grafana:
- Grafana Cloud: The API is rolling out gradually and might not be available on your stack yet.
- Self-managed Grafana: The API is disabled by default. To enable it, set
enabled = truein the[annotations.app_platform]section of the Grafana configuration.
All paths use the annotation.grafana.app group and the v0alpha1 version. Replace :namespace with your namespace. To learn more about which namespace to use, refer to the
API overview.
Alert annotations aren’t available in this API yet
Requirements
If you’re running Grafana Enterprise or Grafana Cloud, you need specific permissions. For more information, refer to Role-based access control permissions.
The scope you need depends on the type of annotation:
- Organization annotations (no
dashboardUID):annotations:*,annotations:type:*, orannotations:type:organization. - Dashboard annotations:
dashboards:*ordashboards:uid:<DASHBOARD_UID>, or the equivalentfolders:*orfolders:uid:<FOLDER_UID>scope for the folder that contains the dashboard.
Listing tags requires annotations:read with an organization scope.
The annotation resource
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"name": "a-123",
"namespace": "default",
"annotations": {
"grafana.app/createdBy": "user:abc123"
}
},
"spec": {
"text": "Deployed version 1.2.3",
"time": 1760000000000,
"timeEnd": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "production"]
}
}metadata.name identifies the annotation in request paths. Grafana assigns it when you create the annotation, and sets metadata.annotations["grafana.app/createdBy"] to the user who created it.
The spec has the following fields:
The only fields you can update after creation are text and tags.
List annotations
GET /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/annotations
Lists the annotations in the namespace, up to limit at a time. To filter annotations by time range, dashboard, panel, tags, or creator, use Search annotations.
Example Request:
GET /apis/annotation.grafana.app/v0alpha1/namespaces/default/annotations?limit=2 HTTP/1.1
Accept: application/json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>Example Response:
HTTP/1.1 200
Content-Type: application/json
{
"kind": "AnnotationList",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {},
"items": [
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"name": "a-123",
"namespace": "default",
"annotations": {
"grafana.app/createdBy": "user:abc123"
}
},
"spec": {
"text": "Deployed version 1.2.3",
"time": 1760000000000,
"timeEnd": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "production"]
}
}
]
}Search annotations
GET /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/search
Finds annotations that match the query parameters. Results are returned most recent first. An annotation matches a time range when its time to timeEnd range overlaps the from to to range.
Query parameters:
Example Request:
GET /apis/annotation.grafana.app/v0alpha1/namespaces/default/search?dashboardUID=dashboard-uid-1&from=1759990000000&to=1760010000000&tag=deploy&limit=50 HTTP/1.1
Accept: application/json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>Example Response:
HTTP/1.1 200
Content-Type: application/json
{
"metadata": {
"continue": "<CONTINUE_TOKEN>"
},
"items": [
{
"metadata": {
"name": "a-123",
"namespace": "default",
"annotations": {
"grafana.app/createdBy": "user:abc123"
}
},
"spec": {
"text": "Deployed version 1.2.3",
"time": 1760000000000,
"timeEnd": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "production"]
}
}
]
}If metadata.continue is empty or missing, there are no more results. Otherwise, pass its value as the continue parameter to get the next page.
Find annotation tags
GET /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/tags
Lists the tags used by annotations, with the number of annotations that use each tag.
Query parameters:
contains: string. Optional. Return only tags that contain this value.limit: integer. Optional. Maximum number of tags to return. Default is100.
Example Request:
GET /apis/annotation.grafana.app/v0alpha1/namespaces/default/tags?contains=prod&limit=10 HTTP/1.1
Accept: application/json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>Example Response:
HTTP/1.1 200
Content-Type: application/json
{
"tags": [
{
"tag": "production",
"count": 12
}
]
}Get an annotation
GET /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/annotations/:name
Retrieves an annotation by name.
name: Themetadata.nameof the annotation.
Example Request:
GET /apis/annotation.grafana.app/v0alpha1/namespaces/default/annotations/a-123 HTTP/1.1
Accept: application/json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>Example Response:
HTTP/1.1 200
Content-Type: application/json
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"name": "a-123",
"namespace": "default",
"annotations": {
"grafana.app/createdBy": "user:abc123"
}
},
"spec": {
"text": "Deployed version 1.2.3",
"time": 1760000000000,
"timeEnd": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "production"]
}
}Create an annotation
POST /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/annotations
Creates an annotation. Set metadata.generateName to a- and Grafana assigns the name. To create a region annotation, set timeEnd. To create an organization annotation, omit dashboardUID.
Example Request:
POST /apis/annotation.grafana.app/v0alpha1/namespaces/default/annotations HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"generateName": "a-"
},
"spec": {
"text": "Deployed version 1.2.3",
"time": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "production"]
}
}Example Response:
HTTP/1.1 201 Created
Content-Type: application/json
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"name": "a-123",
"namespace": "default",
"annotations": {
"grafana.app/createdBy": "user:abc123"
}
},
"spec": {
"text": "Deployed version 1.2.3",
"time": 1760000000000,
"timeEnd": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "production"]
}
}Create an annotation in Graphite format
POST /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/graphite
Creates an organization annotation by using the Graphite-compatible event format. Grafana joins what and data into the annotation text, separated by a new line. The tags field can also be a string with multiple tags separated by a space.
Required JSON body fields:
what: The title of the event.tags: The tags of the event, as an array of strings or a single string with the tags separated by spaces.
Optional JSON body fields:
when: The time of the event, in Unix seconds. Defaults to the current time.data: More details about the event.
Example Request:
POST /apis/annotation.grafana.app/v0alpha1/namespaces/default/graphite HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>
{
"what": "Event - deploy",
"tags": ["deploy", "production"],
"when": 1760000000,
"data": "version 1.2.3"
}Example Response:
HTTP/1.1 200
Content-Type: application/json
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"name": "a-124",
"namespace": "default",
"annotations": {
"grafana.app/createdBy": "user:abc123"
}
},
"spec": {
"text": "Event - deploy\nversion 1.2.3",
"time": 1760000000000,
"timeEnd": 1760000000000,
"tags": ["deploy", "production"]
}
}Update an annotation
PUT /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/annotations/:name
Replaces an annotation. Provide the entire annotation, including metadata.name and metadata.namespace. You can only change text and tags. The time, timeEnd, dashboardUID, and panelID values must match the existing annotation, and you can’t modify them after creation.
name: Themetadata.nameof the annotation.
Example Request:
PUT /apis/annotation.grafana.app/v0alpha1/namespaces/default/annotations/a-123 HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"name": "a-123",
"namespace": "default"
},
"spec": {
"text": "Deployed version 1.2.4",
"time": 1760000000000,
"timeEnd": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "production", "hotfix"]
}
}Example Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"name": "a-123",
"namespace": "default",
"annotations": {
"grafana.app/createdBy": "user:abc123"
}
},
"spec": {
"text": "Deployed version 1.2.4",
"time": 1760000000000,
"timeEnd": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "production", "hotfix"]
}
}Patch an annotation
PATCH /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/annotations/:name
Updates only the fields you provide, using a JSON merge patch. The same restrictions as for Update an annotation apply: You can only change text and tags, and you can’t modify time, timeEnd, dashboardUID, and panelID after creation.
name: Themetadata.nameof the annotation.
Example Request:
PATCH /apis/annotation.grafana.app/v0alpha1/namespaces/default/annotations/a-123 HTTP/1.1
Accept: application/json
Content-Type: application/merge-patch+json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>
{
"spec": {
"text": "Deployed version 1.2.4",
"tags": ["deploy", "hotfix"]
}
}Example Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"kind": "Annotation",
"apiVersion": "annotation.grafana.app/v0alpha1",
"metadata": {
"name": "a-123",
"namespace": "default",
"annotations": {
"grafana.app/createdBy": "user:abc123"
}
},
"spec": {
"text": "Deployed version 1.2.4",
"time": 1760000000000,
"timeEnd": 1760000000000,
"dashboardUID": "dashboard-uid-1",
"panelID": 2,
"tags": ["deploy", "hotfix"]
}
}Delete an annotation
DELETE /apis/annotation.grafana.app/v0alpha1/namespaces/:namespace/annotations/:name
Deletes an annotation.
name: Themetadata.nameof the annotation.
Example Request:
DELETE /apis/annotation.grafana.app/v0alpha1/namespaces/default/annotations/a-123 HTTP/1.1
Accept: application/json
Authorization: Bearer <SERVICE_ACCOUNT_TOKEN>Example Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Success",
"code": 200
}Status codes
The Annotations HTTP API uses the following status codes:
Migrate from the legacy Annotations API
This API replaces the legacy
Annotations API (/api/annotations).
Alert annotations aren’t available in this API yet. For the moment, use the legacy API to work with them.
The following table describes how the legacy API maps to this API:


