Annotations
A curve that rises or dips is easier to read with what happened that day: the newsletter going out, the release of the new checkout flow, a payment outage. Annotations are these markers.
An annotation
Section titled “An annotation”| Field | Contents |
|---|---|
| Site | one site, or all sites |
| Start and end | a date, or a period |
| Title | “Autumn newsletter” |
| Description | optional |
| Category | campaign, release, incident, other |
They are entered in the site’s Annotations tab, which also shows those shared by all sites; shared annotations are managed in Administration › Settings.
Through the API
Section titled “Through the API”A deployment pipeline can annotate its releases, with an eoa_… integration token:
curl -X POST https://stats.example.com/api/v1/sites/$SITE_ID/annotations \ -H "Authorization: Bearer $EODIA_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "starts_at": "2026-10-04T09:30:00+02:00", "title": "Version 4.2: new checkout flow", "category": "release" }'POST /api/v1/annotations creates an annotation shared by all sites (empty site_id).
The annotations view
Section titled “The annotations view”One row per annotation and per site: shared annotations are copied to each site, so that the insights row rule lets them through with the rest.
| Column | Contents |
|---|---|
site_id, annotation_id | the site, the annotation |
starts_at, ends_at | the start, the end of a period |
day, end_day | the corresponding days, in the site’s time zone |
title, description, category | the marker |
all_sites | true for a shared annotation |
In insights, an annotation is overlaid on a curve through a join on the day:
SELECT s.day, count(DISTINCT s.session_id) AS visits, max(a.title) AS markerFROM analytics.sessions sLEFT JOIN analytics.annotations a ON a.site_id = s.site_id AND s.day BETWEEN a.day AND a.end_dayGROUP BY s.dayORDER BY s.dayeodia analytics is free software by Eodia.