Widgets (Generic)
The generic widgets endpoint provides a unified, read-only view of every item on a canvas regardless of its type. A single request returns all notes, images, videos, PDFs, browsers, anchors, video inputs, connectors, and every other widget type in one list.
Each widget in the response includes a widget_type field that tells you what kind of content it represents. The fields returned vary by type -- an image widget includes hash and original_filename, while a note widget includes text and background_color.
When you would use this API:
- Getting a complete inventory of everything on a canvas in a single call
- Building a canvas viewer or dashboard that needs to display all content types
- Searching across all widget types (e.g., finding all items at a specific location)
- Monitoring canvas changes with
?subscribefor real-time updates across all types - Reading widget properties when you do not know the type in advance
When to use type-specific endpoints instead:
If you need to create, update, or delete widgets, use the type-specific endpoints (e.g., /canvases/:id/notes, /canvases/:id/images). The generic widgets endpoint is primarily for reading.
Authentication
The GET endpoints require authentication via the Private-Token header, unless the canvas has link sharing enabled (View or Edit permission), in which case no authentication is needed.
Private-Token: YOUR_TOKEN
Streaming
All GET endpoints support the ?subscribe query parameter for long-poll streaming. When present, the server holds the connection open and sends newline-delimited JSON updates whenever any widget on the canvas changes. See the API overview for details.
Widget Types
The widget_type field identifies the kind of widget. Possible values:
"Note"-- A sticky note with text content"Image"-- An uploaded image file"Video"-- An uploaded video file"PDF"-- An uploaded PDF document"Browser"-- An embedded web browser"Anchor"-- A named anchor point on the canvas"VideoInput"-- A live video capture feed from a hardware device"IpVideo"-- A network video stream (RTSP, etc.)"RdpConnection"-- A remote desktop connection"Connector"-- A line connecting two widgets"Table"-- A grid-based table widget"TableCell"-- A cell within a Table widget grid"SharedCanvas"-- The root canvas container widget. Not directly modifiable via the API."VideoOutputAnchor"-- A region defining video output bounds"CanvasBackground"-- The canvas background widget
Common Widget Fields
All widget types share a base set of fields:
id(string) -- Unique identifier for the widgetwidget_type(string) -- The type of widget (see list above)location(object) -- Position on the canvas as{"x": ..., "y": ...}depth(number) -- Z-order value. Higher values render on top of lower values.parent_id(string) -- ID of the parent widget (typically the SharedCanvas root)state(string) -- Current widget state (e.g.,"normal")
Most widget types also include:
size(object) -- Width and height as{"width": ..., "height": ...}scale(number) -- Display scale factorpinned(boolean) -- Whether the widget is pinned in place
Asset-based widgets (Image, Video, PDF) additionally include:
hash(string) -- Content hash for the uploaded file. Used with the mipmaps and assets endpoints.original_filename(string) -- The filename of the uploaded filetitle(string) -- Display title
List All Widgets on a Canvas
Returns every widget on the specified canvas.
- Method:
GET - URL:
/api/v1/canvases/:canvas_id/widgets - Authentication: Required (unless canvas has link sharing)
- Streaming: Supported via
?subscribe
Path parameters:
canvas_id(uuid, required) -- ID of the canvas
Query parameters:
subscribe(boolean, optional) -- Enable long-poll streaming
Example request:
curl -H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/canvases/3ad9ece4-28be-4e19-9f9a-1a01a4dbae28/widgets
Example response (200 OK):
[
{
"depth": 0,
"id": "eab4c3da-0fc3-46f2-a7a7-bf9d16494348",
"location": {
"x": 0,
"y": 0
},
"parent_id": "",
"pinned": false,
"scale": 1,
"size": {
"height": 5400,
"width": 9600
},
"state": "normal",
"widget_type": "SharedCanvas"
},
{
"depth": 0,
"hash": "cbcb439a796b",
"id": "2a59b935-02b6-47dc-820c-caab1de64247",
"location": {
"x": 5291.9,
"y": 2564.2
},
"original_filename": "photo.jpg",
"parent_id": "eab4c3da-0fc3-46f2-a7a7-bf9d16494348",
"pinned": false,
"scale": 1,
"size": {
"height": 100,
"width": 100
},
"state": "normal",
"title": "A dog",
"widget_type": "Image"
},
{
"background_color": "#ffffff",
"depth": 0,
"id": "dc3ca5b6-0fb4-4628-bf4e-2008087b9430",
"location": {
"x": 5997.6,
"y": 3253.6
},
"parent_id": "eab4c3da-0fc3-46f2-a7a7-bf9d16494348",
"pinned": false,
"scale": 1,
"size": {
"height": 300,
"width": 300
},
"state": "normal",
"text": "Remember to review the Q3 numbers",
"widget_type": "Note"
},
{
"anchor_index": 0,
"anchor_name": "Overview",
"depth": 0,
"id": "5da69125-a5f5-417d-8d8d-a633a0499560",
"location": {
"x": 4676.8,
"y": 2432.8
},
"parent_id": "eab4c3da-0fc3-46f2-a7a7-bf9d16494348",
"pinned": false,
"scale": 1,
"size": {
"height": 800,
"width": 1200
},
"state": "normal",
"widget_type": "Anchor"
}
]
Get a Single Widget
Returns a single widget by ID. The widget can be of any type.
- Method:
GET - URL:
/api/v1/canvases/:canvas_id/widgets/:widget_id - Authentication: Required (unless canvas has link sharing)
- Streaming: Supported via
?subscribe
Path parameters:
canvas_id(uuid, required) -- ID of the canvaswidget_id(uuid, required) -- ID of the widget
Query parameters:
subscribe(boolean, optional) -- Enable long-poll streaming
Example request:
curl -H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/canvases/3ad9ece4-28be-4e19-9f9a-1a01a4dbae28/widgets/2a59b935-02b6-47dc-820c-caab1de64247
Example response (200 OK):
{
"depth": 0,
"hash": "cbcb439a796b",
"id": "2a59b935-02b6-47dc-820c-caab1de64247",
"location": {
"x": 5291.9,
"y": 2564.2
},
"original_filename": "photo.jpg",
"parent_id": "eab4c3da-0fc3-46f2-a7a7-bf9d16494348",
"pinned": false,
"scale": 1,
"size": {
"height": 100,
"width": 100
},
"state": "normal",
"title": "A dog",
"widget_type": "Image"
}
Clone Widget
Copy a widget from any canvas you have access to into the destination canvas.
- Method:
POST - URL:
/api/v1/canvases/:canvas_id/notes(or the appropriate typed endpoint) - Auth:
Private-Tokenrequired
Supply source_canvas_id and source_widget_id in the request body instead of the widget's normal creation fields. The server reads the source widget, copies all its properties to the destination canvas, and returns the newly created widget.
Request body:
{
"source_canvas_id": "uuid-of-source-canvas",
"source_widget_id": "uuid-of-widget-to-clone"
}
An optional location override can be included to place the clone at a specific position:
{
"source_canvas_id": "uuid-of-source-canvas",
"source_widget_id": "uuid-of-widget-to-clone",
"location": { "x": 100, "y": 200 }
}
Supported widget types: Note, Image, Browser, Video, PDF, Anchor, Table.
Response: The newly created widget object, identical to a normal POST response for that widget type.
Notes:
- Asset-based widgets (Image, Video, PDF) require the source asset file to be locally available on the server. If not, returns 400 Bad Request.
- The clone is created as a top-level widget on the destination canvas regardless of the source widget's parent.
- Use the typed endpoint matching the source widget type (e.g. /notes for a Note, /images for an Image).
Error Responses
- 401 Unauthorized -- Missing or invalid
Private-Token(and canvas does not have link sharing) - 404 Not Found -- The specified canvas or widget does not exist
All errors return a JSON body:
{
"msg": "error description"
}