---
title: "Document generation"
url: "https://docs.signnow.com/docs/document-generations"
type: "page"
section: "Documentation"
slug: "document-generations"
---

# Document generation

# Document generation

Generate pre-filled PDF documents from DOCX templates with tags using SignNow API.

**Tags** are placeholders you add to a DOCX template. Tags serve two purposes:

- **Pre-fill the document with data** — tags are automatically replaced with values from a CRM, ERP, database, or other source. The size of each tag adjusts to fit the inserted content, giving the document a uniform appearance and making it dynamic.
- **Add fillable fields** — tags are rendered as highlighted rectangular areas where recipients can enter their own data, such as a signature, initials, or text.

Once a document has been generated from a DOCX template, tags are automatically replaced with the corresponding values or rendered as fillable fields, depending on their type.

## How it works

### Step 1. Create a DOCX template with tags

Add tags directly to your DOCX file to define where data should be inserted or where recipients should fill in information.

> For tag names (the text inside {{}}), only letters, numbers, dots, and underscores are allowed. Tag names should not contain spaces, should not start with a number or a dot, and should not end with a dot.

### Supported tags

| Tag | Syntax example | Usage | Data input |
| --- | --- | --- | --- |
| **Text** | `{{TagName}}` | Inserts text, a number, or a date. Tag names don't need to be unique — multiple tags with the same name are all populated with the same value. | `"TagName": "value"` |
| **If** | `{{if(ConditionFieldName='Value1')}}`<br>Output 1<br>`{{else(ConditionFieldName='Value2')}}`<br>Output 2 <br>`{{endif}}` | Shows or hides paragraphs based on a condition. Must be unique per document. | Not required |
| **for** | `{{for(ListName)}}` <br>`{{ListItem1Name}}`<br>`{{ListItem2Name}}`<br>`{{endfor}}` | Inserts a list with a dynamic number of items. Must be unique per document. | `"ListName": [{"ListItem1Name": "value", "ListItem2Name": "value"}]` |
| **table** | `{{table(TableName)}}`<br>`{{ColumnField1}}`<br>`{{ColumnField2}}`<br>`{{endtable}}` | Inserts a table with a dynamic number of rows. Must be unique per document. | `"TableName": [{"ColumnField1": "value", "ColumnField2": "value"}]` |
| **System variables**\* | `{{numFormat(TagName,'$#,###.00')}}`<br>`{{numFormat(TagName*TagName2,'$#,###.00')}}`<br>`{{$sumabove}}`<br>`{{$total}}`<br>`{{$today}}` | `numFormat` — formats a numeric value or expression with a number format and currency symbol. <br>`$sumabove` — calculates the sum of all numeric values in the cells above this tag in the same table column. <br>`$total` — assigns a value to a variable for use elsewhere in the document, for example in conditional logic. <br>`{{$today}}` – inserts the current date automatically in `MM-DD-YYYY` format. | Not required |

\* This is not a complete list of system variables.

<!-- theme: info -->
> **Quotes in `numFormat`:** The API accepts straight quotes in the format pattern, as shown above. Integration apps might require a different format: in the SignNow apps for Salesforce and HubSpot, the pattern must use Word-style curly quotes, for example `{{numFormat(TotalPrice, ‘$#,###.00’)}}`. Check the guide for your integration.

### Fillable field tags

| Field type | Tag syntax | Notes |
| --- | --- | --- |
| Text field | `{{t:t;r:y;o:"Role name";w:100;h:15;}}` | `t:t` — text field; `r:y` — required; `o` — recipient role name; `w` — width; `h` — height. |
| Signature | `{{t:s;r:y;o:"Role name";w:100;h:15;}}` | `t:s` — signature field; `r:y` — required; `o` — recipient role name; `w` — width; `h` — height. |
| Initials | `{{t:i;r:y;o:"Role name";w:100;h:15;}}` | `t:i` — initials field; `r:y` — required; `o` — recipient role name; `w` — width; `h` — height. |
| Dropdown | `{{t:d;r:y;o:"Role name";w:100;h:15;dd:"Option1, Option2, Option3";}}` | `t:d` — dropdown field; `r:y` — required; `o` — recipient role name; `w` — width; `h` — height; `dd` — comma-separated list of options. |
| Checkbox | `{{t:c;r:y;o:"Role name";w:100;h:15;}}` | `t:c` — checkbox field; `r:y` — required; `o` — recipient role name; `w` — width; `h` — height. |
| Date | `{{t:t;r:y;o:"Role name";w:100;h:15;v:"13435fa6c2a17f83177fcbb5c4a9376ce85befeb";}}` | `t:t` — text field with date validation; `r:y` — required; `o` — recipient role name; `w` — width; `h` — height; `v` — validator ID for the date format (MM/DD/YYYY). |

Both single-brace `{...}` and double-brace `{{...}}` syntax are supported for fillable field tags. For example, `{t:s;r:y;o:"Role name";w:100;h:15;}` and `{{t:s;r:y;o:"Role name";w:100;h:15;}}` are equivalent. All other tags must use double braces.

Learn more about [tags for fillable fields](/docs/text-tags).

### Step 2. Call the API

Use one of the following endpoints to pre-fill the DOCX template with data:

- [`POST /v2/document-generations/url`](/docs/document-generation/operations/post-v2-document-generations-url) — provide a publicly accessible URL to the DOCX file with tags.
- [`POST /v2/document-generations/upload`](/docs/document-generation/operations/post-v2-document-generations-upload) — upload the DOCX file with tags directly.

The `data` object in the request payload maps tag names to their values.

The generated document appears in your SignNow account, where you can send it for signature.

The following sections walk through each supported tag type with DOCX template examples, data object examples, and generated document screenshots.

---

## Generate a pre-filled document

Use **text tags** (`{{TagName}}`) to insert individual values such as names, dates, or numbers.


<!--
type: tab
title: DOCX template
-->
<!--
focus: center
bg: "#FAF0E6"
-->
![docx_tags.png](/reference-assets/images/Document_generation/docx_tags.png)


<!--
type: tab
title: data object example
-->

```json
{
  "data": {
    "CompanyName": "Acme Corp",
    "CompanyAddress": "123 Main St, New York, NY 10001",
    "InvoiceNumber": "INV-2026-0042",
    "CustomerName": "Jane Smith",
    "CustomerAddress": "456 Oak Ave, Los Angeles, CA 90001"
  }
}
```

<!--
type: tab
title: Generated document
-->
<!--
focus: center
bg: "#FAF0E6"
-->
![docx_prefilled.png](/reference-assets/images/Document_generation/docx_prefilled.png)

<!-- type: tab-end -->

> `$today` is a system tag — it auto-populates with the current date in `MM-DD-YYYY` format and doesn't need to be included in the `data` object. The fillable fields `Sales Manager signature` and `Sales manager` are completed by the recipient after the document is sent for signing.


The example above covers the simplest case — inserting individual values into a document. SignNow document generation also supports more complex scenarios: dynamic tables and lists, and nested structures. The sections below walk through each case.

---

## Generate a dynamic table

Use the **`table` tag** to generate a table with a dynamic number of rows.

In the DOCX template, wrap the row content between `{{table(TableName)}}` and `{{endtable}}`. Each tag in a table cell maps to a key in the `data` object.

In the `data` object, the table tag name becomes the key for an array of objects. Each object represents one row, with keys matching the column tag names. The generated table contains as many rows as there are objects in the array.

`ItemName`, `ItemPrice`, and `ItemQuantity` are the names of the column tags.

> You can use formulas to calculate values across columns. To build a multiplication formula, insert the tag names you want to multiply inside `{{}}` with an asterisk `*` between them — for example, `{{ItemPrice*ItemQuantity}}` outputs the product of those two values in the generated document.

<!--
type: tab
title: DOCX template
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![simple_table_tags.png](/reference-assets/images/Document_generation/simple_table_tags.png)


<!--
type: tab
title: data object example
-->

```json
{
  "data": {
    "Products": [
      {
        "ItemName": "T-shirt",
        "ItemPrice": "8",
        "ItemQuantity": "10"
      },
      {
        "ItemName": "Belt",
        "ItemPrice": "4",
        "ItemQuantity": "5"
      },
      {
        "ItemName": "Dress",
        "ItemPrice": "20",
        "ItemQuantity": "2"
      }
    ]
  }
}
```

<!--
type: tab
title: Generated document
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![simple_table_prefilled.png](/reference-assets/images/Document_generation/simple_table_prefilled.png)

<!-- type: tab-end -->

---

## Generate a dynamic list

Use the **`for` tag** to generate a list with a dynamic number of items.

In the DOCX template, wrap the list item content between `{{for(ListName)}}` and `{{endfor}}`. You can also combine text tags outside the loop with list tags inside it.

In the `data` object, the `for` tag name becomes the key for an array of objects. Each object represents one list item.

<!--
type: tab
title: DOCX template
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![list_tags.png](/reference-assets/images/Document_generation/list_tags.png)

<!--
type: tab
title: data object example
-->

```json
{
  "data": {
    "ManagerFullName": "Jane Smith",
    "Clients": [
      {
        "ClientFullName": "Robert Brown",
        "DateofInvoice": "01/03/2026"
      },
      {
        "ClientFullName": "Emily Carter",
        "DateofInvoice": "05/03/2026"
      },
      {
        "ClientFullName": "Michael Torres",
        "DateofInvoice": "10/03/2026"
      }
    ]
  }
}
```

<!--
type: tab
title: Generated document
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![list_prefilled.png](/reference-assets/images/Document_generation/list_prefilled.png)

<!-- type: tab-end -->

---

## Generate a table with a nested table

You can nest a **table tag** inside another table tag to generate a table where each row contains its own inner table.

In the DOCX template, place the inner `{{table(InnerTableName)}}...{{endtable}}` block inside a cell of the outer table. Each outer row can have a different number of inner rows.

In the `data` object, each object in the outer array contains its own nested array that drives the inner table.

<!--
type: tab
title: DOCX template
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![table_nested_tags.png](/reference-assets/images/Document_generation/table_nested_tags.png)


<!--
type: tab
title: data object example
-->

```json
{
  "data": {
    "Employees": [
      {
        "EmployeeFullName": "Sarah Collins",
        "Tasks": [
          {
            "TaskName": "Prepare Q2 campaign report",
            "TaskDeadline": "15/04/2026",
            "TaskPriority": "High"
          },
          {
            "TaskName": "Review social media strategy",
            "TaskDeadline": "20/04/2026",
            "TaskPriority": "Medium"
          }
        ]
      },
      {
        "EmployeeFullName": "David Marsh",
        "Tasks": [
          {
            "TaskName": "Fix authentication bug",
            "TaskDeadline": "10/04/2026",
            "TaskPriority": "High"
          },
          {
            "TaskName": "Write unit tests for payment module",
            "TaskDeadline": "18/04/2026",
            "TaskPriority": "Medium"
          }
        ]
      }
    ]
  }
}
```

<!--
type: tab
title: Generated document
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![table_nested_prefilled.png](/reference-assets/images/Document_generation/table_nested_prefilled.png)

<!-- type: tab-end -->

---

## Generate a table with a nested list

You can place a **for tag** inside a table cell to generate a list within each table row.

In the DOCX template, add the `{{for(ListName)}}...{{endfor}}` block inside a cell of the `{{table(TableName)}}...{{endtable}}` structure. The other cells in the same row use regular column tags.

In the `data` object, each object in the outer table array contains its own nested array that drives the list inside that row's cell.

<!--
type: tab
title: DOCX template
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![table_nested_list_tags.png](/reference-assets/images/Document_generation/table_nested_list_tags.png)

<!--
type: tab
title: data object example
-->

```json
{
  "data": {
    "Employees": [
      {
        "FullName": "Sarah Collins",
        "Department": "Marketing",
        "Position": "Campaign Manager",
        "Tasks": [
          {
            "TaskName": "Prepare Q2 campaign report",
            "TaskDeadline": "15/04/2026",
            "TaskPriority": "High"
          },
          {
            "TaskName": "Review social media strategy",
            "TaskDeadline": "20/04/2026",
            "TaskPriority": "Medium"
          }
        ]
      },
      {
        "FullName": "David Marsh",
        "Department": "Engineering",
        "Position": "Backend Developer",
        "Tasks": [
          {
            "TaskName": "Fix authentication bug",
            "TaskDeadline": "10/04/2026",
            "TaskPriority": "High"
          },
          {
            "TaskName": "Write unit tests for payment module",
            "TaskDeadline": "18/04/2026",
            "TaskPriority": "Medium"
          }
        ]
      }
    ]
  }
}
```

<!--
type: tab
title: Generated document
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![table_nested_list_prefilled.png](/reference-assets/images/Document_generation/table_nested_list_prefilled.png)

<!-- type: tab-end -->

---

## Generate a list with a nested list

You can nest a **for tag** inside another for tag to generate a list where each item contains its own sub-list.

In the DOCX template, place the inner `{{for(InnerListName)}}...{{endfor}}` block inside the outer `{{for(OuterListName)}}...{{endfor}}` block.

In the `data` object, each object in the outer array contains its own nested array that drives the inner list.

<!--
type: tab
title: DOCX template
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![list_nested_tags.png](/reference-assets/images/Document_generation/list_nested_tags.png)

<!--
type: tab
title: data object example
-->

```json
{
  "data": {
    "Managers": [
      {
        "ManagerFullName": "Jane Smith",
        "Clients": [
          {
            "ClientFullName": "Robert Brown",
            "DateofInvoice": "01/03/2026"
          },
          {
            "ClientFullName": "Emily Carter",
            "DateofInvoice": "05/03/2026"
          }
        ]
      },
      {
        "ManagerFullName": "Tom Walker",
        "Clients": [
          {
            "ClientFullName": "Michael Torres",
            "DateofInvoice": "10/03/2026"
          },
          {
            "ClientFullName": "Laura Bennett",
            "DateofInvoice": "14/03/2026"
          }
        ]
      }
    ]
  }
}
```

<!--
type: tab
title: Generated document
-->
<!--
focus: center
bg: "#FAF0E6"
-->

![list_nested_prefilled.png](/reference-assets/images/Document_generation/list_nested_prefilled.png)

<!-- type: tab-end -->



---
*Full page: https://docs.signnow.com/docs/document-generations*
