JSON trees
The structured document model that represents every visual element in editable image ads and design templates.
A JSON tree is a Figma-like node hierarchy in JSON. It represents every element in an editable image ad or a design template — frames, text, rectangles, images, and effects.
Mental model
Think of a JSON tree as a small, structured document you can read and mutate. Editable image ads and design templates both produce trees. The fields and node types are the same; the difference is purpose: a design template is the layout blueprint, an editable image ad is the realized creative bound to a brand, product, and audience.
The shared schema lives in the workspace package @sal/json-tree. Public consumers don't need to install it — the API returns standard JSON.
Node types
| Type | Description |
|---|---|
FRAME | Container with layout properties (position, size, auto-layout) |
TEXT | Text content with font, size, color, alignment |
RECTANGLE | Shapes with fills (solid colors, images, gradients) |
EFFECT | Drop shadows, blur, and other visual effects on a node |
Each node has a unique id (UUID). The tree's root is typically a FRAME containing all other nodes.
Common shapes
A text node
{
"id": "2c210453-5a8f-4c41-bcae-604a7994e223",
"type": "TEXT",
"characters": "The GOAT of leggings",
"fontSize": 48,
"fontFamily": "Inter",
"fills": [{ "type": "SOLID", "color": { "r": 0, "g": 0, "b": 0, "a": 1 } }]
}An image rectangle
{
"id": "ac39635c-cd64-42ec-a420-da71ee472cb5",
"type": "RECTANGLE",
"fills": [
{
"type": "IMAGE",
"imageFillUrl": "https://cdn.example.com/lifestyle.jpg"
}
]
}Mutating a tree
Two paths:
node_overridesat creation time — pass{ [nodeId]: { characters | imageFillUrl } }inPOST /v1/image-ads. Simpler. Use when you know what to override before generation.PATCH /v1/image-ads/:idwith the full updatedcurrent_json_tree. Use after generation, especially when iterating in an editor.
Always send the entire tree on PATCH, not a diff.
Image rules
JSON trees never embed raw image bytes. Image fills carry a public URL (imageFillUrl). When you need to swap an image:
- Upload the binary first via
POST /v1/images(multipart) and use the returnedsrcURL, OR - Provide your own publicly-accessible URL.
Base64 in JSON is rejected.
Endpoints
JSON trees are part of the Image ads and Design templates resources. There are no standalone JSON tree endpoints.
Pitfalls
- The tree is large for typical ads (a few KB to ~100 KB). Don't log the full tree in production.
- Node IDs are stable across versions of the same ad — use them to track "the headline node" reliably.
- The shape evolves. Treat unknown fields as "preserve as-is" rather than failing on them.
Related
Prompt for your agent
Read https://www.staticadslab.com/docs/resources/json-trees.mdx and write a helper findTextNodeByCharacters(tree, query) that returns the node whose characters include the query string.