Filters
Scribe supports four filter formats. It auto-detects which one you’re using, so pick whatever fits your context. If you’re deciding which format to use, see Choosing a Filter Format.
Format detection
Section titled “Format detection”Auto-detection order for filter syntax
Filters are detected in this order:
| Format | Detection | Best for |
|---|---|---|
| JSON | Starts with { or [ | Programmatic queries, SDKs |
| LDAP | Starts with ( and ends with ) | Legacy systems, LDAP clients |
| FleX | Tried next | Interactive queries, config files |
| SCIM | Fallback | REST APIs, SCIM clients |
Quick comparison
Section titled “Quick comparison”| Operation | FleX | JSON | SCIM | LDAP |
|---|---|---|---|---|
| Equality | cn = John | {"cn": "John"} | cn eq "John" | (cn=John) |
| Not equal | cn != John | {"cn": {"ne": "John"}} | cn ne "John" | (!(cn=John)) |
| Starts with | cn ^= J | {"cn": {"sw": "J"}} | cn sw "J" | (cn=J*) |
| Contains | cn %= oh | {"cn": {"co": "oh"}} | cn co "oh" | (cn=*oh*) |
| Exists | cn? | {"cn": {"pr": true}} | cn pr | (cn=*) |
| AND | a=1 b=2 | {"a": "1", "b": "2"} | a eq "1" and b eq "2" | (&(a=1)(b=2)) |
| OR | a=1 or b=2 | {"_or_": [...]} | a eq "1" or b eq "2" | (|(a=1)(b=2)) |
| Attr group | a|b = x | {"a|b": "x"} | — | — |
All four formats work identically in REST and GraphQL queries.
Temporal references
Section titled “Temporal references”Timestamp attributes (createTimestamp, modifyTimestamp, verifiedTimestamp) accept flexible temporal references instead of absolute timestamps. Works with all filter formats.
| Format | Example | Description |
|---|---|---|
now | modifyTimestamp ge now | Current time |
now-duration | modifyTimestamp ge now-1h | 1 hour ago |
now+duration | verifiedTimestamp lt now+1d | 1 day from now |
| Duration | createTimestamp ge 7d | 7 days ago |
| ISO duration | modifyTimestamp ge P30D | 30 days ago |
| Partial date | createTimestamp ge 2024 | Start of 2024 |
| Day keywords | modifyTimestamp ge today | Midnight UTC |
| Period keywords | createTimestamp ge this_week | Start of period |
| Relative periods | modifyTimestamp ge last 3 days | N units ago |
Day keywords: yesterday, today, tomorrow
Period keywords: this week, last week, this month, last month, this year, last year
(Also: this_week, thisweek, last-month, etc.)
Relative periods: last N units where units can be days, hours, minutes, weeks, etc.
FleX (Flexible Filter Expressions) is a query language that reads like plain English. Values rarely need quoting, whitespace is lenient, and every operator has a natural-language form alongside short symbols and SCIM keywords.
Quick start
Section titled “Quick start”# Reads like a sentence — no quotes, no special syntaxdepartment is Engineeringname starts with Johnmodified after 2024-01-01
# Same queries, terse styledepartment=Engineeringname ^= Johnmodified > 2024-01-01
# Or use SCIM-style operator keywordsdepartment eq Engineeringname sw Johnmodified gt 2024-01-01Values like Engineering, John, numbers, dates, UUIDs, IPs, and durations (50ms, 5s) need no quoting. Quote only when a value contains spaces — backticks, single quotes, or double quotes all work: cn = `John Doe`.
# Combine with AND (implicit) and ORdepartment is Engineering status is activerole in (admin, editor) or department is Engineering
# Natural negationstatus isnt disabledname not starts with Testrole not in (guest, anonymous)
# Phonetic and pattern matchingsn sounds like Smithcn like John*mail ends with @example.comOperators
Section titled “Operators”Comparison
Section titled “Comparison”| Operator | Aliases | Description |
|---|---|---|
=, == | eq, is, equals | Equality |
!=, !== | ne, isnt, is not | Not equal |
> | gt, after, greater than | Greater than |
>= | ge, min, at least | Greater or equal |
< | lt, before, less than | Less than |
<= | le, max, at most | Less or equal |
String matching
Section titled “String matching”| Operator | Aliases | Description |
|---|---|---|
^= | sw, starts with, prefix | Starts with |
$= | ew, ends with, suffix | Ends with |
%= | co, contains, has | Contains substring |
*= | matches, like, glob | Wildcard/glob pattern |
~= | approx, sounds like, similar to | Approximate match (phonetic) |
Presence and set membership
Section titled “Presence and set membership”| Operator | Aliases | Description |
|---|---|---|
? | exists, present, pr | Attribute exists |
in | one of | Value in set |
not in | !in, not one of | Value not in set |
Combinators
Section titled “Combinators”Whitespace between conditions implies AND. Use or, ,, |, or || for OR. AND binds tighter than OR — use parentheses to override:
# Implicit ANDresult=ok duration<=50ms
# Explicit ORresult=ok or result=warn
# Parentheses override precedencechannel=LDAP (op=Search or op=Bind)Modifiers
Section titled “Modifiers”FleX treats is, not, and ! as modifier words you can drop in front of operators for more natural phrasing.
is is optional before comparison, set, presence, and approximate operators — it reads better but changes nothing:
count is at least 10 # same as: count >= 10status is in (a, b, c) # same as: status in (a, b, c)name is present # same as: name existsname is similar to john # same as: name ~= johnStandalone is means equals: status is active is the same as status = active.
not and ! negate any operator:
result != okcn not starts with 'Test'status not in (admin, root)!(result = ok)not(result = ok)is not, isnt, isn't combine both — natural negation for the same operators is supports:
status isnt active # same as: status != activecount is not greater than 5 # same as: count <= 5name isn't present # same as: name not existsValues
Section titled “Values”Simple values need no quotes. Use backticks, single quotes, or double quotes for values with spaces:
status = activecn = `John Doe`Special values: null and nil map to “not exists”; true and false are booleans. Quote them to match the literal string.
FleX recognizes unquoted numbers, hex (0xFF), durations (50ms, 5s), timestamps (2024-01-15), UUIDs, IPs, and emails.
Attribute groups
Section titled “Attribute groups”Search across multiple attributes with a single condition. Exclusive to FleX and JSON — LDAP and SCIM require explicit OR clauses.
# Pipe syntax (no whitespace around |)sn|givenName|cn|mail contains 'admin'
# Brace syntax (whitespace allowed){sn, givenName, cn, mail} contains 'admin'Both expand to the same OR expression. Use pipe for compact inline filters; use braces for readability with many attributes.
Set membership
Section titled “Set membership”status in (active, pending, review)role not in (admin, superuser)Empty sets check presence: status in () is equivalent to status exists, and status not in () is equivalent to status not exists.
LDAP extensible match
Section titled “LDAP extensible match”For DN-based matching (LDAP :dn modifier):
member:dn := "cn=John,ou=users,dc=example,dc=com"ou:dn := EngineeringFleX works in log filtering rules and HOCON config files too.
Structured, programmatic filters for SDKs and code generation.
Quick start
Section titled “Quick start”// Simple equality{"cn": "john"}
// Multiple conditions (AND){"cn": "john", "sn": "doe"}
// Array of values (OR){"cn": ["john", "jane"]}
// Operator with value{"cn": {"sw": "A"}}
// Explicit logical operators{"_or_": [{"cn": "a"}, {"cn": "b"}]}{"_not_": {"disabled": "true"}}Root structure
Section titled “Root structure”- Object
{...}: Keys are combined with AND - Array
[...]: Elements are combined with AND
Operators
Section titled “Operators”| Operator | Aliases | Meaning |
|---|---|---|
eq | equals, is, = | Equals |
ne | notEquals, != | Not equals |
co | contains, % | Contains substring |
sw | startsWith, ^ | Starts with |
ew | endsWith, $ | Ends with |
pr | exists | Attribute present |
gt | >, after | Greater than |
ge | gte, >=, min | Greater or equal |
lt | <, before | Less than |
le | lte, <=, max | Less or equal |
approx | ~, soundsLike | Approximate match |
matches | * | Wildcard pattern |
includes | in, oneOf | Value in set |
excludes | notIn, notOneOf | Value not in set |
Logical operators
Section titled “Logical operators”Use _and_, _or_, and _not_ (or without underscores):
{"_or_": [{"status": "active"}, {"status": "pending"}]}{"_not_": {"disabled": "true"}}{"_and_": [ {"type": "user"}, {"_or_": [{"role": "admin"}, {"role": "operator"}]}]}Value coercion
Section titled “Value coercion”| JSON Type | Result |
|---|---|
| String | Used as-is |
| Number | Plain string (no scientific notation) |
| Boolean | "true" or "false" |
| Null | Treated as “not exists” |
Attribute groups
Section titled “Attribute groups”Pipe syntax works identically to FleX:
{"sn|givenName|cn": {"co": "admin"}}SCIM 2.0 filter syntax (RFC 7644). Basic SCIM filters work through FleX parsing. Complex value filters (emails[type eq "work"]), dotted paths, and URN-qualified attributes are not supported.
Quick start
Section titled “Quick start”cn eq "john"cn sw "A" and sn prnot (disabled eq "true")userName eq "john" or email co "@example.com"Operators
Section titled “Operators”| Operator | Description |
|---|---|
eq | Equals |
ne | Not equals |
co | Contains |
sw | Starts with |
ew | Ends with |
pr | Present (attribute exists) |
gt | Greater than |
ge | Greater or equal |
lt | Less than |
le | Less or equal |
Logical operators: and, or, not (...). Group with parentheses.
FleX compatibility
Section titled “FleX compatibility”SCIM operators are valid FleX syntax. FleX adds aliases like = for eq, != for ne, >= for ge, contains for co, and implicit AND via whitespace. See the FleX operators table for the full mapping.
Standard LDAP filter syntax (RFC 4515) for existing LDAP infrastructure.
Quick start
Section titled “Quick start”(cn=john)(cn=john*)(&(objectClass=user)(cn=john*))(|(cn=john)(cn=jane))(!(disabled=true))Operators
Section titled “Operators”| Pattern | Description |
|---|---|
(attr=value) | Equality |
(attr=*) | Presence (attribute exists) |
(attr=prefix*) | Starts with |
(attr=*suffix) | Ends with |
(attr=*substring*) | Contains |
(attr~=value) | Approximate match |
(attr>=value) | Greater or equal |
(attr<=value) | Less or equal |
Composite filters: (&(...)(...)) for AND, (|(...)(...)) for OR, (!(...)) for NOT. Nest freely.
Extensible match
Section titled “Extensible match”DN-component matching:
(member:dn:=cn=John,ou=users,dc=example,dc=com)(ou:dn:=Engineering)Migrating to FleX
Section titled “Migrating to FleX”| LDAP | FleX |
|---|---|
(cn=John) | cn = John |
(&(a=1)(b=2)) | a=1 b=2 |
(|(a=1)(b=2)) | a=1 or b=2 |
(!(a=1)) | a != 1 |
(cn=*) | cn exists |
(cn=John*) | cn ^= John |
(cn=*John*) | cn %= John |
Related
Section titled “Related”- REST Channel — filter parameter, pagination, request headers
- GraphQL Channel — filter argument, collection queries
- Logging — FleX filters in log filtering rules
- Configuration — FleX in HOCON config files
- Error Codes —
FILTER_INVALID_SYNTAX,FILTER_UNKNOWN_ATTRIBUTE