Documentation Index

Fetch the complete documentation index at: https://docs.darwinium.com/llms.txt

Use this file to discover all available pages before exploring further.

Signals Dashboard

Prev Next

Overview

Signals Dashboard gives you a flexible way to measure how your signals are performing. You can define your own columns - trigger rate, reject count, fraud rate, or any metric you need - and see them calculated across every signal in. Aggregations are performed at a journey & step level.

Image

Aggregates

Each aggregate becomes a column on the Signals Dashboard. To build one, you define:

  1. Column Name - unique column name
Column Name should no spaces
  1. Display Name - Name as will appear in signals dashboard column
  2. Variables - the underlying counts or values that should be computed to use in the aggregate template
Variable Name lower case, no spaces
  1. Template - a Jinja2 expression that combines those variables into the final displayed value. Jinja2 >=3.1.6

Example Aggregate

  • Column Name: Reject
  • Display Name: Reject
  • Template: {{ rejected_events }}
  • Variables:
    • rejected_events: count distinct identifier per signal, with reject filter
      Image

Default aggregates

The following persist by default in the signals dashboard:

  1. Triggers (triggers): Count distinct identifier, per signal
  2. Total Events (total_events): Count distinct identifier, overall
  3. Trigger Rate (trigger_rate) : triggers / total_events

Variables

Each variable (or 'inner aggregate') defines a single data point that is made available to the template. You configure:

Variable Names should be lower case, no spaces
Field Description
Variable Name name you'll reference in the aggregate template (e.g. triggers)
Aggregate Function Computation to perform. Tip: Count distinct identifier is common to count events.
Scope Per Signal applies only to events where the signal fired. Overall applies across all events matching the journey and step.
Attribute The attribute to compute on (e.g. identifier)
Filter (optional) A condition to narrow which events are counted. It is the same expression language as Investigations view.

Scope is what makes ratio-style metrics possible. For example, a trigger rate needs to know both how many events triggered a signal (Per Signal) and how many events occurred in total (Overall), so you can divide one by the other.

Filters let you count a specific subset of events — for example, only events where the decision outcome was "reject".

Template (Jinja Expression)

Templates use Jinja2 >=3.1.6 syntax to turn your variables into a formatted result. A few examples:

Metric Template Result
Simple variable reference {{ rejected_events }} 42
Ratio with formatting {{ '%.1f' | format(fraud / triggers) }} 0.3
Percentage with div0 escape {{ '%.2f' | format(((triggers / total_events) if total_events != 0.0 else 0.0) * 100) }}% 14.23%

Templates support the full Jinja2 expression language - arithmetic, conditionals, and filters like format - so you can handle edge cases (like dividing by zero) directly in the template. See: https://jinja.palletsprojects.com/en/stable/templates/

Template = Jinja Template

"Template" here means the Jinja expression template

Export and Import config

The aggregate and variables definitions can be exported and reimported as JSON.

Example:
reject_rate_signals_dashboard.json

Export from the configuration screen (cog top right) > Export config (bottom left)
Image

Import from file by just dragging the JSON file into the config box
Image

Example 1: Building a Reject Count Column

An aggregate that counts how many events led to a rejection:

  1. Create the aggregate with column name Reject, display name Reject
  2. Add a rejected_events variable — use count_distinct on identifier, scope Per Signal, with a filter:
    outcome[CHAMPION].decision_strategy.result = "reject"
    
    This counts only events where the champion decision strategy resulted in a reject.
  3. Write the template: {{ rejected_events }}
  4. Each signal now shows how many rejections it contributed to — helping you identify which signals are driving enforcement actions.

Example 2: Building a Reject Rate Column

Here's a step-by-step walkthrough for creating a "Reject Rate" aggregate. That is, when signal fired, how many % were overall reject?

  1. Create the aggregate and set the column name to reject_rate, display name to Reject Rate
  2. Add a reject variable
    1. use count_distinct on the identifier attribute
    2. scope set to Per Signal. This counts distinct identifiers (e.g. events) where triggered each signal.
    3. Filter: outcome[CHAMPION].decision_strategy.result = "reject" . This means only count reject events
  3. Add a total_events variable
    1. use count_distinct aggregation
    2. on identifier
    3. with scope set to Overall. This counts all distinct identifiers across all events on that journey & step, regardless of whether a signal fired.
  4. Write the template to render the percentages.
    {{ '%.2f' | format(((triggers / total_events) if total_events != 0.0 else 0.0) * 100) }}%
    
    Explaining this template inside out:
    • (triggers / total_events) if total_events != 0.0 else 0.0 - divides triggers variable by total_events variable, but returns 0.0 if total_events is zero (avoids division by zero)
    • * 100- converts the ratio to a percentage
    • '%.2f' | format(...) - formats the number to 2 decimal places (e.g., 12.50)
    • {{ ... }}% - outputs the result with a % sign appended

Reject Rate: Full Template

{
  "version": "1.0",
  "timestamp": "2026-04-27T03:59:52.833Z",
  "aggregates": [
    {
      "column_name": "reject_rate",
      "display_name": "Reject Rate",
      "aggregates": [
        {
          "aggregate_name": "reject",
          "aggregate_function": "count_distinct",
          "aggregate_subject": "identifier",
          "aggregate_scope": "compute_per_signal",
          "aggregate_filter": "outcome[CHAMPION].decision_strategy.result = 'reject'"
        },
        {
          "aggregate_name": "total",
          "aggregate_function": "count_distinct",
          "aggregate_subject": "identifier",
          "aggregate_scope": "compute_overall",
          "aggregate_filter": ""
        }
      ],
      "render_template": "{{ '%.2f' | format(((reject / total) if total_events != 0.0 else 0.0) * 100) }}%"
    }
  ]
}