A Transaction Risk Analysis exemption is not a compliance box you tick once. It is a live scoring model whose right to exist depends on a fraud rate you have to hold under a regulator’s threshold, quarter after quarter.
Most writing about strong customer authentication treats the exemptions as a lookup table: low-value here, trusted beneficiary there, recurring transaction over there. The Transaction Risk Analysis (TRA) exemption is the one that does not fit that model, because it is the only one whose availability is contingent on your own measured performance. You do not simply qualify for it. You earn it continuously, and you can lose it. That distinction is the whole engineering problem, and it is why TRA belongs in an architecture conversation rather than a policy one.
What the exemption actually buys, and the string attached
Under the current SCA regime — Commission Delegated Regulation (EU) 2018/389, the regulatory technical standards that sit under PSD2 — Article 18 lets a payment service provider skip the second authentication factor on a remote electronic payment if it runs real-time transaction risk analysis and the transaction falls under an exemption threshold value (ETV). The bands are fixed: up to EUR 100, up to EUR 250, and up to EUR 500. Above EUR 500 there is no TRA exemption at all. Every one of those bands is gated by a reference fraud rate published in the Annex: 0.13% for the EUR 100 band, 0.06% for EUR 250, and 0.01% for EUR 500. The higher the value you want to wave through unauthenticated, the lower the fraud rate you must be running.
The friction saving is real. Fewer challenges means fewer abandoned baskets and fewer failed authentications on legitimate payers. But the price is that Article 19 defines the fraud rate as the total value of unauthorised or fraudulent remote transactions divided by the total value of all remote transactions, calculated on a rolling basis, and Article 20 says that if your fraud rate exceeds the reference rate for a given band over two consecutive quarters, you must stop applying the exemption in that band and report the breach to your competent authority. The right to exempt is a metric you monitor, not a permission you file for once and forget.
PSD3 and the accompanying Payment Services Regulation do not dismantle this. The Commission proposed the package in June 2023, and a provisional agreement was reached in late November 2025, with the PSR expected to apply around eighteen months after it enters into force. The PSR keeps SCA and keeps the TRA exemption, but it hands the European Banking Authority a mandate to write fresh technical standards that tighten the governance of exemptions. Engineer for the mechanism, then, and expect the specific numbers to be re-set by the new RTS rather than to stand still. The band-and-fraud-rate machinery is what you are building against.
The scoring service is a latency problem before it is a fraud problem
The exemption decision sits directly in the authorisation path. The payer has tapped pay; a score, a band check and an exempt-or-challenge decision all have to happen before the authorisation message leaves. That is a hard real-time budget — single-digit to low tens of milliseconds — and it shapes the design more than the model does. This is the same discipline as scoring risk inside an instant-payments window, which I have written about in the context of keeping real-time fraud controls inside a ten-second SLA: the constraint is that the control cannot become the thing that breaks the payment.
In practice that means the features feeding the score are pre-computed and read, not calculated inline. Velocity counters, device and beneficiary history, the payer’s typical amount and geography, and the current realised fraud rate for the relevant band all live in a low-latency store the scorer reads by key. Article 18 lists the risk factors the analysis has to consider — abnormal spending patterns, known fraud scenarios, the payer’s device and location, malware indicators — and those become your feature set. The model itself can be modest; a well-calibrated gradient-boosted model or even a scorecard will clear the latency bar comfortably. What you cannot afford is a synchronous feature computation or a cold cache in the authorisation path.
A scoring service with the guardrail built in
The decision has two gates, and they must be independent. First, is the band even claimable right now, given the realised fraud rate? Second, is this specific transaction low-risk enough to exempt? Collapsing the two — letting a low score override a breached band — is exactly how firms drift past the threshold without noticing. The sketch below keeps them separate: the band guardrail is checked from monitored fraud rates before the model score is ever consulted.
from collections import deque
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
# Reference fraud rates from the SCA-RTS Annex (Reg (EU) 2018/389),
# expressed as basis points against each exemption threshold value (ETV).
# The PSR mandates fresh EBA standards, so treat these as the current
# regime rather than a permanent constant.
REFERENCE_BPS = {100: 13.0, 250: 6.0, 500: 1.0}
BANDS = (100, 250, 500) # ascending; no TRA exemption above 500
@dataclass
class Decision:
exempt: bool
band: int | None
reason: str
class FraudRateMonitor:
"""Rolling realised fraud rate per ETV band, per Article 19:
value of fraudulent remote transactions over value of all remote
transactions. Breaching the reference rate for two consecutive
quarters forces cessation under Article 20."""
def __init__(self, window_days: int = 90):
self.window = timedelta(days=window_days)
self._events = {b: deque() for b in BANDS} # (ts, value, fraud_value)
self._suspended = set() # bands stood down after a breach
def record(self, band: int, value: float, is_fraud: bool, ts=None):
ts = ts or datetime.now(timezone.utc)
self._events[band].append((ts, value, value if is_fraud else 0.0))
def rate_bps(self, band: int, now=None) -> float:
now = now or datetime.now(timezone.utc)
cutoff = now - self.window
q = self._events[band]
while q and q[0][0] < cutoff:
q.popleft()
total = sum(v for _, v, _ in q)
if total == 0:
return 0.0
fraud = sum(f for _, _, f in q)
return (fraud / total) * 10_000
def claimable(self, band: int, now=None) -> bool:
if band in self._suspended:
return False
return self.rate_bps(band, now) <= REFERENCE_BPS[band]
def choose_band(amount: float) -> int | None:
"""Lowest ETV band that covers the amount; None means SCA is required."""
for b in BANDS:
if amount <= b:
return b
return None
def decide(amount: float, risk_score: float, monitor: FraudRateMonitor,
score_threshold: float = 0.15) -> Decision:
band = choose_band(amount)
if band is None:
return Decision(False, None, "above EUR 500 ETV: SCA required")
if not monitor.claimable(band):
return Decision(False, band, "band fraud rate at or over reference")
if risk_score > score_threshold:
return Decision(False, band, "transaction scored too risky")
return Decision(True, band, "TRA exemption applied")
if __name__ == "__main__":
m = FraudRateMonitor()
print(decide(240.0, 0.04, m)) # exempt in the 250 band
print(decide(600.0, 0.01, m)) # over 500: challenged
Two design notes carry the real weight. The claimable check reads the monitored rate for the band, so a rising fraud rate quietly removes the higher bands from play before you breach — the system degrades gracefully rather than failing a regulatory test. And because this endpoint sits on the authorisation path, it has to be safe to retry without double-counting; the same discipline that applies to making a POST safe to retry with idempotency keys applies to the score-and-record call, or your realised fraud rate becomes fiction.
Monitoring realised fraud rate by band is the actual product
The scoring model gets the attention; the monitoring is what keeps you compliant. You are tracking a value-weighted fraud rate per band, on a rolling window, with the reference rate as a hard line. The number that matters is not today’s fraud rate but its trajectory: a band creeping from 0.008% toward the 0.01% line needs to trigger action while you still have room, not at the moment of breach. That means alerting on the gradient, dashboarding the rate against reference per band, and treating a two-quarter breach as a pre-planned operational event — stand the band down, notify the competent authority, and fall back to full SCA — rather than a scramble. Fraud is settled with a lag, so your realised rate is always partly an estimate maturing over the recovery and chargeback window; build the pipeline that reconciles provisional fraud flags against confirmed losses, or the number you are governing against is wrong in your favour, which is the dangerous direction.
This is where the exemption stops being a payments feature and becomes an availability and data-lineage concern that reaches into the ledger. Getting the realised numbers right depends on clean, reconciled postings of exactly the kind that surface when you re-architect a core ledger for real-time, irrevocable settlement — the fraud rate is only as trustworthy as the transaction record feeding it.
Who owns the number when it drifts
The failure mode is organisational, not technical. The team that ships the scoring model optimises for approval rates and low friction. The team that owns the regulatory relationship finds out the fraud rate has breached when the quarter closes. Between them, nobody is watching the gradient in real time, and the first sign of trouble is a notification obligation instead of a tuning decision. Decide, before you go live, who is accountable for the realised fraud rate per band, what the alert thresholds are below the reference line, and what the automatic response is when a band breaches. Wire the cessation into the system so it happens whether or not anyone is looking.
A TRA exemption is a standing bet that your fraud controls are good enough to justify less authentication. The regulator lets you keep that bet only while the evidence holds. Build the monitoring first, and the exemption is a controlled metric. Build the model first, and the threshold becomes a surprise breach you report after the fact.
Build and rescue work
Hands-on delivery of this kind is handled by Sixteen Pillars Studio.
Free interactive tool
Website compliance checklist
What your site has to do, based on what it actually does
Answer as much or as little as you like — the list builds as you go. Nothing is stored against your name and no email is required.
Everything that applies
Ordered by what to do first: legal requirements you can close quickly, then larger pieces of work, then what is expected rather than required. Not exhaustive, and not a legal audit.
Dated PDF, yours to keep or circulate.
Can you trust the architecture you have?
Architecture diagrams rarely show the reality of how systems actually operate. An independent review establishes what is really there.