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

# Call an external API from a process

> Connect a public REST API through a data source, wrap it in an integration workflow, and map the result back into process data - the send, workflow, receive pattern end to end.

Every FlowX integration that fetches data for a running process follows the same round trip: the process **sends** a request to an integration workflow, the workflow calls the external system and shapes the result, and the process **receives** the output into its instance data. This cookbook builds that round trip once, end to end, with a real public API - and shows you where each hop breaks, what the error looks like, and how to fix it.

You build a one-time-code generator: a process asks the [random.org](https://www.random.org) integers API for a 4-digit number and displays it. The API is deliberately minimal - no authentication, a plain-text response - so every step stays visible. Swap in your own API and the steps are identical.

<Info>
  **Prerequisites**: a project in your workspace and access to FlowX.AI Designer. If integration workflows are new to you, read [Build your first workflow](/5.9/docs/getting-started/building-your-first-workflow) first - it introduces the same three building blocks conceptually. This cookbook is the hands-on companion: a concrete build you can reproduce click for click, plus the runtime failure modes.
</Info>

***

## The pattern

Three resources, one hop each:

1. A **data source** holds the connection: base URL, authorization, and reusable endpoint definitions.
2. An **integration workflow** calls the endpoint and declares what it returns. Whatever the workflow declares as output becomes a runtime contract.
3. In the process, a **Send Message Task** starts the workflow and a **Receive Message Task** maps its output into process data.

Each hop has its own key namespace, and each has its own failure signature when a key doesn't match - the [When it fails](#when-it-fails) section maps all three.

***

## Step 1: Create the data source

<Steps>
  <Step title="Add a RESTful System">
    In FlowX.AI Designer, go to your project → **Integrations** → **Data Sources**, click **+**, and pick **RESTful System**:

    * **Name**: `RandomNumber`
    * **Base URL**: `https://www.random.org/`
    * **Authorization**: **No Auth** - the random.org integers endpoint is public
  </Step>

  <Step title="Define the endpoint">
    Add an endpoint named `getNumber`:

    * **Method**: `GET`
    * **Path**: `integers/`
    * **Query parameters**:

    | Parameter | Value   | What it does                                             |
    | --------- | ------- | -------------------------------------------------------- |
    | `num`     | `1`     | One number per request                                   |
    | `min`     | `1000`  | Lower bound                                              |
    | `max`     | `9999`  | Upper bound - together with `min`, always a 4-digit code |
    | `col`     | `1`     | One column of output                                     |
    | `base`    | `10`    | Decimal                                                  |
    | `format`  | `plain` | Plain-text response body                                 |
    | `rnd`     | `new`   | Freshly generated randomness                             |

    <Frame>
      ![The getNumber endpoint in the RandomNumber data source, with the base URL, the integers/ path, and the seven query parameters defined in the Query tab](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/cookbooks/cb-ext-api-01-data-source-endpoint.png)
    </Frame>
  </Step>
</Steps>

<Info>
  `format=plain` means the API answers with `text/plain` - the body is the bare number followed by a newline, for example `7841\n`, not JSON. That trailing newline is invisible in most tools but matters later: see [Plain-text responses](#plain-text-responses-and-the-end-node) below.
</Info>

***

## Step 2: Build the workflow

<Steps>
  <Step title="Create the workflow">
    Go to **Integrations** → **Workflows** and create a workflow named `getNumber`. It starts with a **Start** node - this workflow needs no input, so leave it empty.
  </Step>

  <Step title="Add the REST API Call node">
    Add a **REST API Call** node after Start and select the `getNumber` endpoint (endpoints are grouped by data source). Set its **Response Key** to `responseKey`.

    The node stores its full result under that key: the response body at `responseKey.data`, plus `responseKey.metadata` (status code and headers) and `responseKey.hasError`. Every placeholder downstream references the body as `${responseKey.data}`.

    <Frame>
      ![The getNumber workflow canvas: Start, the Call random.org REST node, a success End node with the output schema, and an End failure node](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/cookbooks/cb-ext-api-02-workflow-canvas.png)
    </Frame>

    <Frame>
      ![The REST API Call node with the getNumber endpoint selected, the seven query parameters inherited from the endpoint, and the Response Key set to responseKey](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/cookbooks/cb-ext-api-03-rest-node-config.png)
    </Frame>
  </Step>

  <Step title="Branch success and failure">
    Connect the REST node to two **End** nodes: one on the **success** branch, one on the **failure** branch. The failure branch keeps a timeout or non-2xx response from masquerading as a result.
  </Step>

  <Step title="Test the REST node on its own">
    Run the workflow from the editor and open the REST node in the run details - it shows the exact input it sent and the output it stored. Confirm the body sits at `responseKey.data` before wiring anything else.
  </Step>
</Steps>

***

## Step 3: Declare the workflow output

The calling process only receives what the workflow declares as output. Declare it through the workflow data model, then mark it as the success End node's output.

<Steps>
  <Step title="Model the output attribute">
    In the workflow's data model, add an object attribute `responseKey` with a string attribute `data` under it - mirroring where the REST node stores the body.
  </Step>

  <Step title="Set the End node output">
    On the success End node, set the output to `responseKey.data`. This is the declared output parameter: the value the calling process gets back.

    <Frame>
      ![The workflow's Output Parameters tab with the End node selected and the responseKey object with its data string attribute declared as the output schema](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/cookbooks/cb-ext-api-04-output-data-model.png)
    </Frame>
  </Step>
</Steps>

<Warning>
  Declared output parameters are a **runtime contract**. If any declared parameter resolves to no value when the run reaches the End node, the run fails and the calling process records an incident - see [mandatory output parameters missing](/5.9/docs/resources/error-glossary#the-mandatory-output-parameters-of-the-workflow-are-missing-at-runtime). A misspelled key resolves silently to `null`, so the contract failing is often the only symptom.
</Warning>

### Plain-text responses and the End node

If you hand-write the End node's payload as JSON instead of mapping the data model, placeholders are substituted as raw text. For this API the body is `7841\n`, and the trailing newline makes `{"value": "${responseKey.data}"}` invalid JSON - the run fails with [Executing an end node produced an error!](/5.9/docs/resources/error-glossary#executing-an-end-node-produced-an-error). Keep the placeholder unquoted for numeric values, or clean the value in a Script node first. The data-model mapping used in this cookbook carries the value as a string and avoids the problem entirely.

***

## Step 4: Start the workflow from the process

<Steps>
  <Step title="Add the Send Message Task">
    In your BPMN process, add a **Send Message Task** node where the code should be requested.
  </Step>

  <Step title="Configure the Start Integration Workflow action">
    Add a **Start Integration Workflow** action on the node and select the `getNumber` workflow. This workflow declares no input, so there is nothing to map - for an API that takes parameters, map process data to the workflow's declared input parameters here.

    <Frame>
      ![The Start Integration Workflow action on the Request code Send Message Task, showing the input mapping panel for the selected getNumber workflow](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/cookbooks/cb-ext-api-05-send-action.png)
    </Frame>
  </Step>
</Steps>

For the action's full options, including when to use it on Task and User Task nodes, see [Start integration workflow](/5.9/docs/building-blocks/actions/start-integration-workflow).

***

## Step 5: Receive the output

<Steps>
  <Step title="Add the Receive Message Task">
    Add a **Receive Message Task** directly after the Send Message Task. The process waits here until the workflow replies.
  </Step>

  <Step title="Select the workflow as the data stream">
    In the node's **Integration Output** section, add a data stream (**Add Stream**), set its **Source** to **Workflow**, and select `getNumber` in the **Select workflow** dropdown.

    <Frame>
      ![The Receive Message Task node config with the Output Mapping section listing the workflow's End and End failure nodes, each with its own mapping](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/cookbooks/cb-ext-api-06-receive-data-stream.png)
    </Frame>
  </Step>

  <Step title="Map the output">
    Open the **Output Mapping** for the workflow's success End node and map the workflow output to the process attribute that should receive it - for example `generatedNumber`. Click **Test** to preview the mapped result, then **Update** to store the mapping.

    <Frame>
      ![The data mapping modal for the workflow's End node: responseKey.data mapped to the generatedNumber process attribute, with the Test button and the previewed mapping output](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/cookbooks/cb-ext-api-07-output-mapping-modal.png)
    </Frame>
  </Step>

  <Step title="Save the node">
    Save the Receive Message Task itself. The mapping is persisted only when the node is saved.
  </Step>
</Steps>

<Warning>
  **Test only previews - Update stores.** Closing the mapping modal without clicking **Update**, or skipping the node save, leaves the node with no mapping. Every reply then fails at runtime with [missing mapping in the data stream](/5.9/docs/resources/error-glossary#workflow-output-cannot-be-appended-to-the-process-instance-due-to-missing-mapping-in-the-data-stream) - and the workflow run itself finishes cleanly, which makes this one easy to misdiagnose.
</Warning>

<Tip>
  The mapping modal belongs to the **data mappers** mode, the default. Older configurations use the **Legacy Mapping** toggle and a single hand-typed key instead - both modes work at runtime. See [Legacy mapping vs data mappers](/5.9/docs/building-blocks/node/message-send-received-task-node#legacy-mapping-vs-data-mappers).
</Tip>

***

## Step 6: Run it end to end

Start a process instance and let it pass the Send Message Task. When the Receive Message Task completes, the instance data holds the code under `generatedNumber` - every node after it can read the value, display it in the UI, or branch on it.

To see the round trip from the workflow's side, open the workflow's run details: each node shows the exact input it received and the output it produced, so you can watch `responseKey.data` travel from the REST node through the End node.

<Frame>
  ![Workflow run details with the End node selected and its Output tab showing the responseKey object carrying the plain-text number in data](https://s3.eu-west-1.amazonaws.com/docx.flowx.ai/cookbooks/cb-ext-api-08-run-details.png)
</Frame>

<Check>
  You built a reusable data source, a workflow with a declared output contract, and a process that delegates the call and maps the result - the pattern behind most FlowX integrations.
</Check>

***

## When it fails

Each hop fails with its own signature. All three are documented in depth in the [error glossary](/5.9/docs/resources/error-glossary#integration-workflow-output):

| Symptom                                                                                                 | Broken hop                                                                                                                                                                    | Where to look                                                                                                                                             |
| ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `The mandatory output parameters of the workflow are missing at runtime.`                               | The End node's output resolved to `null` - usually a misspelled key. The REST call itself likely succeeded.                                                                   | [Glossary entry](/5.9/docs/resources/error-glossary#the-mandatory-output-parameters-of-the-workflow-are-missing-at-runtime)                               |
| `Workflow output cannot be appended to the process instance due to missing mapping in the data stream.` | The Receive Message Task has no persisted output mapping - **Update** or the node save was skipped. The workflow run finishes fine.                                           | [Glossary entry](/5.9/docs/resources/error-glossary#workflow-output-cannot-be-appended-to-the-process-instance-due-to-missing-mapping-in-the-data-stream) |
| `Executing an end node produced an error!`                                                              | The End node's hand-written payload stopped being valid JSON after placeholder substitution - typically a plain-text response with a trailing newline inside a quoted string. | [Glossary entry](/5.9/docs/resources/error-glossary#executing-an-end-node-produced-an-error)                                                              |

<Warning>
  A failed workflow reply is **not retried**. An instance whose call failed stays blocked at the Receive Message Task permanently - after fixing the configuration, always test with a new process instance.
</Warning>

***

## Related resources

<CardGroup cols={2}>
  <Card title="Build your first workflow" icon="diagram-next" href="/5.9/docs/getting-started/building-your-first-workflow">
    The conceptual introduction to data sources, workflows, and process actions.
  </Card>

  <Card title="Integration Designer" icon="plug" href="/5.9/docs/platform-deep-dive/integrations/integration-designer">
    The full reference: endpoint parameters, authorization, variables, and every workflow node.
  </Card>

  <Card title="Send and Receive Message Tasks" icon="envelope" href="/5.9/docs/building-blocks/node/message-send-received-task-node">
    Node configuration in detail, including data streams and mapping modes.
  </Card>

  <Card title="Error glossary: integration workflow output" icon="circle-exclamation" href="/5.9/docs/resources/error-glossary#integration-workflow-output">
    The three runtime errors of this pattern, with causes and fixes.
  </Card>
</CardGroup>


## Related topics

- [Cookbooks](/5.9/cookbooks/overview.md)
- [Consuming FlowX from external apps](/5.9/docs/platform-deep-dive/integrations/consuming-flowx-from-external-apps.md)
- [Get build info by process instance](/5.9/docs/api/start-process/build-info-by-process-instance.md)
- [FlowX.AI 5.2.0 Release Notes](/release-notes/v5.x/v5.2.0-november-2025/v5.2.0-november-2025.md)
- [FlowX.AI 5.1.0 Release Notes](/release-notes/v5.x/v5.1.x-lts/v5.1.0-october-2025/v5.1.0-october-2025.md)
