Images, Pages and More

Worked examples for the rest of a design: images, pages, pictures of a tab and copies.

A tab's elements change through changesets, but a design holds more than elements: the images it shows and its pages. Each has its own endpoints, shown here with curl. The examples assume your API token is in $TOKEN and a design id in $DOC; paths are relative to https://livedesign.app/api, and /api/openapi.json has every field.

Every write here reaches anyone with the design 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://livedesign.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://livedesign.app/api/designs/$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 designs 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 403 gallery_full once your gallery holds 100 images or 100 MB, counted across every liveworkspace app.

Pages

POST /designs/$DOC/tabs/$TAB/pages changes a tab's pages, up to 50 changes as one edit. A locked tab is refused.

# Add a logo page and a phone wireframe, then rename the first page
curl -X POST https://livedesign.app/api/designs/$DOC/tabs/$TAB/pages \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{ "pages": [
    { "op": "add", "kind": "logo", "name": "Mark" },
    { "op": "add", "kind": "wireframe", "device": "iphone", "name": "Sign in" },
    { "op": "set", "page": 1, "name": "Cover" }
  ] }'

A page change is add (a kind of logo, wireframe or photo, with an optional name, background, layout and at; a wireframe takes its device, frameLook and systemBars, and a photo its width and height in pixels, 1920 x 1080 when left out), set, layout, move, duplicate, delete or apply_background_to_all; a page is named by its id, its place in the row (from 1) or its name. The answer lists every page with its rectangle on the canvas, which is where a changeset puts elements to land them on that page.

A Tab as a Picture

curl https://livedesign.app/api/designs/$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 Design

curl -X POST https://livedesign.app/api/designs/$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 design. Leave out name for Copy of <name>. Anything you can read can be copied; share links are not copied with it.

Was this article helpful?