Condition fields
Every Transaction Monitoring rule is a condition over a namespaced field. The builder groups fields into Transaction, Lists, Identity, and Velocity. This page is the glossary: what each field means, the unit it uses, and a short example.
Amounts are stored in minor units of the currency (the smallest unit: cents for EUR and
USD, pence for GBP). The dashboard label is Amount (minor units) (transaction.amountMinor).
It is not a banknote denomination. €10.00 is 1000; €1,000.00 is 100000. Pair amount cutoffs
with transaction.currency so a EUR threshold is not applied to a USD payment.
Time fields (hourOfDay, dayOfWeek, isOutsideBusinessHours) are computed in the
organization timezone from Settings,
not in UTC and not per rule.
Transaction
| Field | Meaning | Example |
|---|---|---|
Amount (minor units) (amountMinor) | Payment amount in the currency’s smallest unit. Integer, never a decimal euro/dollar amount. | amountMinor >= 100000 on EUR is “€1,000 or more”. |
| Currency | ISO 4217 code of the payment. | currency Equals EUR |
| Direction | Deposit, Withdrawal, or Transfer. | direction Equals WITHDRAWAL |
| Payment status | Lifecycle status: Pending, Settled, Failed, Canceled, Reversed. | Fire only on Settled. |
| Hour of day (0–23) | Hour in the organization timezone. | Night-time: hourOfDay >= 0 AND hourOfDay <= 5 |
| Day of week (1 = Monday) | ISO day number in the organization timezone. | Weekend: dayOfWeek >= 6 |
| Outside business hours | True when the event falls outside weekday business hours in the organization timezone. | isOutsideBusinessHours Equals true |
| Counterparty country | ISO 3166-1 alpha-2 of the other leg. Derived from IBAN when you omit it. | counterpartyCountry Equals IR |
| Origin country | Country on the monitored identity’s side. | originCountry Equals IT |
| Counterparty name | Name of the other party. | counterpartyName Contains exchange |
| Counterparty account / IBAN | Account identifier of the other party. | Used with list hits more often than compared directly. |
| Channel | How the payment was initiated (free string, e.g. mobile, branch). | channel Equals mobile |
| Rail | Payment network or provider (free string, e.g. sepa, open_banking). | rail Equals sepa |
| Payment description | Free-text reference / SEPA causale. Keyword lists match against this. | description Contains prestito |
| External ID | Your transaction identifier (also the idempotency key). | Rarely used in rules. |
| External user ID | Your identifier for the verified identity. | Rarely used in rules. |
Amount vs average (%) (amountVsAvgPercent) | This amount as an integer percentage of the identity's 90-day mean transaction amount. 100 is exactly average, 250 is 2.5×. | amountVsAvgPercent >= 500 is "five times the usual". |
amountVsAvgPercent is absent, not zero, on a first transactionThe field is only present when the identity has prior history in the last 90 days and that
history has a positive mean. On the very first transaction it is omitted from the condition
context entirely, so a rule that references it does not fire rather than firing against a
fabricated baseline. The mean it compares against is identity.historicalAvgAmount.
Lists
List matches are boolean flags computed at ingest against your managed lists. Updating a list updates every rule that references it.
| Field | Meaning | Example |
|---|---|---|
| Counterparty blocklist hit | The counterparty account is on a block list. | Hard-block template: blocklistHit Equals true |
| Counterparty allowlist hit | The counterparty account is on an allow list. Use to suppress noise on known-good flows. | allowlistHit Equals true |
| Any country-risk list hit | Origin or counterparty country is on any enabled country-risk list. | countryRiskHit Equals true |
| Country-risk hit (per list) | Same, but for one list key (for example the Italian MEF/BdI set). | countryRisk_it_high_risk Equals true |
| Keyword list hit | The payment description contains a term from a keyword list. | keywordHits Equals true |
| Matched keywords | The list entries that actually matched the description. A list of strings, not a boolean. | Read it on the fired-rule provenance; keywordHits is what you compare in a condition. |
Identity
These fields come from the verified identity the transaction is tied to, not from the payment payload.
| Field | Meaning | Example |
|---|---|---|
| KYC risk score (%) | The identity’s latest Risk score, 0–100. | riskScorePercent >= 51 (High or Critical) |
| Account age (minutes) | Minutes since the identity was verified. | New account: ageMinutes Less Than 1440 (24 hours) |
Historical average amount (historicalAvgAmount) | The identity’s mean transaction amount over the last 90 days, in minor units. Excludes the transaction being evaluated and any failed, canceled, or reversed payment. | amountMinor > historicalAvgAmount — but prefer transaction.amountVsAvgPercent for ratios. |
Like transaction.amountVsAvgPercent, historicalAvgAmount is omitted when the identity has
no prior history in the window. It is read directly from the transaction book, not from the
velocity counters below, so it is exact rather than bucketed.
Velocity
Velocity fields answer "how much, and how often, has this subject moved money recently". They are maintained as rolling counters per identity (and, for the counterparty metrics, per counterparty) and are available in the condition builder and as the metric of a banded rule.
Every field below is an integer, and every one is always present — a subject with no
history reads 0 rather than being absent, so a velocity rule never silently goes dormant.
Amount fields are in minor units, on the same scale as transaction.amountMinor.
Identity flow
Each of these six metrics exists over four windows: 1h, 24h, 7d, 30d. The window is a
suffix on the field name, so the deposit count over 24 hours is velocity.depositCount24h.
| Metric | Meaning | Unit |
|---|---|---|
depositSum1h … depositSum30d | Total value of the identity's deposits. | minor units |
depositCount1h … depositCount30d | Number of deposits. | count |
withdrawalSum1h … withdrawalSum30d | Total value of the identity's withdrawals. | minor units |
withdrawalCount1h … withdrawalCount30d | Number of withdrawals. | count |
transferSum1h … transferSum30d | Total value of the identity's transfers. | minor units |
transferCount1h … transferCount30d | Number of transfers. | count |
Net flow
| Field | Meaning | Unit |
|---|---|---|
velocity.netFlow24h | Deposits minus withdrawals over 24 hours. Transfers are treated as flow-neutral and contribute nothing. Can be negative. | minor units, signed |
Net flow exists only at 24h.
Counterparty
These are keyed on the other party, not on the identity, so they see activity across every identity in your organization that touched the same counterparty.
| Field | Meaning | Unit |
|---|---|---|
velocity.counterpartyInboundSum24h | Value moving toward this counterparty in 24 hours — the withdrawal and transfer legs pointed at it. | minor units |
velocity.counterpartyInboundCount24h | Number of such payments. | count |
velocity.counterpartyDistinctIdentities24h | How many distinct verified identities of yours transacted with this counterparty in 24 hours. | count |
velocity.counterpartyDistinctIdentities30d | The same over 30 days. A classic shared-beneficiary / money-mule signal. | count |
"Inbound" is relative to the counterparty: value leaving your identity and arriving at the other
side. Deposits do not contribute to it. counterpartyInbound* and counterpartyDistinctIdentities*
exist only at the windows listed — there is no 1h or 7d variant.
Semantics you should know before writing a threshold
The current transaction counts. A payment is folded into the counters at ingest, before the
rules are evaluated. depositCount24h >= 3 therefore fires on the third deposit, not the fourth.
Reversals decrement. When you move a payment to Failed, Canceled, or Reversed, a
compensating decrement removes exactly what the original ingest added. Moving a payment to
Settled changes nothing — it was already counted.
Windows are rolling, approximated by sub-buckets. Counters are kept in fixed time buckets and a window is the sum of the buckets it covers, including the current partial one:
| Window | Bucket size | Buckets summed | Real history covered |
|---|---|---|---|
1h | 5 minutes | 12 | 55–60 minutes |
24h | 1 hour | 24 | 23–24 hours |
7d | 6 hours | 28 | 6.75–7 days |
30d | 1 day | 30 | 29–30 days |
So a 24h window covers between 23 and 24 hours of real history depending on where in the current
hour the payment lands — worst-case truncation is under ~8% of the window. Buckets are aligned to
UTC and keyed on the event time you reported (occurredAt), not on when Zyphe processed it, so
a late or replayed report lands in the correct historical bucket.
Counters are currency-blind. A counter key does not include the currency, so a mixed-currency
book sums minor units across currencies. On a book that is not single-currency, pair a velocity
sum cutoff with a transaction.currency condition, or prefer the count metrics.
counterpartyDistinctIdentities* is exact. Unlike every other velocity field, it is counted
directly over the transaction book rather than from buckets, so it is not subject to the
truncation above.
Concurrent bursts can under-count. A payment whose contribution has been recorded but not yet folded into the stored counters is invisible to a rule evaluating a different payment in the same instant. Two simultaneous deposits for the same identity can each miss the other. Counters converge within about a minute. Size structuring thresholds with that tolerance in mind rather than expecting exact burst detection.
A counter failure fails the ingest. If Zyphe cannot record a transaction's velocity
contribution, the ingest request returns a 5xx rather than silently dropping it — a lost
contribution would permanently under-count the windows and let later payments miss blocks they
should have hit. The transaction and its verdict are already stored, so retry the same request
with the same externalId: the retry is idempotent and completes the missing bookkeeping.
Fields that are not in the builder yet
Counterparty screening fields (counterparty.*) are reserved for a later phase. A rule
authored against them is rejected at save time with a clear error rather than being stored as a
silently dormant rule. Every velocity.* field listed above is live.
Additional payload fields (for example ATECO / nature of business) cannot be added from the dashboard today. Send the list of fields you need and they can be wired into the condition palette.
Related
- Rules and Templates
- Settings and Alerts — timezone and verdict thresholds
- Lists