Video input widgets
A video input widget shows the live feed of a capture device (a webcam, capture card or HDMI input) on a canvas. The device is physically connected to one Canvus client. That client reads the device, and the widget shows its feed on the canvas.
Use these endpoints to place a capture feed on a canvas from a script, for example to put a document camera on a meeting canvas, or to move, resize, rename or remove a feed that is already there.
Do not confuse these endpoints with Video inputs (/clients/:client_id/video-inputs). That endpoint lists the capture devices on a client. The endpoints on this page manage the widgets that show those devices on a canvas.
Workflow for showing a capture device on a canvas:
- Call List all clients and note the
idof the client that has the capture device. - Call List all video inputs for a client with that client ID and copy the
sourcevalue of the device you want. - Create a video input widget with that
sourceassourceand the client ID ashost-id.
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.
Common widget properties
Every video input widget shares these properties with other canvas widget types:
id(string, uuid) -- Unique identifier assigned by the server. Read-only.widget_type(string) -- Always"VideoInput"for this resource. Read-only.location(object) -- Position as{"x": float, "y": float}, relative to the widget's parent.size(object) -- Dimensions as{"width": float, "height": float}. Change it with PATCH; create requests do not read it.depth(number, float) -- Z-order relative to sibling widgets. Higher values render on top. Must be >= 1.0 on PATCH.scale(number, float) -- Scale factor. Default:1.pinned(boolean) -- Whentrue, the widget cannot be moved or resized through the touch UI. API writes are unaffected. Default:false.input_locked(boolean) -- Whentrue, the widget cannot be moved, resized or operated by touch on a Canvus client, but it can still be annotated with a pen. API changes still apply. Default:false. Requires Canvus Server 26.10.0 or later; on older servers the field is left out of responses and a PATCH that sets it is ignored. Set it with PATCH; create requests do not read it.state(string) -- Widget state. Typically"normal".parent_id(string, uuid) -- ID of the parent widget or canvas root. Can be set on create and changed with PATCH. Omit it to use the canvas root.
Video input properties
source(string) -- Device identifier of the capture device, as returned in thesourcefield of Video inputs. Set on create; it cannot be changed afterwards.host-id(string) -- Theidof the client that has the capture device, as returned by Clients. Set on create; it cannot be changed afterwards. Note the hyphen in the field name.title(string) -- Display title for the widget. Patchable.
Auto-raise
All PATCH requests accept an optional auto_raise boolean parameter (default false). When set to true, the widget's depth is set above all its siblings.
Streaming
All GET endpoints support the ?subscribe query parameter for real-time updates. A list subscription first sends the full list, then sends arrays that contain only the items that changed (usually one), including deleted items with "state": "deleted". Merge each update into your copy of the list by id; see Streaming.
curl -H "Private-Token: YOUR_TOKEN" \
"https://canvus.example.com/api/v1/canvases/09348962-32aa-480d-b3d6-cacef4030ac2/video-inputs?subscribe"
List video input widgets
Returns all video input widgets on the specified canvas.
GET /api/v1/canvases/:canvas_id/video-inputs
Path parameters:
canvas_id(uuid, required) -- ID of the canvas
Query parameters:
subscribe(flag, optional) -- Enable streaming updates. The parameter takes no value; its presence alone turns streaming on, so?subscribe=falsealso streams. See Streaming.
Example request:
curl -H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/canvases/09348962-32aa-480d-b3d6-cacef4030ac2/video-inputs
Example response:
[
{
"depth": 3,
"host-id": "e5cad8d4-7051-4051-97bc-13e41fd81ca7",
"id": "4c1d2e3f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"input_locked": false,
"location": {
"x": 1200,
"y": 800
},
"parent_id": "08596c44-389c-45d6-9f32-a9940c54b7d9",
"pinned": false,
"scale": 1,
"size": {
"height": 1080,
"width": 1920
},
"source": "video=@device_pnp_\\\\?\\usb#vid_3277&pid_0031&mi_00#6&399d7860&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global",
"state": "normal",
"title": "Document camera",
"widget_type": "VideoInput"
}
]
Get single video input widget
Returns a single video input widget by ID.
GET /api/v1/canvases/:canvas_id/video-inputs/:widget_id
Path parameters:
canvas_id(uuid, required) -- ID of the canvaswidget_id(uuid, required) -- ID of the video input widget
Query parameters:
subscribe(flag, optional) -- Enable streaming updates. 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/09348962-32aa-480d-b3d6-cacef4030ac2/video-inputs/4c1d2e3f-5a6b-4c7d-8e9f-0a1b2c3d4e5f
The response is a single widget object with the same fields as in the list response.
Create video input widget
Creates a video input widget on the canvas.
POST /api/v1/canvases/:canvas_id/video-inputs
Path parameters:
canvas_id(uuid, required) -- ID of the canvas
Body parameters (JSON):
source(string, required) -- Device identifier from Video inputs. A missing or empty value returns400 Bad Request.host-id(string, required) -- Theidof the client that has the device, from Clients. A missing or empty value returns400 Bad Request.title(string, optional) -- Display title for the widget. Default:"".parent_id(string, optional) -- ID of the parent widget. Defaults to the canvas root. Returns404 Not Foundif no such widget exists.location(object, optional) -- Position as{"x": float, "y": float}. If omitted, the widget is placed near the center of its parent, offset at random by up to one eighth of the parent's width and height.depth(number, optional) -- Z-order.scale(number, optional) -- Scale factor. Default:1.0.pinned(boolean, optional) -- Whether the widget is pinned in the UI. Default:false.
Example request:
curl -X POST \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"source": "video=@device_pnp_\\\\?\\usb#vid_3277&pid_0031&mi_00#6&399d7860&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\\global",
"host-id": "e5cad8d4-7051-4051-97bc-13e41fd81ca7",
"title": "Document camera",
"location": {"x": 1200, "y": 800},
"depth": 3
}' \
https://canvus.example.com/api/v1/canvases/09348962-32aa-480d-b3d6-cacef4030ac2/video-inputs
Copy the source value exactly as the Video inputs endpoint returns it. Device identifiers often contain backslashes, which must be escaped in JSON.
Response: the created widget, with the same fields as in the list response.
Update video input widget
Updates one or more properties of a video input widget. Only include the fields you want to change.
PATCH /api/v1/canvases/:canvas_id/video-inputs/:widget_id
Path parameters:
canvas_id(uuid, required) -- ID of the canvaswidget_id(uuid, required) -- ID of the video input widget
Body parameters (JSON):
title(string, optional) -- New display title.parent_id(string, optional) -- ID of the new parent widget. Send it together withlocation, because coordinates are relative to the parent.location(object, optional) -- New position.size(object, optional) -- New dimensions.depth(number, optional) -- New z-order. Must be >= 1.0.scale(number, optional) -- New scale factor.pinned(boolean, optional) -- New pinned state.input_locked(boolean, optional) -- New input lock state. Requires Canvus Server 26.10.0 or later.auto_raise(boolean, optional) -- Whentrue, depth is set above all siblings.
source and host-id cannot be changed. To show a different device, delete the widget and create a new one.
Example request:
curl -X PATCH \
-H "Private-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "Whiteboard camera", "size": {"width": 1280, "height": 720}}' \
https://canvus.example.com/api/v1/canvases/09348962-32aa-480d-b3d6-cacef4030ac2/video-inputs/4c1d2e3f-5a6b-4c7d-8e9f-0a1b2c3d4e5f
Response: the updated widget.
Delete video input widget
Removes a video input widget from the canvas. The capture device itself is not affected.
DELETE /api/v1/canvases/:canvas_id/video-inputs/:widget_id
Example request:
curl -X DELETE \
-H "Private-Token: YOUR_TOKEN" \
https://canvus.example.com/api/v1/canvases/09348962-32aa-480d-b3d6-cacef4030ac2/video-inputs/4c1d2e3f-5a6b-4c7d-8e9f-0a1b2c3d4e5f
A successful deletion returns an empty response with HTTP status 200.
Annotations
Pen strokes on a video input widget are available through the Annotations endpoints, with video-inputs as the widget type in the path.
Error responses
- 400 Bad Request -- Invalid JSON, a missing or empty
sourceorhost-idon create, or depth below 1.0 on update. - 401 Unauthorized -- Missing
Private-Tokenheader. - 403 Forbidden -- View-only users cannot create, update or delete widgets.
- 404 Not Found -- The canvas ID, widget ID or
parent_iddoes not exist.
Current behavior
- An invalid or expired token returns
403 Forbidden, not401. See Current behavior. - Create does not yet enforce the
depthlimit. A widget created withoutdepthgets0.
All errors return a JSON body:
{
"msg": "host-id parameter is mandatory"
}