Build Xero where filters safely. Xero's filter is an expression
over the record's fields, e.g.
Type=="ACCREC" AND Status=="AUTHORISED" AND Date>=DateTime(2026,01,01)
Contact.ContactID==guid("6d2b51ce-...")
condition checks the field name and operator and writes the value
as the right literal: Strs in double quotes, GUIDs with guid(...),
dates with DateTime(y,m,d), numbers and Bools bare. Xero documents
no escape for a " inside a string, so a Str value containing " or
\ is an Err rather than a guess: use the dedicated parameters
instead (searchTerm, IDs, ContactIDs, InvoiceNumbers,
Statuses), which Xero also recommends because they are indexed and
faster on large organisations.
::w ::xero::where
::w/all-of([
["Type", "==", "ACCREC"],
["Status", "==", "AUTHORISED"],
["Date", ">=", ::w/date(2026, 1, 1)],
["Contact.ContactID", "==", ::w/guid("6d2b51ce-0a4f-4a8b-9f7a-3c1e2d4b5a69")]
])
Values travel URL-encoded in the where query parameter.
Values
OPERATORS
OPERATORS: Vec [
"==",
"!=",
"<",
">",
"<=",
">="
]
Functions
all-of
fn (conditions: Vec): Str
Join conditions with AND (each parenthesised). Each part is a
[field, operator, value] Vec or an expression Str; any invalid part
makes the result an Err.
::xero::where/all-of([["Type", "==", "ACCREC"], ["AmountDue", ">", 0]])
// (Type=="ACCREC") AND (AmountDue>0)
any-of
fn (conditions: Vec): Str
Join conditions with OR (each parenthesised); parts as for all-of.
clause
fn (part: Any): Str
One part for all-of / any-of: a [field, op, value] Vec becomes condition(field, op, value); a Str (an expression you built) passes through. Anything else is an Err.
combine
fn (parts: Vec, joiner: Str): Str
condition
fn (name: Str, op: Str, value: Any): Str
One comparison: field, an operator (==, !=, <, >, <=,
>=) and a value. Returns the expression Str, or an Err for a bad
field, operator or value.
::xero::where/condition("AmountDue", ">", 0) // "AmountDue>0"
date
fn (year: Int, month: Int, day: Int): Map
A DateTime(y,mm,dd) literal (month and day zero-padded), or an Err for an impossible date.
field
fn (name: Str): Str
Check a field path (Status, Contact.ContactID): letters, digits, _ and dots. Returns it, or an Err.
guid
fn (value: Str): Map
A guid("...") literal for an id field (ContactID, InvoiceID, ...), or an Err when the value is not a GUID.
literal
fn (value: Any): Str
The filter literal for a value: a {literal} Map from guid / date / raw as is, Strs quoted (see quote), Ints and Decs bare, Bools true/false. Null is an Err.
pad2
fn (n: Int): Str
quote
fn (value: Str): Str
A double-quoted string literal, or an Err when the value contains " or \ (Xero documents no escape for them).
raw
fn (text: Str): Map
Wrap an expression you have built and checked yourself so condition writes it unchanged.