← Back to Articles
Chapter 2: Pricing Rules
Published: 31. 3. 2026 Author: Michal Keller pricing-rulesbilling-categorypriorityAPI

Chapter 2: Pricing Rules

Pricing rules connect customers and groups to price lists. Learn how matching works, what billing_category means, how priority is applied, and why one data record can produce multiple rated entries.


What Are Pricing Rules?

Pricing rules are records that tell the engine: “For this customer (or group), within this time window, use this price list.” They connect a customer or customer group to a specific price list and define the pricing category — for example, whether the price is retail, wholesale, or an internal cost rate.

A pricing rule does not contain any conditions on data record attributes. The selection of the specific price list item is handled automatically by the rating engine based on the code (code) of the data record.

Pricing Rule Structure

A pricing rule consists of the following fields:

FieldRequiredDescription
nameHuman-readable rule name
codeRule code (identifies the service category)
billing_categoryPrice type: cost, retail, wholesale, reseller
price_list_idID of the price list to use
valid_fromRule start date (ISO date)
valid_toRule end date (NULL = no expiry)
customer_idID of a specific customer (NULL = applies to all)
group_idID of a customer group
priorityInteger, default 0 — higher number = higher priority
scopeself (default), children, subtree
is_activeBoolean, default true

Example — creating a rule via the API:

POST /api/v1/pricing-rules
Content-Type: application/json

{
  "name": "VIP customers — retail pricing 2026",
  "code": "VIP-RETAIL-2026",
  "billing_category": "retail",
  "price_list_id": "uuid-vip-price-list",
  "group_id": "uuid-vip-group",
  "priority": 100,
  "valid_from": "2026-01-01",
  "valid_to": null
}

How the Engine Selects Rules

When rating each data record (DR), the engine follows these steps:

1. Load the customer’s groups Determines which groups the customer belongs to.

2. Load all active rules for the partner Filters only rules with is_active = true.

3. Filter to applicable rules A rule is considered applicable if it satisfies one of:

And the DR must fall within the rule’s validity window:

4. Sort by priority descending The rule with the highest priority number is processed first.

5. For each applicable rule, look up the price list item Searches for an item with the same code as the data record (dr.code → price_list_item.code). If found, calculates the price and creates a rated record. If not found, skips to the next rule.

Multiple Ratings per Record

An important characteristic: the engine does not stop after the first matching rule. It processes all applicable rules, and for each one where it finds a matching price list item, it creates a separate rated record.

This allows a single DR to receive both:

Both records are generated from the same DR, each using a different rule and a different price list.

Billing Category

The billing_category field defines the type of pricing level. Supported values:

ValueUse case
costCost price — what the operator pays the supplier
retailRetail price — what the customer pays the operator
wholesaleWholesale price — for B2B sales
resellerReseller price — for distribution partners

A typical telecom operator configuration has two rules per record type: one cost (referencing the cost price list) and one retail (referencing the customer price list). This creates a complete margin view.

Priority

Priority is an integer — higher number means higher priority, rules are evaluated in descending order. The default is 0.

Example priority hierarchy:

PriorityCustomer / GroupBilling categoryPrice list
200specific customerretailIndividual list
100VIP groupretailVIP list
10(default)retailStandard list
5(default)costCost list

A customer with an individual rule at priority 200 is processed before the group rule at priority 100.

Rule Validity Window

Unlike price list versions, a pricing rule has its own time window: valid_from and valid_to. This enables:

The combination of valid_from/valid_to on the rule and valid_from/valid_to on the price list version allows very precise control over which price applies at what time.

Deactivating a Rule

To temporarily disable a rule without deleting it, set is_active: false:

PUT /api/v1/pricing-rules/{id}
Content-Type: application/json

{ "is_active": false }

The engine skips deactivated rules when loading. Reactivation is symmetric: is_active: true.

Default (Fallback) Rule

A rule without customer_id or group_id applies to all customers of the partner. It serves as a safety net for customers who aren’t in any specific group:

{
  "name": "Standard retail — all customers",
  "code": "DEFAULT-RETAIL",
  "billing_category": "retail",
  "price_list_id": "uuid-standard-list",
  "customer_id": null,
  "group_id": null,
  "priority": 0,
  "valid_from": "2026-01-01"
}

Best Practices

Always have a default rule. A customer with no matching rule produces an empty rating — this shows as an error in reporting. A default rule at priority 0 catches this.

Set priorities systematically. Define a convention: e.g. 1–9 default, 10–99 group, 100+ individual customer rules.

Use valid_to instead of deleting. A rule with a past valid_to is still historically traceable. A deleted rule is gone from history.

Name rules clearly. "VIP group — retail Q1 2026" is still understandable a year from now. "rule_42" is not.

Test combinations. With multiple applicable rules, verify that the combination of billing categories and price lists makes sense — especially that each DR receives exactly one retail rating.

Conclusion

Pricing rules are a flexible tool for assigning price lists to customers and groups, with support for multiple pricing categories, time validity, and priority. Unlike systems with dynamic conditions, they work on a simple direct mapping principle — customer/group → price list — clearly and without side effects. Chapter 3 covers customer groups, which form the foundation of segmentation.

← Back to Articles Back to Home