Some test text!

Hamburger Icon

Core / Guides / Data Model

Document Generation Data Model

General principles

  • Each document will have one or more template keys, denoted by the {{ start tag, and }} closing tag -- these are often referred to as "moustache templates" (turn the { around 90 degrees, and it looks like a moustache...).
  • The API should be supplied with a json dictionary, where each template key within the document is a property within the dictionary. The value associated with each key can take a number of forms, as described below.
  • There are a number of error conditions for invalid template documents and invalid JSON. These errors will cause an exception to be thrown with a descriptive message.

To see templates in practice check out this list of examples .

This data model will be expanded going forward in order to meet customer needs. If you require a specific feature, or don't believe that the current template framework can meet your needs, then please contact us.

Format for content values

Text String

Can be one of:

  • Simple string: "key":"Value Text"
  • A JSON object with the text property: "key": {"text": "Value Text"}
  • A JSON object with the text_lines property: "key": {"text_lines": ["Line 1", "Line 2"]}. The inserted text strings will be separated by line breaks.


An image value is a JSON dictionary with the following required properties:

  • image_url: [string] On web systems this can be a URL, on server/desktop systems it is expected to be a local filesystem path (absolute, or relative to the process working directory).
  • width: [number] Image width, in points (this is the physical width in the document, not the number of pixels)
  • height: [number] Image height, in points (this is the physical height in the document, not the number of pixels)

Take a look at the image insertion example to see this in practical usage.

Structured input

Structured input inserts document content that is more powerful that simple text replacement. It supports dynamic document structure, formatting, and styling. To insert structured input, use a JSON dictionary with one of the following properties:

  • html: [string] HTML input or
  • markdown: [string] Markdown input

Not all features of html and markdown are supported, for more information please see: structured input


The JSON data can also be organized into objects. The tag {{a.b}} will retrieve the value of property b in object a: {"a": {"b": "value"} }.


Loops can be used to repeat content in a document and fill in unique data for each repetition. A Loop over the key var is created using the syntax
{{loop var}} ... {{endloop}}:

The corresponding JSON value for the loop key must be an array of objects. The loop body is duplicated for each item in the array, and the tags in the body of the loop use values that are overridden by the JSON object in each iteration of the loop. Example JSON:

    "var": [
        {"item": "First iteration."},
        {"item": "Second iteration."}


Loops can be nested and combined with conditionals.

List Loops

To generate a bulleted or numbered list with dynamic content, you can create a list loop as follows:

  1. The {{loop}} tag must be within an item of the list.
  2. The {{endloop}} tag must be within a different item of the list.


The JSON for list loops uses the same format as normal loops. Note: If there is any extra text (including whitespace) in the {{loop}} or {{endloop}} list items, those items will not be removed. For more details, see: content removal .

Table Row Loops

To generate a table with dynamic row content, add a table in the template document with the desired column structure, following the constraints:

  1. The {{loop}} tag must be in the first column.
  2. The {{endloop}} tag must be in the last column (if the table only has one column, it can't be in the same cell as the {{loop}} tag, otherwise it would loop within the cell, so place the {{endloop}} tag in the next row).


The JSON for tables row loops uses the same format as normal loops.


Conditionals can be used to conditionally include content in a document. A conditional on the key cond is created using the syntax
{{if cond}} ... {{endif}}:

The JSON value corresponding to the condition key (cond here) is converted to a boolean. It is evaluated as false when either:

  • The key is not present in the JSON
  • The value is false, "", 0, or null

If the evaluated value is false, the conditional's body is removed.

Conditionals can also have an {{else}} clause:

The else clause body will be removed if and only if the condition evaluates to true.


Tag expressions can also use operators. There are currently four operators:

  1. <expr>.<key>: evaluates expr (must evaluate to a JSON object), then returns the property given by "key". "key" is limited to alphanumeric characters.
  2. not(<expr>): evaluates expr, converts it to a boolean, and inverts the result.
  3. equal(<expr>, <expr>): evaluates each expression and returns true if they have the same value. Template keys can be compared to strings by using a string literal enclosed in single or double quotes. For example: equal(country, 'United States').
  4. empty(<expr>): evaluates expr (must evaluate to a JSON array), and returns if the array is empty.

These operators can also be used in combination. For example:
{{if not(equal(customer.first_name, 'Paul'))}}.

Further Reading

For more information, see the following resources:

Advanced features
For a specification of advanced features, and greater detail on behavior

Live Web Sample
To try a live sample of template filling using our WebViewer

Structured input
For inserting dynamic content using html or markdown

Get the answers you need: Chat with us