Unqork documentation is available in two workspaces: UnqorkAI for the latest AI-first platform, and legacy Unqork for previous versions. Use the drop-down near the logo to switch.

Build a Bulk Delete Module

Prev Next

This guide walks you through building a UI module that deletes submission records in bulk. The module handles the two-stage delete process: archiving records first (soft delete), then permanently removing them if needed (hard delete). Creators set the date range in the UI, and the module displays job status after each stage.

Download the example module bundle 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

pluginDelete, pluginHardDelete

The resource ID of the Data Model or module containing the records to delete.

BDO Delete is disabled by default. Contact an Unqork representative to enable it for your environment. Hard delete is permanent and cannot be reversed.

Prerequisites

  • Creator or Express Administrator access to your workspace.

  • The BDO Delete endpoint enabled by an Unqork representative.

  • The resource ID of the Data Model or module containing the records to delete.

  • Familiarity with the Plug-In, Decisions, and Button components.

Module Overview

Organize the module into three field groups: for initialization logic, for the Creator-facing UI, and for the backend Plug-In component sequence.

Name

Key

Component

Purpose

On-Load Initializer

initOnload

Initializer

Triggers on page load.

Refresh Button

btnRefresh

Button

Lets the Creator check job status manually; enabled when a job is running.

Delete Button

btnDelete

Button

Starts the soft-delete sequence.

Hard Delete Button

btnHardDelete

Button

Starts the hard-delete sequence; enabled when soft delete completes.

Start Date

startDate

Date

Filters records created after this date.

End Date

endDate

Date Input

Filters records created on or before this date.

Error Initializer

initError

Initializer

Sets the response field to indicate failure.

Soft Delete

pluginDelete

Plug-In

Calls the Delete endpoint to archive records in the date range.

Hard Delete

pluginHardDelete

Plug-In

Calls the Delete endpoint with destroy=true to permanently remove archived records.

Get Job Status

pluginGetJobDetails

Plug-In

Checks delete progress using the job ID.

Check Status Rule

ruleCheckStatus

Decisions

Shows a status message and enables the btnHardDelete Button component when soft delete is complete.

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.

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, date inputs, and HTML instructions the Creator interacts with.

fgConfig

All Plug-In components, status logic, the error Initializer, and hidden fields.

Create the Supporting Fields

Add the following fields to fgConfig. These fields carry data between components throughout the delete sequence.

Property ID

Component

Default

Purpose

jobId

Hidden

—

Stores the delete job ID returned by pluginDelete or pluginHardDelete.

status

Hidden

—

Stores the current job status returned by pluginGetJobDetails.

response

Hidden

—

Set to Fail by initError when any Plug-In encounters an error.

Before You Begin

Unqork recommends exporting a copy of records before running a bulk delete. See Build a Bulk Download Module for those steps.

BDO Delete removes a maximum of 500,000 records per operation. For larger collections, run the operation multiple times.

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 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 a job is running. It starts disabled.

  1. Add a 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 btnDelete

The btnDelete Button component starts the soft-delete sequence. After validation passes, it triggers the pluginDelete Plug-In component.

  1. Add a Button component to fgUI after the Refresh button.

  2. Configure the following settings:

    Setting

    Value

    Property ID

    btnDelete

    Label

    Delete Records

    Action

    Validate

    Theme

    Danger

  3. Under Triggers, set the On Validation Success drop-down to pluginDelete.

Configure btnHardDelete

The btnHardDelete Button component permanently removes the archived records. It starts disabled and is enabled by the ruleCheckStatus Decisions component after the soft delete reaches completed. After validation passes, it triggers the pluginHardDelete Plug-In component.

  1. Add a Button component to fgUI after btnDelete.

  2. Configure the following settings:

    Setting

    Value

    Property ID

    btnHardDelete

    Label

    Permanently Delete

    Action

    Validate

    Theme

    Danger

    Initial State

    Disabled

  3. Under Triggers, set the On Validation Success drop-down to pluginHardDelete.

Configure startDate

The startDate Date Input lets the Creator specify the start of the date range. The pluginDelete Plug-In component and the pluginHardDelete Plug-In component read its value as dateFieldStartToFilterOn.

  1. Add a Date Input component to fgUI after the buttons.

  2. Configure the following settings:

    Setting

    Value

    Property ID

    startDate

    Label

    Start Date (created after)

    Required

    ON

Configure endDate

The endDate Date Input lets the Creator specify the end of the date range. The pluginDelete Plug-In component and the pluginHardDelete Plug-In component read its value as dateFieldEndToFilterOn.

  1. Add a Date Input component to fgUI after startDate.

  2. Configure the following settings:

    Setting

    Value

    Property ID

    endDate

    Label

    End Date (created on/before)

    Required

    ON

Configure initError

The initError Initializer component sets the response field to Fail when something goes wrong. Both delete Plug-Ins 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 pluginDelete

The pluginDelete Plug-In component calls the Delete endpoint to archive records in the selected date range (soft delete). It is triggered by the btnDelete Button component. On success, it triggers the pluginGetJobDetails Plug-In component to begin polling.

  1. Add a Plug-In component to fgConfig.

  2. Configure the following settings:

    Setting

    Value

    Property ID

    pluginDelete

    Trigger Type

    Manual

    Endpoint URL

    https://{environment}.unqork.io/fbu/uapi/bulkOperations/delete

    Method

    POST

  3. Configure the Inputs:

    #

    Property ID

    Value

    1

    resourceId

    'REPLACE_WITH_DATA_MODEL_ID'

    2

    name

    'Bulk Delete'

    3

    dateFieldToFilterOn

    'created'

    4

    dateFieldStartToFilterOn

    startDate

    5

    dateFieldEndToFilterOn

    endDate

  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.

To delete records from a previous Export operation instead, set dataSource to 'EXPORT' and include exportOperationId as an additional input. See Bulk Data Operations for all available parameters.

Configure pluginHardDelete

The pluginHardDelete Plug-In component permanently removes all archived records in the same date range. It is triggered by the btnHardDelete Button component after the soft delete completes, and targets ARCHIVED records to avoid affecting active records.

  1. Add a Plug-In component to fgConfig after pluginDelete.

  2. Configure the following settings:

    Setting

    Value

    Property ID

    pluginHardDelete

    Trigger Type

    Manual

    Endpoint URL

    https://{environment}.unqork.io/fbu/uapi/bulkOperations/delete?destroy=true

    Method

    POST

  3. Configure the Inputs:

    #

    Property ID

    Value

    1

    resourceId

    'REPLACE_WITH_DATA_MODEL_ID'

    2

    name

    'Bulk Hard Delete'

    3

    targetRecordType

    'ARCHIVED'

    4

    dateFieldToFilterOn

    'created'

    5

    dateFieldStartToFilterOn

    startDate

    6

    dateFieldEndToFilterOn

    endDate

  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.

Hard delete is permanent. Unqork cannot recover records after this step completes.

Configure pluginGetJobDetails

The pluginGetJobDetails Plug-In component checks the status of the current delete job. It is triggered by both the pluginDelete Plug-In component and the pluginHardDelete 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 pluginHardDelete.

  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

  4. Under Triggers, set the Post Trigger drop-down to ruleCheckStatus.

All BDO endpoints in this module use the bulkOperations  (camelCase, no hyphen).

Configure ruleCheckStatus

The ruleCheckStatus Decisions component reads the job status from the pluginGetJobDetails Plug-In component, triggers a pop-up message, and enables the btnRefresh Button component while a job is running. When the soft delete reaches completed, it also enables the btnHardDelete Button component so the Creator can proceed to the permanent delete.

  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

    btnHardDelete

    Disabled

    3

    fgUI

    Pop Message

  5. Add row per job status in the Decision grid:

    Status

    btnRefresh_disabled

    btnHardDelete_disabled

    fgUI_popMessage

    created

    =IF(LEN(A)>0,'no','yes')

    yes

    Delete started.

    inProgress

    =IF(LEN(A)>0,'no','yes')

    yes

    Delete in progress.

    completed

    =IF(LEN(A)>0,'no','yes')

    no

    Records archived. Click Permanently Delete to remove them, or leave them archived.

    partiallyCompleted

    =IF(LEN(A)>0,'no','yes')

    yes

    Delete partially complete.

    canceled

    =IF(LEN(A)>0,'no','yes')

    yes

    Delete canceled.

    failed

    =IF(LEN(A)>0,'no','yes')

    yes

    Delete failed.

    The formula in the disabled column uses A (the jobId alias). btnHardDelete is set to a literal yes (always disabled) for all rows except completed, where it is set to no.

Test the Module

  1. Open the module in Preview.

  2. Enter a Start Date and End Date to define the range of records to delete.

  3. Click Delete Records to begin the soft delete.

  4. Click Refresh until the pop-up message reads Records archived. Click Permanently Delete to remove them, or leave them archived.

  5. Open the submission using the platform's submission inspection method. See Debugger for how to access submission data from Express View.

  6. Confirm the jobId and status fields contain the expected values.

  7. To permanently remove the archived records, click Permanently Delete.

  8. Click Refresh again until the pop-up message updates to confirm the hard delete is complete.

Step 7 is irreversible. proceed if you are certain the archived records should be permanently removed.


Changelog

Date

Change

2026-10-06

Set btnDelete and btnHardDelete Action to Validate; added Required ON to startDate and endDate; corrected startDate label from "created on/after" to "created after" to match exclusive API behavior; updated bundle to match (EN-8164).

2026-10-06

Full restructure from tested POC: added startDate/endDate Date Input components, corrected pluginHardDelete to use targetRecordType ARCHIVED and dynamic date fields, fixed URLs to bulkOperations (camelCase), per-component Configure sections, Inputs/Outputs tables, bundle download link (EN-8164).

2026-09-30

Initial publication (EN-8164).