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

# How to Create a Custom Detector

> Write a rule that flags the transactions your close process actually cares about, using a worked example of large journal entries posted to cash.

Custom detectors let you set your own thresholds. Reach for one when you can write the rule down in a sentence: nothing over this amount, nothing posting to this account, nothing with this word in the memo, nothing dated to this day.

A rule has no confidence scoring and no second pass. Every transaction that matches becomes a visible alert immediately. Write the first version narrower than you think you need.

## Before you begin

Write the rule as one plain sentence before you open the form. If you cannot finish the sentence "alert me when a transaction is \_\_\_ and \_\_\_", the rule is not ready and you will end up with a detector that alerts on things nobody acts on.

Then confirm two things about the rule you have in mind:

* **The conditions are expressible.** A rule tests one transaction at a time against a fixed list of fields, and each field accepts only some operators. Dates are the common surprise: they test only whether a date is or is not one specific day. Check your conditions against [Available fields and operators](#available-fields-and-operators) before you build.
* **You know the scope.** A rule created on the Anomaly Detection page watches every company in the organization. If it should watch one entity instead, decide which one now, because entity scoping is a condition inside the rule rather than a setting on the form.

Creating a detector requires the transaction monitor create permission. Roles are configurable per organization, so check yours if the New Detector button is not available.

## Worked example

The rule we are building: **alert me when a journal entry of \$50,000 or more posts to a cash account.**

This is the manual-entry blind spot at close. Large cash movements normally arrive through AP, AR, or the bank feed, so a journal entry hitting cash at that size is either a correction worth reviewing or a mistake worth catching.

<Steps>
  <Step title="Open the New Detector form">
    On **Home > Anomaly Detection**, select **New Detector**. The form opens with a name field and an empty rule containing one condition group.

    The rule always begins with the same trigger, **When a transaction created or edited**, which you cannot change. Rules evaluate transactions, not balances, so every alert points at a record you can open.
  </Step>

  <Step title="Name the detector for the card, not for yourself">
    Enter `JE to Cash > 50k`.

    The card shows the name and nothing else, so a name carrying the object and the threshold beats "Cash review" six weeks from now. Most orgs follow this shape already: `JE > 1mn`, `CS > 200k`, `AP over $500k`.
  </Step>

  <Step title="Add the first condition">
    In Conditions Group 1, select **select condition**, then choose:

    * Field: **Transaction Type**
    * Operator: **is**
    * Value: **Journal Entry**

    Choosing a field sets the operator to the first one that field allows, so **is** is already selected here.

    This scopes the rule to manual entries. Without it, the rule fires on every bill, invoice, and payment above the threshold as well, which is a noisier detector.
  </Step>

  <Step title="Add the remaining conditions">
    Select **Add condition** twice and fill in:

    * **Amount** **greater than or equal to** `50000`
    * **Account Type** **is** **Bank**

    There is no Cash account type; cash and bank accounts both sit under **Bank**.

    Conditions inside a group always combine with AND: the first row is labeled **If** and every row after it **And**, with no toggle to change that. OR requires a second condition group.
  </Step>

  <Step title="Scope the rule">
    There is no company selector on the New Detector form, so a rule you create there applies to every company in the organization.

    To scope a rule to one entity, add a **Company** **is** condition to the group. Do that when the threshold is entity-specific: a \$50,000 journal entry is routine at your largest subsidiary and alarming at a shell entity, and one threshold cannot express both.
  </Step>

  <Step title="Create and verify">
    Select **Create**. The detector appears as a card on the Anomaly Detection page.

    Rule-based checks run on each transaction as it posts, plus a full pass daily at 00:00 UTC. To confirm the rule works, post a transaction you know should match rather than assuming silence means correctness.
  </Step>
</Steps>

After the next pass, every journal entry of \$50,000 or more that posts to a bank account raises an alert under the `JE to Cash > 50k` card, and a callout appears on each flagged entry for whoever opens it next.

## Available fields and operators

Conditions test one field against one value. Which operators you get depends on the field, and the restrictions matter more than the list itself.

Operators available per field:

| Field                                                                                                                                                  | Operators available                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| Amount                                                                                                                                                 | greater than, less than, greater than or equal to, less than or equal to |
| Memo                                                                                                                                                   | contains, does not contain, starts with, ends with                       |
| Account, Account Type, Classification, Company, Customer, Vendor, Item, Record Status, Transaction Type, Posting Date, Transaction Date, Creation Date | is, is not                                                               |

Read that table before designing a rule. Amount cannot test equality, memo cannot be compared, and the three date fields only test whether a date **is** or **is not** one specific day. There is no date range, no relative comparison (this month versus last), no count, and no aggregation across transactions. Rules answer questions about one transaction at a time.

The per-field restrictions are a limitation of the rule builder rather than of the rule engine, which evaluates the comparison operators on any field. If you need a comparison the form will not offer, it is worth raising rather than working around.

Record Status offers every status except draft, so drafts cannot be targeted by rule.

## More rules worth having

Five custom detectors that earn their place on most ledgers, each stated as the goal and the conditions that express it.

Goals and the conditions that express them:

| Goal                                                          | Conditions                                                                                                                         |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Flag anything posted on a date your business does not operate | **Transaction Date** **is** the date, plus **Company** **is** the entity                                                           |
| Surface memos that signal a known problem                     | **Memo** **contains** `reclass`, in a second group **Memo** **contains** `plug`, in a third **Memo** **contains** `to be reviewed` |
| Watch a single sensitive account                              | **Account** **is** the account, AND **Amount** **greater than** your review threshold                                              |
| Catch large entries against a vendor who should not have them | **Vendor** **is** the vendor, AND **Amount** **greater than** the threshold                                                        |
| Watch a classification that keeps getting miscoded            | **Classification** **is** the value, AND **Amount** **greater than** the threshold                                                 |

Build these as separate detectors rather than one rule with many condition groups. Separate cards give you separate alert counts, and an alert that names its own rule is faster to triage.

Two rules people reach for that cannot be built: backdated entries into a closing period (needs **Creation Date** compared against a date, and dates only test **is**) and unposted drafts (draft is not selectable on Record Status). Both remain manual checks at close.

## Using multiple condition groups

Groups combine with OR, and the form draws an **Or** between them. A transaction matches the rule if it satisfies every condition in any one group.

Select **Add condition group** when you need OR logic. A rule that should fire on either a large amount or a suspicious memo cannot be expressed inside one group, because conditions within a group are always AND. Put the amount condition in group 1 and the memo condition in group 2.

Groups are also how you cover several values of the same field. A rule watching three memo keywords needs three groups, one keyword each, because a single group would demand that all three appear in the same memo. The same applies to a rule that should watch two accounts or two companies.

Each group carries its own three-dot menu with **Duplicate** and **Delete**, and duplicating is usually faster than rebuilding: copy the group, then change the one value that differs. Groups you leave empty are discarded when you save, so a half-built group does not silently widen the rule.

## If the rule does not behave

Rules fail quietly in both directions, and neither failure announces itself. Work through the symptom you have.

**The rule has never fired.** Confirm the detector card reads active, and confirm a scheduled pass has run since you created it: checks run as transactions post plus a full pass at 00:00 UTC, so a rule created after the transactions you expect it to catch may genuinely have had no pass yet. If both are true, the conditions are probably contradictory. Every condition in a group must hold at once, so a group testing **Transaction Type** **is** **Journal Entry** AND **Vendor** **is** a vendor will never match, because journal entries carry no vendor. Split conditions like these into separate groups, which combine with OR.

**The rule fires on everything.** A missing condition is the usual cause: an amount threshold with no transaction type scoping catches every bill and invoice above the figure as well. Open three alerts and find the shared trait that you meant to exclude, then add it as a condition rather than raising the threshold.

**The rule fires on the wrong entity.** Rules apply organization-wide unless a **Company** condition scopes them. Add one rather than creating a second detector.

<Warning>
  Every rule match becomes a visible alert with no confidence filtering. A rule written loosely enough to match a few hundred transactions will bury the detectors that are working. Set the threshold at the level where you would genuinely open the record, not at the level where you are mildly curious.
</Warning>

## Next steps

* [How to Clear the Anomaly Queue During Close](./clear-the-anomaly-queue)
* [Anomaly Detection: How Alerts Are Raised and Resolved](./anomaly-detection) for how rule alerts differ from AI alerts
* [How to Lock and Unlock Accounting Periods](../core-financials/general-ledger/period-locking)
