> ## 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.

# Creating and uploading a new document

> A comprehensive guide to integrating document creation from templates, managing uploads, and configuring workflows for document processing.

> [!NOTE]
>
> User task nodes provide a flexible framework to defining and configuring UI templates and actions for specific template config nodes, such as an upload file button.

![Upload and preview process with the client\_data, create\_document, receive\_reply, create\_document\_path, preview\_generated\_document, and upload\_document nodes](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/14-docs_upload_proc.png)

## Prerequisites

Before you begin, ensure the following prerequisites are met:

* **Access Permissions**: Ensure that you have the necessary permissions to use the Documents Plugin. The user account used for these operations should have the required access rights.
* **Kafka Configuration**: Verify that the Kafka messaging system is properly configured and accessible. The Documents Plugin relies on Kafka for communication between nodes.

  * **Kafka Topics**: Familiarize yourself with the Kafka topics used for these operations (later in this section).

> [!WARNING]
>
> **Important: Document replacement behavior**
>
> When uploading a file with the **same `customId` AND `documentType` combination** as an existing document, the previous document will be automatically **marked as deleted** and replaced by the new file.
>
> This means:
>
> * The previous file's URLs will stop working
> * Only the most recent file with that `customId` + `documentType` combination will be accessible
>
> **Best practices:**
>
> * Always use **unique, dynamic values** for `customId` (e.g., `${processInstanceId}`, client ID, or a generated UUID)
> * Do not copy examples with hardcoded values like `customId: "1234"` without changing them to unique values
> * If you need to store multiple documents of the same type for the same entity, ensure each has a unique identifier
>
> ```json Example: Using dynamic values theme={"dark"}
> {
>   "customId": "${processInstanceId}",  // or use a client-specific ID
>   "documentType": "CONTRACT",
>   "tempFileId": "..."
> }
> ```

**Terminology note:** the Designer UI labels this concept **Document Tag** (formerly **Document Type**). The rename affects UI labels only: the `documentType` field in Kafka requests and responses is unchanged.&#x20;

To upload a document using this process, follow the steps outlined below.

## Step-by-step guide: uploading and previewing a document

In the [Generating from HTML templates](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/generating-from-html-templates.md) guide, you learned how to generate documents from HTML templates. This section focuses on creating a process where users can generate a document, review and sign it, and subsequently upload it.

<video controls autoPlay muted loop src="https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/4.5/upload_and_preview.mp4" />

### Process overview

This process involves several key nodes, each performing specific tasks to ensure smooth document creation, preview, and upload:

* **Start and End Nodes**: These nodes mark the beginning and end of the process, respectively.
* **User Task Node**: Collects user input necessary for document generation.
* **Send and Receive Message Tasks (Kafka)**: Handle communication with Kafka for generating the document and retrieving it after processing.
* **Service Task Node**: Appends the path of the generated document to the process, enabling further actions.
* **User Task Nodes**: Facilitate the preview of the generated document and manage the upload of the signed document.

## Configuring the process

**1. Document generation**

Follow the steps outlined in [**Generating from HTML templates**](https://docs.flowx.ai/6.x/docs/platform-deep-dive/core-extensions/content-management/documents-plugin/generating-from-html-templates.md) configure the document generation part of the process.

![Document generation part of the process highlighted, from client\_data to receive\_reply](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/15-doc_plugin_upload_prev_ex.png)

> [!NOTE]
>
> If you only need to upload a new file without generating it from templates, skip the template generation steps.

After configuration, your request and response messages should resemble the examples below.

#### Request message example

This JSON structure represents a Kafka message sent through the `..in` topic to initiate a request in the Process Engine. It includes information for generating an "AccountCreation" document with a custom ID "119237" in English. Data specifies client details extracted dynamically from user input (first name, last name, age, country) and company information (name, registration date).

> [!NOTE]
>
> This an example of a message that follows the custom integration data model.

```json theme={"dark"}
{
  "documentList": [
    {
      "customId": "119246", //this will match the name of the folder in the storage solution
      "templateName": "AccountCreation",
      "language": "en",
      "data": {
        "application": {
          "client": {
            "firstName": "John",
            "lastName": "Doe",
            "age": "33",
            "country": "AU"
          },
          "company": {
            "name": "ACME",
            "registrationDate": "24.01.2024"
          }
        }
      },
      "includeBarcode": false
    }
  ]
}
```

#### Response message example

This JSON structure represents the response received on the `..out` Kafka topic, where the Process Engine expects a reply. It contains details about the generated PDF file corresponding to the custom ID "119237" and the "AccountCreation" template. The response provides file-related information such as file ID, document type, document label, storage path, download path, number of pages, and any potential errors (null if none). The paths provided in the response facilitate access and download of the generated PDF file.

```json theme={"dark"}
{
  "generatedFiles": {
    "119246": {
      "AccountCreation": {
        "customId": "119246",
        "fileId": "f705ae5b-f301-4700-b594-a63b50df6854",
        "documentType": "AccountCreation",
        "documentLabel": "GENERATED_PDF",
        "minioPath": "flowx-dev-process-id-119246/119246/457_AccountCreation.pdf", // path to the document in the storage solution
        "downloadPath": "internal/files/f705ae5b-f301-4700-b594-a63b50df6854/download", //link for download
        "noOfPages": 1,
        "error": null
      }
    }
  },
  "error": null
}
```

**2. Preview document**

Configure the **preview** part of the process.

![Preview part of the process highlighted: create\_document\_path and preview\_generated\_document](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/16-preview_path.png)

#### Service task node

We will configure the service task node to construct the file path for the generated document.

Configure a business rule to construct a file path for the generated document. Ensure the base admin path is specified.

> [!TIP]
>
> With a **URL** source, File Preview uses the value at its key as-is, so the business rule must build a complete, absolute URL. The renderer attaches the user's access token only to URLs that end in `download`, which is how the `downloadPath` from the reply ends.

You can skip this business rule: File Preview reads `downloadPath` directly with **Source** set to **Document Plugin path** and adds the Documents plugin base URL itself. See [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).&#x20;

#### Actions

**Action Edit**

* **Action Type**: Set to **Business Rule**
* **Trigger Type**: Choose **Automatic** because is not a user-triggered action
* **Required Type**: Set as **Mandatory**

![Business Rule action on the create\_document\_path node that builds the document file path](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/08-create_document_path.png)

**Parameters**

* **Language**: We will use **MVEL** for this example
* **Body Message**: Fill in the body message request

```js theme={"dark"}
adminPath = "https://{your-flowx-api-host}/document/";
processInstanceId = input.?generatedDocuments.?generatedFiles.keySet().toArray()[0];
downloadPath = input.?generatedDocuments.?generatedFiles.?get(processInstanceId).Company_Client_Document.downloadPath;

if(downloadPath != null){
    output.put("generatedDocuments", {
        "filePath" : adminPath + downloadPath
    });
}
```

> [accordion] Explanation of MVEL code
>
> * **adminPath**: Base URL of the Documents plugin. Replace `{your-flowx-api-host}` with the host that serves the FlowX APIs to your renderer; the Documents plugin is exposed on it under `/document`, as listed in the [ingress service route reference](https://docs.flowx.ai/6.x/setup-guides/ingress-configuration.md#service-route-reference). Keep the trailing slash, because `downloadPath` is relative (for example `internal/files/{fileId}/download`).
>
> ```java theme={"dark"}
> adminPath = "https://{your-flowx-api-host}/document/";
> ```
>
> * **processInstanceId**: Extracts the process instance ID from the input. Assumes an input structure with a generatedDocuments property containing a generatedFiles property. Retrieves the keys, converts them to an array, and selects the first element.
>
> ```java theme={"dark"}
> processInstanceId = input.?generatedDocuments.?generatedFiles.keySet().toArray()[0];
> ```
>
> * **downloadPath**: Retrieves the downloadPath property using the obtained processInstanceId.
>
> ```java theme={"dark"}
> downloadPath = input.?generatedDocuments.?generatedFiles.?get(processInstanceId).Company_Client_Document.downloadPath;`
> ```
>
> * **if condition**: Checks if downloadPath is not null and constructs a new object in the output map.
>
> ```java theme={"dark"}
> if(downloadPath != null){
>     output.put("generatedDocuments", {
>         "filePath" : adminPath + downloadPath
>     });
> }
> ```

### User Task

Now we will configure the user task to preview the generated document.

#### Actions

Configure the **Actions edit** section:

* **Action Type**: Set to **Save Data**.
* **Trigger Type**: Choose **Manual** to allow user-triggered action.
* **Required Type**: Set as **Mandatory**.

![Save Data action on the preview\_generated\_document user task](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/09-document_preview_action.png)

Let's see what we have until now.

The screen where you can fill in the client details:

![Client Details](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/release34/upload_fill_data.gif)

The screen where you can preview and download the generated document:

![Preview Document](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/release34/preview_document_vis.gif)

**3. Upload document**

Configure the user task where we will upload the signed document genereated from the previous document template.

#### Node Config

* **Swimlane**: Choose a swimlane (if multiple) to restrict access to specific user roles.
* **Stage**: Assign a stage to the node.
* **Integration Output**: Add a data stream (**Source**: **Custom Topic**) with the topic where the response will be sent; in this example the default Documents plugin persist reply topic `ai.flowx.engine.receive.plugin.document.persist.document.results.v1` and its key: `uploadedDocument`.

![upload\_document node config with a Custom Topic data stream on the persist reply topic and the key uploadedDocument](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/07-upload_document_node_config.png)

#### Actions

Configure the following node actions:

* Upload File action with two child actions:
  * Business Rule
  * Send Data to User Interface
* Save Data action

![upload\_document actions: an Upload File action with Business Rule and Send data to user interface child actions, and a Save Data action](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/06-upload_document_actions.png)

#### Upload file action

This is a standard predefined FlowX Node Action for uploading files. This is done through Kafka and by using `persist` topics.

> [accordion] Configuring the File Upload action
>
> #### Action edit
>
> * **Action Type**: Set to **Upload File**.
> * **Trigger Type**: Choose **Manual** to allow user-triggered action.
> * **Required Type**: Set it as **Optional**.
> * **Repeatable**: Check this option if the action can be triggered multiple times.
>
> #### Parameters
>
> * **Topics**: Kafka topic where the file will be posted, in this example the default `ai.flowx.plugin.document.trigger.persist.document.v1`.
>
> > [!TIP]
> >
> > To identify your defined topics in your current environment, follow the next steps:
> >
> > * In FlowX Designer, open **Platform Status** from the left sidebar of your workspace, or from **Organization settings** in the account menu.&#x20;
> > * In the **Services** list, scroll to the **document-plugin** line and press the eye icon on the right side.
> > * In the details screen, expand the `kafkaTopicsHealthCheckIndicator` line and then **details → configuration → topic → document → persist**. Here you'll find the in and out topics for persisting (uploading documents).
> >
> > ![document-plugin details in Platform Status, with the Kafka topics health check expanded to the document persist topics](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/kafka-topics-persist-document-plugin.png)
>
> * **Document Type**: Metadata for the document plugin, in this example `BULK`.
> * **Folder**: Configure a value by which the file will be identified, in this example it will be the`${processInstanceId}` (it will be replaced at runtime with a generated process instance id).
> * **Advanced configuration (Show headers)**: This represents a JSON value that will be sent on the headers of the Kafka message, in this example:
>
> ```json theme={"dark"}
> {"processInstanceId": ${processInstanceId}, "destinationId": "upload_document", "callbacksForAction": "uploadDocument"}`
> ```
>
> > [!TIP]
> >
> > `callbacksForAction` - the value of this key is a string that specifies a callback action associated with the "upload\_document" destination ID (node). This is part of an event-driven system (Kafka send action) where this callback will be called once the "upload\_document" action is completed.
>
> #### Data to send
>
> * **Keys**: Used when data is sent from the frontend via an action for data validation.

![Upload File action parameters with the persist topic, Document Type BULK, and Folder](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/03-upload_config_b_params.png)
![Upload File action Folder and headers with processInstanceId, destinationId, and callbacksForAction](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/03b-upload_config_b_headers.png)

> [!NOTE]
>
> When configuring the event handler that corresponds to the Upload File node action, you must set the **Action Type** to **Upload**. This ensures proper integration between the frontend interface and the backend upload functionality.
>
> ![File Upload event handler with Action Type set to Upload](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/10-ui_action_upload.png)

Now, configure the child actions of Upload File Action.

#### Business rule

This is necessary to create the path to display the uploaded document.

> [accordion] Configuring the Business Rule action
>
> **Action Edit**
>
> * **Order**: Set to **1** so it will be processed before the second child action.
> * **Action Type**: Set to **Business Rule**.
> * **Trigger Type**: Choose **Automatic**, it does not need user intervention.
> * **Required Type**: Set as **Mandatory**.
> * **Repeatable**: Check this option if the action can be triggered multiple times.
>
> **Parameters**
>
> * **Language**: In this example we will use **MVEL**.
> * **Body Message**: Fill in the body of the message request by applying a logic similar to the one utilized in configuring the "preview\_document" node. Establish a path that will be later employed to showcase the uploaded document within a preview UI component.
>
> ```js theme={"dark"}
> adminPath = "https://{your-flowx-api-host}/document/";
> downloadPath = input.?uploadedDocument.?downloadPath;
>
> if(downloadPath != null){
>     output.put("uploadedDocument", {
>         "filePath" : adminPath + downloadPath
>     });
> }
> ```
>
> The rule replaces the reply's `filePath`, which is a storage path, with the preview URL. The other keys from the reply stay as they are.

![Business Rule child action settings under the Upload File action](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/04a-upload_business_rule_a.png)
![Business Rule child action script](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/04b-upload_business_rule_b.png)

#### Send Data to User Interface

This is necessary to send the previously created information to the frontend.

> [accordion] Configuring the Send Data to User Interface action
>
> **Action Edit**
>
> * **Order**: Set to **2** so it will be processed after the previously created Business Rule.
> * **Action Type**: Set to **Send data to user interface**.
> * **Trigger Type**: Choose **Automatic**, it does not need user intervention.
> * **Required Type**: Set as **Mandatory**.
> * **Repeatable**: Check this option if the action can be triggered multiple times.
>
> **Parameters**
>
> * **Message Type**: Set to **Default**.
> * **Body Message**: Populate the body of the message request; this object will be utilized to bind it to the File Preview UI element.
>
> ```json theme={"dark"}
> {
>     "uploadedDocument": {
>         "filePath": "${uploadedDocument.filePath}"
>     }
> }
> ```
>
> * **Target Process**: Used to specify to what running process instance should this message be sent - set to **Active Process**.

![Send data to user interface child action settings](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/05a-send_to_UI_a.png)
![Send data to user interface child action message body](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/05b-send_to_UI_b.png)

#### Save Data

Configure the last node action to save all the data.

**Action edit**

* **Order**: Set to **3**.
* **Action Type**: Set to **Save Data**.
* **Trigger Type**: Choose **Manual** to allow user-triggered action.
* **Required Type**: Set as **Mandatory**.

#### Request message example

To initiate the document processing, a Kafka request with the following JSON payload will be sent through `..in` topic:

> [!NOTE]
>
> This an example of a message that follows the custom integration data model.

```json theme={"dark"}
{
  "tempFileId": "05081172-1f95-4ece-b2dd-1718936710f7", //a unique identifier for the temporary file
  "customId": "119246", //a custom identifier associated with the document
  "documentType": "BULK" //the type of the document 
}
```

#### Response message example

Upon successful processing, you will receive a JSON response on the `..out` topic with details about the processed document:

```json theme={"dark"}
{
  "customId": "119246",
  "fileId": "96975e03-7fba-4a03-99b0-3b30c449dfe7",
  "documentType": "BULK",
  "documentLabel": null,
  "minioPath": "flowx-dev-process-id-119246/119246/458_BULK.pdf",
  "downloadPath": "internal/files/96975e03-7fba-4a03-99b0-3b30c449dfe7/download",
  "noOfPages": null,
  "error": null
}
```

Now the screen is configured for uploading the signed document:

![Upload File](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/release34/upload_document_signed.gif)

***

## Uploading multiple files

For the backend action configuration, see the [Upload File action](https://docs.flowx.ai/6.x/docs/building-blocks/actions/upload-file-action.md) documentation. To show each uploaded file on the same user task, see [Preview files in a collection](https://docs.flowx.ai/6.x/docs/building-blocks/ui-designer/ui-component-types/file-preview.md#preview-files-in-a-collection).

***

## Receiving the reply

The response, containing information about the generated and uploaded documents, is sent to the output Kafka topic defined in the Kafka Receive Event Node. The response includes details such as file IDs, document types, and storage paths.

![Process instance variables showing the upload reply, with filePath replaced by the document preview URL](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/upload-reply-variables.png)

The reply body is expected to contain the following values:

* **customId**: A custom identifier associated with the document.
* **fileId**: The ID of the file.
* **documentType**: The document type.
* **minioPath**: The path where the uploaded file is saved. It represents the location of the file in the storage system, whether it's a MinIO path or an S3 path, depending on the specific storage solution.
* **downloadPath**: The download path for the uploaded file. It specifies the location from where the file can be downloaded.
* **noOfPages**: The number of pages in the document (if applicable).
* **filePath**: The object path of the file in storage (MinIO or S3). It isn't a URL: to display the document, build a URL from `downloadPath`, as the business rule in this example does.


## Related topics

- [Fill a document template from a workflow and download it](https://docs.flowx.ai/6.x/cookbooks/generate-and-download-a-document.md)
- [File preview](https://docs.flowx.ai/6.x/docs/building-blocks/ui-designer/ui-component-types/file-preview.md)
- [Creating a new project](https://docs.flowx.ai/6.x/docs/flowx-designer/managing-a-project-flow/creating-a-project.md)
- [Creating a user interface](https://docs.flowx.ai/6.x/docs/flowx-designer/managing-a-project-flow/creating-a-user-interface.md)
- [Creating and managing process definitions](https://docs.flowx.ai/6.x/docs/flowx-designer/managing-a-project-flow/creating-a-new-process-definition.md)


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