Skip to main content

CallFlow Node

The CallFlow node invokes another flow as a sub-flow, passing data and receiving results. It enables modular workflow design, allowing you to reuse common logic across multiple workflows.

How It Works

The CallFlow node:

  1. Takes input data from the current flow
  2. Passes parameters to the target sub-flow
  3. Executes the sub-flow (which has a FromFlow trigger)
  4. Receives the response data
  5. Continues processing in the parent flow

Adding a CallFlow

  1. Drag CallFlow from the Inputs section of the Element Panel
  2. Connect it to your data flow
  3. Click the CallFlow node to configure
  4. Select the target flow and map parameters

Configuration Panel

Target Flow Selection

Select Flow: Choose which flow to invoke. Only flows with FromFlow triggers are available as targets.

Requirements for target flow:

  • Must have a FromFlow trigger (not HTTP or Schedule)
  • Must be saved (not necessarily deployed)
  • Must have defined input parameters

Input Mode

Choose how data is passed to the sub-flow:

Single Row Mode

Calls the sub-flow once for each row:

How it works:

  • Each input row triggers one sub-flow execution
  • Row fields are available as parameters
  • Sub-flow runs N times for N input rows

Use when:

  • Processing individual records
  • Each item needs separate processing
  • Results should map back to input rows

Example:

10 orders → CallFlow → 10 sub-flow executions → 10 results

Batch Mode

Calls the sub-flow once with all data:

How it works:

  • All input rows passed as a single parameter
  • Sub-flow runs once
  • Returns aggregated results

Use when:

  • Bulk processing
  • Aggregated operations
  • Performance optimization

Example:

10 orders → CallFlow → 1 sub-flow execution → bulk results

Parameter Mapping

Map data from the current flow to sub-flow parameters:

Configuration:

Sub-Flow ParameterSource
customerId{CustomerID}
orderDate{OrderDate}
amount{Total}

Source types:

  • Field reference - {FieldName} from upstream data
  • Literal value - Fixed value for all calls
  • Expression - Calculated value
  • Parent parameter - {triggerParam} from parent trigger

Response Handling

Configure how sub-flow results are integrated:

Structured Response Format

CallFlow returns a structured response with status and results:

Success Response:

{
"status": true,
"response": [
{ "field1": "value1", "field2": "value2" },
{ "field1": "value3", "field2": "value4" }
]
}

Failure Response:

{
"status": false,
"response": "Flow 'ProcessOrder' returned no data"
}

Output Fields:

FieldTypeDescription
statusBooleantrue if sub-flow executed successfully, false otherwise
responseArray or StringArray of result rows on success, error message on failure

Tip: Use a Condition node after CallFlow to check ${status} before processing ${response} data. This ensures robust error handling in your parent flow.

Include Response Fields

Select which fields from the sub-flow response to include:

All fields: Sub-flow output fields are added to the result.

Selected fields: Choose specific fields to include.

Field Naming

Prevent field name conflicts:

  • Prefix - Add prefix like subflow_
  • Rename - Map individual field names
  • Replace - Sub-flow fields replace input fields

Synchronous vs Asynchronous

Synchronous Execution (Default)

Flow waits for sub-flow to complete:

Parent: [Node A] → [CallFlow] → [Node B]

Waits for result

Continues to B

Use when:

  • You need the sub-flow result to continue
  • Subsequent processing depends on output
  • Real-time response required

Asynchronous Execution

Flow continues without waiting:

Parent: [Node A] → [CallFlow Async] → [Node B]

Queues sub-flow

Immediately continues to B

Use when:

  • Sub-flow is fire-and-forget
  • No result needed
  • Performance is priority

Note: Async mode doesn't return data to parent flow.

Common Use Cases

Data Enrichment

Parent flow: Customer orders Sub-flow: Get customer credit rating

[Orders] → [CallFlow: GetCreditRating] → [Continue with enriched orders]
Params: customerId = {CustomerID}
Returns: creditScore, creditLimit, rating

Validation Logic

Parent flow: Process transactions Sub-flow: Validate transaction

[Transactions] → [CallFlow: ValidateTransaction] → [Condition: Valid?]
Params: amount, type, account
Returns: isValid, validationMessages

Calculation Services

Parent flow: Invoice processing Sub-flow: Calculate tax

[InvoiceLines] → [CallFlow: CalculateTax] → [Continue]
Params: amount, state, productType
Returns: taxRate, taxAmount, totalWithTax

Complex Transformations

Parent flow: Reporting Sub-flow: Aggregate metrics

[Raw Data] → [CallFlow: ComputeMetrics (batch)] → [Report Output]
Params: all data as array
Returns: aggregated metrics

External System Integration

Parent flow: Order processing Sub-flow: Check inventory (encapsulates external API)

[Orders] → [CallFlow: CheckInventory] → [Continue with availability]
Params: sku, quantity
Returns: available, warehouse, estimatedDate

Designing Sub-Flows

Sub-Flow Structure

A well-designed sub-flow has:

  1. FromFlow Trigger - Defines input parameters
  2. Processing Logic - Transforms, lookups, calculations
  3. Response Node - Returns output data
[FromFlow: params] → [Processing] → [Response]

Input Parameters

Define clear, typed parameters:

Example sub-flow inputs:

ParameterTypeRequiredDefault
customerIdStringYes-
includeHistoryBooleanNofalse
maxRecordsNumberNo100

Output Schema

Return consistent, well-defined output:

Example sub-flow outputs:

FieldTypeDescription
successBooleanOperation result
dataObjectRequested data
errorMessageStringError if failed

Error Handling

Sub-flows should handle errors gracefully:

  1. Catch potential errors
  2. Return error information in response
  3. Let parent flow decide how to proceed
Response: { success: false, errorCode: "NOT_FOUND", message: "Customer not found" }

Row-by-Row Processing

For single row mode, each input row is processed:

Parent flow data:

OrderIDCustomerIDAmount
O001C100500
O002C101750
O003C100200

CallFlow executes 3 times:

  1. With CustomerID=C100
  2. With CustomerID=C101
  3. With CustomerID=C100

Results merged back:

OrderIDCustomerIDAmountCreditScoreRating
O001C100500750A
O002C101750680B
O003C100200750A

Batch Processing

For batch mode, all data passed at once:

Parent flow: 100 line items

CallFlow (batch mode):

  • Sub-flow receives array of 100 items
  • Processes all items together
  • Returns aggregate or individual results

Performance benefit: 1 call instead of 100 calls

Nesting Depth

CallFlow nodes can be nested:

Flow A → CallFlow B → CallFlow C → CallFlow D

Considerations:

  • Each level adds latency
  • Debugging becomes harder
  • Keep nesting shallow (2-3 levels max)

Best practices:

  • Flatten when possible
  • Use batch mode to reduce calls
  • Monitor execution time

Error Handling

Sub-Flow Errors

When a sub-flow fails:

Default behavior:

  • Parent flow fails if sub-flow fails
  • Error propagates up

Error response handling:

  • Sub-flow returns error in response
  • Parent checks and handles
  • Parent continues or branches

Example:

[CallFlow] → [Condition: success = true?]
├── True → [Continue processing]
└── False → [Error handling]

Timeout Handling

Configure sub-flow timeouts:

Timeout options:

  • Default timeout (from system settings)
  • Custom timeout per CallFlow

On timeout:

  • Sub-flow execution cancelled
  • Error returned to parent
  • Handle in parent flow

Performance Optimization

Minimize Calls

Before: 1000 calls for 1000 rows

[1000 rows] → [CallFlow: Single Row Mode]

After: 1 call for 1000 rows

[1000 rows] → [CallFlow: Batch Mode]

Cache When Possible

If sub-flow returns same result for same input:

  • Consider caching at sub-flow level
  • Or pre-fetch and use Lookup instead of CallFlow

Parallel Execution

Multiple CallFlow nodes can run in parallel:

[Data] → [CallFlow A] ─┐
├─ [Merge/Append]
→ [CallFlow B] ─┘

Both sub-flows execute simultaneously.

Troubleshooting

Sub-Flow Not Found

Possible causes:

  • Target flow deleted
  • Flow name changed
  • Wrong workspace

Solutions:

  • Verify flow exists
  • Reselect target flow
  • Check workspace context

Parameter Mismatch

Possible causes:

  • Sub-flow parameters changed
  • Required parameter missing
  • Type mismatch

Solutions:

  • Review sub-flow FromFlow trigger
  • Update parameter mapping
  • Ensure types are compatible

Empty Results

Possible causes:

  • Sub-flow not returning data
  • Response node not configured
  • Data filtered out in sub-flow

Solutions:

  • Test sub-flow independently
  • Check Response node configuration
  • Preview sub-flow output

Performance Issues

Symptoms: Slow execution with many calls

Solutions:

  • Switch to batch mode
  • Cache repeated lookups
  • Optimize sub-flow logic
  • Consider denormalizing

Examples

Customer Enrichment Sub-Flow

Parent: Order Processing

[Orders] → [CallFlow: EnrichCustomer] → [Continue]
Params: customerId = {CustomerID}

Sub-Flow: EnrichCustomer

[FromFlow: customerId]
→ [Entity: Customers WHERE ID = customerId]
→ [Lookup: CustomerSegments]
→ [Transform: add calculated fields]
→ [Response: customer details]

Tax Calculation Service

Parent: Invoice Creation

[LineItems] → [CallFlow: CalculateTax (batch)] → [Append tax to lines]
Params: items = all rows
Returns: items with tax amounts

Sub-Flow: CalculateTax

[FromFlow: items array]
→ [Lookup: TaxRates by state and productType]
→ [Transform: calculate tax per item]
→ [Response: items with taxAmount, taxRate]

Inventory Check

Parent: Order Fulfillment

[OrderLines] → [CallFlow: CheckInventory] → [Condition: In Stock?]
Params: sku, quantity
Returns: available, warehouse

Sub-Flow: CheckInventory

[FromFlow: sku, quantity]
→ [Entity: Inventory WHERE SKU = sku]
→ [Transform: available = QuantityOnHand >= quantity]
→ [Response: available, warehouse, quantityOnHand]

Next Steps