A tab's elements change through changesets, but a canvas holds more than elements: the images it shows, pictures of its tabs, copies of it. Each has its own endpoints, shown here with curl. The examples assume your API token is in $TOKEN and a canvas id in $DOC; paths are relative to https://livediagram.app/api, and /api/openapi.json has every field.
Every write here reaches anyone with the canvas open straight away, credited to you.
Images
Upload the raw bytes of a PNG, JPEG, WebP or GIF, up to 10 MB, with its pixel size in two headers:
curl -X POST https://livediagram.app/api/images \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: image/png" \
-H "X-Image-Width: 1200" -H "X-Image-Height: 800" \
-H "X-Image-Original-Name: architecture.png" \
--data-binary @architecture.png
{
"image": {
"id": "9f2c…",
"contentType": "image/png",
"byteSize": 48211,
"width": 1200,
"height": 800,
"originalName": "architecture.png",
"createdAt": 1760180000000
},
"deduped": false
}
Uploading the same bytes again answers the image you already have, with "deduped": true. Then put it on a tab with a changeset that adds a whole image element:
curl -X POST https://livediagram.app/api/documents/$DOC/tabs/$TAB/changesets \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{ "operations": [ { "op": "add", "element": { "type": "image", "imageId": "'"$IMAGE"'", "x": 0, "y": 0, "width": 600, "height": 400, "naturalWidth": 1200, "naturalHeight": 800, "alt": "Architecture overview" } } ] }'
GET /images lists your uploads, GET /images/usage maps each to the canvases that use it, GET /images/{id} downloads one, and DELETE /images/{id} removes it from your gallery. Refusals are 415 unsupported_type, 413 file_too_large, and on a host that sets a gallery limit, 403 gallery_full.
A Tab as a Picture
curl https://livediagram.app/api/documents/$DOC/tabs/$TAB/render.svg \
-H "Authorization: Bearer $TOKEN" -o overview.svg
The tab drawn by the same renderer the CLI's tab render and pull --svg use, as image/svg+xml, with images inlined when the host stores them. It is never cached, so it always shows the tab now. For an image to embed somewhere public, use a live image instead.
Copy a Canvas
curl -X POST https://livediagram.app/api/documents/$DOC/copy \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{ "name": "Service map (2027 draft)" }'
Makes a copy in your own files and answers 201 with the new document. Leave out name for Copy of <name>. Anything you can read can be copied; share links are not copied with it.
Shape Libraries
Your shape libraries belong to you, not to a canvas.
# A shape library: each item is a reusable shape, its elements placed from its top-left corner
curl -X POST https://livediagram.app/api/shape-libraries \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{ "id": "'"$(uuidgen)"'", "name": "Network kit", "source": "drawio",
"items": [ { "id": "'"$(uuidgen)"'", "title": "Router", "width": 120, "height": 60,
"elements": [ { "id": "r1", "type": "shape", "shape": "square", "x": 0, "y": 0, "width": 120, "height": 60, "label": "Router" } ] } ] }'
A library holds up to 1,000 items and you can keep 100; a name you already use gets a number added. PUT /shape-libraries/{id} renames one or replaces its items, and DELETE removes it (shapes already placed stay in their canvases). GET /shape-libraries lists yours.
Was this article helpful?