📘 Public beta · Endpoints are stable; OpenAPI specs and SDKs ship monthly. See changelog →
Products
Anti-Fraud Platform
Rules engine

Rules engine

The Anti-Fraud rules engine is similar in shape to the AML rules engine but distinct in vocabulary and action verbs. Rules here output allow, flag, review, or block — not just severity scores.

Anatomy

{
  "id": "rul_01HXY...",
  "code": "VL-003",
  "name": "High amount unverified counterparty",
  "description": "Transactions ≥ IDR 50M to a counterparty not in the customer's known-good list.",
  "lane": "transaction",
  "category": "velocity",
  "type": "threshold",
  "severity": "high",
  "action": "review",
  "bypassMl": false,
  "score": 20,
  "conditions": { ... },
  "status": "active",
  "approvedById": "usr_01HXY...",
  "createdAt": "...",
  "updatedAt": "...",
  "fireStats30d": {
    "fired": 8421,
    "truePositives": 412,
    "falsePositives": 8009
  }
}

Action verbs

ActionEffect
allowReduces fraudScore (negative contribution). Used for "known good" rules.
flagAdds to score; if final decision is allow, the alert is still recorded.
reviewAdds to score; if final decision is flag/allow, upgrade to review.
blockForce-block regardless of score (subject to bypassMl policy).

bypassMl

If bypassMl: true, the rule's action is never downgraded by ML suppression. Use for hard regulatory or known-bad rules (sanctioned country, internal blocklist). Default: false (ML can suppress).

fireStats30d

A rolling 30-day window of true/false positive counts based on analyst dispositions on the resulting alerts. Use it to tune your rule library — high-FP rules should have their score lowered or be retired.

List + create

GET/api/rules
Auth · API keyScope · rules:read

Filters: lane, status, type, category (tag-based), search (free-text against name and description).

POST/api/rules
Auth · API keyScope · rules:write

New rules start in draft. They require approval before going active (see below). Admin-only.

Approval

POST/api/rules/{id}/approve
Auth · API keyScope · rules:write
{
  "decision": "approve | reject",
  "notes": "Validated against last 90 days; FP rate 8.2% acceptable."
}

Four-eyes enforced: approver must differ from drafter when the rule's action is block (configurable for other actions).

Backtest

POST/api/rules/{id}/backtest
Auth · API keyScope · rules:write
{
  "lookbackDays": 90,
  "sampleSize": 50000
}

Returns:

{
  "data": {
    "totalEvaluated": 412875,
    "wouldHaveFired": 3284,
    "estimatedFalsePositiveRate": 0.082,
    "byLane": { "onboarding": 412, "transaction": 2872 },
    "topMatchingCustomers": [
      { "customerId": "cus_01HXY...", "fireCount": 14 }
    ]
  }
}

Version history

GET/api/rules/{id}/versions
Auth · API keyScope · rules:read

Returns every prior version with the editor + timestamp. Required for examiner audit ("what was the rule on date X?").

Categories we ship by default

CategorySample rules
VelocityHigh amount, repeat-merchant burst, daily-sum exceed
DeviceJailbroken, rooted, emulator, attestation-fail
GeographyHigh-risk-country IP, geo-distance vs registered address
Synthetic identityEmail-domain young, phone-recently-ported, name-DOB mismatch
Account-takeoverNew device + sensitive action, IP change + immediate transfer
Mule / structuringFunnel-account pattern, fast-pass-through, sudden activity
Card / QRISHigh-risk MCC, prepaid-instrument burst, declined-then-approved
OnboardingNIK-on-blocklist, duplicate-NIK-different-account, sanctioned country

Out-of-box ~120 rules across these categories. You can disable, edit, score-tune, or fork any of them.

Status flow

draft → pending_approval → active

                     paused (admin emergency-off)

                     retired (terminal)

Retiring a rule keeps it in audit logs forever but stops it from firing on new evaluations. Use this rather than deletion.

Right-size scores by elasticity, not gut

We strongly recommend that all new rules be tested via backtest before promotion. The reflex is to give important-feeling rules high scores; backtest lets you see what the rule actually does to your block rate and FP rate before it touches production traffic.