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

# Tutorial: Build your first workflow

> Connect FlowX to an external REST API, build an integration workflow around it, and call that workflow from a BPMN process.

Tested · October 2026

> [!TIP]
>
> **Built and run by the FlowX docs team on a live FlowX environment.** The workflow ran on its own, then the process called it and finished with the exchange rate in its instance data.

In this tutorial you build your first **integration workflow**: a small flow that calls a public exchange-rates API, picks one rate out of the response with a script, and hands the result back to a Business Process Model and Notation (BPMN) process. By the end, you'll know how to:

* Define a data source with a tested REST endpoint
* Build a workflow from REST API Call, Script, and End nodes and run it
* Start a workflow from a process and map data in and out of it
* Find the result in the finished process instance

> [!NOTE]
>
> **Time required:** about 20 minutes
>
> **Prerequisites:**
>
> * Access to FlowX Designer
> * A workspace and project set up ([create one here](https://docs.flowx.ai/6.x/docs/projects/workspaces.md))
> * Outbound internet access from your FlowX environment, so the workflow can reach the public API

> [!TIP]
>
> Remember the distinction: a **process** is a BPMN flow with user and service tasks; a **workflow** is integration logic built in the Integration Designer. Processes delegate data fetching and transformations to workflows. See the [Glossary](https://docs.flowx.ai/6.x/docs/getting-started/glossary.md) if any term here is new.

***

## What you'll build

A currency lookup. A process holds the currency a customer picked, starts a workflow with it, and waits. The workflow calls the [Frankfurter](https://frankfurter.dev) exchange-rates API (free, no API key), extracts the USD rate, and returns it. The process stores the result under `exchangeResult`.

```mermaid theme={"dark"}
flowchart LR
  subgraph P [Process: currencyLookup]
    S((Start)) --> A[Get exchange rate]
    A --> B[Receive exchange rate]
    B --> E((End))
  end
  subgraph W [Workflow: Get exchange rate]
    WS((Start)) --> R[Get rates]
    R --> X[Pick USD rate]
    X --> WE((End))
  end
  A -. baseCurrency .-> WS
  WE -. rate, currency .-> B
```

The API is a stand-in. Swap in any REST API you have access to and the steps stay the same.

This is how the finished workflow looks in the Integration Designer:

![The finished Get exchange rate workflow on the canvas: a Start node, a Get rates REST API Call node, a Pick USD rate Script node, and an End node with rate and currency in its Output Schema](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-workflow-canvas.png)

Watch the workflow being built and run, from the REST API Call node to the USD rate in the output:

<video controls playsInline preload="metadata" poster="https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/first-workflow-v3.jpg" src="https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/first-workflow-v3.mp4">
  <track kind="captions" srcLang="en" label="English" src="https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/first-workflow-v3.vtt" default />
</video>

***

## Step 1: Create the data source

A data source is a reusable connection to an external system: its base URL, authorization, and the endpoints you call on it. Every workflow in the project can use it.

**1. Create a RESTful system**

In FlowX Designer, go to **Workspaces** → your workspace → **Projects** → your project → **Integrations** → **Data Sources**. Click **+**, and in the **Add Data Source** modal pick **Restful System**. Fill in:

* **Name**: `Exchange Rates`
* **Description**: `Frankfurter exchange-rates API`

Click **Create Data Source**. The system page opens.

**2. Set the base URL**

In the **Base URL** card on the system page, enter `https://api.frankfurter.dev/v1`.

> [!TIP]
>
> Base URLs usually differ per environment. You can write them as `https://api.${environment}.example.com/v1` and resolve the variable through [configuration parameters overrides](https://docs.flowx.ai/6.x/docs/projects/runtime/configuration-parameters-overrides.md).

**3. Check the authorization**

Open the **Settings** tab. Under **Authorization**, the **Auth Type** options are `NO_AUTH`, `BEARER`, `BASIC`, `SERVICE_ACCOUNT`, `PRIVATE_KEY`, and `ACCESS_KEY`. Frankfurter needs no credentials, so leave `NO_AUTH`. For a real API, pick what it requires. Token values are best defined here at system level and overridden per environment.

**4. Add an endpoint**

Open the **Endpoints** tab and click **+**. In the **Add Endpoint** dialog, pick the `GET` method and set the **Name** to `getLatestRates`, then confirm. On the endpoint page:

* **Path**: `/latest`
* On the **Query** tab, add one parameter: **Name** `base`, **Value** `EUR`, then click the green check to add the row. The value is the default the endpoint test uses; the workflow overrides it at runtime.

![Endpoint page for GET getLatestRates with the read-only Base URL, the Path set to /latest, and the Query tab showing one parameter named base with the value EUR](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-endpoint-query.png)

Back on the system page, the **Endpoints** tab now lists `getLatestRates`.

![Exchange Rates system page with the Base URL card set to the Frankfurter API and the Endpoints tab listing the GET getLatestRates endpoint](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-data-source-system.png)

**5. Test the endpoint**

Click **Test** on the endpoint page. The **Test GET getLatestRates** modal shows the resolved URL and the query parameter. Click **Test** in the modal and read the response:

```json theme={"dark"}
{
  "base": "EUR",
  "date": "2026-10-02",
  "rates": {
    "GBP": 0.85033,
    "JPY": 176.99,
    "USD": 1.1225
  }
}
```

The real response lists about 30 currencies; the rate values change daily. Click **Use as Response Example** to store the shape on the endpoint's **Response Example** tab.

![Test GET getLatestRates modal with the Exchange Rates system, the endpoint URL, the base query parameter, and a response pane showing status 200 and a JSON body with base, date, and rates](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-endpoint-test.png)

> [!TIP]
>
> The test returns status 200 and a JSON body whose `rates` object contains `USD`. If it does, the data source is ready for the workflow.

> [card] [Learn more about data sources](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md#creating-a-new-data-source-definition)

> [card] [Learn more about REST endpoints](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md#defining-rest-integration-endpoints)

***

## Step 2: Build the workflow

**1. Create the workflow**

Go to **Projects** → your project → **Integrations** → **Workflows** and click **+**. In the **Add Workflow** dialog, set the **Name** to `Get exchange rate`, add a description, under **Set Workflow Type** keep **Output Focused**, and click **Save**. The workflow editor opens with a **Start** node already on the canvas.

**2. Place the End node**

Drag an **End Flow** node from the palette onto the canvas and leave it unconnected for now; you connect it after the script. It keeps its default name, `End Flow 001`; that is the name Step 3 shows for it.

The End node comes first because output parameters belong to it: until it exists, the **Output Parameters** tab of the Data Model page says **No End node present in the workflow**.

**3. Declare the data model, inputs, and outputs**

Open the workflow's **Data Model** page from the left rail and add three attributes: `baseCurrency` (String), `rate` (Number), and `currency` (String). Select `rate` and, in **Attribute Settings**, set **Subtype** to **Floating Point**. Then:

* On the **Input Parameters** tab, add `baseCurrency`.
* On the **Output Parameters** tab, with `End Flow 001` selected in the node dropdown, click **Define parameters**, tick `rate` and `currency`, and click **Done**.

> [!WARNING]
>
> A **Number** attribute's **Subtype** defaults to **Integer**. Left that way, the workflow returns the rate `1.1225` as `1`.

This is what makes the process able to talk to the workflow in Step 3: the input mapper offers only declared input parameters, and the End node exposes only declared output parameters.

> [!NOTE]
>
> Finish the Data Model page before you configure the nodes. Going back to it later and returning to the editor can drop the **Start payload** and show the REST API Call node's endpoint as unselected; reopening the workflow from the **Workflows** list brings the endpoint back.

**4. Set the Start node sample input**

Back in the editor, the **Start** node's **Start payload** field carries the input every run begins with, as JSON. It is pre-filled from the input parameters as `{"baseCurrency": ""}`. Set it to:

```json theme={"dark"}
{
  "baseCurrency": "EUR"
}
```

At runtime the process supplies this value. The sample is what **Run Workflow** uses inside the editor.

**5. Add the REST API Call node**

Drag a **REST API Call** node from the palette, connect **Start** to it, and name it `Get rates` (double-click the node title to rename it). Configure it:

* **Endpoint**: pick `GET getLatestRates` under the Exchange Rates system (the dropdown groups endpoints by system).
* **Query Parameters** → `base`: enter `${baseCurrency}` in the field that reads **Add value or variable**. This replaces the test default with the workflow input.
* **Response Key**: `rates`

![Get rates node card with the GET getLatestRates endpoint selected and the base query parameter set to the baseCurrency workflow variable](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-rest-node.png)

The Response Key is where the next node finds the call result: the node writes the whole HTTP response under `input.rates`, and the JSON body sits at `input.rates.data`.

**6. Pick the rate with a Script node**

Drag a **Script** node after `Get rates`, connect the two, and name it `Pick USD rate`. Keep the **JS** language tab and paste:

```javascript theme={"dark"}
// input.rates = REST API Call result
const body = input.rates.data;
output.rate = body.rates.USD;
output.currency = "USD";
```

Scripts read the previous nodes' data from `input` and publish their result by assigning keys on `output`. There is no return statement.

![Pick USD rate Script node card with the JS tab selected and the four-line script that reads input.rates.data and sets output.rate and output.currency](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-script-node.png)

**7. Connect the End node**

Connect `Pick USD rate` to `End Flow 001`. The End node's card shows an **Output Schema** with `rate` and `currency`. Whatever the previous nodes wrote under those keys is the workflow's output, and it is what the calling process receives.

![End node card showing the Output Schema with rate of type number and currency of type string](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-end-node.png)

**8. Run the workflow**

Click **Run Workflow** in the top-right corner. On a draft project version the run starts immediately with the Start node's JSON, and the **Run Logs** panel opens at the bottom: a **Nodes** list with the time each node took, and **Logs**, **Input**, and **Output** tabs. Open **Output**:

```json theme={"dark"}
{
  "rate": 1.1225,
  "currency": "USD"
}
```

Each node card also gains **Input** and **Output** tabs with that run's data, which is the quickest way to see what the REST call returned.

![Run Logs panel after a successful run, listing the Workflow, Start, Get rates, Pick USD rate, and End nodes with their timings, and the Output tab showing rate 1.1225 and currency USD](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-workflow-run.png)

> [!NOTE]
>
> On a committed project version, **Run Workflow** opens a **Test Workflow** dialog first, where you edit the **Test Input** before running.

> [!TIP]
>
> The run finishes with no errors and the Output tab shows a numeric `rate` and `"USD"`. The rate differs from the one above, because the API publishes new rates every working day.

> [card] [Learn more about workflows](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md#creating-a-workflow)

> [card] [Learn more about workflow data models](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/workflow-data-models.md)

***

## Step 3: Call the workflow from a process

The process needs two things: a place to keep the input and the result, and a pair of nodes that start the workflow and wait for its answer.

**1. Create the process and its data model**

Go to **Processes**, click **+**, and create a process named `currencyLookup`. Open its **Data Model** page from the left rail and set up two attributes:

* `selectedCurrency` (String): the input the process passes to the workflow
* `exchangeResult`: where the workflow's output lands. It is an object with `rate` and `currency`, and objects are built from a data type:
  1. In the **Data Types** panel, click **+** and name the new type `ExchangeResult` in **Data Type Settings**.
  2. Add two attributes to `ExchangeResult`: `rate` (Number, with **Subtype** set to **Floating Point**, as in the workflow) and `currency` (String).
  3. Add the `exchangeResult` attribute and, in its type menu, click **Custom data type**, then pick `ExchangeResult` under **Existing** → **Process**.

**2. Add the nodes**

On the canvas, build: **Start** → **Send Message Task** named `Get exchange rate` → **Receive Message Task** named `Receive exchange rate` → **End Process**. Connect them in that order. To rename a node, select it and, in **Node settings** → **Node Config**, change **Node name** and click **Save**. The start and end nodes keep their default names, `Start_001` and `End_001`.

![The currencyLookup process on the canvas: Start, a Get exchange rate Send Message Task, a Receive exchange rate Receive Message Task, and End in one swimlane](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-process-diagram.png)

The **Start Integration Workflow** action also works on **Task** and **User Task** nodes. The send-and-receive pair is the plain form: the send node fires the workflow, the receive node parks the token until the output arrives.

**3. Add the Start Integration Workflow action**

Select `Get exchange rate`, open **Node settings** → **Actions**, and click **+**. Give the action a name, check that **Action Type** is **Start Integration Workflow** (the default on a Send Message Task), and leave **Trigger**, **Execution**, and **Navigation** at their defaults, so the action runs on its own when the token arrives.

In the workflow field (**Search workflow by name**), pick `Get exchange rate`. Under **Data mapping**, leave **Legacy mapping** off. The **Input Mapping** section lists the **Workflow nodes** that take input: click the wrench on the **Start** row.

![Action Edit form with Action Type set to Start Integration Workflow, the Get exchange rate workflow selected, Legacy mapping off, and the Input Mapping section listing the Start workflow node with its wrench button](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-action-config.png)

**4. Map the process data to the workflow input**

The **Data Mapping Integration Start Node Start** modal opens. The left pane lists the process attributes sent to the workflow; the right pane lists the workflow's input parameters.

1. If the left pane says **No process Parameters**, click **Define parameters**, tick `selectedCurrency`, and click **Done**.
2. In the right pane, click the field next to `baseCurrency`, type `${selectedCurrency}`, and pick the suggestion that appears.
3. Click **Confirm**, then **Save** on the action form.

![Data mapping modal for the workflow Start node: selectedCurrency listed under Variables sent by the main process on the left, and baseCurrency mapped to the selectedCurrency variable under Variables expected by the workflow on the right](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-input-mapping.png)

**5. Receive the workflow output**

Select `Receive exchange rate` and open **Node settings** → **Node Config**. Under **Integration Output**, click **Add Stream** and configure the **Data Stream**:

* **Source**: **Workflow** (the default)
* **Select workflow**: `Get exchange rate`
* **Legacy Mapping**: leave off

The **Output Mapping** section lists the workflow nodes that produce output. Click the wrench on the **End Flow 001** row.

![Receive exchange rate node configuration with a Data Stream whose Source is Workflow and workflow is Get exchange rate, Legacy Mapping off, and the Output Mapping section listing the End workflow node with its wrench button](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-receive-output-config.png)

**6. Map the workflow output to the process**

The **Data Mapping Integration End Node End Flow 001** modal opens, mirrored: the workflow's output parameters on the left, the process attributes on the right.

1. Add the targets to the right pane: it says **No process Parameters**, so click **Select from data model**, tick `rate` and `currency` under `exchangeResult`, and click **Done**.
2. Next to `exchangeResult.rate` type `${rate}` and pick the suggestion; next to `exchangeResult.currency` type `${currency}` and pick the suggestion.
3. Click **Confirm**, then **Save** on the node.

![Data mapping modal for the workflow End node: rate and currency listed under Variables returned by the workflow on the left, and the exchangeResult object on the right with its rate and currency attributes mapped to the rate and currency variables](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-output-mapping.png)

> [!NOTE]
>
> **Legacy Mapping** is the alternative: turn it on and set a single **Key Name**, and the whole workflow output lands under that key without per-attribute mapping. The mapper is the default because it keeps the process data model explicit.

> [card] [Learn more about the Start Integration Workflow action](https://docs.flowx.ai/6.x/docs/building-blocks/actions/start-integration-workflow.md)

***

## Step 4: Run it end to end

**1. Start the process**

Click **Start Process** in the top-right corner. In the dialog, set **JSON data** to:

```json theme={"dark"}
{
  "selectedCurrency": "EUR"
}
```

and click **Start Process**. The JSON editor closes braces for you, so if you type or paste the block, check that it ends with a single `}`.

There is no screen to fill in: the token runs through the four nodes on its own. The editor switches to a preview that keeps loading; you can leave it and go on to **Runtime**.

**2. Inspect the instance**

Switch to **Runtime** and open **Process Instances**. The newest `currencyLookup` instance is **FINISHED** with `End_001` as its current node. Open it: the diagram highlights the path Start → Get exchange rate → Receive exchange rate → End, the **Variables** tab shows the data, and the **Tokens** tab shows the single token with `End_001` as its current node.

![A finished currencyLookup process instance with its diagram, a FINISHED status badge, and the Variables tab showing selectedCurrency EUR and an exchangeResult object with rate 1.1225 and currency USD](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/fw-process-instance.png)

> [!TIP]
>
> `exchangeResult.rate` holds a number and `exchangeResult.currency` holds `USD`. That round trip, process to workflow to external API and back into the process data, is the pattern behind most FlowX integrations.

***

## Troubleshooting

> [accordion] The input mapper's left pane says No process Parameters
>
> The action does not know yet which process attributes to offer. Click **Define parameters** in the left pane, tick `selectedCurrency`, and click **Done**. The attribute then appears and can be mapped.

> [accordion] The input mapper's right pane is empty
>
> The workflow has no input parameters declared, so there is nothing to map to. Open the workflow's **Data Model** page and add `baseCurrency` under **Input Parameters**, then reopen the mapper.

> [accordion] Typing the attribute name only offers Add new attribute
>
> The mapper matches the expression form, not the bare name. Type the full `${selectedCurrency}` (with the dollar sign and braces) and pick the suggestion that appears below the field.

> [accordion] The rate comes back as a whole number, such as 1
>
> A **Number** attribute's **Subtype** defaults to **Integer**, which drops the decimals. Open the workflow's **Data Model** page, select `rate`, and set **Subtype** to **Floating Point** in **Attribute Settings**. Do the same for `rate` in the process's `ExchangeResult` data type, then run again.

> [accordion] The Output Parameters tab says No End node present in the workflow
>
> Output parameters belong to an End node. Add the **End Flow** node to the canvas first, then open **Output Parameters**, pick the End node in the dropdown, and click **Define parameters**.

> [accordion] The script fails reading rates
>
> The Script node reads `input.rates.data`, so the REST API Call node's **Response Key** must be exactly `rates`. If you used another key, change either the key or the first line of the script to match. Open the `Get rates` node's **Output** tab after a run to see the exact shape it produced.

***

## What you learned

| Concept | How you used it |
| - | - |
| **Data source** | A RESTful system with a base URL, an auth type, and a tested `GET` endpoint |
| **Workflow data model** | Input and output parameters that make the Start and End nodes typed |
| **REST API Call node** | Calling the endpoint with a workflow variable and naming the result with a Response Key |
| **Script node** | Shaping the response into the two values the process needs |
| **Start Integration Workflow action** | Starting the workflow from a Send Message Task with mapper-mode input mapping |
| **Integration Output** | Receiving the output on a Receive Message Task and mapping it into `exchangeResult` |

***

## Where to go next

> [card] [Integration Designer](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/integration-designer.md)
>
> The full reference: endpoint parameters, authorization, caching, file handling, and every workflow node.

> [card] [Workflow data models](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/workflow-data-models.md)
>
> Typed inputs and outputs for workflows, with automatic Start-node pre-fill.

> [card] [Start integration workflow action](https://docs.flowx.ai/6.x/docs/building-blocks/actions/start-integration-workflow.md)
>
> Everything about calling workflows from processes, including when to use subprocesses instead.

> [card] [Cookbook: call an external API](https://docs.flowx.ai/6.x/cookbooks/call-external-api.md)
>
> Your next build: send data to a workflow, call a real API, and map the reply back into the process.

> [card] [Cookbooks](https://docs.flowx.ai/6.x/cookbooks/overview.md)
>
> Tutorials, guides, and patterns to build on what you just learned.


## Related topics

- [Tutorial: Build your first UI Flow](https://docs.flowx.ai/6.x/docs/getting-started/building-your-first-ui-flow.md)
- [Tutorials](https://docs.flowx.ai/6.x/ai-platform/tutorials/overview.md)
- [Tutorial: Build a credit card application](https://docs.flowx.ai/6.x/docs/getting-started/building-your-first-proc.md)
- [Workflow data model](https://docs.flowx.ai/6.x/docs/platform-deep-dive/integrations/workflow-data-models.md)
- [Start integration workflow action](https://docs.flowx.ai/6.x/docs/building-blocks/actions/start-integration-workflow.md)


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