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

# Document generation

# Document generation

Document generation allows users to create a document pre-filled with Salesforce record data and send it for signature in one click, without leaving the record page.

You prepare a .docx template with tags, and each tag is replaced with the matching value from the record when the document is generated. Tags can also add fillable fields for recipients to complete.

## Ways to generate a document

There are three document generation paths in Salesforce. They differ in where the template is stored and how the document is launched.

| Path | Where the template lives | How it is launched | Where the data comes from |
|---|---|---|---|
| Document generation template with a custom button | SignNow Admin Tools > Document Generation | A custom button on a record page | The record the button is placed on |
| Document generation template with the [**Send SignNow Template**](/docs/apex-send-template) Apex action | SignNow Admin Tools > Document Generation | A record-triggered or screen flow | The Salesforce record passed to the action |
| .docx file in Salesforce Files with the [**Generate and Send Document via SignNow**](/docs/apex-generate-and-send-document) or [**Generate Document via SignNow**](/docs/apex-generate-document) Apex action | Salesforce Files | A record-triggered or screen flow | A SOQL query you write in the action |

This article covers the document generation template path. For the Salesforce Files path, see [Generate and Send Document via SignNow](/docs/apex-generate-and-send-document) and [Generate Document via SignNow](/docs/apex-generate-document).

## How it works

- Prepare a .docx template with tags.
- Upload the template in **SignNow Admin Tools** > **Document Generation** and check that its status is **Ready**.
- Optionally, create a document flow to define recipients and invite settings.
- Create a custom button that sends the template, or connect the template to the [Send SignNow Template](/docs/apex-send-template) Apex action in a flow.
- On the record, a user clicks the button to generate and send the document in one click.

## Prepare the .docx template

Before you add tags, decide which Salesforce object the document is sent from. That object determines which fields the tags can pull.

Add tags to your .docx file. A tag is text wrapped in double braces, for example `{{Account.Name}}`.

Tags bind by name: SignNow matches each tag against the fields of the record the document is generated from. There is no mapping step and no query to write.

Tags use **Salesforce API field names**, not field display labels, and they are case-sensitive. `{{Owner.Name}}` is filled with data, while `{{Owner.name}}` stays unfilled in the generated document.

### Data tags

Data tags pull values from the record the document is generated from, and from its related records.

#### Own fields of the record you send from

Write the field API name on its own, with no object prefix. For example, when the document is generated from an Opportunity:

```
{{Name}}
{{OrderNumber__c}}
{{CloseDate}}
```

#### Fields from a related record

Reach a related record's field with dot notation, using the relationship name followed by the field name. Relation paths can cross more than one level:

```
{{Account.Name}}
{{Account.BillingCity}}
{{Owner.Name}}
{{Owner.Email}}
```

<!-- theme: info -->
> `Owner` is a lookup to the User record, so `{{Owner.Name}}` is a related field, not an own field of the record you send from.

### Dynamic tables

Build a repeating table from a child collection with a `table` tag. Pass the **relationship name** of the child collection, for example `OpportunityLineItems`. Put the opening `{{table(...)}}` tag, the row of item fields, and the closing `{{endtable}}` tag on separate table rows. The item fields are written flat inside the table, with no prefix:

| Item | Quantity | Unit Price | Amount |
|---|---|---|---|
| `{{table(OpportunityLineItems)}}` | | | |
| `{{Name}}` | `{{Quantity}}` | `{{UnitPrice}}` | `{{TotalPrice}}` |
| `{{endtable}}` | | | |
| **Subtotal** | | | `{{$sumabove}}` |

At generation time, SignNow repeats the middle row once for each child record. An Opportunity with four line items produces four rows.

<!-- theme: warning -->
> **Item fields must belong to the child record itself.** A child collection resolves one level deep, so a related record's field cannot be reached from inside a table row. For example, in an `OpportunityLineItems` table, `{{Name}}` returns the product name, while `{{PricebookEntry.Name}}` stays empty because the related PricebookEntry record is not part of the row's data. For the same reason, a table nested inside another table's rows is not supported on this path.

<!-- theme: info -->
> A table tag must be unique per document: the same collection cannot open two `table` blocks in one template.

Learn more about [table tags](/docs/document-generations#generate-a-dynamic-table).

### Lists

To repeat a block of text instead of a table row, use a `for` tag. It takes the same child collection as a table tag, and the same rules apply: pass the relationship name, and use only the child record's own fields inside the block.

```
{{for(OpportunityLineItems)}}
{{Name}} - {{Quantity}} x {{UnitPrice}}
{{endfor}}
```

Each entry in the collection produces one copy of the block.

<!-- theme: info -->
> A list tag must be unique per document: the same collection cannot open two `for` blocks in one template.

Learn more about [list tags](/docs/document-generations#generate-a-dynamic-list).

<!-- theme: warning -->
> **The same tag can mean different records.** A field tag is resolved against whichever record is in scope where it sits. Inside a `table` or `for` block, that is the child record; outside one, it is the record you send from. So in a template built on an Opportunity, `{{Name}}` inside an `OpportunityLineItems` table returns the line item's product name, while the same `{{Name}}` written outside the block returns the Opportunity name.

### Find a Salesforce API field name

- In Salesforce, go to **Setup** > **Object Manager**.
- Select the object you are working with, or a related object, for example **Opportunity**.
- Click **Fields & Relationships**.
- Locate the field by its label. The **Field Name** column shows the API name.

![docgen_field_api_name.png](/reference-assets/images/SignNow_Salesforce/salesforce_docgen/docgen_field_api_name.png)

For standard fields such as `Name` or `AccountNumber`, the API name matches the field label without spaces. For custom fields, the API name ends with `__c`, for example `OrderNumber__c`.

<!-- theme: info -->
> **Compound address fields:** Some fields appear in the Object Manager as a single entry with the data type **Address**, for example `BillingAddress`. Compound fields cannot be used in tags. Use the individual component names instead, following the pattern **[prefix] + [component]**: `BillingStreet`, `BillingCity`, `BillingState`, `BillingPostalCode`, `BillingCountry`. These names are Salesforce conventions and do not appear as separate entries in the Object Manager UI. See the [Salesforce Address Compound Fields documentation](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/compound_fields_address.htm) for the full list.

### System tags and formatting

- `{{$today}}` inserts the current date.
- `{{$sumabove}}` adds up the numeric column above it, which is useful for a total row under a table.
- `{{numFormat(TotalPrice, ‘$#,###.00’)}}` formats a number as currency.

<!-- theme: danger -->
> **Number formatting with `numFormat`:** The format pattern must be wrapped in Word-style curly quotes (`‘` and `’`), for example `{{numFormat(TotalPrice, ‘$#,###.00’)}}`. Straight quotes (`'`) and backticks are not recognized and the tag will not render. Because Word converts straight quotes to curly quotes as you type, enter the tag directly in the .docx template instead of pasting it from a code editor.

### Fillable field tags

Fillable field tags create empty fields for recipients to complete in the generated document. They do not pull Salesforce data. Use straight quotes in these tags.

- Signature: `{{t:s;r:y;o:"Manager";w:100;h:20;}}`
- Text: `{{t:t;r:y;o:"Manager";w:100;h:20;}}`
- Checkbox: `{{t:c;r:n;o:"Manager";}}`

`r:y` marks the field required, `r:n` optional. The value in `o:"Role"` maps to a recipient role in the document flow.

<!-- theme: info -->
> Fillable field tags accept both single-brace (`{...}`) and double-brace (`{{...}}`) syntax. All other tags must use double braces.

<!-- theme: warning -->
> The role name must match a role defined in your SignNow document flow. Do not use spaces in role names: use `SalesManager` instead of `Sales Manager`.

Learn more about [fillable field tags](/docs/document-generations#fillable-field-tags).

### Check the data behind your tags

To see exactly what data the template receives, add `{{toJson($sysConstants)}}` anywhere in the .docx file and generate the document once. It prints the full payload, so you can copy key names verbatim, including letter case, and confirm the values look right.

The payload shows the structure the tags are matched against:

- Fields of the record you send from appear at the top level, so they are tagged without a prefix.
- Related records appear as nested objects named after the relationship, for example `Account` or `Owner`, so their fields are tagged as `{{Account.Name}}`.
- Child collections appear as arrays named after the relationship, for example `OpportunityLineItems`, and each entry holds only that record's own fields.

<!-- theme: info -->
> The dump lists every field of the record you send from, but for related records it lists only the fields your template already tags. Use it to verify the tags you have written rather than to discover related fields you have not tagged yet.

Remove this tag before you use the template for real, since it puts raw data into the document.

### Example of a template with tags

<!--
type: tab
title: Template with tags
-->

<!--
focus: center
bg: none
-->
![docgen_docx_template_tags.png](/reference-assets/images/SignNow_Salesforce/salesforce_docgen/docgen_docx_template_tags.png)

<!--
type: tab
title: Generated document
-->

<!--
focus: center
bg: none
-->
![docgen_generated_document.png](/reference-assets/images/SignNow_Salesforce/salesforce_docgen/docgen_generated_document.png)

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

The tags used in this example:

| Tag type | Tag | What it does |
|---|---|---|
| Data tag | `{{OrderNumber__c}}` | Inserts a field of the Opportunity itself |
| Data tag | `{{Account.Name}}`, `{{Account.BillingStreet}}`, `{{Account.BillingCity}}`, `{{Account.BillingState}}`, `{{Account.BillingPostalCode}}`, `{{Account.BillingCountry}}`, `{{Owner.Name}}`, `{{Owner.Email}}` | Insert fields from related records |
| Table tag | `{{table(OpportunityLineItems)}}` … `{{endtable}}` | Repeats a row for each line item |
| Table tag | `{{Name}}`, `{{Quantity}}`, `{{UnitPrice}}`, `{{TotalPrice}}` | Insert the line item's own fields inside the table. In this example, `UnitPrice` and `TotalPrice` are wrapped in `numFormat`, as is `$sumabove` in the Subtotal row |
| System tag | `{{$today}}` | Inserts the current date |
| System tag | `{{$sumabove}}`, `{{$total=$sumabove}}` | Totals the column above and stores the value |
| System tag | `{{numFormat(UnitPrice, ‘$#,###.00’)}}` | Formats a number as currency |
| System tag | `{{if($total > 5000.00)}}` … `{{else}}` … `{{endif}}` | Shows different text depending on the total |
| Fillable field tag | `{{t:s;r:y;o:"Manager";w:100;h:20;}}` | Adds a signature field for the Manager role |
| Fillable field tag | `{{t:t;r:y;o:"Manager";w:100;h:20;}}` | Adds a text field for the Manager role |

## Upload the template

- Go to **App Launcher** > **SignNow Admin Tools**.
- Click **Document Generation** in the left-hand menu.
- Click **Upload .docx Template** and select your tagged file. The file must be 10 MB or smaller.

![docgen_templates_list.png](/reference-assets/images/SignNow_Salesforce/salesforce_docgen/docgen_templates_list.png)

The template appears in the list with its **Name**, **ID**, **Last Modified** date, and **Status**. The template name is taken from the uploaded file name. Use the search field to find a template by name, and the date filter to narrow the list by when templates were last modified.

When you upload a template, SignNow reads its tags and validates them. The **Status** column shows the result:

- **Ready** means the tags passed validation and the template can be sent.
- **Failed** means there is a problem in the tags. The error message from the tag check is shown so you can correct the .docx file and upload it again.

<!-- theme: info -->
> Templates are validated at upload, not at send time.

Note the template **ID**. You need it to send the template with the [Send SignNow Template](/docs/apex-send-template) Apex action.

To replace a template with a new version, rename it, or delete it, use the actions in the row's overflow menu.

## Create a document flow (optional)

A document flow defines recipients, signing order, and the invite email for the generated document. Creating one is optional, but it lets you preset recipient roles and a branded invite so the sender does not have to configure them each time.

To create one, go to **SignNow Admin Tools** > **Document Flows** and follow the steps in [Document flows](/docs/document-flows).

<!-- theme: warning -->
> The recipient roles you define in the flow must match the roles used in your template's fillable field tags, that is, the `o:"Role"` values.

## Send the document with a custom button

A custom button generates and sends the document in one click from a record page.

Create the button in **SignNow Admin Tools** > **Custom Links**, following the steps in [Custom links](/docs/custom-links). When you choose what the button sends, you have two options:

- **Templates: pre-selected by the Admin**: pick the document generation template yourself, and the button always sends that one.
- **Templates: selected by the sender**: the sender chooses a template when they click the button.

Document generation templates are marked **DOCX** in the list.

![docgen_custom_link_select_template.png](/reference-assets/images/SignNow_Salesforce/salesforce_docgen/docgen_custom_link_select_template.png)

A user opens the record, clicks the button, and SignNow generates the document pre-filled with that record's data and sends it according to the document flow. The generated document group is named after the template.

If generation fails, the user sees an error message with a process ID.

## Track the generated document

To follow the document after it is sent, add the [Invites Status widget](/docs/salesforce-invites-status-widget) to the record page.

> Having trouble? See [Troubleshooting](/docs/salesforce-troubleshooting#document-generation-templates).


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