- Introduction
- Getting Started with UiPath Agents
- Getting Started with UiPath Agents using LangGraph
- Building a Low-Code Agent in Studio Web
- Adding Tools to Your UiPath Agent
- Getting Started with UiPath Maestro Flow
Build the flow
Build the Price Watch Flow using VS Code by adding each of the 6 nodes and configuring them.
Now that we have scaffolded our project from Step 1, we will cover the foundational building blocks, and then add the five remaining nodes, the three trigger inputs, and the one output variable for our Flow.
We will be using the terms "downstream" and "upstream" for the rest of this tutorial, and you should familiarize yourself with them.
- Upstream: the nodes that come before a given node in the flow's execution path. A node's upstream nodes are everything it depends on: their outputs feed into it, and they must complete before it can run.
- Downstream: the nodes that come after a given node in the flow's execution path. A node's downstream nodes are everything that depends on it: they consume its outputs and are affected if it fails, changes, or is re-run.
How to rename a node ID
During this tutorial, we will be renaming the generated node ID values in most of the steps for this tutorial to make them easier to read. It is easier to understand what a node called fetchRate1 does than httpRequest1. A node consists of a label and an ID.
You can have multiple nodes with the same label, but each ID is required to be unique. When adding a new node, the default value for ID is the node type with a number appended, starting at 1. As an example, adding the first End node type will have an ID of end1 and the second will be end2. Changing the label of a node does not update the ID.
The steps to change a node's ID are:
- Select the node on the canvas to show the inline toolbar above it.
- Select the pencil, Edit.
- Open the Advanced tab, and you will see the ID field displayed as a read-only field, with a pencil button beside it to Rename node ID.
- Select that pencil to open a Rename node ID dialog with an input for New ID.
- Enter the new ID and select Rename.
The dialog will include details for any updates required when renaming the ID field, for example "3 references will be updated", "2 connections", and "1 expression in other nodes". The Rename option will stay disabled until you make a change to the value, and will then update all the references that were shown.
Step 2 - Building the Flow
We will now build our Price Watch workflow one node at a time. In VS code, open PriceWatch/PriceWatch.flow - you should see one Manual trigger node named start on the canvas.
Step 2.1 - Declare the trigger inputs
We need to add three inputs to the starting trigger node that we will use in our Frankfurter API call. The baseCurrency is the one we require the current exchange rate for from the quoteCurrency, and the alertThreshold is the value below which we want to be alerted on. Let's add these 3 inputs with:
-
Select the Manual trigger node on the canvas.
-
Open the properties of the node with the "Edit" button.
-
Use the
+ Add input argumentbutton to addbaseCurrencywith typeStringand default valueUSD. -
Use the
+ Add input argumentbutton to addquoteCurrencywith typeStringand default valueEUR. -
Use the
+ Add input argumentbutton to addalertThresholdwith typeNumberand default value0.9. -
Confirm that you have added all 3 input variables by comparing it to the image below:
Step 2.2 - Add the HTTP Request node
The HTTP node type will be used to call the Frankfurter API to retrieve the exchange rate data using our 3 trigger input variables. Create it with the following steps:
-
Select the + on the outgoing handle of the Manual trigger node.
-
Search the node palette for HTTP Request and select it.
-
Open the properties of the new node with the "Edit" button.
-
Set the node Label to
Fetch rate. -
Rename the
IDfield fromhttpRequest1tofetchRate1. -
In the properties panel, leave Authentication set to Manual authentication.
-
Set the HTTP Method to
GET. -
Set the URL to
https://api.frankfurter.dev/v2/rates. -
Under the Query parameters section, use
+ Add pairtwice to add two empty key/value pairs. -
For the first pair, set the key to
baseand value to$vars.start.output.baseCurrency. -
For the second pair, set the key to
quotesand value to$vars.start.output.quoteCurrency.
Confirm the node's ID in the properties panel reads fetchRate1 under the Advanced tab and that both query parameters are saved. At run time the node requests https://api.frankfurter.dev/v2/rates?base=USD"es=EUR and exposes exactly three keys:
$vars.fetchRate1.output.body- the parsed response body$vars.fetchRate1.output.code- the HTTP response status code$vars.fetchRate1.output.headers- the HTTP response headers
Under the hood, any HTTP Request node requires an Integration Service to make an API call. This usually requires first creating one, and then referencing it from the HTTP Request node. As the Frankfurter API does not require authentication, setting the Authentication method to Manual authentication creates an implicit connection using the configuration we provided instead of requiring us to create the connection first, and then selecting it from the dropdown.
Step 2.3 - Reshape the response with a Script node
We will use a Script node to extract the current exchange rate, and compare it to our alert threshold value. The data from the body of Frankfurter API's response JSON is an array as you can request the exchange rate for multiple currencies in a single API call. The array will have one entry per quoted currency - we will only include 1 quoteCurrency value, so the array will always contain only 1 result:
[
{
"date": "2026-09-01",
"base": "USD",
"quote": "EUR",
"rate": 0.86111
}
]
[
{
"date": "2026-09-01",
"base": "USD",
"quote": "EUR",
"rate": 0.86111
}
]
Follow these steps to create the Script node:
-
Select the + on the outgoing handle of the Fetch rate node.
-
Search the node palette for Script and select it.
-
Open the properties of the new Script node with the "Edit" button.
-
Set the node's Label to
Reshape rate. -
Rename the
IDfromscript1toreshapeRate1. -
In the script editor, enter the following:
const rates = $vars.fetchRate1.output.body; const quote = $vars.start.output.quoteCurrency; const match = rates.find(function (entry) { return entry.quote === quote; }); const rate = match.rate; return { pair: match.base + "/" + quote, rate: rate, asOf: match.date, belowThreshold: rate < $vars.start.output.alertThreshold };const rates = $vars.fetchRate1.output.body; const quote = $vars.start.output.quoteCurrency; const match = rates.find(function (entry) { return entry.quote === quote; }); const rate = match.rate; return { pair: match.base + "/" + quote, rate: rate, asOf: match.date, belowThreshold: rate < $vars.start.output.alertThreshold };
Even though we know there will only be a single result in the API, the script shouldn't assume the value we want is the first entry. Instead of using an index location reference with rates[0] or searching for an entry with "EUR" in it, we find the entry where quote matches the quoteCurrency value supplied from the trigger's input variable. The script then compares the current rate against the threshold and includes the result in the node's output object, keeping the comparison logic next to the code that consumes the API data rather than repeating it in the Decision node.
Enter the body exactly as shown, with no function wrapper. A function main(input) { … } wrapper around the code will still execute successfully, but it will return null instead of the return object. This will prevent downstream nodes using the data - this is different from UiPath Coded Function, which does use the wrapper.
Downstream nodes can now read the output variables as:
$vars.reshapeRate1.output.pair$vars.reshapeRate1.output.rate$vars.reshapeRate1.output.asOf$vars.reshapeRate1.output.belowThreshold
Step 2.4 - Route based on the result
A Decision node splits the flow into two paths based on the value of belowThreshold - it is a boolean, so can only be true or false. For each of these branches, we will add an End node to return the result using an output variable. We set the value of this output variable on each of the Decision node's branches, but first we need to create the variable, and then use it when adding our Decision node:
-
Select the Variables tab in the properties panel with no node selected.
-
Use the
+next to "Outputs" to open the dialog to add an output variable. -
Create the variable with the name
watchResult, typeObject, and no default value. -
Select the + on the outgoing handle of the Reshape rate node.
-
Search the node palette for Decision and select it.
-
Open the properties of the new node with the "Edit" button.
-
Set the node's Label to
Below threshold. -
Rename the node's
IDfromdecision1tobelowThreshold1. -
Set Condition to:
$vars.reshapeRate1.output.belowThreshold === true$vars.reshapeRate1.output.belowThreshold === trueNo
=js:prefix here, unlike the query parameters on the HTTP node. A Decision expression is a native Flow field that the Flow engine evaluates itself, so it is already JavaScript. -
Set the True branch label to
Alert. -
Set the False branch label to
No action.The labels appear on the node's two output handles, so the canvas and the execution trace both read as business rules rather than as
trueandfalse.
Step 2.5 - Add the Alert End node
The Decision node has 2 branches, first, add the Alert branch's one with:
-
Select the + on the Alert branch.
-
Search the node palette for End and select it.
-
Open the properties of the new End node with the "Edit" button.
-
On the Parameters tab, set the Expression for
watchResultto:$vars.reshapeRate1.output$vars.reshapeRate1.output -
On the Advanced tab, set the Label to
End alert. -
Rename the node's ID from
end1toendAlert1.
Step 2.6 - Add the No Action End node
Now add the No action End node for the other branch of the Decision node with:
-
Select the + on the No action branch.
-
Search the node palette for End and select it.
-
Open the properties of the new End node with the "Edit" button.
-
On the Parameters tab, set the Expression for
watchResultto:$vars.reshapeRate1.output$vars.reshapeRate1.output -
On the Advanced tab, set the node's Label to
End no action. -
Rename the node's ID from
end2toendNoAction1.
Review
The canvas should now show six connected nodes and five edges, a single fork after the Decision node, and both End nodes carry a mapping for watchResult. Your Flow should now look similar to the one below, you can use the broom icon to arrange the nodes in the Flow, and the Fit to screen button to resize the Canvas to fit your screen.
Next Step
Now that it is built, we will Verify the Flow using the uip maestro flow validate command.
- How to rename a node ID
- Step 2 - Building the Flow
- Step 2.1 - Declare the trigger inputs
- Step 2.2 - Add the HTTP Request node
- Step 2.3 - Reshape the response with a Script node
- Step 2.4 - Route based on the result
- Step 2.5 - Add the Alert End node
- Step 2.6 - Add the No Action End node
- Review
- Next Step