> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Fill a document template from a workflow and download it

> Map a Script node's output into the Template Filling node, fix a node that shows no mapping options, and turn the returned downloadPath into a working download URL.

Tested · October 2026

> [!TIP]
>
> **Built and run by the FlowX docs team on a live FlowX environment.** The workflow ran end to end: a Script node's output was mapped into the Template Filling node, the PDF was generated with the mapped values, and the download URL returned the file with a token and rejected the request without one.

This guide answers three questions about generating a document in an integration workflow:

1. How do I pass a Script node's output into the **Template Filling** node?
2. Why does the Template Filling node show no mapping options?
3. How do I build the download URL for the generated document?

The download URL section also applies when you generate documents from a process through the Documents plugin.

> [!NOTE]
>
> **Prerequisites**: a project with an integration workflow, and a document template in the project's **Document templates**. For creating and editing templates, see [Managing templates](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/managing-html-templates.md).

***

## How do I pass a Script node's output into the Template Filling node?

A Script node's `output` is merged into the root of the workflow data, with no prefix for the node name. A key the script writes as `output.customer` is available to every later node as `customer`, and its fields as `customer.fullName`. The Template Filling node reads its template values from that workflow data.

**1. Write the values from the Script node**

Assign each value the template needs to a key on `output`:

```javascript theme={"dark"}
// Script node placed before the Template Filling node
output.customer = {
  fullName: input.applicant.firstName + " " + input.applicant.lastName,
  contractNumber: input.contractNumber
};
```

Later nodes reference these values as `${customer.fullName}` and `${customer.contractNumber}`. For the expression rules, see [Referencing workflow data in node configurations](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md#referencing-workflow-data-in-node-configurations).

**2. Declare the keys in the workflow data model**

The data mapper in the Template Filling node lists the attributes of the workflow's **Data Model** as its source, and a key the Script node writes isn't offered until it's declared there. Add the keys to the workflow data model with the same names and nesting (in this example, a `customer` object with `fullName` and `contractNumber`). See [Workflow data models](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/workflow-data-models.md).

> [!TIP]
>
> You can also declare a key from inside the mapper. In a template field, type the path, for example `${customer.fullName}`, click **Add new attribute**, and save the **Attribute Settings**. The attribute is added to the workflow data model when you save the mapping.

**3. Define the template's input parameters**

The mapper fills only the template attributes selected as input parameters. Open the document template and:

1. On the **Data Model** tab, add an attribute for each value, for example `fullName` and `contractNumber` of type string.
2. On the **Input Parameters** tab, click **Define parameters**, select the attributes, and click **Done**.

In the template markup, insert each value with a Thymeleaf `th:text` attribute:

```html theme={"dark"}
<p>Contract number: <strong th:text="${contractNumber}"></strong></p>
<p>Customer: <strong th:text="${fullName}"></strong></p>
```

A bare `${fullName}` outside a `th:` attribute is printed as is in the generated document.

![Template Input Parameters tab listing contractNumber and fullName as string input parameters](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/final-3-template-input-parameters.png)

**4. Add and configure the Template Filling node**

Add **Template Filling** from the node palette after the Script node and set:

* **Template**: the document template to fill, from this project or one of its library dependencies
* **Language**: the template language
* **Document Tag**: the tag stored with the generated file, for example `ContractTemplate`
* **Document format**: **PDF** (default) or **DOCX**
* **Response Key**: the key that holds the generated file's details, for example `generatedContract`

**Template**, **Language**, **Document Tag**, and **Response Key** are required.

**5. Map the workflow attributes onto the template**

Under **Input Mapping**, click the wrench icon (**Configure mapping**) on the **Template Input** card. In the **Input Mapping** window:

1. In the workflow panel on the left, click **Define parameters**, select the workflow attributes to map (for example `customer`), and click **Done**.
2. In the field next to each template attribute, type `${customer.` and pick the suggested path, for example `${customer.fullName}`.
3. Optionally, click **Test** to see the mapped output under **Preview results**.
4. Click **Save**.

![Input Mapping window with customer.fullName and customer.contractNumber mapped onto the fullName and contractNumber template attributes](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/final-2-input-mapping-modal.png)

The **Template Input** card then shows how many attributes are mapped, for example **2 mapped**.

![Template Filling node after the Script node, with the Template Input card showing 2 mapped](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/final-1-template-filling-node.png)

### Template Filling nodes created before data mapping

Data mapping arrived in FlowX.AI 5.13. Template Filling nodes created before then show an **Enable data mapping** toggle:

* **On**: the node uses the data mapper (**Configure mapping** on the **Template Input** card). Values typed by hand are ignored.
* **Off**: under **Template Variables**, click **Configure Variables** and enter a value for each template variable, either fixed text or an expression such as `${customer.fullName}`.

New nodes always use the mapper and don't show the toggle.

***

## Why does the Template Filling node show no mapping options?

The mapper needs a selected template whose data model has input attributes. Find the message or symptom you see in the table below:

| What you see | Cause | Fix |
| - | - | - |
| **No template selected** | No template is set in **Template**. | Select a template. |
| **This template has no input attributes to map onto** | The template has no data model attributes, or none is selected as an input parameter. | Open the template, add attributes on its **Data Model** tab, and select them on the **Input Parameters** tab. Then reopen the node. |
| The same message, followed by **so it can only be filled in by hand**, and the **Enable data mapping** toggle is unavailable | The node predates data mapping, and the template has no input attributes. | Add input parameters to the template as in the previous row, or fill the values by hand under **Template Variables**. |
| The mapper opens with **No workflow parameters** on the left | No workflow attributes have been added to the mapper yet. | Click **Define parameters**, select the attributes, and click **Done**. |
| The mapper opens, but the Script node's keys aren't listed as sources | The keys aren't declared in the workflow data model. | Add them to the workflow **Data Model**, as in [Declare the keys in the workflow data model](#how-do-i-pass-a-script-node’s-output-into-the-template-filling-node). |
| The document is generated, but every template value is empty | Data mapping is on, but no mapping was saved. The node sends empty template data. | Click **Configure mapping**, map the attributes, and save. |
| The document shows `${fullName}` literally instead of the value | The template markup uses a bare `${...}` placeholder. | Insert the value with a `th:text` attribute, for example `<strong th:text="${fullName}"></strong>`. |
| The run fails with **Workflow is missing outgoing sequences** | The Template Filling node failed and the document wasn't generated. Only the node's green (success) exit is connected, so the failed run has no path to follow. | Connect the node's red (failure) exit to a branch that handles a failed generation. |

For the template data model and the **Input Parameters** tab, see [Managing templates](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/managing-html-templates.md).

***

## How do I build the download URL for the generated document?

All Deployments

The download URL is the Documents plugin base URL followed by the `downloadPath` the plugin returns:

```
https://{your-flowx-api-host}/document/ + downloadPath
```

`downloadPath` is relative, for example `internal/files/{fileId}/download`, so the complete URL has the form `https://{your-flowx-api-host}/document/internal/files/{fileId}/download`. The `/document` prefix is the route the Documents plugin is exposed on, as listed in the [ingress service route reference](https://docs.flowx.ai/6.x/setup-guides/ingress-configuration.md). Keep the trailing slash after `document`, because `downloadPath` doesn't start with one.

### What does the Template Filling node return?

The node stores the Documents plugin response under its **Response Key**. With the response key `generatedContract`, the workflow data contains:

```json theme={"dark"}
{
  "generatedContract": {
    "customId": null,
    "fileId": "{fileId}",
    "documentType": "ContractTemplate",
    "documentLabel": "GENERATED_PDF",
    "filePath": "{storage-object-path}",
    "downloadPath": "internal/files/{fileId}/download",
    "originalFileName": "ContractTemplate.pdf",
    "noOfPages": 1,
    "error": null
  }
}
```

`customId` holds the **Folder** value, and is `null` when **Folder** is empty. The response also carries `minioPath`, which is deprecated: use `filePath` instead. `filePath` is the object path in file storage, not a URL.

If generation fails, the node run fails. The Documents plugin error is returned under the response key, or, when the node can't reach the plugin, the output holds an `error` message and an `errorType`.

### Build the URL in the workflow

Add a Script node after the Template Filling node and prefix `downloadPath`:

```javascript theme={"dark"}
var downloadPath = input.generatedContract.downloadPath;

if (downloadPath != null) {
  output.contractUrl = "https://{your-flowx-api-host}/document/" + downloadPath;
}
```

Return `contractUrl` in the End node output, then map it into process data in the process that started the workflow. For the round trip from process to workflow and back, see [Call an external API from a process](https://docs.flowx.ai/6.x/cookbooks/call-external-api.md).

### Build the URL in a process

When you generate documents from a process through the Documents plugin, the reply carries the same `downloadPath`. To show the document in File Preview, you don't need the complete URL: set its **Source** to **Document Plugin path** and point it at `downloadPath`, and the renderer adds the Documents plugin base URL. See [Generating documents](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/generating-from-html-templates.md) for the request and reply, and [Preview an uploaded file](https://docs.flowx.ai/6.x/docs/building-blocks/ui-designer/ui-component-types/file-preview.md#preview-an-uploaded-file) for the binding.

When you need the complete URL in process data, for example for a **URL** source, build it in a business rule as in [Creating and uploading a new document](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/uploading-a-new-document.md).

> [!NOTE]
>
> The download endpoint requires authentication. The FlowX renderer recognizes a Documents plugin download by the URL ending in `download`, which is how `downloadPath` ends, and fetches it with the user's token. A plain browser link to the same URL has no token and is rejected. For linking to a stored file from a **File download** component, see [File download](https://docs.flowx.ai/6.x/docs/building-blocks/ui-designer/ui-component-types/file-download.md).

***

## Related resources

> [card] [Template Filling node](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md#template-filling-node)
>
> Every field of the Template Filling node.

> [card] [Script node](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md#script-node)
>
> How Script node output merges into workflow data.

> [card] [Managing templates](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/managing-html-templates.md)
>
> Create document templates and define their data model.

> [card] [Generating documents](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/generating-from-html-templates.md)
>
> Generate documents from a process through the Documents plugin.


## Related topics

- [Integration Designer](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md)
- [AI node types](https://docs.flowx.ai/6.x/ai-platform/agent-builder/node-types.md)
- [Generating documents](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/generating-from-html-templates.md)
- [FlowX.AI 5.10.0 Release Notes](https://docs.flowx.ai/release-notes/v5.x/v5.10.0-july-2026/v5.10.0-july-2026.md)
- [Reusable UI Templates](https://docs.flowx.ai/6.x/docs/building-blocks/reusable-resources/reusable-ui.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.