---
title: "List annotations"
method: GET
path: "/api/annotations.list"
tags: ["Web Analytics"]
---

# List annotations

`GET /api/annotations.list`

Returns the workspace's annotations, most recent moment first. Every filter is optional; with none the most recent 100 rows come back.

Gated by the web_analytics read permission, like the rest of the web analytics surface.

## Query parameters

- `workspace_id` string, required
- `start` string, date-time
- `end` string, date-time
- `sources` string
- `limit` integer

## Response `200`

Annotations matching the filters

- ListAnnotationsResponse
  - `annotations` Annotation[]
    - `id` string, required — Server-generated identifier (a UUID with its dashes removed).
    - `annotated_at` string, date-time, required — The moment the annotation marks, as a real instant.
    - `timezone` string, required — IANA timezone the moment was entered in. This is display intent only — annotated_at already fixes the instant, and filtering never uses this field. It is what lets "9am in Tokyo" render back as 9am instead of the reader's local equivalent.
    - `title` string, required — Counted in characters, not bytes.
    - `description` string — Optional longer note. Counted in characters, not bytes.
    - `color` string, required — Six-digit hex colour used for the marker on the charts.
    - `source` 'manual' | 'broadcast', required — Who wrote the row. `manual` is anything typed by an operator or posted to this API; `broadcast` rows are written automatically when a broadcast starts sending. There is deliberately no API source — see the note on annotations.create.
    - `source_id` string — The entity that caused an automatic annotation (a broadcast id today). Always absent on manual rows, and never settable through the API. An annotation outlives the entity it points at: deleting a broadcast leaves its annotation, because the send did happen.
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required

## Other responses

- `400` — Bad request - invalid query parameters
- `401` — Unauthorized - invalid or missing authentication token
- `403` — Forbidden - missing required permission
- `500` — Internal server error

## Changes

- **2026-08-17** `d26605f2fc47` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/pierre-b/apis/notifuse-api/changes/api/annotations.list/get.md)

---

[API](https://skmtc.dev/pierre-b/apis/notifuse-api.md) · [All operations](https://skmtc.dev/pierre-b/apis/notifuse-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/pierre-b/notifuse-api/revisions/d26605f2fc47/schema)
