Skip to main content
This page is a reference for every building block available when defining rule conditions and actions. For a guided walkthrough of the Rule Builder, see Building rules.

Condition logic

Conditions are organized into a tree of groups:
  • all (AND) — Every condition in the group must match.
  • any (OR) — At least one condition in the group must match.
At the top level, a rule can have multiple paths connected with OR logic. If any path matches, the rule triggers. Within each path, you nest all / any groups to express complex boolean logic.
This rule triggers if the transaction amount exceeds $50,000 **and** the client is high-risk, **or** if the amount exceeds $100,000 regardless of risk tier.

Entities

Each condition targets one of five entities:

Custom fields

Entities that support custom fields expose them as customFields.<key> properties (for example, customFields.deviceRiskScore on the Device entity). Values are set during ingestion — for devices, include device.customFields on session create. A custom field’s type is inferred from its ingested values, and the type determines which operators it supports: Custom fields cannot be used in aggregations. Newly ingested fields become available in the rule builder after a short sync delay.

Entity relationships

For non-transaction entities, you can specify which participant the condition applies to: Custom-field conditions on participant entities (Client, Wallet, Bank account, Device) must set entityRelationship to sender or receiver — all is not supported.

Operators

Comparison operators

Array operators

String operators

Prefix and suffix checks on text facts (referenceId, txHash, memos, string custom fields) and enum-like strings. Matching is case-insensitive, same as string contains. Missing, null, or undefined facts do not match.
"DEP-abc" matches startsWith "dep-" because comparison is case-insensitive. "xdep-abc" does not — the value must be a prefix, not a substring in the middle (that is contains).

Range operator

between is advertised on numeric facts (for example amount, balances, numeric custom fields) and on dates. The value is a two-element array [min, max]. Both bounds are inclusive. Numeric aggregation results (sum, count, avg, …) also accept between. A range of two conditions (>= AND <=) still works.

Null-check operators

Null-check operators test whether a field is set at all. They take no value — the condition is just entity + property + operator. In the Rule Builder they appear as is empty / is set. Flag deposits from clients whose KYC tier was never set:
Notes:
  • Only the exact empty string "" counts as empty. A whitespace-only string like " " is a present value.
  • 0 and false are present values — they match isNotNull, never isNull.
  • Available on custom fields (customFields.<key>) of any scalar type, and on static facts that can actually be empty. Not available on array fields, aggregation results, or aggregation filters (a null check on an aggregation filter is rejected when the rule is saved).
  • is empty / is set refer to the evaluated fact, not to whether the field was sent in the API payload. Some facts are stored with a default when not provided, so they are never empty and do not offer these operators:
    • KYC Status (stored as account status, defaults to ACTIVE) — use KYC Level to test whether a KYC tier was set.
    • Activity Status (defaults to UNKNOWN) and client Risk Score (defaults to 0).
    • Built-in yes/no flags such as Is PEP and Is Sanctioned (default to false) — use PEP Score / Adverse Media Score isNull to test whether screening has run.
    • Date of Birth is evaluated as a date filter rather than a value — use Age isNull to test whether a date of birth is on record.
  • Facts that behave as expected include nullable fields (Onboarded At, KYC Level, PEP Score, Partner Client ID) and text fields stored as empty text when not provided (Occupation, Gender, Source of Funds).
  • A missing participant counts as empty. isNull on a sender or receiver field also matches when the transaction has no such participant — for example, “sender client occupation is empty” matches a deposit that has no sender client at all. To match only when the participant exists but the field is empty, combine it with a condition that requires the participant, such as isNotNull on another of its fields.
  • These operators do not change notEqual / notIn behaviour: a notEqual condition on a missing custom field still does not match. Use isNotNull + notEqual together when a rule must only fire when the field is present and different.

Aggregation operators

Aggregation conditions compute a value over a set of historical transactions before comparing with the operator and value. This enables velocity checks, cumulative thresholds, and statistical analysis.

Aggregation fields

When using an aggregation, provide these additional fields on the condition:

Time windows

Time windows define the lookback period for aggregation conditions.

Time types

Time periods

Used with aggregationTimeValue to define the window length:

Example: velocity check

“Count of deposits in the last 24 hours exceeds 10”:

Aggregation filters

Filters narrow which transactions are included in the aggregation. Each filter is a simple condition with property, operator, and value — the same comparison operators listed above apply. Common filter patterns:
  • Filter by transaction type: { "property": "type", "operator": "equal", "value": "WITHDRAW" }
  • Filter by currency: { "property": "currency", "operator": "in", "value": ["USD", "EUR"] }
  • Filter by direction: { "property": "direction", "operator": "equal", "value": "OUTGOING" }

Actions

Actions define what happens when a rule matches. Each rule must have at least one action.

CREATE_ALERT

Creates a compliance alert for analyst review.

HALT_TRANSACTION

Freezes the transaction until an analyst resolves the associated alert. Always used alongside CREATE_ALERT.
A rule with HALT_TRANSACTION blocks settlement on every match. Reserve this for high-confidence patterns where false positives are rare.

Common rule patterns

Large transaction detection

Alert when a single transaction exceeds a threshold:

Velocity check (structuring detection)

Alert when a customer makes more than 5 deposits under $10,000 in 24 hours:

High-risk customer with large withdrawal

Combine entity conditions for targeted detection:

Device custom field

Alert when the destination client’s device has a high risk score. Corsa uses the device from the session linked to the transaction, or from the client’s most recent session when none is linked:

Cumulative threshold

Alert when total outgoing volume exceeds $200,000 in 30 days: