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

# Start a workflow from a User Task and show the result

> A user clicks a button, an integration workflow runs, and its output appears on the same screen - a User Task that loops through a Send and a Receive Message Task and back, with the two races that can lose data and how to prevent them.

Tested · October 2026

> [!TIP]
>
> **Built and run by the FlowX docs team on a live FlowX environment.** A user typed a customer ID, clicked **Get score**, and saw the workflow's score and tier on the same screen without reloading the page. Clicking **Continue** then finished the process with the score kept.

A common screen needs data the user can't type: a credit score, an address lookup, a price. The user fills in a key, clicks a button, an integration workflow fetches the data, and the result should appear on the screen they are still looking at. This cookbook builds that screen with a customer-scoring example, end to end.

The workflow here derives a score from the customer ID with a Script node, so the example runs without any external system. Replace the Script node with a REST API Call node and the process side stays the same.

> [!NOTE]
>
> **Prerequisites**: a project in your workspace and access to FlowX.AI Designer. This cookbook reuses the send, workflow, receive round trip from [Call an external API from a process](https://docs.flowx.ai/6.x/cookbooks/call-external-api.md) - start there if Send and Receive Message Tasks are new to you.

***

## Why not run the workflow from the User Task itself

A **Start Integration Workflow** action also works on a User Task, and the User Task can receive the output through its own data stream. The output lands in process data, but **the open screen does not refresh**: the user sees the new values only after reloading the page. Adding a **Send data to user interface** action to the same User Task doesn't help either, because it doesn't run again when the workflow replies.

The screen re-renders from process data every time the token enters the User Task. So instead of keeping the token on the User Task, send it through the workflow and back.

***

## The pattern

The process loops:

1. **Customer details** (User Task) shows the form with a **Get score** and a **Continue** button.
2. **Next step** (exclusive gateway) reads which button was clicked.
3. **Start scoring** (Send Message Task) starts the workflow with the customer ID.
4. **Receive score** (Receive Message Task) maps the workflow's output into process data.
5. The token returns to **Customer details**, which re-renders with the score.

When the user clicks **Continue**, the gateway sends the token to the End event instead. Both buttons run the User Task's Save Data action, and each one writes a different value to `app.next` - that value is how the gateway tells the two clicks apart.

***

## Step 1: Build the workflow

**1. Create the workflow and declare its data**

Go to **Integrations** → **Workflows** and create a workflow named `getCustomerScore`. In its data model, add three attributes: `customerId` (string), `score` (number, integer), and `tier` (string).

**2. Set the input**

On the **Start** node, set `customerId` as the input. This is the value the process sends.

**3. Add the Script node**

Add a **Script** node named `Calculate score` after Start, with this JavaScript:

```javascript theme={"dark"}
// Stand-in for a real lookup: derive a score from the customer ID.
var id = String(input.customerId || "");
var score = 500;
for (var i = 0; i < id.length; i++) {
  score += id.charCodeAt(i) % 50;
}
output.score = score;
output.tier = score >= 700 ? "GOLD" : "STANDARD";
```

**4. Set the output**

Connect the Script node to an **End** node and set `score` and `tier` as its output. These declared outputs are what the process receives.

**5. Test the workflow on its own**

Run the workflow from the editor with `{"customerId": "CUST-1042"}`. The End node output is `{"score": 763, "tier": "GOLD"}`.

***

## Step 2: Model the process data

In the process data model, add two objects:

| Attribute | Type | Holds |
| - | - | - |
| `customer.id` | string | The ID the user types |
| `customer.score` | number (integer) | The workflow's score |
| `customer.tier` | string | The workflow's tier |
| `app.next` | string | Which button was clicked: `score` or `done` |

Add a service task named **Init Data** right after the Start event, with a business rule (JavaScript) that seeds the values. The data model declares the shape, but it doesn't create any values at runtime:

```javascript theme={"dark"}
output.customer = { id: "", score: 0, tier: "" };
output.app = { next: "" };
```

***

## Step 3: Build the loop

**1. Add the nodes**

After **Init Data**, add the User Task **Customer details**, an exclusive gateway **Next step**, a Send Message Task **Start scoring**, a Receive Message Task **Receive score**, and an End event. Connect them in this order: Customer details → Next step → Start scoring → Receive score → back to Customer details. Connect Next step to the End event as its second path.

Place Customer details in a [navigation area](https://docs.flowx.ai/6.x/docs/building-blocks/process/navigation-areas.md) (a page), or its screen won't render at runtime.

![The customerScoreLoop process: Start, Init Data, Customer details, the Next step gateway, Start scoring, and Receive score, which loops back to Customer details, with the gateway's second path going to End](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/01-process-loop.png)

**2. Route the gateway**

In the gateway's **Gateway Decisions**, set the language to JavaScript, send the token to **Start scoring** when this condition is true, and to the End event otherwise:

```javascript theme={"dark"}
input.app != null && input.app.next == "score"
```

**3. Start the workflow**

On **Start scoring**, add a **Start Integration Workflow** action and select `getCustomerScore`. Open **Input Mapping** and map the process attribute `customer.id` to the workflow input `customerId`.

![The Start scoring input mapping: the process attribute customer.id is mapped as a source path to the getCustomerScore input customerId](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/02-start-scoring-input-mapping.png)

**4. Receive the output**

On **Receive score**, add a data stream with **Source** set to **Workflow** and select `getCustomerScore`. In the End node's **Output Mapping**, map `score` to `customer.score` and `tier` to `customer.tier`, click **Confirm**, and save the node.

> [!WARNING]
>
> **Map the customer ID as a source path, not as a typed value.** In the data mapper, `customer.id` must be selected from the process data model. A `${customer.id}` typed as a static value resolves only against project configuration parameters, so the workflow receives the literal text `${customer.id}` and scores the wrong input without any error.

***

## Step 4: Design the screen

On **Customer details**, add a form with three fields bound to `customer.id`, `customer.score`, and `customer.tier`. Then add the two buttons **outside the form**, as siblings of the form rather than children. Both buttons get an **On Click** event handler with **Action Type** set to **Node Action** and the User Task's Save Data action as the **Node Action Name**. They differ in what they send:

| Option | Get score | Continue |
| - | - | - |
| **Add form to submit** | The customer form | None |
| **Add custom keys** | `app.next` | `app.next` |
| **Add custom body** | `{"app": {"next": "score"}}` | `{"app": {"next": "done"}}` |
| **Show loader** | On | Off |

**Get score** submits the form so the ID the user just typed reaches the workflow, and the form's fields are added to the saved keys automatically. List `app.next` under **Add custom keys** as well: a custom body on its own is not saved to the process.

![The Get score button's On Click handler in the UI Designer: Node Action saveData, the customer form submitted, custom keys app.next, customer.id, customer.score and customer.tier, a custom body that sets app.next to score, and Show loader on](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/03-get-score-handler.png)

> [!WARNING]
>
> **Continue must not submit the form.** If the user clicks **Continue** after the workflow has replied but before the screen has re-rendered, the form still holds the old values, and submitting it overwrites the new score with them: the process finishes with a score of `0`. Keep **Continue** to `app.next` only. If it must also save fields the user edits, list those keys under **Add custom keys**, never the keys the workflow writes.

> [!WARNING]
>
> **Turn on Show loader for Get score.** The workflow round trip takes a moment. Without the loader, the user can click **Continue** while the token is still on its way through the workflow. That click fails with `Token is not active on process instance`, but its `app.next` value can still reach the gateway, so the process skips the score and ends with no result. With **Show loader** on, the screen blocks clicks until the refreshed screen arrives.

***

## Step 5: Run it end to end

Start a process instance and open the Customer details screen:

1. Type `CUST-1042` in the customer ID field and click **Get score**. The loader shows, and within a few seconds the screen shows score `763` and tier `GOLD`. The ID stays filled in.
2. Change the ID to `CUST-2001` and click **Get score** again. The screen updates to `809` and `GOLD`.
3. Click **Continue**. The process finishes, and the instance data keeps the last score and tier.

![The Customer details screen at runtime after Get score: customer ID CUST-1042, score 763, and tier GOLD](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/04-runtime-score-result.png)

> [!TIP]
>
> You built a screen that calls a workflow on demand and shows the result in place, without a page reload, plus the button configuration that keeps a fast click from losing the result.

Each **Get score** click is a full round trip: the token leaves the User Task, and the screen re-renders from process data when it returns. Anything the user typed but didn't submit with the form is lost on that re-render, so make sure every field the user can edit belongs to the submitted form.

***

## When it fails

| Symptom | Cause | Fix |
| - | - | - |
| The score appears only after reloading the page | The workflow is started by an action on the User Task itself, and the output arrives through the User Task's data stream | Route the token through a Send and a Receive Message Task and back, as in this cookbook |
| The process finishes with score `0` and an empty tier | **Continue** submitted the form and saved the stale screen values | Remove **Add form to submit** from Continue and keep only `app.next` |
| **Continue** fails with `Token is not active on process instance` | It was clicked while the workflow was running | Turn on **Show loader** for Get score |
| The workflow input is the literal text `${customer.id}` | The ID was typed as a static value in the input mapping | Map `customer.id` as a source path |
| The process stays at Receive score | The Receive Message Task has no confirmed output mapping | See [missing mapping in the data stream](https://docs.flowx.ai/6.x/docs/resources/error-glossary.md#workflow-output-cannot-be-appended-to-the-process-instance-due-to-missing-mapping-in-the-data-stream) |

***

## Related resources

> [card] [Call an external API from a process](https://docs.flowx.ai/6.x/cookbooks/call-external-api.md)
>
> The send, workflow, receive round trip with a real REST API.

> [card] [Start integration workflow action](https://docs.flowx.ai/6.x/docs/building-blocks/actions/start-integration-workflow.md)
>
> Every option of the action that starts the workflow.

> [card] [Event handlers](https://docs.flowx.ai/6.x/docs/building-blocks/ui-designer/event-handlers.md)
>
> Form submission, custom keys, custom body, and the loader.

> [card] [Exclusive gateway](https://docs.flowx.ai/6.x/docs/building-blocks/node/exclusive-gateway-node.md)
>
> Conditions and default paths.


## Related topics

- [Start integration workflow action](https://docs.flowx.ai/6.x/docs/building-blocks/actions/start-integration-workflow.md)
- [User task node](https://docs.flowx.ai/6.x/docs/building-blocks/node/user-task-node.md)
- [Workflow data model](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/workflow-data-models.md)
- [Cookbooks](https://docs.flowx.ai/6.x/cookbooks/overview.md)
- [Tutorial: Build a credit card application](https://docs.flowx.ai/6.x/docs/getting-started/building-your-first-proc.md)


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