Skip to main content
You are going to build a discount calculation: orders of 100 or more get 10% off. Every output shown below is what the engine actually returns.

Step 1 — Define the facts

Facts are the step’s input: a flat object of keys and values.
The key is yours to choose. .value is a naming convention that keeps related keys apart — orderTotal.value and orderTotal.formatted are two independent facts, not a nested object. The engine does not read the dot as a path. In a real flow you would map facts in from earlier steps with variable mapping rather than typing them:
Those $. expressions resolve before any rule runs.

Step 2 — Write a rule

1

The key

qualifiesForDiscount.value names the fact this rule produces. Later rules can read it with @fact:qualifiesForDiscount.value.
2

The operator

>= is greater than or equal. The name must come from the operations reference exactly — a typo produces no error, just a missing result.
3

The input

An array of two values: the fact, and what to compare it against. @fact: is how a rule reads a fact.
Run it and you get:
With orderTotal.value of 75 you get false; with 100, true, because the operator is >= rather than >.

Step 3 — Add the step to your flow

  1. Open the flow and add a Rules step.
  2. In Facts, map the values in from an earlier step, or paste the test facts above.
  3. In Rules, paste the rule JSON.
  4. Save, then use the play button in the editor toolbar to test the flow and check the step’s output.
Saving changes the draft. A flow that is already live keeps running its published version until you press Publish. If a rule change appears to have had no effect, this is usually why.

Step 4 — Calculate the discount

Add two more rules. The second is an if/else ladder: an array of cells tried in order, where the first matching condition wins and the last cell — the one with no condition — is the default.
With orderTotal.value of 120:
With 75: false, 0, 75. With 100: true, 10, 90. You did not have to order these rules. The engine reads the @fact: references, works out that finalPrice depends on discountAmount which depends on qualifiesForDiscount, and evaluates accordingly.

Step 5 — Use the result

The step emits a flat object of rule names to outcomes, exactly as shown above.
A rule name containing a dot needs bracket notation. Variable mapping is JSONPath, and it reads the dot as a path separator. If the step is called rules_1:
  • $.rules_1['finalPrice.value'] gives 108
  • $.rules_1.finalPrice.value gives nothing at all
If you would rather avoid the brackets, name your rules without dots.

Mistakes to watch for

An operator name the engine does not recognise fails the step and says which rule and which operator. Several other mistakes give you nothing at all: a ladder that matches nothing, a calculation that produces NaN, an outcome of null. The key is simply absent from the output. See when a rule produces nothing.
"input": ["orderTotal.value", 100] compares the literal string "orderTotal.value" against 100. Write "@fact:orderTotal.value".
The key is input, singular. inputs is ignored and the operator runs with no inputs at all — a comparison written this way returns false for every value you give it.
If none of the conditions matches and there is no final cell without a condition, the rule produces no fact at all rather than a fallback value, and nothing warns you.
between takes its bounds as a nested array: [value, [low, high]]. Written flat as [value, low, high] it returns false for every input, without complaint.

Quick reference

Dynamic value
If/else ladder
Reading a fact or another rule
Operators you will use first

What’s next

Core Concepts

Rule shapes, evaluation order, defaults, wildcards and failure modes.

Operations Reference

Every operator, with an executed example.

Common Patterns

Worked solutions to recurring problems.