--- title: "Build a Bulk Download Module" slug: "build-a-bulk-download-module" description: "Build a module to export Unqork submission data in bulk with a single click, managing job status and download links seamlessly." status: "update" updated: 2026-10-13T15:33:38Z published: 2026-10-13T15:33:38Z canonical: "docs.unqork.io/build-a-bulk-download-module" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.unqork.io/llms.txt > Use this file to discover all available pages before exploring further. # Build a Bulk Download Module This guide walks you through building a UI module that exports submission data from Unqork in bulk. The module handles the full sequence: starting the export job, checking its status, and generating a download link, all from a single button click. [Download the example module bundle](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Setting/bulk-download-poc.uqbundle?sv=2026-02-06&spr=https&st=2026-10-27T23%3A15%3A07Z&se=2026-10-28T00%3A15%3A07Z&sr=c&sp=r&sig=fmkXWMSyP5gXrXBsGytQR4%2BWwND%2FVTE%2FJdlqtPRZTC0%3D) to use as a starting point. After importing, replace every placeholder before using the module: | Placeholder | Appears in | Replace with. | | --- | --- | --- | | `REPLACE_WITH_DATA_MODEL_ID` | `pluginExport` | The resource ID of the Data Model or module containing the records to export. | ## Prerequisites - Creator or Express Administrator access to your workspace. - The resource ID of the Data Model or module containing the records to export. - Familiarity with the **Plug-In**, **Decisions**, and **Button** components. ## Module Overview Organize the module into three field groups: one for initialization logic, one for the Creator-facing UI, and one for the backend Plug-In component sequence. | Name | Key | Component | Purpose | | --- | --- | --- | --- | | On-Load Initializer | `initOnload` | Initializer | Triggers on page load. | | Export Button | `btnExport` | Button | Starts the export sequence. | | Refresh Button | `btnRefresh` | Button | Lets the user check job status manually; enabled when a job is running. | | Error Initializer | `initError` | Initializer | Sets the response field to indicate failure. | | Generate Export | `pluginExport` | Plug-In | Calls the Export endpoint to start the job. | | Get Job Status | `pluginGetJobDetails` | Plug-In | Checks export progress using the job ID. | | Check Status Rule | `ruleCheckStatus` | Decisions | Shows a status message and triggers the download link when complete. | | Get Download Link | `pluginGetDownloadLink` | Plug-In | Calls the Download-Link endpoint to get a signed download URL. | | File Count | `numFilesToGen` | Number | Hidden; controls `numberOfFilesToGenerate`; default value `1`. | > [!NOTE] > The example Property IDs in this guide use a `plugin` prefix (for example, `pluginExport`) for clarity. The platform default for Plug-In components is `plug` — see [Property ID Naming Conventions](/unqorkai/docs/property-id-naming-conventions). > **How to read settings tables** > > > The tables below describe each configurable option as it shows in the platform. Values are formatted as follows: `inline code` — a value to type exactly as shown | **Bold** — a value selected from a drop-down, radio button, tab, or choice chip | **ON**/**OFF** — toggle state | ✓ — checkbox checked | ☐ — checkbox unchecked ## Set Up the Field Groups Create three field groups in the module to keep components organized. | Field Group | Contains | | --- | --- | | `fgOnLoad` | The on-load Initializer that fires when the page renders. | | `fgUI` | The buttons and any visible HTML the user interacts with. | | `fgConfig` | All Plug-In components, Decisions logic, Initializers, and hidden fields. | ## Create the Supporting Fields Add the following fields to `fgConfig`. These fields carry data between components throughout the export and download sequence. | Property ID | Component | Default | Purpose | | --- | --- | --- | --- | | `jobId` | Hidden | — | Stores the export job ID returned by `pluginExport`. | | `status` | Hidden | — | Stores the current job status returned by `pluginGetJobDetails`. | | `exportLocation` | Hidden | — | Stores the file location from the completed export job. | | `downloadLink` | Hidden | — | Stores the signed download URL returned by `pluginGetDownloadLink`. | | `response` | Hidden | — | Set to `Fail` by `initError` when any Plug-In encounters an error. | | `numFilesToGen` | Number | `1` | Controls `numberOfFilesToGenerate`; set Hidden to **ON** and Allow Decimal to **OFF**. | ## Configure `initOnload` The `initOnload` Initializer component fires when the module first loads and serves as the module's entry point. It has no outputs and no connections to other components. 1. Add an **Initializer** component to `fgOnLoad`. 2. Configure the following settings: | Setting | Value | | --- | --- | | Property ID | `initOnload` | | Trigger Type | **New Submission** | ## Configure `btnExport` The `btnExport` Button component starts the export sequence. When a Creator clicks it, it triggers the `pluginExport` Plug-In component. 1. Add a **Button** component to `fgUI`. 2. Configure the following settings: | Setting | Value | | --- | --- | | Property ID | `btnExport` | | Label | `Export Records` | | Action | **Event** | 3. Under **Triggers**, set the **On Click** drop-down to `pluginExport`. ## Configure `btnRefresh` The `btnRefresh` Button component lets the Creator manually re-check job status. It triggers the `pluginGetJobDetails` Plug-In component on click, and the `ruleCheckStatus` Decisions component enables it once a job is running. It starts disabled. 1. Add a second **Button** component to `fgUI`. 2. Configure the following settings: | Setting | Value | | --- | --- | | Property ID | `btnRefresh` | | Label | `Refresh` | | Action | **Event** | | Initial State | **Disabled** | 3. Under **Triggers**, set the **On Click** drop-down to `pluginGetJobDetails`. ## Configure `initError` The `initError` Initializer component sets the `response` field to `Fail` when something goes wrong. All three Plug-In components reference it as their error handler. 1. Add an **Initializer** component to `fgConfig`. 2. Configure the following settings: | Setting | Value | | --- | --- | | Property ID | `initError` | | Trigger Type | **Manual** | 3. Configure the **Outputs**: | # | Property ID | Type | Value | | --- | --- | --- | --- | | 1 | `response` | Value | `Fail` | ## Configure `pluginExport` The `pluginExport` Plug-In component starts the bulk export job. It is triggered by the `btnExport` Button component. On success, it triggers the `pluginGetJobDetails` Plug-In component to begin polling for job status. 1. Add a **Plug-In** component to `fgConfig`. 2. Configure the following settings: | Setting | Value | | --- | --- | | Property ID | `pluginExport` | | Trigger Type | **Manual** | | Endpoint URL | `https://{environment}.unqork.io/fbu/uapi/bulkOperations/export` | | Method | **POST** | 3. Configure the **Inputs**: | # | Property ID | Value | | --- | --- | --- | | 1 | `resourceId` | The Data Model ID or module ID containing the records to export | | 2 | `name` | A descriptive label for the operation | | 3 | `fileFormat` | `'CSV'` (uppercase) | | 4 | `exportFullRecord` | `'false'` (Unqork recommends `false` to export only the `data` object) | | 5 | `numberOfFilesToGenerate` | `numFilesToGen` (reads from the hidden Number field; defaults to `1`) | | 6 | `targetRecordType` | `'ALL'` (uppercase; or `'ACTIVE'` or `'ARCHIVED'`) | 4. Configure the **Outputs**: | # | Property ID | Value | | --- | --- | --- | | 1 | `jobId` | `id` | 5. Under **Triggers**, set the **Post Trigger** drop-down to `pluginGetJobDetails` and the **Error Handler** drop-down to `initError`. > [!NOTE] > To filter by date range, add `dateFieldToFilterOn`, `dateFieldStartToFilterOn`, and `dateFieldEndToFilterOn` to the Inputs. See [Bulk Data Operations](/unqorkai/docs/bulk-data-operations#export) for all available parameters. ## Configure `pluginGetJobDetails` The `pluginGetJobDetails` Plug-In component checks the status of the export job. It is triggered by the `pluginExport` Plug-In component on success, and by the `btnRefresh` Button component when the Creator clicks it manually. On completion, it triggers the `ruleCheckStatus` Decisions component. 1. Add a **Plug-In** component to `fgConfig` after `pluginExport`. 2. Configure the following settings: | Setting | Value | | --- | --- | | Property ID | `pluginGetJobDetails` | | Trigger Type | **Manual** | | Endpoint URL | `https://{environment}.unqork.io/fbu/uapi/bulkOperations/jobs/{{data.jobId}}` | | Method | | 3. Configure the **Outputs**: | # | Property ID | Value | | --- | --- | --- | | 1 | `status` | `data.status` | | 2 | `exportLocation` | `data.steps[0].files[0].destination.location` | 4. Under **Triggers**, set the **Post Trigger** drop-down to `ruleCheckStatus`. > [!NOTE] > All BDO endpoints in this module use the `bulkOperations` path (camelCase, no hyphen). ## Configure `ruleCheckStatus` The `ruleCheckStatus` Decisions component reads the job status written by the `pluginGetJobDetails` Plug-In component and triggers a pop-up message to the Creator. It enables the `btnRefresh` Button component once a job is running and triggers the `pluginGetDownloadLink` Plug-In component automatically when the job reaches `completed`. 1. Add a **Decisions** component to `fgConfig` after `pluginGetJobDetails`. 2. Configure the following settings: | Setting | Value | | --- | --- | | Property ID | `ruleCheckStatus` | | Trigger Type | **Manual** | 3. Configure the **Inputs**: | # | Property ID | Alias | Type | | --- | --- | --- | --- | | 1 | `jobId` | `A` | Exact | | 2 | `status` | | Exact | 4. Configure the **Outputs**: | # | Property ID | Type | | --- | --- | --- | | 1 | `btnRefresh` | Disabled | | 2 | `fgUI` | Pop Message | | 3 | `pluginGetDownloadLink` | Trigger | 5. Add one row per job status in the **Decision** grid: | Status | Refresh Button (`btnRefresh_disabled`) | Pop Message (`fgUI_popMessage`) | Download Trigger (`pluginGetDownloadLink_trigger`) | | --- | --- | --- | --- | | `created` | `=IF(LEN(A)>0,'no','yes')` | `Export started.` | | | `inProgress` | `=IF(LEN(A)>0,'no','yes')` | `Export in progress.` | | | `completed` | `=IF(LEN(A)>0,'no','yes')` | `Export complete. Generating download link.` | `GO` | | `partiallyCompleted` | `=IF(LEN(A)>0,'no','yes')` | `Export partially complete.` | | | `canceled` | `=IF(LEN(A)>0,'no','yes')` | `Export canceled.` | | | `failed` | `=IF(LEN(A)>0,'no','yes')` | `Export failed.` | | The formula in the disabled column uses `A` (the `jobId` alias); the button enables when a job ID is present. ## Configure `pluginGetDownloadLink` The `pluginGetDownloadLink` Plug-In component generates a signed URL for downloading the exported file. It is triggered by the `ruleCheckStatus` Decisions component when the job status reaches `completed`, and writes the result to the `downloadLink` field. 1. Add a **Plug-In** component to `fgConfig` after `ruleCheckStatus`. 2. Configure the following settings: | Setting | Value | | --- | --- | | Property ID | `pluginGetDownloadLink` | | Trigger Type | **Manual** | | Endpoint URL | `https://{environment}.unqork.io/fbu/uapi/bulkOperations/downloadLink` | | Method | **POST** | 3. Configure the **Inputs**: | # | Property ID | Value | | --- | --- | --- | | 1 | `fileLocation` | `exportLocation` | 4. Configure the **Outputs**: | # | Property ID | Value | | --- | --- | --- | | 1 | `downloadLink` | `downloadLink` | 5. Under **Triggers**, set the **Error Handler** drop-down to `initError`. ## Test the Module 1. Open the module in **Preview**. 2. Click **Export Records**. 3. Click **Refresh** until the pop-up message reads `Export complete. Generating download link.` 4. Open the submission using the platform's submission inspection method. See [Debugger](/unqorkai/docs/api-debugger) for how to access submission data from Express View. 5. Locate the `downloadLink` field value. It contains a relative path in the format `/files/{fileId}`. 6. Construct the full download URL by prepending `https://{environment}.unqork.io/api` to the path (for example, `https://qa22.unqork.io/api/files/6abe94956afacf4d485c59a2`). > [!NOTE] > The URL must include `/api/` between the environment domain and `/files/`. Navigating to `/files/` directly returns a bad route. 7. Paste the full URL into a browser. The file should begin downloading. --- **Changelog** | Date | Change. | | --- | --- | | 2026-10-01 | Converted all Inputs/Outputs to UI-matching tables with # column; Decisions grid documented with column header labels. | | 2026-10-01 | Converted field group list to table; added connection sentences to each Configure section; reformatted configuration steps as numbered lists. | | 2026-10-01 | Updated Export and Download-Link URLs to `bulkOperations` (camelCase); added `numFilesToGen` Number field; added example bundle download link. | | 2026-09-30 | Initial publication. | The UI (user interface) is a device's end-user interaction and communication point. It can include display screens, keyboards, and mouse. It is also how a user interacts with your application. Also known as Unqork Users, or Designer Users; is anyone who is inside the Unqork platform. Includes the Short Answer component, Long Answer component, Select Boxes, Radio component, Dropdown, Number component and Single Checkbox. An API endpoint is the location where an API receives requests for a specific resource on its server. It's the point of contact between an API client and an API server, and is usually a uniform resource locator (URL) that provides the location of the resource. A URL (uniform resource locator) is a unique identifier used to locate a resource on the internet. Also known as a web address. The Number data type accepts integer or floating point values. The number data type does not use quotes around numerical values. A Property ID is the unique field ID used by Unqork to track and link components in your module. Rendering is the process of loading components and displaying the final result on the front-end screen. HTML (Hyper Text Markup Language) is the standard markup language for for achieving font, color, graphic, and hyperlink effects when creating web pages. A Property ID is the unique field ID used by Unqork to track and link components in your module. Deteremines how the component triggers. The component fires when the page or called module loads without an existing submission ID. Dashboards and remote execute modules are great uses for this trigger. Label Text conveys what the input component is and what information it displays. Enter the purpose of the corresponding component or field. Enter the Property ID of the component that you want to trigger on each button-click. Enter outputs components and actions you want the component to perform. The HTTP POST method is used to send data to a server to create or update a resource, typically including the data in the body of the request. Enter inputs components and actions you want the component to perform.. An object is a type of data structure that represents a single, self-contained entity that acts as a container for the characteristics of that entity. The Post Trigger value fires after a component has completed its action. For example, post triggering a component to display the data received from a Plug-In component's API call. An API endpoint is the location where an API receives requests for a specific resource on its server. It's the point of contact between an API client and an API server, and is usually a uniform resource locator (URL) that provides the location of the resource. A naming convention for computer programming. Use camelCase for Property IDs, for example: newUser, lastName, & rdoButton. Express View is how your end-user views your application. Express View also lets you preview your applications to test your configuration and view the styling. This is also the view your end-users will see when interacting with your application. After configuring a module, click Preview in the Module Builder to interact with the module in Express View. ## Related - [Bulk Operations: Utilities](/bulk-operations-utilities.md) - [Record Operations API](/record-operations-api.md) - [Bulk Data Operations](/bulk-data-operations.md)