Shield
Rules: tune, simulate, deploy
A compliance team can change a rule, see what it would have done to the last month of transactions, and put it live — without a code release.
Rules
Each rule has parameters (for example an amount threshold in AZN qəpik: 500000 = 5,000.00 AZN), a base score, a default outcome and a mode: active (affects outcomes), shadow (recorded only) or disabled. A rule that lacks the data it needs does not fire. The sanctions and PEP rules (SAN_01, SAN_02, CMP_01) are always on, in every ruleset; only their name and description can change.
List them with GET /v1/risk/rules; the fields a rule can read and the operators it can use are at GET /v1/risk/schema/events.
Tune → simulate → deploy
Simulate the change
Read the comparison
Completed: how often the rule fires before and after, outcome counts before and after, the transitions (for example review → clear), up to 25 changed decisions, and caveats. Once-a-month AML rules count condition matches, not firings.Deploy exactly what was simulated
simulationId, a rationale, the approver and the version it ran against. The API refuses it if the simulation is not completed (SIMULATION_NOT_COMPLETED), ran on another version (SIMULATION_STALE) or simulated a different change (SIMULATION_MISMATCH). The next decision uses the new version.# 1. Simulate: raise TXN_01's threshold to 8,000 AZN over the last 30 days
curl -X POST https://api.verifex.dev/v1/risk/rules/RULE_GUID/simulate \
-H "Authorization: Bearer vfx_your_api_key" -H "Content-Type: application/json" \
-d '{ "params": { "threshold": 800000 }, "days": 30 }'
# → 202 { "simulationId": "sim_…", "status": "Queued", "baseVersion": 1 }
# 2. Poll until "status": "Completed"
curl https://api.verifex.dev/v1/risk/simulations/sim_… \
-H "Authorization: Bearer vfx_your_api_key"
# 3. Deploy exactly the simulated change
curl -X PATCH https://api.verifex.dev/v1/risk/rules/RULE_GUID \
-H "Authorization: Bearer vfx_your_api_key" -H "Content-Type: application/json" \
-d '{ "params": { "threshold": 800000 }, "simulationId": "sim_…",
"rationale": "Raise the high-value threshold after a 30-day simulation",
"approvedBy": "Head of Compliance", "expectedVersion": 1 }'Info
429 SIMULATION_LIMIT). The dashboard's rule page does the same three steps with buttons. On the compatible API: POST /api/General/Transaction/Rule/{guid}/Simulate and PUT …/Rule/{guid} with simulationId.The Parameter Register
Every change is a new version with who made it, who approved it and why (GET /v1/risk/rules/{id}/versions), an audit entry naming the simulation, and a rule.changed webhook. Each decision records the rule versions it used, so an old decision replays with the rules of its day.
Alarm thresholds
GET / PUT /v1/risk/alarm-thresholds with veryLow, low, medium, high, critical (non-decreasing): a decision's alarm is the highest level whose threshold its totalScore reaches; a total of 0 raises none. Compatible API: General/Transaction/RiskThreshold.
MCC and currency risk
Give merchant category codes and currencies a risk level (1 Low, 2 Medium, 3 High); rules read them as mcc_risk_level and currency_risk_level. Native: PUT /v1/risk/mcc-codes and /v1/risk/currency-risk-levels with { items: [...] }. Compatible: SanctionScanner's .xlsx upload (MCC Code, Name, Description, Risk Level). Invalid rows are skipped and reported. No built-in rule uses these: add a rule that does.
Customer risk score
A registered customer has a risk score that rules read as customer_risk_score. Raise or lower it with a reason (POST /v1/risk/customers/{customer}/risk with { delta, reason }); it never goes below 0, and every change is kept. Its level (VeryLow … Critical) comes from the customer risk thresholds.