> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Rules & Scoring

> Configure KYT rules with conditions, velocity windows, and automated actions. Start from preset bundles or build custom. Pay-per-call $0.02 per transaction.

Every transaction submitted to Didit is evaluated against all active rules for your application. Rules define conditions, velocity checks, and actions that determine the transaction's final status and score.

<Note>
  Rules are **configured from the Business Console**. There is no public rule-CRUD API — the design goal is to keep rules tightly reviewed by your compliance team rather than changed by code. Rules are evaluated on every transaction submitted via [`POST /v3/transactions/`](/management-api/transactions/create), and the result appears in the transaction's `rule_runs[]` array (see [response schema](/transaction-monitoring/response-schema)).
</Note>

## Built-in rule bundles

Didit provides a pre-configured rule library for every application with transaction monitoring enabled. These rules are based on common regulatory typologies and can be customized or disabled. For the complete catalogue of every preset rule with thresholds and actions, see the [Rules library](/transaction-monitoring/rules-library).

| Bundle                  | Examples                                                                                                                                                                                   |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Finance**             | Structuring detection (inbound/outbound), large single transactions above reporting thresholds                                                                                             |
| **AML/CTF**             | Cumulative volume limits, rapid in-and-out movement, sanctions counterparty matching, PEP counterparty exposure, suspicious payment reference keywords                                     |
| **Anomaly detection**   | High velocity inbound/outbound, dormant account reactivation after 12+ months of inactivity                                                                                                |
| **FATF**                | High-risk jurisdiction exposure for counterparties and subject IPs                                                                                                                         |
| **Device intelligence** | Repeated bonus-campaign use from the same device fingerprint, multiple device fingerprints for the same subject                                                                            |
| **Fraud prevention**    | Multi-accounting via shared device fingerprints across distinct subjects                                                                                                                   |
| **Crypto monitoring**   | Mixer/obfuscation service exposure, high-risk wallet addresses (darknet, sanctioned, stolen funds)                                                                                         |
| **Crypto screening**    | High-risk source-of-funds exposure (>30%), multiple risky counterparties, terrorist financing / child exploitation auto-decline, screening-pending hold, medium wallet risk score flagging |
| **Responsible gaming**  | Rapid deposit bursts within short windows                                                                                                                                                  |
| **E-commerce**          | E-commerce specific transaction patterns                                                                                                                                                   |

## Rule sources

Every rule has a `source` that indicates who manages it:

| Source     | Description                                                                                                                                                                                                                                |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Preset** | Rules from Didit's built-in library. These are automatically created for every application with transaction monitoring enabled. You can customise their thresholds, disable them, or switch them to test mode, but they cannot be deleted. |
| **Custom** | Rules created by your team from the Business Console. You have full control over custom rules — create, edit, and delete as needed.                                                                                                        |

## Rule anatomy

Each rule consists of:

| Component               | Description                                                                                                                                |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| **Title & description** | Human-readable name and explanation of what the rule detects                                                                               |
| **Category**            | Logical grouping (e.g., `finance`, `aml_ctf`, `crypto_monitoring`, `device_intelligence`)                                                  |
| **Mode**                | `Active` (live evaluation), `Disabled` (skipped), or `Test` (evaluated but results don't affect the transaction)                           |
| **Evaluation mode**     | `All` (every condition must match) or `Any` (at least one condition must match)                                                            |
| **Scope**               | Limits which transactions the rule applies to — by transaction type, direction, or other filters                                           |
| **Conditions**          | Field-level checks — compare transaction fields against values using operators like `eq`, `lt`, `gte`, `in`, `contains_any`, `exists`      |
| **Aggregation**         | Velocity windows — aggregate historical transactions over a time period (e.g., count, sum, or distinct count over 1 hour, 7 days, 30 days) |
| **Actions**             | What happens when the rule matches (see below)                                                                                             |

## Actions

When a rule matches a transaction, one or more actions are executed. Each rule can have multiple actions that are all applied together:

| Action            | Description                                                                                                                                                                                 |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Add score**     | Add a specified number of points to the transaction's risk score. The cumulative score across all matched rules determines whether the transaction crosses the review or decline threshold. |
| **Change status** | Directly set the transaction status to `IN_REVIEW`, `DECLINED`, or `AWAITING_USER`. This takes effect immediately regardless of the score.                                                  |
| **Add tags**      | Automatically tag the transaction for categorization and filtering (e.g., `high-risk`, `structuring-suspect`).                                                                              |
| **Add note**      | Attach an automated note to the transaction for analyst context.                                                                                                                            |
| **Add to list**   | Add the applicant, counterparty, or other entity to a blocklist, allowlist, or custom list.                                                                                                 |

Most preset rules combine **add score** with **change status** — for example, a sanctions counterparty rule adds 90 points to the score *and* immediately declines the transaction.

## Scoring

When a transaction matches one or more rules, the scores are combined:

1. Each rule match contributes to the transaction's overall **risk score** via the `add_score` action
2. The final score determines the transaction status based on your application's **score thresholds**
3. If any rule has a `change_status` action, that status is applied directly — `DECLINED` always takes priority

Default score thresholds (configurable in the console):

| Setting               | Default | Description                                       |
| --------------------- | ------- | ------------------------------------------------- |
| **Review threshold**  | 60      | Scores at or above this value trigger `IN_REVIEW` |
| **Decline threshold** | 85      | Scores at or above this value trigger `DECLINED`  |

## Creating custom rules

Custom rules are created and managed from the **Business Console**:

1. Go to **Transactions** > **Rules** in the console
2. Click **Create Rule**
3. Define the rule title, description, and category
4. Set the **mode** — `Active` to run live, or `Test` to evaluate without affecting transactions
5. Choose the **evaluation mode** — `All` (every condition must match) or `Any` (at least one)
6. Set the **scope** — which transaction types or directions the rule applies to
7. Add **conditions** — field comparisons like amount thresholds, country codes, custom property checks
8. Optionally add **aggregation** — velocity checks over a time window (count, sum, or distinct count)
9. Define one or more **actions** — add score, change status, add tags, add notes, or add to list
10. Save and enable the rule

Rules take effect immediately for all new transactions.

## Backtesting

Before activating a rule, you can validate it against historical data:

* Set a rule to **Test** mode — the rule is evaluated on every new transaction, but results don't affect the transaction's status or score. Execution statistics (matched count, affected entities) accumulate so you can assess impact before going live.
* Use the **backtest** feature to retroactively evaluate a rule's conditions and aggregation against transactions from a specified time period. The backtest returns the number of transactions evaluated, matched, and the affected entities — without modifying any historical data.

## Velocity windows (aggregation)

Velocity rules aggregate historical transaction data over a time period to detect patterns that single-transaction checks would miss:

| Metric             | Description                                                                            |
| ------------------ | -------------------------------------------------------------------------------------- |
| **Count**          | Number of transactions matching the filters in the window                              |
| **Sum**            | Total of a numeric field (e.g., `preferred_currency_amount`) in the window             |
| **Distinct count** | Number of unique values for a field (e.g., distinct device fingerprints) in the window |

Each aggregation specifies:

* A **time window** (e.g., `1h`, `6h`, `1d`, `7d`, `30d`)
* **Filters** to narrow which historical transactions are included (e.g., same subject, same direction, same device)
* An **operator and threshold** (e.g., count >= 20)

### Example patterns

| Pattern                  | How it works                                                                                         |
| ------------------------ | ---------------------------------------------------------------------------------------------------- |
| **Structuring**          | Count of transactions below \$10,000 for the same subject in 30 days >= 20                           |
| **High velocity**        | Count of inbound transactions for the same subject in 7 days >= 20                                   |
| **Rapid in-and-out**     | Current transaction is outbound + count of inbound transactions for the same subject in 6 hours >= 1 |
| **Multi-accounting**     | Distinct count of subjects sharing the same device fingerprint in 7 days >= 3                        |
| **Dormant reactivation** | Days since subject's previous transaction >= 365, combined with amount >= \$1,000                    |

## Condition operators

Rules support the following comparison operators for conditions:

| Operator       | Description               | Example                                             |
| -------------- | ------------------------- | --------------------------------------------------- |
| `eq`           | Equal to                  | `direction eq "OUTBOUND"`                           |
| `lt`           | Less than                 | `amount lt 10000`                                   |
| `gte`          | Greater than or equal     | `preferred_currency_amount gte 25000`               |
| `gt`           | Greater than              | `travel_rule_obligations_count gt 0`                |
| `in`           | Value is in a list        | `counterparty_country in ["IRN", "PRK", "SYR"]`     |
| `contains_any` | Text contains any keyword | `payment_details contains_any ["terror", "weapon"]` |
| `exists`       | Field is present          | `subject_device_fingerprint exists true`            |

### Referencing custom properties

Every key submitted in the `custom_properties` object of [`POST /v3/transactions/`](/transaction-monitoring/transactions) is stored on the transaction as `custom_values` and can be used in conditions with the field path `custom_values.<key>`. For example, a transaction submitted with `"custom_properties": {"channel": "mobile_app"}` matches the condition `custom_values.channel eq "mobile_app"`. All operators above work with custom properties, and they can also be compared against other fields or used in velocity filters.

In the Console rule builder, keys observed on recently ingested transactions appear automatically in the condition field selector under **Custom Properties**. You can also reference a key before any transaction carries it: choose **Enter custom property** in the same group and type the key exactly as your integration sends it (keys are case-sensitive). The rule simply evaluates as not-matching until transactions carrying that key arrive.

## Automatic blocklist decline

Before any rules are evaluated, Didit checks the transaction's entities against your application's blocklists. If **any** match is found, the transaction is **immediately declined** — rules are not evaluated.

The following entities are checked:

| Entity                 | Blocklist type               | What is checked                                                       |
| ---------------------- | ---------------------------- | --------------------------------------------------------------------- |
| **User (applicant)**   | User Blocklist               | The applicant's `vendor_data` identifier                              |
| **Business**           | Business Blocklist           | The business's `vendor_data` identifier                               |
| **Wallet address**     | Wallet Address Blocklist     | The `account_id` of crypto wallet payment methods                     |
| **Bank account**       | Bank Account Blocklist       | The `account_id` of bank transfer payment methods                     |
| **IP address**         | IP Address Blocklist         | The IP address from the party's device context (supports CIDR ranges) |
| **Device fingerprint** | Device Fingerprint Blocklist | The device fingerprint or persistent device ID                        |

When a blocklist match occurs:

* Transaction status is set to `DECLINED`
* Decision reason is set to `blocklisted`
* An activity record is created for audit tracking

<Note>
  Blocklist checks run before rule evaluation. A blocklisted entity will always be declined regardless of rule configuration or score thresholds.
</Note>

## Transaction screening

Didit integrates with external AML and blockchain analytics providers to enrich transactions with risk intelligence. When a transaction is submitted, the system can:

* **Screen counterparties** against global sanctions and watchlist databases
* **Evaluate wallet addresses** (for crypto transactions) against blockchain intelligence data, including mixer exposure, sanctioned entity connections, and high-risk service interactions
* **Check applicant AML status** by cross-referencing the transaction's linked user against their latest AML screening results

Screening results are attached to the transaction and factor into the rule engine's scoring. If a counterparty or wallet matches a sanctions list, the corresponding rule automatically flags or declines the transaction.

## Next steps

<CardGroup cols={2}>
  <Card title="Submitting transactions" icon="arrow-right-to-bracket" href="/transaction-monitoring/transactions">
    How transactions are structured for rule evaluation.
  </Card>

  <Card title="Crypto screening" icon="link" href="/transaction-monitoring/aml-screening">
    Crypto screening results and how preset rules use them.
  </Card>

  <Card title="Settings" icon="gear" href="/transaction-monitoring/settings">
    Configure score thresholds and remediation workflows.
  </Card>

  <Card title="API reference" icon="code" href="/management-api/transactions/create">
    Create Transaction API endpoint.
  </Card>
</CardGroup>
