Skip to content

Mipmaps and assets

The mipmaps and assets endpoints provide direct access to canvas content files by their content hash. Mipmaps are progressively downscaled versions of image and PDF assets that enable efficient rendering at different zoom levels. The server generates them the first time they are requested and caches the result. The assets endpoint provides access to the original, full-resolution file.

These endpoints use a content-addressable scheme: you access files by their hash rather than by widget ID or canvas ID. The hash is available on image and PDF widgets via the hash field (see the widgets endpoint).

When you would use this API:

  • Building a custom canvas viewer that needs to render images at different zoom levels
  • Downloading thumbnail or preview versions of canvas images without fetching the full file
  • Implementing efficient WebGL-based rendering of canvas content
  • Downloading the original asset file by its content hash
  • Retrieving individual pages of a multi-page PDF

Key concepts

Mipmap levels:

  • Level 0 is the original resolution. For PDFs, level 0 is the page rendered to fit within a fixed raster size (2048 x 2048 pixels by default).
  • Each higher level halves the dimensions (level 1 = half size, level 2 = quarter size, etc.)
  • Levels stop at the first one where the longer side is at most 128 pixels, or where either side has reached 1 pixel
  • Mipmap levels are generated on demand and cached by the server

File format:

  • Mipmap images are usually returned in WebP format, regardless of the original file type. WebP is limited to 16383 pixels per side, so a larger level is returned as PNG or JPEG instead (for level 0, possibly in the original file's format).

Caching:

  • All mipmap and asset responses include Cache-Control: private, max-age=157680000, immutable. Content is immutable once generated -- the hash changes if the content changes. Clients should cache aggressively.

Multi-page assets (PDFs):

  • Use the page query parameter to access individual pages
  • Page numbering starts at 0 (first page is page=0)

Where to find the asset hash:

  • On Image widgets: use the hash field
  • On PDF widgets: use the hash field
  • On canvas backgrounds: use the image.hash field from the canvas background endpoint

Authentication

Both the Private-Token and canvas-id headers are required. The canvas ID identifies which canvas the asset belongs to, and the token authenticates the user's access to that canvas. Browser-based clients can send the canvas ID as a canvas-id cookie instead; the cookie is used when the header is absent.

Private-Token: YOUR_TOKEN (required)
canvas-id: <canvas-uuid> (required)

Note: The canvasId query parameter is NOT a substitute for the canvas-id header. Requests without a canvas-id header or cookie will return 404 regardless of query parameters.


Get mipmap info

Returns metadata about the available mipmap levels for an asset, including the original resolution, the maximum mipmap level, and the page count.

  • Method: GET
  • URL: /api/v1/mipmaps/:hash
  • Authentication: See above
  • Streaming: Not supported

Path parameters:

  • hash (string, required) -- The content hash of the asset (from the widget's hash field)

Query parameters:

  • page (integer, optional) -- Page number for multi-page assets (default: 0)

Request headers:

  • Private-Token (string, required) -- API access token
  • canvas-id (string, required) -- UUID of the canvas that contains this asset

Example request:

curl -H "Private-Token: YOUR_TOKEN" \
  -H "canvas-id: 3ad9ece4-28be-4e19-9f9a-1a01a4dbae28" \
  https://canvus.example.com/api/v1/mipmaps/cbcb439a796b

Example response (200 OK):

{
  "resolution": {
    "width": 4096,
    "height": 3072
  },
  "max_level": 5,
  "pages": 1
}

Response fields:

  • resolution (object) -- Original image dimensions as width and height in pixels. For PDFs, the page size fitted within the raster size used for level 0.
  • max_level (number) -- The highest mipmap level available. Level 0 is original size, and each subsequent level halves the dimensions.
  • pages (number) -- Number of pages in the asset. Always 1 for images; may be higher for PDFs.

Example request for a PDF page:

curl -H "Private-Token: YOUR_TOKEN" \
  -H "canvas-id: 3ad9ece4-28be-4e19-9f9a-1a01a4dbae28" \
  "https://canvus.example.com/api/v1/mipmaps/a1b2c3d4e5f6?page=2"

Download a mipmap level

Downloads the image data for a specific mipmap level. The response is a binary image file, usually WebP (see File format).

  • Method: GET
  • URL: /api/v1/mipmaps/:hash/:level
  • Authentication: See above
  • Streaming: Not supported

Path parameters:

  • hash (string, required) -- The content hash of the asset
  • level (integer, required) -- The mipmap level to download (0 = original size)

Query parameters:

  • page (integer, optional) -- Page number for multi-page assets (default: 0)

Request headers:

  • Private-Token (string, required) -- API access token
  • canvas-id (string, required) -- UUID of the canvas that contains this asset

Example request -- download the smallest mipmap (thumbnail):

curl -H "Private-Token: YOUR_TOKEN" \
  -H "canvas-id: 3ad9ece4-28be-4e19-9f9a-1a01a4dbae28" \
  -o thumbnail.webp \
  https://canvus.example.com/api/v1/mipmaps/cbcb439a796b/5

Example request -- download half-resolution version:

curl -H "Private-Token: YOUR_TOKEN" \
  -H "canvas-id: 3ad9ece4-28be-4e19-9f9a-1a01a4dbae28" \
  -o half-res.webp \
  https://canvus.example.com/api/v1/mipmaps/cbcb439a796b/1

Response:

Binary image data, usually WebP. The Content-Disposition header is attachment with no filename. The Cache-Control header is set to private, max-age=157680000, immutable.


Download an asset by hash

Downloads the original, full-resolution asset file by its content hash. Unlike mipmap downloads, this returns the file in its original format (JPEG, PNG, PDF, MP4, etc.).

  • Method: GET
  • URL: /api/v1/assets/:hash
  • Authentication: See above
  • Streaming: Not supported

Path parameters:

  • hash (string, required) -- The content hash of the asset

Request headers:

  • Private-Token (string, required) -- API access token
  • canvas-id (string, required) -- UUID of the canvas that contains this asset

Example request:

curl -H "Private-Token: YOUR_TOKEN" \
  -H "canvas-id: 3ad9ece4-28be-4e19-9f9a-1a01a4dbae28" \
  -o original-photo.jpg \
  https://canvus.example.com/api/v1/assets/cbcb439a796b

Response:

Binary file data in the original format. The Content-Disposition header is attachment with no filename, so choose the local file name yourself. The Cache-Control header is set to private, max-age=157680000, immutable.


Error responses

  • 400 Bad Request -- Mipmap level is outside the valid range (less than 0 or greater than max_level)
  • 401 Unauthorized -- Missing or invalid authentication
  • 403 Forbidden -- User is blocked or does not have access
  • 404 Not Found -- No asset exists with the given hash
  • 501 Not Implemented -- The asset type does not support mipmap generation

Current behavior

  • An invalid or expired token returns 403 Forbidden, not 401. See Current behavior.
  • An asset type without mipmap support returns 500 Internal Server Error with {"msg": "Not supported"}, not 501.

These are being corrected.

All errors return a JSON body:

{
  "msg": "error description"
}

Typical workflow

  1. List widgets on a canvas using GET /api/v1/canvases/:canvas_id/widgets
  2. Find an image or PDF widget in the response and note its hash value
  3. Call GET /api/v1/mipmaps/:hash to get the mipmap info (resolution, max level, page count)
  4. Choose the appropriate mipmap level based on your display size
  5. Download the mipmap level with GET /api/v1/mipmaps/:hash/:level
  6. Or download the original file with GET /api/v1/assets/:hash