← Back to Articles
Chapter 6: Triggers
Published: 31. 3. 2026 Author: Michal Keller triggersaggregate-conditionsadvancedbilling

Chapter 6: Triggers

Triggers are BillingEngine's advanced tool for conditionally creating new data records — from scalar conditions on individual records to aggregate logic over historical data. Learn to model volume bonuses, overage charges, and loyalty programs.


What Are Triggers?

Triggers are an advanced mechanism in BillingEngine that automatically creates new data records when defined conditions are met. While pricing rules decide which price list to use for each record, triggers respond to an incoming record and generate a new DR based on a template (action_template).

Key principle: a trigger does not modify the rating of an existing record — it creates a separate new record that is then rated by the standard engine through pricing rules.

Typical use cases for triggers:

Trigger Structure

A trigger consists of the following fields:

FieldRequiredDescription
nameHuman-readable trigger name
conditionsConditions on data record attributes
action_templateTemplate for the new DR created when the trigger fires
aggregate_conditionsConditions on cumulative values
is_activeBoolean, default true
POST /api/v1/triggers
Content-Type: application/json

{
  "name": "Large SMS batch surcharge",
  "conditions": {
    "code": "SMS",
    "quantity": { "op": "gt", "value": 500 }
  },
  "action_template": {
    "code": "SMS_SURCHARGE",
    "quantity": 1
  },
  "is_active": true
}

action_template: The New Record Template

action_template defines what the new DR created by the trigger will look like. At minimum it must contain code. The new record automatically inherits partner_id, customer_id, time_from, and time_to from the record that fired the trigger.

Special values:

The new record is immediately rated by the standard engine after creation — through your configured pricing rules. For a trigger to be functional, a pricing rule must exist for the code used in action_template.

Scalar Conditions

The conditions field is an object whose keys match data record field names and whose values are either a scalar (equality) or an object with an operator:

{
  "conditions": {
    "code": "SMS",
    "quantity": { "op": "gt", "value": 500 }
  }
}

When scalar conditions match, a new record is created for each qualifying DR.

Supported operators:

OperatorDescription
eqEqual (default for scalar values)
neNot equal
gtGreater than
gteGreater or equal
ltLess than
lteLess or equal
likeText pattern (SQL LIKE)
inList of values

Aggregate Conditions

Aggregate conditions allow decisions based on cumulative values for the current month. When met, the trigger creates one new record per customer (not per DR).

{
  "aggregate_conditions": [
    {
      "func": "sum",
      "field": "quantity",
      "filter": { "code": "VOICE_MIN" },
      "op": "gt",
      "value": 200,
      "group_by": "customer_id"
    }
  ]
}

Aggregate condition structure:

Combining Conditions

A trigger can have both sets of conditions simultaneously. Both must be satisfied at the same time (logical AND):

{
  "name": "SMS loyalty bonus",
  "conditions": {
    "code": "SMS"
  },
  "aggregate_conditions": [
    {
      "func": "count",
      "field": "id",
      "filter": { "code": "SMS" },
      "op": "gt",
      "value": 1000,
      "group_by": "customer_id"
    }
  ],
  "action_template": {
    "code": "SMS_LOYALTY",
    "quantity": 1
  },
  "is_active": true
}

This trigger fires for a customer who has sent more than 1,000 SMS in total AND whose current record is also SMS. The result is ONE new SMS_LOYALTY record per customer.

Integration with Pricing Rules

The entire pricing mechanism for triggers works through standard pricing rules:

  1. Create a price list with an item for the code used in action_template (e.g. SMS_SURCHARGE)
  2. Create a pricing rule referencing that price list
  3. When the trigger fires, it creates a DR with the specified code — the rule automatically rates it

Example: trigger generates SMS_SURCHARGE records → a rule with billing_category: "retail" references a price list with item code: "SMS_SURCHARGE" and price 2.50 → the customer is charged a surcharge for each trigger activation.

Real-World Examples

Example 1: SMS Overage Charge

An operator has a base tariff for the first 1,000 SMS per month. For each SMS above this limit, the customer pays a higher rate.

{
  "name": "SMS overage charge",
  "conditions": {
    "code": "SMS"
  },
  "aggregate_conditions": [
    {
      "func": "count",
      "field": "id",
      "filter": { "code": "SMS" },
      "op": "gte",
      "value": 1000,
      "group_by": "customer_id"
    }
  ],
  "action_template": {
    "code": "SMS_OVERAGE",
    "quantity": 1
  },
  "is_active": true
}

After reaching 1,000 SMS in a month, the engine generates an SMS_OVERAGE record for each subsequent SMS, rated at the higher rate.

Example 2: Monthly Voice Bonus

Customers who make more than 200 minutes of calls in a month receive one bonus record with a negative price (discount).

{
  "name": "Voice volume — monthly bonus",
  "conditions": {
    "code": "VOICE_MIN"
  },
  "aggregate_conditions": [
    {
      "func": "sum",
      "field": "quantity",
      "filter": { "code": "VOICE_MIN" },
      "op": "gt",
      "value": 200,
      "group_by": "customer_id"
    }
  ],
  "action_template": {
    "code": "VOICE_BONUS",
    "quantity": 1
  },
  "is_active": true
}

Example 3: Loyalty Program

A customer who exceeds 1,000 data records in a month receives a loyalty credit.

{
  "name": "Loyalty program — 1000+ records",
  "conditions": {},
  "aggregate_conditions": [
    {
      "func": "count",
      "field": "id",
      "op": "gt",
      "value": 1000,
      "group_by": "customer_id"
    }
  ],
  "action_template": {
    "code": "LOYALTY_CREDIT",
    "quantity": 1
  },
  "is_active": true
}

Triggers vs. Pricing Rules

AspectPricing RulesTriggers
OutputRecord ratingNew data record
EvaluationPer each recordPer record + historical data
ConditionsCustomer/group + timeDR attributes + aggregates
PricingDirect price listPrice list via rule for action_template code
Use caseStandard pricingSurcharges, bonuses, loyalty rewards

Pricing rules and triggers complement each other — rules rate original records, triggers add supplemental records for special scenarios.

Best Practices

Always create a rule for the action_template code. Triggers generate new DRs — without a matching pricing rule the new record ends up in error state.

Name action_template codes clearly. SMS_OVERAGE, VOICE_BONUS, LOYALTY_CREDIT are descriptive names. A clear code makes price list configuration and debugging easier.

Test on historical data. Aggregate conditions depend on customer history — when deploying a new trigger, verify how it behaves for customers with varying usage volumes.

Monitor records with source=trigger. Records created by triggers have the flag source: "trigger". Track their count — unexpectedly high frequency signals a poorly calibrated threshold.

Combine with pricing rules. Trigger + rule = complete pricing logic. Standard rates via rules, bonuses and surcharges via triggers.

Conclusion

Triggers are the last piece of the BillingEngine puzzle. By combining scalar conditions on the current record and aggregate conditions on historical data, they allow modeling arbitrarily complex pricing strategies — from simple surcharges to sophisticated loyalty programs. This concludes the overview of BillingEngine’s core entities. For specific integration scenarios, consult the API documentation and explore the test environment.

← Back to Articles Back to Home