REST API

Annotations

Manage the chart annotations pinned to one of the current team's sites. An annotation is a timestamped note (annotated_at + body) any team member can pin to a chart; editing or deleting it is restricted to its author or a team Admin/Owner. A site is addressed by {siteKey} (UUID or domain). All endpoints require Authorization: Bearer {token}. See Conventions for the base URL, headers, and date-range/error conventions shared by every endpoint.

List annotations

GET /api/sites/{siteKey}/annotations

List a site's annotations pinned within the resolved date range, ordered chronologically.

Path parameters

Parameter Type Required Description
siteKey string Yes Site UUID or domain.

Query parameters — the shared date-range inputs (see Date ranges): range, or from/to. Defaults to today.

Response — flat JSON array of:

Field Type Description
id string (uuid) Annotation id.
annotated_at string (ISO 8601) The UTC instant the note is pinned to on the chart.
body string Note text.
author object | null { id, name } of the team member who wrote it, or null once they are removed from the team.
created_at string (ISO 8601) | null When the annotation was created.
updated_at string (ISO 8601) | null When the annotation was last edited.

Status: 200 OK.

curl "https://clickbase.so/api/sites/example.com/annotations" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
await fetch('https://clickbase.so/api/sites/example.com/annotations', { headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' } })
requests.get('https://clickbase.so/api/sites/example.com/annotations', headers={'Authorization': f'Bearer {token}', 'Accept':'application/json'})

Create an annotation

POST /api/sites/{siteKey}/annotations

Pin a new note to a site's chart. The author is always the token's user — there is no author/user_id payload field, so an annotation can never be created on someone else's behalf.

Body parameters

Parameter Type Required Description
annotated_at string Yes Any parseable date/instant. Stored verbatim in UTC.
body string Yes Note text. Max 10000 chars.

Response — the created annotation (same fields as the list). Status: 201 Created.

curl -X POST "https://clickbase.so/api/sites/example.com/annotations" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"annotated_at": "2026-07-11T12:00:00Z", "body": "Pricing page redesign shipped"}'
await fetch('https://clickbase.so/api/sites/example.com/annotations', {
  method: 'POST',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', Accept: 'application/json' },
  body: JSON.stringify({ annotated_at: '2026-07-11T12:00:00Z', body: 'Pricing page redesign shipped' }),
})
requests.post(
    'https://clickbase.so/api/sites/example.com/annotations',
    headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
    json={'annotated_at': '2026-07-11T12:00:00Z', 'body': 'Pricing page redesign shipped'},
)

Update an annotation

PATCH /api/sites/{siteKey}/annotations/{annotation}

Edit an annotation's note text. The annotated_at anchor is immutable once set — only body can change. Only the annotation's author, or a team Admin/Owner, may edit it; any other team member gets 403 Forbidden, and a foreign/unknown annotation id (not on this site) returns 404 Not Found.

Path parameters

Parameter Type Required Description
siteKey string Yes Site UUID or domain.
annotation string Yes Annotation id. A foreign/unknown id returns 404.

Body parameters

Parameter Type Required Description
body string Yes Note text. Max 10000 chars.

Response — the updated annotation. Status: 200 OK.

curl -X PATCH "https://clickbase.so/api/sites/example.com/annotations/{annotation}" \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"body": "Pricing page redesign shipped (v2)"}'
await fetch(`https://clickbase.so/api/sites/example.com/annotations/${annotationId}`, {
  method: 'PATCH',
  headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', Accept: 'application/json' },
  body: JSON.stringify({ body: 'Pricing page redesign shipped (v2)' }),
})
requests.patch(
    f'https://clickbase.so/api/sites/example.com/annotations/{annotation_id}',
    headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
    json={'body': 'Pricing page redesign shipped (v2)'},
)

Delete an annotation

DELETE /api/sites/{siteKey}/annotations/{annotation}

Remove an annotation. Cannot be undone. Same author-or-Admin/Owner rule as update — a non-author, non-admin member gets 403 Forbidden; a foreign/unknown annotation id returns 404 Not Found.

Path parameters

Parameter Type Required Description
siteKey string Yes Site UUID or domain.
annotation string Yes Annotation id. A foreign/unknown id returns 404.

Status: 204 No Content.

curl -X DELETE "https://clickbase.so/api/sites/example.com/annotations/{annotation}" \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
await fetch(`https://clickbase.so/api/sites/example.com/annotations/${annotationId}`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${token}`, Accept: 'application/json' },
})
requests.delete(
    f'https://clickbase.so/api/sites/example.com/annotations/{annotation_id}',
    headers={'Authorization': f'Bearer {token}', 'Accept': 'application/json'},
)