Control Classes Nestings


Overview

Control Classes are a pricing and inventory management feature in Betterez that allows operators to define hierarchical pricing levels for ticket sales. Through a tree-based structure of classes, operators can create fine-grained pricing rules that respond to purchase characteristics such as sales channel, fare type, seat class, brand, and how far in advance a ticket is purchased.

Control Classes integrate (optionally) with an external Revenue Management System (RMS) which governs how many tickets can be sold at each pricing level for each trip segment. This enables dynamic revenue optimization: the RMS decides how many seats are available at each price tier, and Betterez enforces those limits during the purchase flow.

In summary, a Control Class defines:

  • When it applies: a set of purchase characteristics that must match the current transaction.
  • How it modifies pricing: an optional price adjustment (percentage or fixed amount) on top of the base ticket price.
  • How many tickets can be sold under it: governed by authorizations received from the RMS.

Control Class Hierarchy (Nestings)

Tree Structure

Control Classes are organized into trees, referred to as Nestings. Each nesting represents a complete set of pricing tiers for a given product.

  • Every nesting has a single Root class at the top.
  • The Root has no parent.
  • Every other class in the nesting has exactly one parent and may have zero or more children.
  • A nesting can be as shallow as a single Root with direct children, or any amount of levels deep.

Inheritance

Each class inherits all the purchase characteristics of its parent. This means a child class is always at least as specific as its parent — it matches the same conditions as the parent, plus potentially one more.

Single-Characteristic Variation

A child class may vary from its parent on exactly one additional characteristic. For example, if a parent class matches a specific product and brand, a child may further narrow the match by also specifying a sales channel.

Sibling Consistency

All siblings (children of the same parent) must vary on the same characteristic. For example, if one child of a parent varies by sales channel, all siblings of that child must also vary by sales channel. Each sibling must specify a unique value for that characteristic, ensuring there is no ambiguity when selecting among them.

Root Properties

The Root class defines the overall product association and the Child Selection Criteria for the nesting, with 2 options:

  • Most Specific: the system selects the deepest class in the nesting whose characteristics match the purchase.
  • Sales Authorizations Availability: the system selects the deepest matching class that also has enough availability according to RMS authorizations (see Control Class Selection).

Purchase Characteristics

Each Control Class may declare a set of purchase characteristics. During a ticket purchase, the system compares these characteristics against the current transaction context to determine which classes apply.

Match Types

Each characteristic (except Advance Purchase) can be configured with one of three match types:

One Of

The purchase value must be one of the values specified in the class. For example, a class configured with Channel = One Of [Websales, Agency Websales] will match only purchases made through those two channels.

Any

The class matches regardless of the purchase value for this characteristic. This is effectively a wildcard — the characteristic is declared but does not filter anything.

All Except

The class matches any purchase value except the ones listed. For example, Channel = All Except [Backoffice] will match purchases from any channel other than Backoffice.

Supported Characteristics

Product

The product associated with the trip. Required on Root classes. Only products using Journey Pricing or Market Pricing are supported.

Brand

The brand under which the trip operates.

Operating Company

The company operating the trip.

Amenity Group

The amenity group(s) associated with the trip's bus or vehicle. A trip may have multiple amenity groups; a match occurs if any of them satisfies the condition.

Fare

The fare type selected by the purchaser.

Fare Class

The fare class (e.g., economy, business) selected for the purchase.

Seat Class

The seat class (e.g., standard, premium) selected for the purchase.

Channel

The sales channel through which the purchase is made. Supported values: Backoffice, Websales, Agency Backoffice, Agency Websales.

Advance Purchase

How many hours before departure the ticket is being purchased. Configured as a range with a minimum and maximum number of hours. A purchase matches if the hours remaining until departure fall within the specified range. Unlike other characteristics, this uses a numeric range rather than a list-based match type. Sibling classes using Advance Purchase must have non-overlapping ranges.


Authorizations

Integration with Revenue Management Systems

Control Classes are designed to work with an external Revenue Management System (RMS) that governs how many tickets may be sold at each pricing level. The only currently supported RMS integration is Appia.

How Authorizations Work

The Appia RMS sends authorizations to Betterez via the POST /rms/appia/authorizations endpoint. An authorization tells Betterez how many tickets may be sold for a specific Control Class on a specific trip.

Each authorization specifies:

  • Schedule and Date: identifies the specific trip (manifest).
  • Origin and Destination: identifies the leg or segment within that trip (an O&D pair).
  • Control Class: identified by the class name/code.
  • Authorized Quantity: the maximum number of tickets that may be sold under this class for this O&D pair.

Storage

Authorizations are stored on the Manifest — the per-trip, per-date record in Betterez. When Appia sends new authorizations for a manifest, the entire set of authorizations for that manifest is replaced with the new data.

Matching

Appia identifies Control Classes by their name (referred to as the class "code" in Appia). Betterez resolves the name to the corresponding Control Class record when processing incoming authorizations. If a class name sent by Appia does not match any existing Control Class, the authorization is rejected with an error.

Webhooks

When authorizations are successfully updated, Betterez emits a controlclasses.authorizations.updated webhook event.


Control Class Selection for a Purchase

During a ticket purchase, Betterez determines which Control Class applies to each trip segment. This selection determines both the pricing and availability for the requested tickets.

Step 1: Nesting Selection

A Control Class Nesting is selected for each trip segment when the segment's schedule has a Control Class Root assigned. If the schedule has no assigned Root, no Control Class logic applies to that segment, and standard pricing is used.

Step 2: Finding the Deepest Matching Class

Within the selected Nesting, the system traverses from the Root downward, at each level selecting the child whose characteristics best match the current purchase context (product, channel, fare, seat class, brand, operating company, amenity group, and advance purchase hours).

Among siblings, the system prefers the most specific match:

  1. A class matching with One Of (exact value match) is preferred over one matching with All Except.
  2. A class matching with All Except is preferred over one matching with Any (wildcard).

The traversal continues until no further matching children are found. The result is a path from the Root to the deepest matching class.

Step 3: Availability Evaluation

When the Nesting's Child Selection Criteria is set to Sales Authorizations Availability, the system evaluates availability for each class along the path.

Availability for a Control Class on a given O&D segment is calculated as:

Availability = min( Segment Capacity, Authorized Sales - Bookings )

Where:

  • Segment Capacity is the physical seating capacity of the bus for that O&D pair, accounting for already-occupied seats from overlapping legs.
  • Authorized Sales is the Appia authorization quantity for the Control Class on that O&D pair, stored on the Manifest.
  • Bookings is the number of tickets already sold under the same Control Class Root for that O&D pair, including any pending bookings.

Additionally, a parent constraint is enforced: a child class can never have more availability than its parent. If the calculated availability for a child exceeds its parent's availability, the child's availability is capped to the parent's value.

Step 4: Class Selection

The system evaluates the path from the deepest class to the Root. The first class with enough availability for the number of tickets being purchased is selected.

If no class along the path has sufficient availability, the Root class is used. The Root is guaranteed to have sufficient availability because the RMS sets the Root's authorization to match the actual physical capacity of the bus.

Most Specific Mode

When the nesting's Child Selection Criteria is set to Most Specific, availability is not evaluated. The deepest matching class from Step 2 is selected directly.


Pricing

Base Price

The Root Control Class does not have its own price. Instead, the base ticket price is determined by the existing Betterez pricing mechanisms — Journey Pricing or Market Pricing — during an earlier step of the purchase flow. The specific pricing mechanism depends on the product configuration.

Price Modifiers

Each non-Root Control Class may define a price modifier that adjusts the base price. A modifier can be:

Percentage (%)

Adds or subtracts a percentage of the base price. For example, +10% increases the base price by 10%, while -15% decreases it by 15%.

Fixed Amount ($)

Adds or subtracts a fixed monetary amount from the base price. For example, +5.00 adds $5 to the base price, while -3.50 subtracts $3.50.

Modifiers can be positive (surcharge) or negative (discount).

Final Price Calculation

The final ticket price for a purchase is:

Final Price = Base Price + Modifier

Where:

  • Base Price is determined by Journey Pricing or Market Pricing for the trip.
  • Modifier is the price adjustment from the selected Control Class. If the selected class is the Root (which has no modifier), the base price is used unchanged.

Percentage modifiers are subject to the account's rounding policy.


Nesting assignment to Schedules

A Nesting can be assigned to a Schedule directly, in the Edit Schedule page.

A Route can define a Default Control Class, that will be assigned to all the Route Schedules when the default is configured, and after that it will apply to newly created Schedules in that Route.

A Nesting can be bulk assigned and unassigned from the Nesting edit page, editing the assignment of many schedules at the same time.

Bulk schedules assignment


Control Classes User Interface

List View

The list view displays all Control Classes for the account, organized in two tabs:

  • Nestings: shows only Nestings classes (tree roots).
  • All: shows all classes regardless of their position in the tree.

Classes can be filtered by name and product. Each entry shows the class name and last revision date. Action icons allow navigating to the tree view, viewing authorizations (when the RMS integration is enabled and at least one nesting Child Selection Criteria is set to Sales Authorizations Availability), or deleting the class.

A Root class cannot be deleted if it has children.

Control Classes Nestings List

Create and Edit

The details form allows creating or editing a Control Class. The form includes:

  • Name: a unique name for the class.
  • Description: an optional description.
  • Tree Context: displays the class's position in the hierarchy — its Root, parent, siblings, and children.
  • Product (Root only): the product this nesting is associated with. Only products with Journey Pricing or Market Pricing are available.
  • Nesting Name (Root only): an optional display name for the entire nesting.
  • Child Selection Criteria (Root only): determines how the system selects among matching classes — either Most Specific or Sales Authorizations Availability.
  • Characteristics: the purchase characteristics that determine when this class applies. Each characteristic is configured with a match type and values.
  • Price Adjustment (non-Root only): the modifier type (percentage or fixed amount) and value to apply on top of the base price.
  • Schedule Assignment (Root only): allows assigning one or more schedules to the Root class, enabling Control Class logic for trips running on those schedules. Schedules can be assigned individually or in bulk.

Edit

Edit

View Authorizations

The authorizations view displays the current RMS authorizations for a Control Class Nesting. The operator selects a schedule and manifest date, and the system shows an authorization table organized by:

  • Rows: Origin-Destination pairs (legs).
  • Columns: All Control Classes in the tree.

For each cell (O&D pair + Control Class), the table displays:

  • Authorization: the number of tickets authorized by the RMS.
  • Bookings: the number of tickets already sold.
  • Availability: the remaining tickets available for sale.

Authorizations