Annotations
Annotations are freehand pen strokes drawn on top of another widget or directly on the canvas. Each annotation belongs to a single parent -- a Note, Image, Video, PDF, Browser, Anchor, Table, VideoInput, IpVideo, or RdpConnection widget, or the canvas itself (the SharedCanvas root). Use annotations for markup, highlighting, or freehand drawing over existing content.
Unlike other widgets, annotations do not have location, size, scale, or pinned properties -- their geometry is entirely described by the points field, in the parent's coordinate space.
Authentication
All endpoints require authentication via the Private-Token header or a CanvusSession cookie, unless the canvas has link sharing enabled (View or Edit permission). Write operations (POST, PATCH, DELETE) require edit access. View-only users receive 403 Forbidden on any write attempt.
Annotation properties
id-- string (uuid, read-only). Unique identifier assigned by the server on creation.widget_type-- string (read-only). Always"Annotation".parent_id-- string (read-only). ID of the parent widget the annotation is drawn on, or the canvas root ID for annotations created directly on the SharedCanvas.points-- string or array (patchable). The stroke geometry: a base64-encodedFloat32Array, or a JSON array of arrays, with 9 floats per node. Required on create; on PATCH, replaces the entire stroke.line_color-- string (patchable). Hex color code including alpha, e.g."#ff0000ff". Defaults to"#000000ff"if omitted on create.page-- integer (patchable). Page number the annotation belongs to. Only valid when the parent is a PDF widget -- setting it on any other parent type returns 400 Bad Request. Omitted from responses when not applicable.depth-- number, float (read-only). Z-order value. Not settable via create or PATCH.
Streaming
All GET endpoints support real-time updates via the ?subscribe query parameter, the same as other widget types. See Streaming for details.
List annotations
Retrieves all annotations on a parent widget, or on the canvas itself.
GET /api/v1/canvases/:canvas_id/:parent_type/:parent_id/annotations
GET /api/v1/canvases/:canvas_id/shared-canvas/annotations
Path parameters:
canvas_id(uuid, required) -- ID of the canvasparent_type(string, required) -- One ofnotes,images,browsers,videos,pdfs,anchors,video-inputs,ip-videos,rdp-connections,tablesparent_id(uuid, required) -- ID of the parent widget
Query parameters:
subscribe(boolean, optional) -- Enable streaming updates
Example request:
curl -H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/notes/f77e17a2-3716-46e4-8143-97dde114b20b/annotations
Example response:
[
{
"depth": 1.0,
"id": "3f9c2a3e-9b3a-4b2e-9f4d-6a8c1e2b5d70",
"line_color": "#ff0000ff",
"parent_id": "f77e17a2-3716-46e4-8143-97dde114b20b",
"points": "AACAPwAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAAAAAAIA/",
"widget_type": "Annotation"
}
]
Example request -- annotations on the canvas itself:
curl -H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/shared-canvas/annotations
Get single annotation
Retrieves a single annotation by ID.
GET /api/v1/canvases/:canvas_id/:parent_type/:parent_id/annotations/:annotation_id
GET /api/v1/canvases/:canvas_id/shared-canvas/annotations/:annotation_id
Path parameters:
canvas_id(uuid, required) -- ID of the canvasparent_type(string, required) -- Parent widget type (see List Annotations)parent_id(uuid, required) -- ID of the parent widgetannotation_id(uuid, required) -- ID of the annotation
Query parameters:
subscribe(boolean, optional) -- Enable streaming updates
Example request:
curl -H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/notes/f77e17a2-3716-46e4-8143-97dde114b20b/annotations/3f9c2a3e-9b3a-4b2e-9f4d-6a8c1e2b5d70
Example response:
{
"depth": 1.0,
"id": "3f9c2a3e-9b3a-4b2e-9f4d-6a8c1e2b5d70",
"line_color": "#ff0000ff",
"parent_id": "f77e17a2-3716-46e4-8143-97dde114b20b",
"points": "AACAPwAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAAAAAAIA/",
"widget_type": "Annotation"
}
Create annotation
Creates a new annotation on the specified parent widget, or directly on the canvas.
POST /api/v1/canvases/:canvas_id/:parent_type/:parent_id/annotations
POST /api/v1/canvases/:canvas_id/shared-canvas/annotations
Path parameters:
canvas_id(uuid, required) -- ID of the canvasparent_type(string, required) -- Parent widget type (see List Annotations)parent_id(uuid, required) -- ID of the parent widget
Request body (JSON):
points(required) -- Stroke geometry. Either a base64-encodedFloat32Array, or a JSON array of 9-float arrays (one array per node).line_color(string, optional) -- Hex color code including alpha, e.g."#ff0000ff". Defaults to"#000000ff".page(integer, optional) -- Page number. Only valid when the parent is a PDF widget.
Example request -- base64 points:
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"points": "AACAPwAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAAAAAAIA/", "line_color": "#ff0000ff"}' \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/notes/f77e17a2-3716-46e4-8143-97dde114b20b/annotations
Example request -- points as a JSON array (one node, 9 floats):
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"points": [[0, 0, 0, 50, 50, 0, 0, 0, 0]], "line_color": "#ff0000ff"}' \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/notes/f77e17a2-3716-46e4-8143-97dde114b20b/annotations
Example request -- annotation on a PDF page:
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"points": [[0, 0, 0, 50, 50, 0, 0, 0, 0]], "page": 1}' \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/pdfs/9b6f3c2a-1234-4de6-ad95-2c0ab7d47b70/annotations
Example response:
{
"depth": 1.0,
"id": "3f9c2a3e-9b3a-4b2e-9f4d-6a8c1e2b5d70",
"line_color": "#ff0000ff",
"parent_id": "f77e17a2-3716-46e4-8143-97dde114b20b",
"points": "AACAPwAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAAAAAAIA/",
"widget_type": "Annotation"
}
Update annotation
Updates one or more properties of an existing annotation. The request body must contain at least one of points, line_color, or page -- an empty body returns 400 Bad Request.
PATCH /api/v1/canvases/:canvas_id/:parent_type/:parent_id/annotations/:annotation_id
PATCH /api/v1/canvases/:canvas_id/shared-canvas/annotations/:annotation_id
Path parameters:
canvas_id(uuid, required) -- ID of the canvasparent_type(string, required) -- Parent widget type (see List Annotations)parent_id(uuid, required) -- ID of the parent widgetannotation_id(uuid, required) -- ID of the annotation to update
Request body (JSON):
Any combination of: points, line_color, page.
Example request -- replace the stroke geometry:
curl -X PATCH \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"points": [[0, 0, 0, 100, 100, 0, 0, 0, 0]]}' \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/notes/f77e17a2-3716-46e4-8143-97dde114b20b/annotations/3f9c2a3e-9b3a-4b2e-9f4d-6a8c1e2b5d70
Example request -- change color:
curl -X PATCH \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"line_color": "#00ff00ff"}' \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/notes/f77e17a2-3716-46e4-8143-97dde114b20b/annotations/3f9c2a3e-9b3a-4b2e-9f4d-6a8c1e2b5d70
Example response:
{
"depth": 1.0,
"id": "3f9c2a3e-9b3a-4b2e-9f4d-6a8c1e2b5d70",
"line_color": "#00ff00ff",
"parent_id": "f77e17a2-3716-46e4-8143-97dde114b20b",
"points": "AACAPwAAgD8AAAAAAAAAAAAAgD8AAIA/AAAAAAAAAAAAAIA/",
"widget_type": "Annotation"
}
Validation errors:
- Empty PATCH body returns 400 Bad Request:
PATCH body must contain at least one of: points, line_color, page - Setting
pagewhen the parent is not a PDF widget returns 400 Bad Request:page is only valid when the parent is a PDF widget
Delete annotation
Permanently removes an annotation.
DELETE /api/v1/canvases/:canvas_id/:parent_type/:parent_id/annotations/:annotation_id
DELETE /api/v1/canvases/:canvas_id/shared-canvas/annotations/:annotation_id
Path parameters:
canvas_id(uuid, required) -- ID of the canvasparent_type(string, required) -- Parent widget type (see List Annotations)parent_id(uuid, required) -- ID of the parent widgetannotation_id(uuid, required) -- ID of the annotation to delete
Example request:
curl -X DELETE \
-H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/canvases/78cfbcc8-aed9-4bbb-95ca-a0b9a5358d5a/notes/f77e17a2-3716-46e4-8143-97dde114b20b/annotations/3f9c2a3e-9b3a-4b2e-9f4d-6a8c1e2b5d70
A successful deletion returns an empty response with status 200 OK.
Error responses
All endpoints return errors as JSON with a msg field.
- 400 Bad Request -- Invalid or malformed
points,pageset on a non-PDF parent, or an empty PATCH body - 401 Unauthorized -- Missing or invalid authentication token
- 403 Forbidden -- View-only user attempted a write operation
- 404 Not Found -- Canvas, parent widget, or annotation does not exist, or the parent widget type does not accept annotations
Example error response:
{"msg": "page is only valid when the parent is a PDF widget"}