Skip to main content

Rules Step

The Rules step evaluates business logic using a declarative rules engine. Instead of writing code, you define facts (your data) and rules (how to process it), and the engine automatically calculates outcomes. Perfect for pricing calculations, eligibility checks, conditional logic, and complex business rules.
New to Rules? The Rules engine lets you build complex business logic without code. Think of it as a powerful decision-making engine for calculations, validations, and conditional outcomes.

How Rules Work

Rules evaluate facts (input data) against declarative rules to produce outcomes:
Agent: Analyzes order
  Output: {total: 1500, tier: "gold"}

Rules: Calculate discount
  Facts: {total, tier}
  Rules: 
    - If tier == "gold" AND total > 1000 → discount = 15%
    - Else → discount = 5%

Output: {discount: 0.15, finalPrice: 1275}

When to Use Rules

Use Rules WhenUse Alternative When
Complex calculations (pricing, scoring)Simple if/then (use Condition)
Multiple conditional outcomesSingle decision point
Business logic with many factorsAgent can interpret situation
Need transparent, auditable logicNeed learning/adaptation
Rules are clearly definedRules are fuzzy or contextual
Combining multiple conditionsSimple comparison
Examples: Use Rules: Calculate insurance premium based on age, location, coverage, claims history
Use Condition instead: If age > 18, approve
Use Rules: Multi-tier pricing with volume discounts, contract terms, add-ons
Use Agent instead: Negotiate custom pricing based on customer relationship
Use Rules: Loan eligibility with income, credit score, debt ratio, employment
Use Condition instead: If credit score > 700, approve

Configuration

Facts (Input Data)

facts
object
required
Input data for rules to evaluateCan reference previous steps:
{
  "orderTotal.value": "${trigger.amount}",
  "customerTier.value": "${customer.tier}",
  "region.value": "${customer.region}",
  "itemCount.value": "${cart.items.length}"
}
Each fact must have .value suffix - this is required by the rules engine
Fact names should be descriptive: orderTotal.value not x.value

Rules (Logic)

rules
object
required
Rules to evaluate against factsTwo types of rules:
  1. Direct calculation - Simple formula
{
  "finalPrice.value": {
    "operator": "-",
    "input": ["${orderTotal.value}", "${discount.value}"]
  }
}
  1. Conditional rules - If/then logic
{
  "discount.value": [
    {
      "condition": {
        "operator": "and",
        "input": [
          {"operator": ">", "input": ["@fact:orderTotal.value", 1000]},
          {"operator": "=", "input": ["@fact:customerTier.value", "gold"]}
        ]
      },
      "outcome": 0.15
    },
    {"outcome": 0.05}
  ]
}
Rules syntax is powerful but can get complex. See detailed documentation for all operators and patterns.

Quick Start Example

Scenario: Calculate order discount based on tier and amount Input:
{
  "facts": {
    "orderTotal.value": 1500,
    "customerTier.value": "gold"
  },
  "rules": {
    "discount.value": [
      {
        "condition": {
          "operator": "and",
          "input": [
            {"operator": ">", "input": ["@fact:orderTotal.value", 1000]},
            {"operator": "=", "input": ["@fact:customerTier.value", "gold"]}
          ]
        },
        "outcome": 0.15
      },
      {"outcome": 0.05}
    ],
    "finalPrice.value": {
      "operator": "-",
      "input": [
        "@fact:orderTotal.value",
        {"operator": "*", "input": ["@fact:orderTotal.value", "@fact:discount.value"]}
      ]
    }
  }
}
Output:
{
  "discount.value": {
    "outcome": 0.15
  },
  "finalPrice.value": {
    "outcome": 1275
  }
}
Gold customer with 1,500ordergets151,500 order gets 15% discount → Final price 1,275

Detailed Rules Documentation

For complete rules syntax, operators, and advanced patterns, see the comprehensive Rules documentation:

Common Flow Patterns

Calculate complex pricing with multiple factors
Agent: Gather requirements
  Output: {product, quantity, contract_length, features}

Rules: Calculate pricing
  Facts: Agent output
  Rules:
    - Base price by product
    - Volume discount tiers
    - Contract length discount
    - Feature add-ons
    - Calculate subtotal
    - Calculate tax
    - Calculate total

Output: Complete pricing breakdown

Agent: Present pricing to customer
Why Rules: Transparent pricing logic, easy to audit, no code needed
Determine if someone qualifies based on multiple criteria
Form: Application data

Rules: Check eligibility
  Facts: {age, income, credit_score, employment, debt_ratio}
  Rules:
    - Must be 18+
    - Income requirements by tier
    - Credit score thresholds
    - Employment status check
    - Debt-to-income ratio limits
    - Overall eligibility decision

Condition: Eligible?
├─ If yes → Continue application
└─ If no → Rejection email
Why Rules: Clear requirements, consistent decisions, easy to update criteria
Score leads based on multiple attributes
HTTP Request: Get lead data

Rules: Calculate lead score
  Facts: {company_size, budget, industry, engagement, role}
  Rules:
    - Company size points (10-30)
    - Budget tier points (10-30)
    - Industry fit points (0-20)
    - Engagement level points (0-20)
    - Decision maker bonus (10)
    - Total score
    - Qualification tier (hot/warm/cold)

Condition: Route by score
├─ Hot → Sales team notification
├─ Warm → Nurture sequence
└─ Cold → Standard follow-up
Why Rules: Consistent scoring, easy to adjust weights, transparent criteria
Calculate shipping based on multiple factors
Cart data: {weight, destination, speed, items}

Rules: Calculate shipping
  Facts: Cart data
  Rules:
    - Base rate by destination zone
    - Weight-based charges
    - Shipping speed multiplier
    - Oversized item surcharge
    - Free shipping threshold check
    - Calculate final shipping cost

Output: Shipping cost breakdown
Why Rules: Complex calculation, transparent to customers, easy to update rates
Determine which discounts apply
Order data: {total, customer, items, date}

Rules: Calculate discounts
  Facts: Order data
  Rules:
    - Customer tier discount
    - Volume discount tiers
    - Promotional discount eligibility
    - Seasonal discount
    - Best discount selection (max)
    - Apply discount to total

Output: Applied discount and final price
Why Rules: Multiple discount types, stacking rules, transparent logic
Calculate SLA based on customer tier and request type
Support ticket: {type, tier, severity}

Rules: Determine SLA
  Facts: Ticket data
  Rules:
    - Base response time by tier
    - Priority multiplier by severity
    - Request type adjustments
    - Business hours consideration
    - Calculate response deadline
    - Calculate resolution deadline

Output: SLA times

Agent: Create ticket with SLA
Why Rules: Consistent SLA application, easy to update policies
Assess risk level for transactions or applications
Transaction data: {amount, location, history, device}

Rules: Risk assessment
  Facts: Transaction data
  Rules:
    - Unusual amount check
    - Location mismatch
    - Device fingerprint
    - Transaction pattern analysis
    - Historical fraud rate
    - Calculate risk score
    - Determine risk level (low/medium/high)

Condition: Route by risk
├─ Low → Auto-approve
├─ Medium → Additional verification
└─ High → Manual review
Why Rules: Clear risk criteria, auditable decisions, easy to adjust thresholds
Calculate pricing across multiple tiers
Usage data: {units_used, plan, billing_period}

Rules: Calculate tiered pricing
  Facts: Usage data
  Rules:
    - Tier 1: 0-100 units @ $1/unit
    - Tier 2: 101-500 units @ $0.80/unit
    - Tier 3: 501+ units @ $0.60/unit
    - Calculate cost per tier
    - Sum total cost
    - Apply plan discount

Output: Detailed usage bill
Why Rules: Complex tiered logic, transparent billing, easy to update tiers

Accessing Rule Outcomes

Reference rule outcomes in subsequent steps:
// Access specific rule outcome
${rules.discount.value.outcome}

// Access calculated value
${rules.finalPrice.value.outcome}

// Use in condition
${rules.eligible.value.outcome} == true

// Use in agent prompt
The calculated discount is ${rules.discount.value.outcome}%

Real-World Examples

Example 1: Insurance Premium Calculation

Scenario: Calculate car insurance premium based on multiple factors
Form: Insurance application

Rules: Calculate premium
  Facts: {
    age.value: ${form.age},
    yearsLicensed.value: ${form.years_licensed},
    accidentHistory.value: ${form.accidents},
    vehicleValue.value: ${form.vehicle_value},
    annualMileage.value: ${form.annual_mileage},
    location.value: ${form.zip_code}
  }
  Rules: {
    basePremium.value: {
      // Base rate by vehicle value
      operator: "*",
      input: ["@fact:vehicleValue.value", 0.03]
    },
    ageMultiplier.value: [
      {condition: {operator: "<", input: ["@fact:age.value", 25]}, outcome: 1.5},
      {condition: {operator: ">=", input: ["@fact:age.value", 65]}, outcome: 1.2},
      {outcome: 1.0}
    ],
    experienceDiscount.value: [
      {condition: {operator: ">=", input: ["@fact:yearsLicensed.value", 10]}, outcome: 0.9},
      {condition: {operator: ">=", input: ["@fact:yearsLicensed.value", 5]}, outcome: 0.95},
      {outcome: 1.0}
    ],
    accidentSurcharge.value: {
      operator: "+",
      input: [1, {operator: "*", input: ["@fact:accidentHistory.value", 0.2]}]
    },
    mileageFactor.value: [
      {condition: {operator: ">", input: ["@fact:annualMileage.value", 15000]}, outcome: 1.15},
      {outcome: 1.0}
    ],
    finalPremium.value: {
      operator: "*",
      input: [
        "@fact:basePremium.value",
        "@fact:ageMultiplier.value",
        "@fact:experienceDiscount.value",
        "@fact:accidentSurcharge.value",
        "@fact:mileageFactor.value"
      ]
    }
  }

Output: Premium calculation with breakdown

Agent: Present quote to customer with explanation

Example 2: SaaS Pricing Calculator

Scenario: Calculate monthly SaaS pricing with features and usage
Agent: Gather requirements
  Output: {users, storage_gb, api_calls, support_level, contract_months}

Rules: Calculate pricing
  Facts: Agent output
  Rules: {
    basePrice.value: [
      {condition: {operator: "<=", input: ["@fact:users.value", 10]}, outcome: 49},
      {condition: {operator: "<=", input: ["@fact:users.value", 50]}, outcome: 149},
      {condition: {operator: "<=", input: ["@fact:users.value", 200]}, outcome: 399},
      {outcome: 999}
    ],
    storageAddon.value: {
      operator: "*",
      input: [
        {operator: "max", input: [0, {operator: "-", input: ["@fact:storage_gb.value", 100]}]},
        0.5
      ]
    },
    apiAddon.value: [
      {condition: {operator: ">", input: ["@fact:api_calls.value", 100000]}, outcome: 99},
      {condition: {operator: ">", input: ["@fact:api_calls.value", 50000]}, outcome: 49},
      {outcome: 0}
    ],
    supportAddon.value: [
      {condition: {operator: "=", input: ["@fact:support_level.value", "premium"]}, outcome: 199},
      {condition: {operator: "=", input: ["@fact:support_level.value", "priority"]}, outcome: 99},
      {outcome: 0}
    ],
    contractDiscount.value: [
      {condition: {operator: ">=", input: ["@fact:contract_months.value", 12]}, outcome: 0.85},
      {condition: {operator: ">=", input: ["@fact:contract_months.value", 6]}, outcome: 0.9},
      {outcome: 1.0}
    ],
    subtotal.value: {
      operator: "+",
      input: [
        "@fact:basePrice.value",
        "@fact:storageAddon.value",
        "@fact:apiAddon.value",
        "@fact:supportAddon.value"
      ]
    },
    monthlyPrice.value: {
      operator: "*",
      input: ["@fact:subtotal.value", "@fact:contractDiscount.value"]
    },
    annualPrice.value: {
      operator: "*",
      input: ["@fact:monthlyPrice.value", 12]
    }
  }

Output: Complete pricing breakdown

Agent: Generate proposal document

Example 3: Loan Approval Decision

Scenario: Multi-criteria loan eligibility determination
HTTP Request: Get applicant financial data

Rules: Loan eligibility
  Facts: {
    income.value: ${http.body.annual_income},
    creditScore.value: ${http.body.credit_score},
    debtToIncome.value: ${http.body.debt_to_income_ratio},
    employmentYears.value: ${http.body.employment_years},
    loanAmount.value: ${http.body.requested_amount},
    downPayment.value: ${http.body.down_payment}
  }
  Rules: {
    incomeEligible.value: {
      operator: ">=",
      input: ["@fact:income.value", 50000]
    },
    creditEligible.value: {
      operator: ">=",
      input: ["@fact:creditScore.value", 680]
    },
    debtRatioEligible.value: {
      operator: "<=",
      input: ["@fact:debtToIncome.value", 0.43]
    },
    employmentEligible.value: {
      operator: ">=",
      input: ["@fact:employmentYears.value", 2]
    },
    loanToValue.value: {
      operator: "/",
      input: [
        {operator: "-", input: ["@fact:loanAmount.value", "@fact:downPayment.value"]},
        "@fact:loanAmount.value"
      ]
    },
    ltvEligible.value: {
      operator: "<=",
      input: ["@fact:loanToValue.value", 0.8]
    },
    overallEligible.value: {
      operator: "and",
      input: [
        "@fact:incomeEligible.value",
        "@fact:creditEligible.value",
        "@fact:debtRatioEligible.value",
        "@fact:employmentEligible.value",
        "@fact:ltvEligible.value"
      ]
    },
    interestRate.value: [
      {
        condition: {
          operator: "and",
          input: [
            {operator: ">=", input: ["@fact:creditScore.value", 760]},
            {operator: "<=", input: ["@fact:loanToValue.value", 0.7]}
          ]
        },
        outcome: 0.035
      },
      {
        condition: {operator: ">=", input: ["@fact:creditScore.value", 720]},
        outcome: 0.042
      },
      {
        condition: {operator: ">=", input: ["@fact:creditScore.value", 680]},
        outcome: 0.055
      },
      {outcome: 0.070}
    ],
    reasonsForDenial.value: [
      // Complex array building of denial reasons if applicable
    ]
  }

Condition: Is eligible?
├─ If yes → Generate loan offer with rate
└─ If no → Generate denial letter with reasons

Best Practices

Use Descriptive Names

Name facts and rules clearly: customerTierDiscount.value not discount1.value

Test with Real Data

Test rules with actual values from your system. Edge cases matter.

Start Simple

Begin with basic rules, add complexity gradually. Test each addition.

Document Complex Logic

Add comments explaining why rules exist, especially business requirements.

Validate Inputs

Check that facts have expected types and ranges before evaluation.

Handle Edge Cases

Always include default outcomes for conditional rules (the final {outcome: X}).

Break Into Steps

For very complex logic, use multiple Rules steps. Easier to debug and maintain.

Version Your Rules

Track rule changes over time, especially for pricing and eligibility that affect customers.

Troubleshooting

Causes:
  • Missing .value suffix on facts or rules
  • Incorrect variable reference
  • Wrong operator syntax
Solutions:
  • Verify all facts end with .value
  • Check variable paths: "@fact:orderTotal.value" not "@fact:orderTotal"
  • Review operator syntax in documentation
  • Check execution logs for error messages
Causes:
  • Condition order wrong (first match wins)
  • Logical operator error (AND vs OR)
  • Data type mismatch
Solutions:
  • Reorder conditions (most specific first)
  • Verify logical operators
  • Check data types (string “100” vs number 100)
  • Add logging to see which condition matched
Causes:
  • Wrong variable path
  • Missing .outcome suffix
  • Rule didn’t execute
Solutions:
  • Use ${rules_step_name.rule_name.value.outcome}
  • Check rule actually executed (logs)
  • Verify step name is correct
Causes:
  • Operator precedence issue
  • Missing parentheses in complex math
  • Wrong operator used
Solutions:
  • Break complex calculations into steps
  • Test each calculation piece separately
  • Verify operator behavior in docs
  • Use explicit nesting with operator objects
Causes:
  • Too many conditions
  • Nested loops in calculations
  • Processing large arrays
Solutions:
  • Simplify rule logic where possible
  • Break into multiple Rules steps
  • Filter data before rules
  • Consider using agent for very complex logic

When to Use Rules vs. Alternatives

Use Rules when:
  • Logic is clearly defined and transparent
  • Multiple factors combine to determine outcome
  • Need auditable business logic
  • Calculations involve multiple steps
  • Requirements are likely to change (easy to update)
Use Condition when:
  • Simple if/then (single decision point)
  • Binary outcome (yes/no, approve/reject)
  • No calculations needed
Use Agent when:
  • Logic requires interpretation
  • Need to understand context
  • Rules are fuzzy or subjective
  • Need to explain reasoning in natural language
Use Eval when:
  • Need custom JavaScript beyond rule operators
  • Highly dynamic logic that can’t be expressed in rules
  • Integration with external libraries

Learn More