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'},
)