Beetles Docs

Rules & Watchers

Implement programmable governance and automated business logic.

Rules & Watchers

Beetles includes a powerful governance layer that allows you to define programmable business logic that is enforced on every transaction. This is achieved through two main components: Rules and Watchers.

Watchers

A Watcher is a monitoring point that "watches" for transactions on a specific resource. You can attach watchers to:

  • Ledgers: Applies to all transfers within that ledger.
  • Accounts: Applies to any transfer where the account is the debit (source) or credit (destination).
  • Identities: Applies to any transfer involving accounts linked to that identity.

When a transfer is initiated on a resource with an active watcher, Beetles automatically switches to a Governance Workflow.

Watcher Configuration

Each watcher has two configurable properties:

FieldTypeDefaultDescription
thresholdinteger60Minimum governance score required to approve the transfer.
modestring"enforce""enforce" blocks transfers below threshold. "observe" always approves but logs the score for analysis.

Observe mode is useful when you want to analyze transaction patterns before enabling enforcement — watchers in this mode act as labelers, tagging transfers with their governance scores without blocking any of them.

Creating a Watcher

curl -X POST /v1/watchers \
  -H "Content-Type: application/json" \
  -d '{
    "target_type": "account",
    "target_id": "01961234-abcd-7000-0000-000000000001",
    "threshold": 60,
    "mode": "observe",
    "rule_ids": [
      "01961234-abcd-7000-0000-000000000010",
      "01961234-abcd-7000-0000-000000000011"
    ]
  }'

You can optionally pass rule_ids at creation time to attach rules in a single request, or attach them later via PUT /watchers/{id}/rules/{ruleId}.

Governance Relationship Model

The execution follows a strict hierarchical evaluation path when a transfer occurs:

Rules

A Rule is a set of conditions that must be met for a transaction to be approved. Rules are attached to Watchers.

Each rule has:

  • Conditions: A list of structured conditions to evaluate.
  • Logical Operator: How conditions are combined — and (all must pass) or or (any must pass).
  • Weight: A penalty value subtracted from the initial score (100) if the rule fails.
  • Priority: The order in which rules are evaluated.

The Scoring System

Beetles uses a score-based approval system:

Transfer starts with score of 100

Every transfer begins with a perfect governance score.

All matching rules are evaluated

Rules attached to the triggered watcher are evaluated in priority order.

Failed rules subtract their weight

If a rule's conditions fail, its weight is subtracted from the score.

Score compared to watcher threshold

If the final score is above the watcher's threshold (default: 60), the transfer is approved. In enforce mode, transfers below threshold are voided. In observe mode, transfers are always approved but the score is logged for analysis.

Conditions

Each condition evaluates a single field against a value using an operator.

Structure

{
  "field_type": "native",
  "native_field": "amount",
  "operator": "<",
  "value": "1000000"
}

Available Operators

OperatorDescription
>Greater than
<Less than
>=Greater than or equal
<=Less than or equal
==Equal
!=Not equal

Native Fields

You can evaluate core transaction data and source/destination account statistics:

FieldDescription
amountThe value of the transfer in cents.
codeThe transfer code (user-defined).
created_atTransfer timestamp (Unix seconds).
source.idSource account ID.
source.nameSource account name.
source.velocity_1hTransfer count from source account in the last hour.
source.daily_totalTotal value transferred from source in the last 24h.
source.monthly_totalTotal value transferred from source in the last 30 days.
source.identity_idID of the identity linked to the source.
source.identity_labelLabel of the identity linked to the source.
destination.idDestination account ID.
destination.nameDestination account name.
destination.velocity_1hTransfer count to destination account in the last hour.
destination.daily_totalTotal value transferred to destination in the last 24h.
destination.monthly_totalTotal value transferred to destination in the last 30 days.
destination.identity_idID of the identity linked to the destination.
destination.identity_labelLabel of the identity linked to the destination.

Metadata Fields

You can also evaluate values from the transaction metadata by referencing a Metadata Field mapping by its ID. See Metadata Mapping for details.

{
  "field_type": "metadata",
  "metadata_field_id": "01961234-abcd-7000-0000-000000000001",
  "operator": ">",
  "value": "75"
}

Creating a Rule

Rules are created with one or more conditions. Use logical_operator to control how they combine.

Single Condition (AND default)

curl -X POST /v1/rules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Max Transfer Limit",
    "logical_operator": "and",
    "weight": 30,
    "priority": 1,
    "conditions": [
      {
        "field_type": "native",
        "native_field": "amount",
        "operator": "<",
        "value": "1000000"
      }
    ]
  }'

Multiple Conditions (AND)

All conditions must pass for the rule to pass:

curl -X POST /v1/rules \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Large + Fast Combo",
    "logical_operator": "and",
    "weight": 50,
    "priority": 0,
    "conditions": [
      {
        "field_type": "native",
        "native_field": "source.velocity_1h",
        "operator": "<",
        "value": "20"
      },
      {
        "field_type": "native",
        "native_field": "amount",
        "operator": "<",
        "value": "2500000"
      }
    ]
  }'

Multiple Conditions (OR)

Any condition passing is sufficient:

{
  "name": "Source or Destination Cap",
  "logical_operator": "or",
  "weight": 25,
  "priority": 2,
  "conditions": [
    {
      "field_type": "native",
      "native_field": "source.daily_total",
      "operator": "<",
      "value": "10000000"
    },
    {
      "field_type": "native",
      "native_field": "destination.daily_total",
      "operator": "<",
      "value": "10000000"
    }
  ]
}

Two-Phase Governance

When a Watcher is triggered, Beetles performs a Two-Phase Enforcement:

Pending Phase

The API creates a pending transfer, reserving the funds in the ledger engine.

Evaluation Phase

A durable workflow executes the Rules Engine, evaluating all attached rules.

Finality

  • Pass (enforce) or always (observe): The workflow captures the transfer (confirm).
  • Fail (enforce only): The workflow releases the funds (void) and records the rejection reason.

On this page