data against it. Anything not in the
manifest is stripped before the render runs — so a key that does not bind is silently dropped,
not rejected.
Scalar variables nest by dot-path
A scalar variable key with dots nests into an object. Declaringcustomer.name and
customer.email means you send:
dataType rules are in Concepts. Note that image and url accept
http(s) URLs only — see Images & signatures.
Select variables (fixed choices)
Aselect variable restricts a field to a fixed set of choices. It carries an options array of
{ value, label } — value is what you send in data (and what is validated), label is display
text. A select requires a non-empty options array at publish time (POST/PUT /v1/templates
reject a select with no options); option values must be unique, and a defaultValue, if set, must
be a string equal to one of them.
value — anything else fails with
invalid_input_data, and the generated JSON Schema emits the field as a string enum of the option
values. options is optional and only meaningful for select, so clients that ignore it are
unaffected.
Loops bind arrays of objects
A loop iterates an array of objects. Each loop declares:string
required
The top-level key your array is sent under. Must be dot-free — see the rule below.
string
required
Human-readable label.
VariableDefinition[]
required
The shape of each row (at least one field). Each field is a normal typed variable.
object[]
Up to 10 sample rows for the builder preview.
data,
keyed by the loop key:
The loop-key rule
This rule applies to both the runtime validator and the JSON Schema returned by
GET /v1/templates/:slug. Recommendation: give every loop a
flat, dot-free key (areas, lineItems, passengers) and keep your scalars under their own
namespaces (booking.*, handover.*). Mixing a handover.* scalar namespace with a
handover.areas loop is the exact shape that silently fails.