Variables allow you to inject dynamic content into your documents. Define variables in the top-level variables object and reference them using {{varName}} syntax in text or via variableRef elements.
Alternative syntax for integrations: The API also accepts ${varName} as an alternative to {{varName}} on input. This is useful when working with automation platforms like Make.com, Zapier, or n8n whose template engines conflict with the {{...}} syntax. Both forms are normalized to {{...}} internally. API responses always use {{...}}.
Important for Bulk Rendering: When using the Bulk Render endpoint, all variables that you want to override per row must be pre-defined in the variables block of your document JSON. The bulk render only substitutes variables that already exist in the document — it does not create new ones. If a variable is only used inline in text (e.g., {{companyName}}) but not declared in variables, it will not be replaced during bulk generation.
Defining variables
The variables object is a key-value map where each key is the variable name and the value defines the content.
Variable names must:
- Start with a letter (
a-z, A-Z)
- Contain only letters, digits, and underscores
- Be at most 50 characters long
{
"variables": {
"companyName": "Acme Inc",
"invoiceDate": "2024-01-15",
"totalAmount": { "type": "number", "value": 1250.00 },
"logo": { "type": "image", "src": "https://example.com/logo.png", "width": 200, "align": "center" },
"features": { "type": "list", "items": ["Fast", "Reliable", "Secure"], "ordered": false },
"pricing": {
"type": "table",
"columns": ["Plan", "Price", "Features"],
"data": [
["Starter", "$9/mo", "Basic features"],
["Pro", "$29/mo", "All features"]
]
}
}
}
Variable types
Text variable
A simple string value. Referenced via {{varName}} in any text content (headings, paragraphs, list items, table cells, header/footer).
{
"companyName": "Acme Inc",
"invoiceDate": "2024-01-15"
}
| Property | Type | Constraints |
|---|
| (value) | string | Max: 1000 characters. Empty strings are allowed. |
Usage in text:
{ "type": "text", "text": "Invoice for {{companyName}}, issued on {{invoiceDate}}." }
Text variable substitution works in all text content: element text, list items, table cells, and header/footer strings.
Number variable
A numeric value. Can be referenced via {{varName}} in text (rendered as string) or via a variableRef element. Useful for charts, calculations, and dynamic numeric content.
{
"totalAmount": { "type": "number", "value": 1250.00 },
"itemCount": { "type": "number", "value": 42 }
}
| Property | Type | Required | Description |
|---|
type | string | Yes | Must be "number" |
value | number | Yes | Numeric value (integer or decimal) |
Usage in text:
{ "type": "text", "text": "Total: {{totalAmount}} EUR" }
Number variables are automatically converted to strings when used in {{varName}} text substitution. When rendered via variableRef, they produce a text element.
Image variable
An image with optional dimensions and alignment. Must be referenced via a variableRef element or {{varName}} in a table cell.
{
"logo": {
"type": "image",
"src": "https://example.com/logo.png",
"width": 200,
"height": 80,
"align": "center",
"caption": "Company Logo"
}
}
| Property | Type | Required | Description |
|---|
type | string | Yes | Must be "image" |
src | string | Yes | Image URL. Supports uploaded image paths (/image/...) or public HTTP/HTTPS URLs. Max: 500 chars. |
width | number | No | Image width in pixels (10–2000) |
height | number | No | Image height in pixels (10–2000) |
align | string | No | Image alignment: "left", "center", "right". Default: "left" |
caption | string | No | Caption text for figure numbering. Max: 200 chars. |
List variable
An ordered or unordered list of string items.
{
"features": {
"type": "list",
"items": ["Fast rendering", "Multiple formats", "Template variables"],
"ordered": false
}
}
| Property | Type | Required | Description |
|---|
type | string | Yes | Must be "list" |
items | string[] | Yes | Array of list item strings. Max: 100 items, 1000 chars each. Empty arrays are allowed. |
ordered | boolean | No | true = numbered list, false = bullet list (default) |
Table variable
A 2D data array with optional named columns. Can be used with variableRef or bound to a table element via dataSource.
{
"pricing": {
"type": "table",
"columns": ["Plan", "Price", "Features"],
"data": [
["Starter", "$9/mo", "Basic features"],
["Pro", "$29/mo", "All features"],
["Enterprise", "Custom", "Everything + support"]
]
}
}
| Property | Type | Required | Description |
|---|
type | string | Yes | Must be "table" |
columns | string[] | No | Column keys for named access. Max: 20 columns, 50 chars each. |
data | string[][] | Yes | 2D array of cell values. Max: 100 rows, 20 columns, 1000 chars per cell. Empty arrays are allowed. |
Referencing variables
Inline text substitution
Use {{varName}} anywhere in text content. Text variables (strings) and number variables are substituted inline. Number values are automatically converted to their string representation. Non-text/non-number variables and undefined references are left as-is.
{
"sections": [{
"type": "flow",
"content": [
{ "type": "h1", "text": "Invoice for {{companyName}}" },
{ "type": "text", "text": "Date: {{invoiceDate}}" }
]
}]
}
Variable substitution also works in:
- List items (both string items and
text property of object items)
- Table cells (both string cells and
text property of object cells)
- Header/footer content (both simple strings and rich text
content arrays)
variableRef element
The variableRef element renders a variable as a full content element. The rendering type is determined automatically by the variable’s type:
- Text variable → rendered as a
text element
- Number variable → rendered as a
text element (value converted to string)
- Image variable → rendered as an
image element (with alignment if specified)
- List variable → rendered as a
list element
- Table variable → rendered as a
table element (columns become headers, data becomes rows)
{
"type": "variableRef",
"variable": "logo",
"spacing": { "before": 10, "after": 10 }
}
| Property | Type | Required | Description |
|---|
type | string | Yes | Must be "variableRef" |
variable | string | Yes | Variable name. Must match a key in the variables block. Pattern: ^[a-zA-Z][a-zA-Z0-9_]*$, max: 50 chars. |
spacing | object | No | Spacing override with before and after in pt (0–100). |
If the referenced variable does not exist, the variableRef element is silently removed from the output.
Table dataSource binding
Table elements can bind to a table variable via the dataSource property instead of defining rows inline. Use mapping to select and reorder columns.
{
"variables": {
"employees": {
"type": "table",
"columns": ["name", "department", "email", "salary"],
"data": [
["Alice", "Engineering", "alice@example.com", "$120k"],
["Bob", "Marketing", "bob@example.com", "$95k"]
]
}
},
"sections": [{
"type": "flow",
"content": [{
"type": "table",
"headers": ["Name", "Department"],
"dataSource": "employees",
"mapping": ["name", "department"]
}]
}]
}
| Property | Type | Required | Description |
|---|
dataSource | string | No | Variable name of a table variable. Pattern: ^[a-zA-Z][a-zA-Z0-9_]*$ |
mapping | string[] | No | Column keys to select from the table variable. Order determines column order. Max: 20 items. |
When mapping is provided, only the specified columns (matched by name against columns in the table variable) are included. Without mapping, all data columns are used as-is.
Image variables in table cells
When a table cell contains exactly one variable reference ({{varName}}) that resolves to an image variable, the cell is automatically rendered as an image instead of text.
{
"variables": {
"checkmark": { "type": "image", "src": "https://example.com/check.png", "width": 20, "height": 20 }
},
"sections": [{
"type": "flow",
"content": [{
"type": "table",
"headers": ["Feature", "Included"],
"rows": [
["PDF Export", "{{checkmark}}"],
["DOCX Export", "{{checkmark}}"]
]
}]
}]
}
Built-in variables
The following variables are always available and do not need to be defined:
| Variable | Description |
|---|
{{pageNumber}} | Current page number |
{{totalPages}} | Total number of pages in the document |
These are especially useful in header/footer configurations:
{
"defaults": {
"footer": {
"right": "Page {{pageNumber}} of {{totalPages}}"
}
}
}
Defaults for variables
There are no global default styles specific to variables. However, the rendered output of variableRef elements inherits the global defaults for the respective element type:
- Text variables inherit
defaults.styles.text and defaults.fontSize, defaults.fontFamily, etc.
- Number variables inherit the same defaults as text variables (rendered as text)
- Image variables inherit default image spacing from
defaults.spacing
- List variables inherit default list spacing
- Table variables inherit
defaults.styles.table for styling