Skip to content

Rule language guide

Rules decide things in RefinePoint: which rows to leave out, what a value is worked out as, which reason code a break gets, when a journal is raised, when an account certifies itself. Every rule is written in the same language, a plain-English sentence that anyone can read back. It is modelled on the Natural Rule Language (NRL 1.4).

amount is greater than 500 and narration contains 'NEFT'

You rarely type a rule. The rule builder writes it as you choose fields, comparisons and values, and shows it as a sentence. You can switch to the text at any time, and the AI rule builder can write one from a description.

Write Means
amount, party, invoice_date A field, by its name
"Ref No" A name with spaces or symbols, in double quotes
column "Narration" A column of the source file, by its heading (filters and preparation steps)
source column "Ref No", target column "Voucher" A column of one side, when mapping two sides
'NEFT' Text, in single quotes. Write a quote inside as two: 'O''Brien'
500, 0.03, -75 A number
'2026-04-01' A date, written year first
today Today’s date
true, false Yes and no

The words the, its and their can be added anywhere for reading; they change nothing. Upper and lower case do not matter in words.

Write Or Means
status is 'OPEN' status = 'OPEN', status is equal to 'OPEN', status equals 'OPEN' The same
status is not 'OPEN' status <> 'OPEN', status != 'OPEN', status does not equal 'OPEN' Different
amount is greater than 500 amount > 500, amount is more than 500, date is after '2026-04-01' More
amount is at least 500 amount >= 500, amount is greater than or equal to 500, date is on or after ... At least
amount is less than 500 amount < 500, date is before today Less
amount is at most 500 amount <= 500, amount is less than or equal to 500, date is on or before ... At most
status is one of 'OPEN', 'HELD' status is not one of ... In a list
amount is between 100 and 500 amount is not between ... From the first to the second, both included
reference is present reference is not present, reference is missing, reference is empty Has a value (not missing, not blank)
narration contains 'NEFT' narration does not contain 'NEFT' Has it inside, ignoring case
narration contains any of 'SMS', 'CHG' does not contain any of Has any of them inside
reference starts with 'INV' does not start with Begins with, ignoring case
account ends with '001' does not end with Ends with, ignoring case
reference matches '^INV[0-9]+$' does not match A regular expression finds a match
account is in BLOCKED_ACCOUNTS is not in The lookup table has it as a key
date is a weekend is a business day, is a number, is a date, is a valid gstin Describes the value

As in NRL, is can be left out: amount greater than 500.

How values compare. Text compares ignoring upper and lower case and spaces at either end: 'Tata Steel ' is 'TATA STEEL'. Numbers compare by value, so 500 is 500.00. Dates compare as dates. When one side is a number or a date, the other side is read as one: a source column holding 1,250.50 is greater than 1000.

Missing values. NRL has no null; a value is either present or not. Blank text counts as missing. A missing value is equal only to another missing value, and is neither greater nor less than anything, so amount is less than 0 is false when there is no amount. Test for it with is present / is not present.

Write Means
a and b Both
a or b Either
not a The opposite
( ... ) Group: work this out first

and binds tighter than or: a or b and c is a or (b and c). Use brackets when you mean otherwise:

(side is 'B' or side is 'C') and amount is greater than 100000
Write Means
igst + cgst + sgst Add. With text on both sides, + joins the text instead
gross - tds Subtract
quantity * rate Multiply (also times)
amount / 100 Divide (also divided by); dividing by 0 gives no value
day mod 7 The remainder
-amount The negative
invoice_date + 30 A date 30 days later; - 30 is 30 days earlier
payment_date - invoice_date The days from one date to the other

*, / and - read text as numbers, so column "Qty" * column "Rate" works on a file. To add two numbers held as text, read one as a number: [number from] column "Debit" + column "Credit".

if amount is greater than 0 then 'CR' else 'DR'
if status is 'MATCHED' then 0 else if amount is less than 1000 then 1 else 2

otherwise can be written for else. Without an else, the value is missing when the condition does not hold.

A function is called the NRL way: its name in square brackets, then its values, joined by words that read naturally (to, with, and, of, from, by, as, using, at, or a comma):

[round] amount to 2
[days between] invoice_date and payment_date
[upper case] [trim] party
[left] 4 of reference
[join with] '/', branch, account

The words between values are only for reading: values go in the order the function lists them. A function’s value ends at + or -, so an addition as a value goes in brackets: [round] (igst + cgst) to 2; [round] amount * rate to 2 needs none. A function inside a calculation is put in brackets: ([round] amount to 2) * 3. The functions are listed at the end of this guide, and in the rule builder under Function.

A workspace can add functions of its own in Settings, Rule language, Your functions, without waiting for a release. Each has a name of a few words, parameters, and the rule it stands for, written with the parameters as fields:

Name and parameters Stands for Then write
net of amount and fee amount - fee [net of] debit and charges is greater than 0
clean ref ref [upper case] [remove spaces from] ref [clean ref] reference is [clean ref] invoice_no
vendor group of party the group of party in VENDORS default 'OTHER' [vendor group of] party is 'METALS'

They are used exactly like the built-in ones, everywhere rules are written, and run in SQL as well. A function of your own may use built-in functions and lookup tables, but not another of your own, and its name cannot be a built-in function’s. Changing its rule changes every rule that uses it.

Lookup tables are set up in Settings, Lookup tables: vendor groups, GL account mappings, tax slabs, anything your rules need to look up.

Write Means
the group of party in VENDORS The group column of the VENDORS row whose key is the party
the group of party in VENDORS default 'OTHER' The same, or ‘OTHER’ when there is no such row
the rate of (party, currency) in RATES A table keyed on two columns
the rate for amount in TDS_SLABS A range table: the row whose range holds the amount
account is in BLOCKED_ACCOUNTS Whether the table has the key

Keys match ignoring case and spaces at either end, and numbers by value (100 and 100.00 are the same key).

As in NRL, a value can be given a name before the rule and used in it. Names go in double quotes and end with a comma:

"net" represents amount - tds, "net" is greater than 0 and "net" is less than 50000
Where Fields Also
A side’s filter The reconciliation’s fields column "..." for the side’s source columns
Preparation steps The source columns, by heading (plain names, or column "...")
Field mapping column "..." (two-sided: source column / target column)
Calculated fields The other fields column "..."
Reason codes The record’s fields, side, status, cause column "..."
Checks over totals A_amount (a total per side and field), A_count
Journal rules The record’s fields, difference, absDifference, reasonCode
Workflow rules The record’s fields, status, side, cause, reasonCode
Close certification balance, prior, change, changePct, supporting, unexplained, items, risk

The rule builder lists what is available where you are, and checks the rule as you write it: an unknown field, a table that does not exist or text compared with a number is pointed out with a suggestion.

The same rule runs in two places with the same meaning:

  • Whole datasets (preparation, mapping, calculated fields and filters during a run) are compiled to SQL and run in DuckDB, an analytical database inside the run service, so a run handles millions of rows. The design keeps the SQL engine replaceable: the same rules compile for Spark SQL.
  • One record at a time (reason codes, journal and workflow rules, testing a rule on a screen) run in Java.
Rule Reads
narration contains any of 'SMS', 'CHG' and amount is less than 500 Bank charges
[days between] invoice_date and payment_date is greater than 30 Paid late
the group of party in VENDORS is 'BANK' A bank vendor
column "Narration" starts with 'OPENING' or column "Amount" is not present An opening balance line or a row without an amount
fee is present and fee is greater than amount * 0.03 Fee above 3%
if currency is 'INR' then amount else amount * the rate of currency in FX_RATES Amount in rupees
[similarity of] party and payee is at least 0.85 Names that nearly agree

For every function with an example, see the function reference.