Expression Syntax Reference
Logic block expressions define validation rules that evaluate against extracted document data. This page covers all supported syntax.
Field References
Section titled “Field References”Reference extracted field values using the $ prefix followed by the field name:
$invoice_number$total_amount$vendor_nameField names must exactly match the names defined in the Processor. Use snake_case naming.
For fields inside a group, use the same $field_name syntax — the expression context determines which group instance is being evaluated.
Literals
Section titled “Literals”Text values are written as plain tokens, without quotes:
$vendor_name = Acme Corp$status != voidMulti-word text stays a single token. Quotes are only needed when the text would otherwise be read as an operator, number, or boolean — for example a literal dash is the token "-", and the literal text 100 is "100". Typing quotes in the expression editor marks the token as text and strips the quotes.
Numbers
Section titled “Numbers”Numeric literals (integer or decimal):
$total_amount > 0abs($expected - $actual) < 0.01$tax_rate = 8.25Dates are represented internally as Unix timestamps in milliseconds:
$invoice_date > 1719806400000The value 1719806400000 represents July 1, 2024. The expression builder provides a date picker that converts selected dates to timestamps automatically, and the date() function parses readable date text:
$invoice_date >= date(2024-07-01)Operators
Section titled “Operators”Arithmetic
Section titled “Arithmetic”| Operator | Description | Example |
|---|---|---|
+ |
Addition | $subtotal + $tax |
- |
Subtraction | $expected - $actual |
* |
Multiplication | $unit_price * $quantity |
/ |
Division | $total / $count |
^ |
Exponentiation | $base ^ 2 |
Comparison
Section titled “Comparison”| Operator | Description | Example |
|---|---|---|
= |
Equal to | $status = approved |
!= |
Not equal to | $vendor_name != "" |
> |
Greater than | $total_amount > 0 |
< |
Less than | $discount < 100 |
>= |
Greater than or equal | $quantity >= 1 |
<= |
Less than or equal | $tax_rate <= 10 |
Numeric = comparisons tolerate rounding differences smaller than a cent.
Logical
Section titled “Logical”| Operator | Description | Example |
|---|---|---|
and |
Both conditions must be true | $total > 0 and $status = approved |
or |
At least one condition must be true | $status = approved or $status = pending |
not |
Negates the following condition | not $is_void |
Grouping
Section titled “Grouping”Use parentheses to control evaluation order:
($subtotal + $tax) = $total_amount($status = approved or $status = pending) and $total > 0Functions
Section titled “Functions”Functions are grouped the same way as the picker in the expression editor.
Numbers
Section titled “Numbers”| Function | Description |
|---|---|
sqrt(x) |
Square root |
abs(x) |
Absolute value |
round(x, decimals?) |
Round to the nearest whole number, or to the given number of decimal places |
roundDown(x) |
Round down to the nearest whole number |
roundUp(x) |
Round up to the nearest whole number |
max(a, b, ...) |
Largest of two or more numbers |
min(a, b, ...) |
Smallest of two or more numbers |
mod(a, b) |
Remainder after dividing a by b |
Text comparisons are case-sensitive.
| Function | Description |
|---|---|
contains(text, search) |
True when text contains search |
startsWith(text, prefix) |
True when text begins with prefix |
endsWith(text, suffix) |
True when text ends with suffix |
length(text) |
Number of characters |
upper(text) |
Uppercase copy of the text |
lower(text) |
Lowercase copy of the text |
trim(text) |
The text without leading or trailing spaces |
concat(a, b, ...) |
Joins two or more values into one text |
matches(text, pattern) |
True when the text matches a regular expression; an invalid pattern is false |
fuzzyEquals(a, b, threshold?) |
Tolerant text comparison — forgiving of typos and case. Optional threshold 0–1, lower is stricter (default 0.4) |
All date math uses UTC and truncates to the calendar day.
| Function | Description |
|---|---|
today() |
Today’s date |
date(text) |
Parses date text (e.g. 2024-07-01 or 7/1/2024) into a comparable date |
year(d) |
The year, e.g. 2024 |
month(d) |
The month, 1–12 |
day(d) |
The day of the month, 1–31 |
weekday(d) |
The day of the week: 1 = Monday through 7 = Sunday |
addDays(d, n) |
The date n days after d (negative n goes backward) |
daysBetween(from, to) |
Whole days from one date to another |
Fields & Values
Section titled “Fields & Values”| Function | Description |
|---|---|
exists(field_name) |
True when the field was extracted with a non-empty value. Takes the bare field name, without the $ — a $field reference would substitute the value first |
isEmpty(field_name) |
True when the field is missing or empty (bare field name, without $) |
isOneOf(value, option1, option2, ...) |
True when the value equals any of the listed options |
if(condition, true_value, false_value) |
Returns true_value when the condition holds, otherwise false_value |
lookup(value, Constant, lookup_column, return_column) |
Finds value in a column of a Constant and returns the matching value from another column. Falls back to fuzzy matching when there is no exact match |
Line Items
Section titled “Line Items”These aggregate across all rows of a repeating field group within a single document. They take the bare field name, without the $.
| Function | Description |
|---|---|
sumItems(field) |
Total of the field across all rows |
avgItems(field) |
Average of the field across all rows |
countItems(field) |
Number of rows |
minItems(field) |
Smallest value across all rows |
maxItems(field) |
Largest value across all rows |
sumItemsIf(field, { condition }) |
Total of the field over only the rows matching the condition |
countItemsIf(field, { condition }) |
Number of rows matching the condition |
Inside the { } condition, reference the row’s fields with a double prefix — $$row_field — while single $field still refers to the document. For example, summing only labor line totals:
sumItemsIf(line_total, { $$item_type = labor }) = $labor_totalA logic block can reference fields from at most one repeating group.
Across Documents
Section titled “Across Documents”These reach beyond the document being evaluated — into other documents of a processor or external data. They depend on document history: associated needs an id field and repeat uploads; lookback and lookahead need a primary date field.
| Function | Description |
|---|---|
sumAll(field_name, processor) |
Total of a field across all documents of a processor, counting each id once (most recent upload wins) |
avgAll(field_name, processor) |
Average of a field across all documents of a processor |
lookback(field_name, processor, { condition }) |
Scans documents backward from this document’s primary date and returns the field value from the most recent document matching the condition; false when nothing matches |
lookahead(field_name, processor, { condition }) |
The same, scanning forward |
associated($id, field_name, processor) |
The field’s value from the most recent earlier upload sharing this document’s id; false when none exists |
cpi(start_date, end_date) |
US CPI inflation ratio between two dates — multiply a base amount by it to inflation-adjust |
Inside a lookback/lookahead { } condition, $$field reads the candidate document being scanned, while single $field is this document’s value. For example, the amount from the last approved document:
lookback(amount, invoices, { $$status = approved }) > 0Examples
Section titled “Examples”Basic field check
Section titled “Basic field check”$total_amount > 0Ensures the total amount is positive.
Non-empty field validation
Section titled “Non-empty field validation”exists(vendor_name) and exists(invoice_number)Ensures both vendor name and invoice number were extracted with values.
Tolerance check
Section titled “Tolerance check”abs($expected - $actual) < 0.01Checks that two values are within a penny of each other.
Allowed values
Section titled “Allowed values”isOneOf($status, approved, pending)Checks the status against a list of acceptable values.
Format validation
Section titled “Format validation”matches($reference_code, ^REF-\d{4}$)Checks that the reference code matches the expected pattern.
Line item reconciliation
Section titled “Line item reconciliation”sumItems(line_item_amount) = $total_amountVerifies that the sum of all line item amounts equals the document total.
Due date validation
Section titled “Due date validation”addDays($invoice_date, 30) = $due_dateChecks that the due date is exactly 30 days after the invoice date.
Weekday check
Section titled “Weekday check”weekday($delivery_date) <= 5Ensures the delivery date falls on a weekday.
Compound business rule
Section titled “Compound business rule”($subtotal + $tax) = $total_amount and $total_amount > 0Validates that subtotal plus tax equals the total, and the total is positive.
Lookup against a constant
Section titled “Lookup against a constant”lookup($procedure_code, rate_schedule, procedure, rate) >= $billed_amountLooks up the expected rate for a procedure code from the “rate_schedule” constant and checks that the billed amount does not exceed it.
Invoice recency check
Section titled “Invoice recency check”daysBetween($invoice_date, today()) <= 365Checks that the invoice date is within the last year.
Conditional tax calculation
Section titled “Conditional tax calculation”if($is_taxable, $subtotal * 1.1, $subtotal) = $total_amountApplies a 10% tax if the item is taxable, then checks the result matches the total.
Rate change against document history
Section titled “Rate change against document history”associated($id, rate, carrier_invoices) = $rateChecks that this document’s rate matches the rate from the previous upload with the same id.