Designs
A design is a reusable document layout. It is the thing you author once and
generate from many times. Internally a design is a tree of pages and
elements — the shape is defined by the shared pdftreejs library, so the
visual editor, the API, and the renderer all agree on it.
The design tree
- A design has one or more pages.
- Each page holds positioned elements.
- Element types include text, tables, images, QR codes, barcodes, and shapes.
- You place elements with explicit coordinates. Text and table sizes are derived — a text box is measured from its content and font, a table from its grid — so a client can never produce a clipped or sprawling box.
You never hand-write the tree. You build it by issuing actions — small,
validated operations like add_element and bind_variable — and ImaginePDF
applies them to the design.
Authoring with actions
Every change to a design’s structure is an action of the form:
{ "type": "add_element", "args": { /* args for this action */ } }The core model is tree + action → tree: each action does one thing (add
one element, bind one variable), and a request carries an ordered list of them.
They apply sequentially and atomically — if any action fails, nothing is
saved and the error names the failing index.
POST /api/v1/designs— create a design (name + optional description). This allocates the design and returns adesignId; it does not take actions.PATCH /api/v1/designs/:id— apply actions (and/or rename / describe). This is where authoring happens, including the first batch on a new design.
Two conventions to know:
- Ids are server-minted.
add_elementdoes not accept anid; give each element a unique, meaningfulname("title","line_items") and address it by that name in later actions. The minted id (text-cfd23) comes back in the result. - Results echo the derived box. Each
add_elementresult includes the element’s final{ x, y, w, h }— use it to place the next element below.
The full set of available actions and their args schemas comes from the catalog:
curl https://api.imaginepdf.com/api/v1/actions \
-H "X-API-Key: $IMAGINEPDF_API_KEY"{
"status": "success",
"data": {
"actions": [
{ "name": "add_element", "description": "...", "args": { /* schema */ } },
{ "name": "bind_variable", "description": "...", "args": { /* schema */ } }
]
},
"error": null
}Actions are validated server-side by pdftreejs, strictly: unknown keys
are rejected with a message that says the fix — e.g. sending position.w for
a text element returns position.w is not allowed for text — width is derived; use position.maxWidth. See the
Designs API for the per-type position shapes.
Reading a design back
Reads are split by cost. GET /api/v1/designs/:id returns just the
metadata (enveloped):
{
"status": "success",
"data": {
"designId": "design_abc123",
"name": "Invoice",
"description": "Standard invoice template",
"fileSize": 12345,
"createdAt": "2026-06-08T12:00:00Z",
"modifiedAt": "2026-06-08T12:00:00Z"
},
"error": null
}To read the layout itself, GET /api/v1/designs/:id/tree returns the full design
tree as raw JSON (this endpoint is not enveloped — the body IS the tree; its
variables are part of it). See the Designs API.
From design to PDF
A design on its own is just a layout. To get a finished document you generate it — supplying values for any variables. See Variables for how binding works and Generate a PDF for the call.
Related
- Designs API — full endpoint reference.
- Variables — bind elements to named fields.
- Assets — images and logos.