Skip to content

Uploads folder

The uploads folder is a temporary staging area for adding content to a canvas. When you upload a file or create a note through this endpoint, Canvus places the item in the canvas's uploads folder. From there, the content appears on the canvas like any other widget.

This is the primary way to add content to a canvas through the API. You can upload images, videos, PDFs, and other files, or create notes with text content. Canvus automatically detects the file type and creates the appropriate widget.

When you would use this API:

  • Adding images, videos, or PDFs to a canvas programmatically
  • Creating notes on a canvas from an external application
  • Building an integration that pushes content from another system onto a Canvus canvas
  • Batch-uploading files to a canvas

Authentication

All Uploads Folder endpoints require authentication via the Private-Token header.

Private-Token: YOUR_TOKEN

Streaming

The GET endpoint supports the ?subscribe query parameter for long-poll streaming. See the API overview for details.


List uploads folder contents

Returns the items currently in the canvas uploads folder.

  • Method: GET
  • URL: /api/v1/canvases/:canvas_id/uploads-folder
  • Authentication: Required
  • 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/863e7a77-0874-4170-9a0c-7f65d7869c37/uploads-folder

Example response (200 OK):

[]

The uploads folder is typically empty, as items are processed and placed on the canvas shortly after upload.

Current behavior

This endpoint currently always returns an empty array, even while uploads are in the folder. This is being corrected.


Upload a note

Creates a new note on the canvas via the uploads folder. The request is a multipart/form-data POST with a single json part containing the note properties. No file upload (data part) is needed for notes.

  • Method: POST
  • URL: /api/v1/canvases/:canvas_id/uploads-folder
  • Authentication: Required
  • Content-Type: multipart/form-data

Path parameters:

  • canvas_id (uuid, required) -- ID of the canvas

JSON part fields:

  • upload_type (string, required) -- Must be "Note". When upload_type is "Note", the data file part may be omitted.
  • text (string, optional) -- Text content of the note
  • title (string, optional) -- Title of the note
  • background_color (string, optional) -- Background color as a hex string (e.g., "#ffeb3b")

Example request:

curl -X POST \
  -H "Private-Token: YOUR_TOKEN" \
  -F 'json={"upload_type":"note","text":"Action item: review the Q3 proposal","title":"Q3 Review","background_color":"#ffeb3b"}' \
  https://canvus.example.com/api/v1/canvases/863e7a77-0874-4170-9a0c-7f65d7869c37/uploads-folder

Example response (200 OK):

{
  "background_color": "#ffeb3b",
  "depth": 0,
  "id": "content",
  "location": {
    "x": 0,
    "y": 0
  },
  "parent_id": "99a81a8b-9605-4122-a233-8de3a03a3f05",
  "pinned": false,
  "scale": 1,
  "size": {
    "height": 300,
    "width": 300
  },
  "state": "normal",
  "text": "Action item: review the Q3 proposal",
  "title": "Q3 Review",
  "widget_type": "Note"
}

Response fields:

  • id -- Always "content" for uploads folder responses. The widget will receive its permanent ID once placed on the canvas.
  • parent_id -- The ID of the folder item that holds this upload inside the uploads folder. Each upload gets its own folder item, so this value is different on every call.
  • widget_type -- "Note" for note uploads
  • All other fields are standard widget fields

Upload a file

Uploads a file (image, video, PDF, or other file type) to the canvas. Canvus automatically detects the file type and creates the appropriate widget. Unrecognized file types are uploaded as generic assets.

The request is a multipart/form-data POST with a mandatory data part (the file) and an optional json part (metadata).

  • Method: POST
  • URL: /api/v1/canvases/:canvas_id/uploads-folder
  • Authentication: Required
  • Content-Type: multipart/form-data

Path parameters:

  • canvas_id (uuid, required) -- ID of the canvas

Multipart form parts:

  • data (file, required) -- The file to upload
  • json (string, optional) -- JSON metadata for the upload

JSON part fields (all optional):

  • upload_type (string) -- Must be "asset", empty, or omitted
  • title (string) -- Display title for the widget
  • original_filename (string) -- Original filename to store with the asset. It is not taken from the uploaded file's name, so send it here if you want it stored.

Example request -- upload an image:

curl -X POST \
  -H "Private-Token: YOUR_TOKEN" \
  -F 'json={"title":"Product Photo"}' \
  -F 'data=@product-photo.jpg' \
  https://canvus.example.com/api/v1/canvases/863e7a77-0874-4170-9a0c-7f65d7869c37/uploads-folder

Example response for an image (200 OK):

{
  "depth": 0,
  "hash": "",
  "id": "content",
  "location": {
    "x": 0,
    "y": 0
  },
  "original_filename": "",
  "parent_id": "b491c355-1bcc-48ff-be30-6df65d6e1ed4",
  "pinned": false,
  "scale": 1,
  "size": {
    "height": 100,
    "width": 100
  },
  "state": "normal",
  "title": "Product Photo",
  "widget_type": "Image"
}

Example request -- upload a video with metadata:

curl -X POST \
  -H "Private-Token: YOUR_TOKEN" \
  -F 'json={"upload_type":"asset","title":"Demo Recording"}' \
  -F 'data=@demo-recording.mp4' \
  https://canvus.example.com/api/v1/canvases/863e7a77-0874-4170-9a0c-7f65d7869c37/uploads-folder

Example response for a video (200 OK):

{
  "depth": 0,
  "hash": "",
  "id": "content",
  "location": {
    "x": 0,
    "y": 0
  },
  "original_filename": "",
  "parent_id": "b491c355-1bcc-48ff-be30-6df65d6e1ed4",
  "pinned": false,
  "playback_position": 0,
  "playback_state": "STOPPED",
  "scale": 1,
  "size": {
    "height": 100,
    "width": 100
  },
  "state": "normal",
  "title": "Demo Recording",
  "widget_type": "Video"
}

Notes:

  • The hash field may be empty in the initial response. The server generates the content hash asynchronously after the upload completes. Query the widget through its type-specific endpoint to get the final hash.
  • The size in the response is a placeholder. The widget dimensions are updated once Canvus finishes processing the asset.
  • The widget_type in the response reflects what Canvus detected: "Image", "Video", "Pdf", or "Asset" for unrecognized file types.

Current behavior

The id returned for an upload is currently not unique, so looking the widget up by it is not reliable. This is being corrected.


Error responses

  • 401 Unauthorized -- Missing or invalid Private-Token
  • 404 Not Found -- The specified canvas does not exist

Current behavior

  • An invalid or expired token returns 403 Forbidden, not 401. See Current behavior.
  • A malformed json part in an upload returns 500 Internal Server Error with a plain-text body instead of 400 Bad Request with JSON.

These are being corrected.

All errors return a JSON body:

{
  "msg": "error description"
}