Create workflow functions to reuse queries and logic
Learn how to create workflow functions.
Workflow functions enable you to create complex logic and queries that can be reused throughout a workflow. You can call workflow functions anywhere in a workflow as function blocks, using JavaScript, or within a Loop block. Workflow functions support optional parameters and have access to the global workflow scope.
While workflow functions can be reused within a single workflow, they cannot currently be reused between multiple workflows.
Single-step and multi-step workflow functions
You can choose whether a workflow function is single-step or multi-step. The type you choose depends on the complexity or functionality required.
- Single-step: The workflow function contains a single query that runs with optional parameters when called. Single-step functions are useful for simple logic, such as retrieving database records or transforming results.
- Multi-step: The workflow function operates as a self-contained workflow with optional parameters. It has its own control flow and is assembled in the same way as its parent workflow. It supports most available block types, including logic and response blocks, and emits block-level logs. Multi-step workflow functions are useful for complex operations with many steps.
1. Add a workflow function
First, click Functions in the left panel, then create a workflow function. Then, configure the workflow function.
- Define any optional parameters to pass into a workflow function when called. Click + Add parameter and set the parameter name. You can optionally provide a test value that is used only when the workflow function is tested.
- Select whether to use a single-step or multi-step workflow function type.
Changing a workflow function from multi-step to single-step permanently deletes the multi-step workflow function logic.
2. Configure workflow function logic
- Single-step
- Multi-step
The Query section contains the query or code that runs when the workflow function is called. You can select a resource to query, Run JS Code or Run Python Code to execute JavaScript or Python code, or Retool Workflow to trigger another workflow.
For example, you could create a workflow function that sends a trial expiration notification to customers when the trial is three days and one day from expiration. Instead of adding two separate blocks to send emails, you can create a single workflow function and reuse it. The workflow first filters the customer data to determine which trials expire in 24 hours or in three days, then calls the same workflow function. The workflow function receives the customer's name and email address as parameters, along with either tomorrow or the trial expiration date.

Configure the resource or code that the workflow function runs when called.
A multi-step workflow function has its own blocks and control flow. Click Edit function to edit the workflow function and assemble its blocks. You can also call other workflow functions from within multi-step workflow functions.
When you edit the workflow function, the canvas switches to Function mode so you can assemble the workflow function's blocks directly on the canvas. When in this mode, the canvas background is blue. Click Return to workflow at any time to go back to the workflow.
For example, you could create a workflow function that sends a trial expiration notification to customers when the trial is three days and one day from expiration. In the single-step workflow function example, the workflow contained the logic to determine which trials expired in 24 hours and in three days. With a multi-step workflow function, the workflow can be streamlined by offloading the logic to the workflow function.

A multi-step workflow function with branched logic.
The customer data is passed as the workflow function parameter, and the multi-step workflow handles the remaining logic. Since there is already a single-step workflow function to send emails, the multi-step workflow function can reference it in the same way as the workflow. As a result, the workflow only needs to call the multi-step workflow function after retrieving the customer data.
Logs for multi-step workflow functions are available in the Run history panel. These block-level logs are nested under whichever block or loop iteration called the workflow function.
By default, multi-step workflow functions return the results of their final block to their parent workflow. These results can be accessed by referencing the .data property of the block that invoked the multi-step workflow function.
4. Test the workflow function
Click ▶︎ Test to run the workflow function. If your workflow function makes use of parameters, any test values you provided are used.
5. Call the workflow function from the workflow
You can call a workflow function using the following methods:
- Using the Function block to the workflow.
- Within a JavaScript Code block.
- As the loop runner for a Loop block.
Loop blocks and Function blocks that call multi-step workflow functions do not support custom timeouts. Instead, these blocks use a total timeout that is calculated by adding the timeouts of each block in the multi-step workflow function.
If a timeout is necessary for a multi-step workflow function, you can call the workflow function within a Code blocks and set a timeout on the Code block itself.
The workflow timeout always takes precedence over timeouts set within blocks or workflow functions.
- Function block
- JavaScript Code block
- Loop block
Click in the left panel to open the Blocks tab, then drag the Function block type to the canvas. You can also right-click anywhere on the canvas to display the Add block contextual menu.
If you defined any parameters for the selected workflow function, the block displays input fields for you to populate. You can then reference any data using {{ }} expressions, such as {{ getCustomersOnTrial.data }}.

A streamlined workflow using a multi-step workflow function.
You can call a workflow function from a JavaScript Code block using await and the workflow function name. For example:
const email = getUsers.data[0].email;
const name = getUsers.data[0].name;
await function1(name, email);
Loop blocks can call a workflow function so that it is used for every loop iteration. Set the Loop runner to the desired workflow function and use {{value}} or {{index}} to reference evaluated items in parameters.

A Loop block that calls a workflow function.
The Function block returns its output back to the block from which it was called, allowing the output to be used in the rest of the workflow.
The Run History menu panel shows the workflow run. Click multi-step workflow functions to expand them and see the run logs of the blocks within them.

Run History that includes a multi-step workflow function.
Convert a group of blocks to a multi-step workflow function
You can convert a group of blocks within an existing workflow to a multi-step workflow function. First, press and hold shift while click-and-dragging on the canvas to select a group of blocks. Next, right-click on the selection area and click Create function.

Convert a group of blocks to a workflow function.
The selected blocks are then replaced in the workflow by a Function block that references the newly created workflow function.