Any .json file not named form.json, autocomplete.json, or presets.json uses this format (project.ypf doesn't count here - it isn't a .json file) - referenced from process.js via overlay(filename[, page]). No special significance of its own; a project with no process.js composites nothing.

{
  "blocks": [
    { "id": "dealer_name", "type": "text", "text": "{dealer_name}", "x_mm": 10, "y_mm": 10, "width_mm": 80, "height_mm": 8 }
  ]
}

Common block keys

Key Required Type Meaning
id yes string Unique across every partial included in one generation run.
type yes string text | image | box | scanCode | grid | pdf | overlay.
x_mm / y_mm yes number Top-left corner, mm from the page's top-left.
width_mm / height_mm yes number Bounding box, mm.
condition no string Bare expression (no {...} wrapper), evaluated by a restricted arithmetic/comparison engine - not full JavaScript, no method calls. Falsy hides the block.
z_index no int Default 0. Higher paints on top.
rotation_deg no number Default 0. Content-only rotation around the block's own center - never affects x_mm/y_mm/width_mm/height_mm.
scale_x / scale_y no number Default 1. Content-only scale around the block's own center, applied before rotation. Negative flips the content; magnitude != 1 stretches it.

There is no page key - the overlay(filename, page) call that included this file decides that.

Color values. Every key below marked "Hex or ref" takes a plain string, either "#RRGGBB" or "inputs:field_id" - the latter resolves that field's (or one of the five My Details color fields') value at generation time. An unresolved/invalid reference falls back to black.

text

Key Required Type Meaning
text no string Template: literal text, or {...}-wrapped real JavaScript for anything dynamic. A bare field name ({sale_price}) resolves directly. \n wraps as a multi-line paragraph.
style.font_size no number Default 12.
style.font_weight no string normal* | bold.
style.font_family no string See Assets Overview.
style.color no Hex or ref Default #000000. No background-fill style - layer a box block underneath instead.
style.align / style.valign no string left*/top* | center | right/bottom | stretch | justify (align only, only meaningful with wrap: true). stretch is ignored once wrap is true.
style.overflow no string visible* | hide.
style.wrap no boolean Default false. Real word-wrap instead of single-line/manual-\n rendering - trades away pixel-exact positioning and stretch for it.
style.stroke_width / stroke_color / stroke_style no number/Hex or ref/string Glyph outline, in points. stroke_style: inside | middle* | outside.

image

Key Required Type Meaning
source no string "assets:filename.png" - path relative to the project folder. Or "inputs:field_id" - field id, value is a file path. Works the same whether the field is an image-type field (a photo picker), a signature-type field, or a drawing-type field (a captured signature/drawing is written to a file the same way). A drawing field's own background_asset is never part of its submitted value - to show that reference image too, add a separate image block with source: "assets:..." pointing at the same file, positioned to match, with the drawing field's own block layered on top.
fit no string contain* | cover | stretch. fill is an older spelling of stretch, still accepted when reading.
align / valign no string left | center* | right and top | center* | bottom. Under fit: contain, positions the image within its box. Under fit: cover, acts as a crop anchor instead - left/top keeps that edge flush, cropping the opposite edge's overflow. No effect under stretch.
filters no string CSS-flavored filter chain, e.g. grayscale() contrast(120%) colorize(#ff0000). See Image Filters.

A missing asset or unfilled field omits the block, not an error.

box

Key Required Type Meaning
fill_color / stroke_color no Hex or ref Omitted for none.
stroke_width_mm no number Default 0.
corner_radius_mm no number Default 0, independent of stroke.
stroke_style no string inside | middle* | outside.

scanCode

Key Required Type Meaning
data no string Same template syntax as text.
format no string qr_code* or any barcode symbology the app supports.
color / background_color no Hex or ref Module color / optional fill.
show_value no boolean Human-readable text under the code. Default false.

Always rendered centered - QR/2D formats render square, 1D barcodes as a wide strip.

grid

Key Required Type Meaning
columns yes int Cells per row.
data no string Bare JS expression evaluating to an array. See Grid.
column_widths no array Weight (number), "20mm", or "30%" per column.
min_rows / max_rows no int No default bound.
source_field / column_keys no string / array Declarative alternative to data.

style (grid default) and a per-cell object share these keys (real CSS names, hyphenated):

Key Meaning
background-color, color, font-family, font-size (default 11), font-weight Cell text styling. background-color/color are Hex or ref.
padding mm. Default 1.
text-align / vertical-align left*/middle* defaults.
border-color / border-width border-color is Hex or ref. Grid-level: outer table border. Per-cell: that cell gets its own border box instead of the shared line.
border-horizontal-color / border-vertical-color Hex or ref. Interior row/column separator lines, grid-level. Per-cell: overrides that direction's own border color (no per-cell -width counterpart - the cell's own border-width covers both directions).
min-height mm floor on a cell's height.

Row height is content-driven and never clips to height_mm; a grid never splits across pages.

pdf

Key Required Type Meaning
source yes string "assets:filename.pdf" (page 1) or "assets:filename.pdf:3" (page 3) - path relative to the project folder, optionally with a page number. Or "inputs:field_id" - swaps in whatever assets:...[:page] value that key in inputs resolves to, typically set by process.js itself (there's no form field type that captures a PDF file).
fit no string contain* | cover | stretch.
overflow no string visible* | hide. Only has a visible effect under fit: cover - contain/stretch never exceed their box.

Renders one page of another PDF file as block content - a simpler alternative to composing a whole page in JSON. The Overlay Editor's Properties panel has an Auto Size button that sets width_mm/ height_mm to that page's own real size.

overlay

Key Required Type Meaning
overlay yes string Path to another layout partial, relative to the project folder.
overflow no string visible* | hide. Unconditional here (no fit concept - nested content always renders at its own native size).

Places another partial's own blocks as one unit, positioned/rotated/ scaled like any other block - the visual alternative to a hand-written overlay() call in process.js for a sub-layout repeated at several positions. The referenced file's own bounding-box top-left lands at this block's x_mm/y_mm; rotation_deg/scale_x/scale_y rotate/scale the whole placed group as one rigid unit. Can nest (a referenced file can itself contain overlay blocks), up to 10 levels deep - deeper, or a file that circularly references itself, fails generation with an error naming the loop. The Overlay Editor's Properties panel has the same Auto Size button as pdf, computing the union bounding box of the referenced file's own blocks instead of a PDF page's size.

Constraints

Every block id must be unique across every partial actually included in one generation run.