> ## Documentation Index
> Fetch the complete documentation index at: https://microstrate-1133-notifications-prefs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Condition

> Branch your flow with conditional logic using the rules engine

# Condition Step

The Condition step adds branching logic to your flows by evaluating conditions using the **rules engine**. Based on the conditions you define, the flow routes to different next steps—or terminates with success or error.

<Info>
  **How Conditions Work**: The Condition step uses the same rules engine as the Rules step, but instead of calculating values, it routes the flow based on which condition matches first. Conditions are checked **top-to-bottom** until one matches.
</Info>

***

## How It Works

The Condition step evaluates conditions in sequence and routes to the outcome of the first matching condition:

<CodeGroup>
  ```text Simple Branch theme={null}
  Previous Step
  ↓
  Condition: Is amount > 1000?
  ↓ (true)           ↓ (false)
  High Value Step    Standard Step
  ```

  ```text Multiple Conditions theme={null}
  Agent: Analyze request
  ↓
  Condition Step
  ├─ If decision == "approve" → Approval Step
  ├─ If decision == "reject" → Rejection Step  
  ├─ If decision == "escalate" → Human Review Step
  └─ Default → Error Handler Step
  ```

  ```text Terminate Flow theme={null}
  Validation Check
  ↓
  Condition Step
  ├─ If valid → Continue Flow
  └─ If invalid → RESOLVE_ERROR
  ```
</CodeGroup>

***

## Configuration

### Facts

Just like the Rules step, you define **facts** that will be evaluated by the conditions. Facts are populated using [variable mapping](/advanced/variable-mapping/overview) from previous steps:

```json theme={null}
{
  "orderTotal": "$.checkout_step.total",
  "customerTier": "$.customer_lookup.tier",
  "agentDecision": "$.support_agent.output.decision",
  "confidence": "$.support_agent.output.confidence"
}
```

<Note>
  Fact keys don't need the `.value` suffix in the Condition step—the system handles this automatically.
</Note>

### Conditions Array

Conditions are evaluated **top-to-bottom**. The first matching condition's outcome is used:

```json theme={null}
{
  "conditions": [
    {
      "condition": {
        "operator": "and",
        "input": [
          {"operator": ">", "input": ["@fact:orderTotal", 10000]},
          {"operator": "=", "input": ["@fact:customerTier", "enterprise"]}
        ]
      },
      "outcome": "enterprise_handler_step_id"
    },
    {
      "condition": {
        "operator": ">",
        "input": ["@fact:orderTotal", 1000]
      },
      "outcome": "business_handler_step_id"
    },
    {
      "outcome": "standard_handler_step_id"
    }
  ]
}
```

<Warning>
  **Order matters!** Place most specific conditions first, more general conditions last. The first matching condition wins.
</Warning>

### Special Outcomes

Instead of routing to another step, you can terminate the flow:

* **`"RESOLVE_SUCCESS"`** - End the flow successfully
* **`"RESOLVE_ERROR"`** - End the flow with an error

```json theme={null}
{
  "conditions": [
    {
      "condition": {
        "operator": "=",
        "input": ["@fact:validationStatus", "valid"]
      },
      "outcome": "processing_step_id"
    },
    {
      "outcome": "RESOLVE_ERROR"
    }
  ]
}
```

***

## Condition Syntax

Conditions use the same **operator-based syntax** as the Rules step. See the [Rules Operations Reference](/advanced/rules/operations-reference) for all available operators.

### Basic Comparisons

```json theme={null}
// Equality
{
  "operator": "=",
  "input": ["@fact:status", "approved"]
}

// Inequality
{
  "operator": "!=",
  "input": ["@fact:status", "pending"]
}

// Greater than
{
  "operator": ">",
  "input": ["@fact:amount", 1000]
}

// Less than or equal
{
  "operator": "<=",
  "input": ["@fact:score", 100]
}
```

### Logical Operators

```json theme={null}
// AND - All conditions must be true
{
  "operator": "and",
  "input": [
    {"operator": ">", "input": ["@fact:amount", 1000]},
    {"operator": "=", "input": ["@fact:tier", "gold"]}
  ]
}

// OR - At least one condition must be true
{
  "operator": "or",
  "input": [
    {"operator": "=", "input": ["@fact:status", "urgent"]},
    {"operator": "=", "input": ["@fact:priority", "high"]}
  ]
}

// NOT - Invert condition
{
  "operator": "not",
  "input": [
    {"operator": "=", "input": ["@fact:approved", true]}
  ]
}
```

### Null Checks

```json theme={null}
// Check if value exists
{
  "operator": "notEmpty",
  "input": ["@fact:email"]
}

// Check if value is empty/null
{
  "operator": "isEmpty",
  "input": ["@fact:optionalField"]
}
```

### String Operations

```json theme={null}
// Contains substring
{
  "operator": "includes",
  "input": ["@fact:message", "refund"]
}

// Starts with
{
  "operator": "startsWith",
  "input": ["@fact:email", "admin@"]
}

// Ends with
{
  "operator": "endsWith",
  "input": ["@fact:filename", ".pdf"]
}

// Case-insensitive comparison
{
  "operator": "=",
  "input": [
    {"operator": "toLower", "input": ["@fact:category"]},
    "support"
  ]
}
```

### Array Operations

```json theme={null}
// Check if array contains value
{
  "operator": "in",
  "input": ["@fact:selectedTag", "@fact:availableTags"]
}

// Check array length
{
  "operator": ">",
  "input": [
    {"operator": "size", "input": ["@fact:items"]},
    0
  ]
}
```

***

## Common Patterns

<AccordionGroup>
  <Accordion title="Agent Decision Routing" icon="robot">
    Route based on agent's structured output decision

    **Facts**:

    ```json theme={null}
    {
      "decision": "$.support_agent.output.decision",
      "confidence": "$.support_agent.output.confidence"
    }
    ```

    **Conditions**:

    ```json theme={null}
    [
      {
        "condition": {
          "operator": "=",
          "input": ["@fact:decision", "approve"]
        },
        "outcome": "approval_flow_step"
      },
      {
        "condition": {
          "operator": "=",
          "input": ["@fact:decision", "reject"]
        },
        "outcome": "rejection_flow_step"
      },
      {
        "condition": {
          "operator": "=",
          "input": ["@fact:decision", "escalate"]
        },
        "outcome": "human_review_step"
      },
      {
        "outcome": "error_handler_step"
      }
    ]
    ```
  </Accordion>

  <Accordion title="Threshold-Based Routing" icon="gauge-high">
    Route based on numeric thresholds

    **Facts**:

    ```json theme={null}
    {
      "orderTotal": "$.order.total"
    }
    ```

    **Conditions**:

    ```json theme={null}
    [
      {
        "condition": {
          "operator": ">=",
          "input": ["@fact:orderTotal", 10000]
        },
        "outcome": "enterprise_sales_step"
      },
      {
        "condition": {
          "operator": ">=",
          "input": ["@fact:orderTotal", 1000]
        },
        "outcome": "business_sales_step"
      },
      {
        "condition": {
          "operator": ">=",
          "input": ["@fact:orderTotal", 0]
        },
        "outcome": "self_service_step"
      },
      {
        "outcome": "RESOLVE_ERROR"
      }
    ]
    ```
  </Accordion>

  <Accordion title="Multi-Factor Validation" icon="shield-check">
    Check multiple criteria before proceeding

    **Facts**:

    ```json theme={null}
    {
      "email": "$.form.email",
      "age": "$.form.age",
      "termsAccepted": "$.form.terms_accepted"
    }
    ```

    **Conditions**:

    ```json theme={null}
    [
      {
        "condition": {
          "operator": "and",
          "input": [
            {"operator": "notEmpty", "input": ["@fact:email"]},
            {"operator": "includes", "input": ["@fact:email", "@"]},
            {"operator": ">=", "input": ["@fact:age", 18]},
            {"operator": "=", "input": ["@fact:termsAccepted", true]}
          ]
        },
        "outcome": "validated_processing_step"
      },
      {
        "outcome": "validation_failed_step"
      }
    ]
    ```
  </Accordion>

  <Accordion title="Status-Based Routing" icon="traffic-light">
    Route based on status or category

    **Facts**:

    ```json theme={null}
    {
      "customerStatus": "$.customer.status",
      "customerTier": "$.customer.tier"
    }
    ```

    **Conditions**:

    ```json theme={null}
    [
      {
        "condition": {
          "operator": "=",
          "input": ["@fact:customerStatus", "new"]
        },
        "outcome": "new_customer_flow_step"
      },
      {
        "condition": {
          "operator": "=",
          "input": ["@fact:customerTier", "vip"]
        },
        "outcome": "vip_flow_step"
      },
      {
        "condition": {
          "operator": "=",
          "input": ["@fact:customerStatus", "returning"]
        },
        "outcome": "returning_customer_flow_step"
      },
      {
        "outcome": "standard_flow_step"
      }
    ]
    ```
  </Accordion>

  <Accordion title="Confidence-Based Routing" icon="chart-line">
    Route based on AI confidence scores

    **Facts**:

    ```json theme={null}
    {
      "confidence": "$.agent.output.confidence",
      "decision": "$.agent.output.decision"
    }
    ```

    **Conditions**:

    ```json theme={null}
    [
      {
        "condition": {
          "operator": ">=",
          "input": ["@fact:confidence", 0.9]
        },
        "outcome": "auto_approve_step"
      },
      {
        "condition": {
          "operator": ">=",
          "input": ["@fact:confidence", 0.6]
        },
        "outcome": "manager_review_step"
      },
      {
        "condition": {
          "operator": "<",
          "input": ["@fact:confidence", 0.6]
        },
        "outcome": "senior_review_step"
      },
      {
        "outcome": "RESOLVE_ERROR"
      }
    ]
    ```
  </Accordion>

  <Accordion title="Error Handling & Validation" icon="triangle-exclamation">
    Validate data and route errors appropriately

    **Facts**:

    ```json theme={null}
    {
      "apiStatus": "$.http_request.status",
      "hasData": "$.http_request.data"
    }
    ```

    **Conditions**:

    ```json theme={null}
    [
      {
        "condition": {
          "operator": "and",
          "input": [
            {"operator": "=", "input": ["@fact:apiStatus", 200]},
            {"operator": "notEmpty", "input": ["@fact:hasData"]}
          ]
        },
        "outcome": "success_processing_step"
      },
      {
        "condition": {
          "operator": "and",
          "input": [
            {"operator": ">=", "input": ["@fact:apiStatus", 400]},
            {"operator": "<", "input": ["@fact:apiStatus", 500]}
          ]
        },
        "outcome": "client_error_handler_step"
      },
      {
        "condition": {
          "operator": ">=",
          "input": ["@fact:apiStatus", 500]
        },
        "outcome": "server_error_handler_step"
      },
      {
        "outcome": "RESOLVE_ERROR"
      }
    ]
    ```
  </Accordion>

  <Accordion title="Data Completeness Check" icon="list-check">
    Verify required fields exist before processing

    **Facts**:

    ```json theme={null}
    {
      "name": "$.form.name",
      "email": "$.form.email",
      "phone": "$.form.phone",
      "address": "$.form.address"
    }
    ```

    **Conditions**:

    ```json theme={null}
    [
      {
        "condition": {
          "operator": "and",
          "input": [
            {"operator": "notEmpty", "input": ["@fact:name"]},
            {"operator": "notEmpty", "input": ["@fact:email"]},
            {"operator": "notEmpty", "input": ["@fact:phone"]},
            {"operator": "notEmpty", "input": ["@fact:address"]}
          ]
        },
        "outcome": "complete_data_processing_step"
      },
      {
        "outcome": "missing_fields_error_step"
      }
    ]
    ```
  </Accordion>
</AccordionGroup>

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Always Have Default" icon="arrows-split-up-and-left">
    Always include a final condition with no condition expression (just `{"outcome": "..."}`) to handle unexpected values.
  </Card>

  <Card title="Order Matters" icon="arrow-down-1-9">
    Conditions are evaluated top-to-bottom. Put most specific conditions first, most general last.
  </Card>

  <Card title="Use Agent Output Schemas" icon="table">
    When routing based on agent decisions, use output schemas for clean, predictable conditions.
  </Card>

  <Card title="Test All Branches" icon="vial">
    Test each condition path with appropriate test data to ensure all outcomes work correctly.
  </Card>

  <Card title="Keep It Simple" icon="minimize">
    For very complex logic, consider using a Rules step to calculate intermediate values, then use a Condition step for routing.
  </Card>

  <Card title="Document Branches" icon="message-lines">
    Use clear, descriptive names for outcome steps so the flow is easy to understand.
  </Card>
</CardGroup>

***

## When to Use Conditions vs. Rules

| Use Condition When                        | Use Rules When                          |
| ----------------------------------------- | --------------------------------------- |
| Need to **route** flow to different steps | Need to **calculate** values            |
| Binary or multi-way branching             | Complex calculations or transformations |
| Flow termination needed                   | Data reshaping needed                   |
| Decision → Action mapping                 | Multiple derived values needed          |

**Example**:

**Use Condition for**: "If approved, go to approval step. If rejected, go to rejection step."

**Use Rules for**: "Calculate discount percentage based on order total, customer tier, and region."

Often you'll use **Rules step → Condition step** together:

1. Rules step calculates complex values
2. Condition step routes based on those calculated values

***

## Complete Example

Here's a complete example showing Facts, Conditions, and routing:

**Scenario**: Route customer support requests based on agent analysis

**Step Configuration**:

```json theme={null}
{
  "facts": {
    "requestType": "$.support_agent.output.type",
    "priority": "$.support_agent.output.priority",
    "confidence": "$.support_agent.output.confidence",
    "requiresHuman": "$.support_agent.output.requires_human"
  },
  "conditions": [
    {
      "condition": {
        "operator": "=",
        "input": ["@fact:requiresHuman", true]
      },
      "outcome": "human_review_step_id"
    },
    {
      "condition": {
        "operator": "and",
        "input": [
          {"operator": "=", "input": ["@fact:requestType", "refund"]},
          {"operator": ">=", "input": ["@fact:confidence", 0.8]}
        ]
      },
      "outcome": "refund_processing_step_id"
    },
    {
      "condition": {
        "operator": "and",
        "input": [
          {"operator": "=", "input": ["@fact:requestType", "technical"]},
          {"operator": ">=", "input": ["@fact:confidence", 0.8]}
        ]
      },
      "outcome": "technical_support_step_id"
    },
    {
      "condition": {
        "operator": "=",
        "input": ["@fact:priority", "urgent"]
      },
      "outcome": "urgent_escalation_step_id"
    },
    {
      "condition": {
        "operator": "<",
        "input": ["@fact:confidence", 0.6]
      },
      "outcome": "low_confidence_review_step_id"
    },
    {
      "outcome": "standard_support_step_id"
    }
  ]
}
```

**Flow Routing**:

1. If agent says human required → Human review
2. If refund with high confidence → Auto-process refund
3. If technical with high confidence → Technical support flow
4. If marked urgent → Urgent escalation
5. If low confidence → Manual review
6. Default → Standard support queue

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Flow fails at condition step" icon="circle-exclamation">
    **Possible causes**:

    * No conditions matched and no default outcome
    * Fact reference is incorrect
    * Data type mismatch
    * Variable mapping failed

    **Solutions**:

    * Always add a default condition with no condition expression
    * Verify fact keys match your facts object
    * Check data types (comparing string to number won't match)
    * Verify previous step output contains expected data
    * Add logging steps before condition to inspect values
  </Accordion>

  <Accordion title="Wrong branch taken" icon="turn-down">
    **Possible causes**:

    * Condition order wrong (earlier condition matched first)
    * Logical operator error (AND vs. OR)
    * Data type mismatch
    * Operator precedence unexpected

    **Solutions**:

    * Reorder conditions (most specific first)
    * Verify logical operators are correct
    * Check data types match (use type conversion if needed)
    * Test each condition individually
    * Add logging to see which condition matched
  </Accordion>

  <Accordion title="Condition always false" icon="ban">
    **Possible causes**:

    * Fact doesn't exist or is null
    * Variable mapping returned unexpected format
    * Case sensitivity issue
    * Whitespace in data

    **Solutions**:

    * Check previous step output structure
    * Add null checks using `notEmpty` operator
    * Use `toLower` for case-insensitive comparison
    * Use `trim` operator to remove whitespace
    * Verify variable mapping path is correct
  </Accordion>

  <Accordion title="Can't access nested properties" icon="folder-tree">
    **Possible causes**:

    * Variable mapping didn't extract nested value
    * Fact contains full object instead of specific property

    **Solutions**:

    * Use JSONPath in variable mapping to extract specific property: `$.step.output.nested.property`
    * If fact contains object, use `jPath` operator in condition to access nested value
    * Consider using Map step before Condition to flatten data
  </Accordion>
</AccordionGroup>

***

## Tips for Better Conditions

<Steps>
  <Step title="Map facts carefully">
    Use variable mapping to extract exactly the values you need. Make facts simple values when possible.
  </Step>

  <Step title="Start simple">
    Begin with basic conditions. Add complexity only when needed.
  </Step>

  <Step title="Use structured agent output">
    Define output schemas on agents for clean, predictable routing decisions.
  </Step>

  <Step title="Test all paths">
    Test each branch with appropriate test data to verify routing works correctly.
  </Step>

  <Step title="Handle null values">
    Always check for null/empty before comparing values using `notEmpty` or `isEmpty`.
  </Step>

  <Step title="Consider Rules + Condition">
    For complex logic, use Rules step to calculate, then Condition step to route based on results.
  </Step>
</Steps>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Rules Step" icon="gavel" href="/flows/steps/rules">
    Learn about the Rules step for complex calculations
  </Card>

  <Card title="Variable Mapping" icon="brackets-curly" href="/advanced/variable-mapping/overview">
    Master variable mapping to populate facts
  </Card>

  <Card title="Rules Operations" icon="list-check" href="/advanced/rules/operations-reference">
    Complete reference for all available operators
  </Card>

  <Card title="Human in the Loop" icon="user-check" href="/flows/steps/human-in-the-loop">
    Add manual approval to branches
  </Card>
</CardGroup>
