Annotations
Dated labels on a project's time series for releases, posts, content updates and incidents, so a change in the numbers can be read next to what happened.
An annotation marks a date, or a range of dates, on a project's charts: a release, a post, a content update, an incident or any other event worth seeing next to the traffic. It is a label for the reader of the numbers. Nothing is tracked, and visitors never see it.
The data model
| Field | Type | Notes |
|---|---|---|
id | string | ann_ plus a UUID, set by the API |
project | string | The project it belongs to; every route is scoped to it |
title | string | 1 to 120 characters |
date | timestamp | When it happened, in UTC |
endDate | timestamp or null | The end of a range; never before date |
kind | release, post, content, incident or other | other when not given |
note | string or null | Up to 2,000 characters |
url | string or null | An http:// or https:// URL of up to 2,048 characters |
createdAt, updatedAt | timestamp | Set by the API |
date and endDate take a calendar date such as 2026-10-01, read as the start of that day in UTC, or an ISO 8601 timestamp with an offset such as 2026-10-01T09:30:00+02:00. Answers always carry UTC timestamps. Annotations live in the annotations table (migration 0031) and are removed with their project.
Routes
| Method | Path | Access | Does |
|---|---|---|---|
| GET | /v2/projects/:project/annotations | project | The annotations that overlap the range, oldest first, paged |
| POST | /v2/projects/:project/annotations | admin | Adds one |
| PATCH | /v2/projects/:project/annotations/:annotation | admin | Changes the fields sent; null clears endDate, note or url |
| DELETE | /v2/projects/:project/annotations/:annotation | admin | Deletes one |
- Reading follows the project: anyone for a public project, and a member or token that lists it for a private one, which answers 404 to anyone else. Writing needs an owner, an admin who lists the project, or an
admintoken that lists it. - The list takes the same range as every read:
fromandto, orperiod(24h,7d,30d,90d,12mo,all; default30d). An annotation with anendDateis listed when any part of it falls in the range.limit(1 to 100, default 20) andcursorpage it. - An
endDatebeforedate, on create or after a change, answers400 VALIDATION_FAILEDwith/endDateindetails.fields. An emptyPATCHbody is alsoVALIDATION_FAILED. An id that belongs to another project is404 NOT_FOUND.
curl https://api.example.com/v2/projects/example.com/annotations \
-H "authorization: Bearer $RA_ADMIN_TOKEN" \
-H "content-type: application/json" \
-d '{"title":"v2.0 released","date":"2026-10-01","kind":"release","url":"https://example.com/changelog"}'From TypeScript, admin.annotations in /admin calls the same routes.