Skip to main content

Notes

List notes

The annotations on this site's chart, most recent first.

GET/sites/{siteId}/notes
List notes
curl --request GET \
  --url 'https://truestat.io/api/v1/sites/{siteId}/notes' \
  --header 'Authorization: Bearer <token>'
{
  "data": [
    {
      "id": "02eae3c2-3790-4edd-a2ff-577eb2a8b0ba",
      "body": "Deployed v2 — new pricing page",
      "author_id": "734c7de3-58f1-46e6-83d1-2be85466ee70",
      "created_at": "2026-09-16T10:02:11.000Z",
      "updated_at": "2026-09-16T10:02:11.000Z",
      "granularity": "minute",
      "occurred_at": "2026-09-16T10:00:00+00:00"
    }
  ],
  "meta": {
    "page": {
      "limit": 100,
      "offset": 0,
      "has_more": false
    },
    "site_id": "6fed8980-a119-4a9c-a4d4-53e448ef9f9e"
  }
}

Every note on the site, newest first.

The window filters by when things happened

Passing period or from/to narrows the list by occurred_at — when the annotated thing happened — not by when the note was written. That is the same question the chart asks, so a caller drawing annotations alongside a timeseries passes the same window to both.

Without a window you get the most recent notes regardless of date, which is what a caller syncing notes into an external system wants.

meta.range appears only when you asked for a window. Its absence is how you can tell the list was unfiltered.

author_id can be null

That is not an error. A note outlives the person who wrote it: when somebody leaves the team their notes stay on the chart and the author becomes null.

The field is an id rather than a name — resolving names would mean reading the user table on a path that does not otherwise need it. Match it against your own records, or ignore it.

Reading and writing are separate permissions

This endpoint needs notes:read. A key with only that can list notes and cannot create, edit or delete them — those need notes:write.

Authorizations

Authorizationstringheaderrequired

An API key from Settings → API keys. Scopes available: analytics:read, sites:read, sites:write, settings:read, settings:write, goals:read, goals:write, funnels:read, funnels:write, notes:read, notes:write, alerts:read, alerts:write, team:read, team:write, revenue:read, revenue:write.

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path parameters

siteIdstring (uuid)pathrequired
The site's id, from `GET /sites`. A site that is not yours and a site that does not exist both answer 403, so this cannot be used to discover other people's ids.

Query parameters

periodenum<string>query
A named window, resolved in `tz`. Cannot be combined with `from`/`to` — a request carrying both is refused rather than guessed at.
options:todayyesterdaylast24hlast7dlast30dlast12mmonthyearall
fromstring (date-time)query
Start of the window, ISO 8601 with an offset. Must be given together with `to`.
tostring (date-time)query
End of the window. Must be given together with `from`.
tzstringquerydefault: UTC
IANA timezone for day boundaries. `period=today&tz=Europe/Istanbul` means the reader's today, not the server's. Defaults to UTC.
botsenum<string>querydefault: excluded
Whether crawler traffic is counted. Excluded by default — the `/ai/*` endpoints report it separately and always include it.
options:excludedincluded
limitintegerquerydefault: 100
Rows per page, 1 to 1000.
offsetintegerquerydefault: 0
Rows to skip.

Response

application/json

The answer.

dataunknown
See the example.
metaobject