Analyses
An analysis is a risk scorer configured on an event type. It accumulates the recent history of events in sliding windows and, on each new event, returns a score from 0 to 100 indicating how far that behavior departs from what is expected.
The analysis does not decide on its own: the decision rests with the rule. The rule feeds the analysis with the record analysis action, queries the result with the run analysis action, and uses that result in the following conditions.
It is intended for questions about velocity and concentration: how many attempts this card has made in the last hour, how many different cards have gone through this user today.
An analysis is transactional: it evaluates one event at a time and answers in time for the rule to act on it. The term refers to the mode of operation, not to the kind of data: an analysis applies to any event type, not only to financial transactions. To track aggregate behavior over time, use metrics and monitors.
Where to configure it
In Settings > Event types, open the event type and go to the Analyses tab.
The analysis has a single field of its own, the Name, which is the identifier used by rules and cannot be changed after creation: actions referencing the old name would be left orphaned. Everything else is configured on the cells.
The cell editor organizes the configuration into four groups: Identity (the cell’s identifier), Window (which events enter, with what key and for how long), Measure (the number extracted from the window) and Trigger (the limit applied to that number). It also offers ready-made examples, such as an attempt counter or a velocity limit, which fill the four groups at once and can be adjusted afterwards.
The cell list can be reordered by dragging. The new order writes each cell’s Priority, that is, it defines the order of the cascade: the first in the list decides first.
How the analysis decides
An analysis is a set of cells. Each cell is an independent question about a slice of the history: a grouping, a time window, a measure, and a target.
Every cell is evaluated, and the most specific one among those that triggered decides the result: the lowest Priority wins and, in a tie, the cell that observed the larger sample. The score returned is that cell’s, not the highest in the analysis: a specific cell scoring 91 decides ahead of a broad cell scoring 99. The cascade chooses by the reach of the block, not by the magnitude of the deviation, so that the action stays restricted to the smallest possible group.
When no cell triggers, the score is the highest any cell reached and the score cell is not reported. When you persist the score cell into an event field, it is filled in only on events where some cell explained the score.
A cell that cannot be evaluated, because the event did not carry the dimension field or because the window is empty, is skipped, never read as if everything were normal.
Cell fields
| Field | Content |
|---|---|
| Name | cell identifier, unique within the analysis; appears in the rule’s results |
| Dimension | field, or combination of fields, that groups the window |
| Window | size of the sliding window, in minutes, hours or days, up to 90 days |
| Signal | how the cell judges the window: statistical, fixed threshold or no trigger |
| Measure | what the cell measures in the window |
| Direction | which side of the target represents risk |
| Target | reference value; on rate measures, a number between 0 and 1 |
| Threshold | score from 0 to 100 at which the cell triggers; default 90 |
| Priority | order in the cascade; the lowest decides first |
| Numerator and Denominator | filters that define the rate, on percentage measures |
| Distinct by | counted field, or the entity of the rate, depending on the measure |
| Record when | filter that decides which events feed the window |
Record when is the only setting that sees fields the cell neither groups by nor counts, and it is what lets you change the question: recording only declined events turns a cell from “different cards for this user” into “different cards this user was declined on”.
Changing the dimension, the window or the measure restarts the accumulated history, with no reprocessing: the cell needs a full window of traffic before it means anything again. Changing the target, the threshold, the priority or the filters preserves the history.
Measure
| Measure | What it measures |
|---|---|
| Count | volume of events in the window, that is, velocity |
| Distinct values | how many different values of a field appear in the window |
| Percentage | the rate of an outcome, such as approval |
| Percentage by distinct values | the same rate, counting each distinct value only once |
Count requires no additional configuration. Distinct values requires the Distinct by field, whose different values are counted.
Percentage requires a Numerator and accepts a Denominator, both filters over the same outcome field: the numerator states which values count in favor, and with an empty denominator the base is every value in the window.
Percentage by distinct values is the same rate measured over entities rather than attempts. Each distinct value enters with one observation, that of its last attempt in the window, so a customer who tried ten times weighs the same as one who tried once.
Both percentage measures are evaluated over the 100 most recent observations in the window.
Signal
It defines how the cell judges the window, and it is the choice that changes the meaning of the Target.
With the Statistical signal, which is the default, the target is the expected normal behavior and the score expresses how far the window departs from it. Use it when the goal is to detect deviations from normal and the exact number does not matter.
With the Fixed threshold signal, the target is the trigger point itself: the cell triggers when the observation reaches it, and the score is always 100 or 0. Use it when the number is part of an agreed policy, for example a cap on declined attempts per period set in a contract. Translating that number into a statistical target would couple it to the analysis’s calibration, and retuning the calibration would silently move a value that an external document pins down.
When choosing the fixed threshold:
- There is no small-sample guard. This is the central difference from the statistical signal, and a real risk on percentage measures: a threshold of 50% triggers on a single declined attempt, because one decline out of one attempt is 100%. Pair it with a window and a record filter that make an early sample meaningful.
- The Threshold field does not apply and disappears from the form, since the score only ever takes 100 or 0.
- The direction is one-sided: “Above” triggers on reaching or passing the target, “Below” on reaching or staying under it. “Both” is rejected, because a single number bounds only one side.
- On volume measures the target must be a whole number: 2.5 events cannot be observed.
No trigger
A cell with the No trigger signal maintains the window and exposes the measured value, without firing. Target, Direction and Threshold do not apply, and the cell stays out of the cascade: it neither decides the result nor counts towards the triggered cells.
A cell with no trigger is suited to exposing a number from the window without turning it into a block: counting an order’s attempts, writing that counter to a field and leaving the decision to a rule condition.
The three signals coexist in the same analysis, and the two that fire score on the same 0 to 100 scale.
The form shows a preview of the cell as soon as measure, direction and target are filled in. On a fixed-threshold cell, it shows the scale jumping straight from 0 to 100 at the target.
Using the analysis in a rule
The analysis only takes effect through a rule:
- the record analysis action feeds the windows with the current event;
- the run analysis action evaluates the analysis and exposes the result;
- the following conditions decide what to do with that result.
The result becomes available as a temporary variable, with the score, the cell it came from, and the set of triggered cells.
Each evaluated cell also publishes the raw value it measured in the window, under %<result>.cells.<cell>.value. A cell with no trigger delivers its number through this variable, to the following conditions or to a field of the event.
Condition 1: $amount > 0 → Record analysis: bot
Condition 2: $amount > 0 → Run analysis: bot
Condition 3: %bot.triggered → Set field: review = "true"
Condition 4: "declines_per_card" in %bot.triggered_cells → Add to list: $card_fingerprint to @blocked_cards
Recording and running are independent: a condition can feed the history without querying it, query it without feeding, or do both.
Rules that use this analysis
The analysis page shows the rules that link to it, one row per rule version, separating those that run it from those that record it, with the fields each one writes and the result name.
Since recording and running are independent, the analysis can sit in one of two incomplete states, both flagged in that listing:
- scores with nobody recording: a rule queries the analysis, but none feeds its windows, so the score is calculated over a history that receives no traffic;
- records with nobody scoring: the windows accumulate, but no rule reads the result, so the analysis has no effect on any decision.
An analysis named by a published rule version or one in observation cannot be removed. The removal reports which rules keep it in use, and becomes possible once those rules stop naming it.
Versions
An analysis is versioned like a rule: the published version is immutable, editing a cell or the order of the cascade starts from it into a draft, and publishing takes the whole cascade live at once. A previous version can be restored, and a version can be published in observation, over the same traffic as the active version, deciding nothing. See Versioning.