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
Every object returned by the widgets endpoints includes:
widget_type(string) -- The type of widget (see list above)state(string) -- Current widget state (e.g.,"normal")
All widget types except Connector and CanvasBackground also include:
id(string) -- Unique identifier for the widgetlocation(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)size(object) -- Width and height as{"width": ..., "height": ...}scale(number) -- Display scale factorpinned(boolean) -- Whether the widget is pinned in place
A Connector has an id but none of the other fields above; see Connectors for its fields. A CanvasBackground has none of them.
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(flag, optional) -- Enable long-poll streaming. The parameter takes no value; its presence alone turns streaming on, so?subscribe=falsealso streams.
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(flag, optional) -- Enable long-poll streaming. The parameter takes no value; its presence alone turns streaming on, so?subscribe=falsealso streams.
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/widgets/clone, or any typed endpoint such as/api/v1/canvases/:canvas_id/notes - 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.
Current behavior
Some properties are not yet copied: a browser's title and scroll offset, a video's playback_position and muted, an anchor's position in the anchor list, table cell contents, and any annotations or child widgets. This is being corrected.
The dedicated widgets/clone endpoint is a convenience for when you do not know the source widget's type in advance -- the server determines the type by reading the source widget. Cloning through a typed endpoint (e.g. /notes) works identically and is equivalent to using widgets/clone; both dispatch to the same clone logic whenever source_canvas_id is present in the request body.
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 widgets/clone when you do not already know the source widget's type, or the typed endpoint matching the source widget type (e.g. /notes for a Note) when you do.
- The /images, /videos and /pdfs endpoints only accept multipart/form-data uploads, so a JSON clone request sent to them returns 400 Bad Request. Clone Image, Video and PDF widgets through widgets/clone.
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
Current behavior
An invalid or expired token returns 403 Forbidden, not 401. See Current behavior.
All errors return a JSON body:
{
"msg": "error description"
}