v2.0

GoRules Version 2 is here - redesigned, now with managed cloud.GoRules Version 2 is here!

Watch the launch videoWatch

Booking Personalization System

Dynamic flight booking platform that tailors UI, discounts, and features based on customer loyalty status, device type, booking history, and traffic source.

Solution

This booking personalization system delivers tailored flight booking experiences by adapting to individual customer contexts. The platform automatically adjusts user interface elements based on device type, presenting mobile users with compact, touch-friendly layouts while desktop users receive expanded search options and detailed filters. Loyalty status recognition enables tiered benefits, with platinum members receiving exclusive deals, concierge service, and 15% discounts while new customers see standard options with loyalty program invitations.

The system identifies traffic sources to present relevant promotions, offering social media visitors special deals with additional discounts, while direct visitors see standard pricing options. For returning customers, the platform activates features based on booking frequency, showing recently viewed items to frequent travelers and offering incremental discounts based on booking history. All these factors combine to calculate a personalization score that determines the overall booking flow template, ensuring each customer journey feels uniquely customized while optimizing conversion rates.

How it works

The personalization engine follows a sequential decision process:

  1. Device Detection: Identifies whether the user is on mobile, tablet, or desktop and adjusts UI elements accordingly.
  2. Loyalty Analysis: Evaluates membership tier to determine available features, priority level, and base discount percentage.
  3. Traffic Source Evaluation: Analyzes how the visitor arrived at the booking platform to display relevant promotions and special offers.
  4. Booking History Assessment: Reviews past travel patterns to determine customer classification and tailors recommendations.
  5. Personalization Scoring: Combines factors including loyalty status, booking history, and traffic source to generate a numerical personalization score.
  6. Experience Compilation: Calculates final discount percentages and selects the appropriate booking flow template based on the personalization score.

Where teams use it

  • Airline ticket reservations
  • Hotel booking platforms
  • Car rental services
  • Vacation package providers
  • Cruise line bookings
  • Tour operator websites
  • Travel metasearch engines
  • Corporate travel portals

Inside the decision model

Booking Personalization System ships as a JDM decision graph with 7 nodes, 5 decision tables and 33 rules. Download it, load it into GoRules, and run it as-is on Zen Engine.

Decision graph7 nodes · read-only
input requesttable Device Type Personalizationtable Loyalty Status Personalizationtable Visit Source Personalizationtable Booking History Personalizationtable Calculate Personalization Scoreexpression Calculate Final Personalization
01

Request

input

Requests identify the trip by flightId and routeId, while the personalization tables read customer context fields such as customer.deviceType, customer.loyaltyStatus, customer.visitSource, and customer.bookingHistory; anything missing simply falls through to the default rows.

Sample requestJSON
{
  "flightId": "FL-123",
  "routeId": "JFK-LAX",
  "daysToDepature": 5,
  "basePrice": 250,
  "availableSeats": 35,
  "totalSeats": 180,
  "demandForecast": 75,
  "avgCompetitorPrice": 275
}
02

Device Type Personalization

table

Screen size drives the first branch: a customer.deviceType of 'mobile' returns 'compactSearch', 'simplifiedNavigation', and 'touchFriendlyControls' with a 'compact' layout that hides extras, 'tablet' and 'desktop' rows step up to 'medium' and 'full' layouts with 'detailedFilters' on desktop, and a blank catch-all serves a 'standard' layout under the first hit policy.

Suppressing ancillary content on phones and reserving detailed filters for desktop follows conversion practice on airline booking sites, where small screens punish dense fare displays. These are UX conventions rather than regulatory requirements, so a carrier would tune the element lists against its own funnel data.

Decision tablefirst hit policy
Device Typecustomer.deviceTypeUI Elementspersonalization.uiElementsLayout Configurationpersonalization.layoutConfig
'mobile'['compactSearch', 'simplifiedNavigation', 'touchFriendlyControls']{ 'type': 'compact', 'imageSize': 'small', 'showExtras': false }
'tablet'['touchFriendlyControls', 'mediumSearch', 'fullNavigation']{ 'type': 'medium', 'imageSize': 'medium', 'showExtras': true }
'desktop'['expandedSearch', 'fullNavigation', 'detailedFilters']{ 'type': 'full', 'imageSize': 'large', 'showExtras': true }
-['standardSearch', 'standardNavigation']{ 'type': 'standard', 'imageSize': 'medium', 'showExtras': true }
03

Loyalty Status Personalization

table

Tier recognition is a straight ladder on customer.loyaltyStatus with first hit: 'platinum' gets priority 1, a discountPercentage of 15, and features including 'conciergeService' and 'exclusiveDeals'; 'gold' and 'silver' step down to 10 and 5 with smaller feature sets; and both 'none' and the blank fallback land at priority 4 with 0 discount and a 'joinLoyaltyBanner'.

A three-tier elite ladder with escalating soft benefits mirrors how most frequent-flyer programs are built, and showing enrollment prompts to non-members instead of discounts is standard acquisition practice. The 15/10/5 percentages are plausible loyalty economics but a commercial choice, not anything mandated.

Decision tablefirst hit policy
Loyalty Statuscustomer.loyaltyStatusCustomer Prioritypersonalization.customerPriorityFeatures to Showpersonalization.loyaltyFeaturesDiscount Percentagepersonalization.baseDiscountPercentage
'platinum'1['priorityBooking', 'exclusiveDeals', 'conciergeService', 'upgradeOffers']15
'gold'2['priorityBooking', 'memberDeals', 'upgradeOffers']10
'silver'3['memberDeals', 'basicUpgrades']5
'none'4['joinLoyaltyBanner', 'standardOptions']0
-4['joinLoyaltyBanner', 'standardOptions']0
04

Visit Source Personalization

table

Channel attribution decides which promotion surface appears: a customer.visitSource of 'partner_site' carries the largest addDiscount at 5, 'social_media' gets 3 with 'socialMediaDeals', 'email_campaign' gets 2, 'search_engine' shows 'searchSpecials' with 0 extra, 'direct' traffic sees no special offers at all, and a blank fallback serves 'standardOffers'.

Giving the deepest incentives to partner and social traffic while direct visitors get none reflects plain channel economics: direct bookers already show intent and need no inducement, while paid and referred channels are where airlines spend to convert. The exact 5/3/2 spread is marketing calibration, not an industry rule.

Decision tablefirst hit policy
Visit Sourcecustomer.visitSourceShow Special Offerspersonalization.showSpecialOffersSpecial Offers Typepersonalization.specialOffersTypeAdditional Discountpersonalization.additionalDiscountPercentage
'email_campaign'true'emailPromotions'2
'search_engine'true'searchSpecials'0
'social_media'true'socialMediaDeals'3
'partner_site'true'partnerOffers'5
'direct'false'none'0
-false'standardOffers'0
05

Booking History Personalization

table

Past behavior is bucketed on two counters read together under first hit: totalBookings above 10 with recentBookings above 2 marks a 'frequentTraveler' with showRecentlyViewed switched on and a discount of 3, more than 5 bookings with recent activity is a 'regularCustomer' at 2, any history with recentBookings == 0 is a lapsed 'returningCustomer' at 1, and zero bookings makes a 'newCustomer' with nothing extra.

Pairing a recent-bookings window with lifetime volume is the classic recency-frequency split airlines and travel platforms use to tell active frequent flyers from lapsed ones, and reserving the recently-viewed module for active customers avoids surfacing stale content. The cutoffs of 10 and 5 bookings are sensible segmentation choices rather than fixed industry standards.

Decision tablefirst hit policy
Total Bookingscustomer.bookingHistory.totalBookingsRecent Bookings (Last 90 Days)customer.bookingHistory.recentBookingsRecommendation Typepersonalization.recommendationTypeShow Recently Viewedpersonalization.showRecentlyViewedHistory Discountpersonalization.historyDiscountPercentage
> 10> 2'frequentTraveler'true3
> 5> 1'regularCustomer'true2
> 0== 0'returningCustomer'false1
== 0== 0'newCustomer'false0
--'standard'false0
06

Calculate Personalization Score

table

Score assignment cross-tabulates three signals: whether customer.bookingHistory.totalBookings is above 0, the loyalty-derived customerPriority, and whether customer.visitSource is 'social_media' or 'partner_site'. Under first hit, a priority-1 member with history arriving from a promoted channel scores the maximum 65, the same member from other channels scores 50, each lower priority tier sheds roughly 10 to 15 points, first-time visitors with top status still earn 30, and the bare catch-all bottoms out at 5.

Weighting booking history and elite tier ahead of arrival channel matches how personalization teams rank signal quality, since owned behavioral data is more predictive than referral context. The point values themselves are arbitrary rungs on an internal scale; what matters is that they line up with the 50/30/10 template thresholds applied in the next step.

Decision tablefirst hit policy
Has Previous Bookingscustomer.bookingHistory.totalBookingsLoyalty Prioritypersonalization.customerPriorityVisit Sourcecustomer.visitSourcePersonalization Scorepersonalization.personalizationScore
> 01'social_media', 'partner_site'65
> 01-50
> 02'social_media', 'partner_site'55
> 02-40
> 03'social_media', 'partner_site'45
> 03-30

+7 more rows in the downloadable template

07

Calculate Final Personalization

expression

Three closing values wrap the run: totalDiscountPercentage sums the base, additional, and history discount percentages, bookingFlowTemplate maps personalizationScore through breaks at 50, 30, and 10 into 'premium', 'enhanced', 'standard', or 'basic', and allFeatures flattens uiElements together with loyaltyFeatures into a single list. Summing the three discounts additively is what makes the earlier tables composable instead of mutually exclusive.

Expressions3 fields
totalDiscountPercentagenumber(personalization.baseDiscountPercentage) + number(personalization.additionalDiscountPercentage) + number(personalization.historyDiscountPercentage)
bookingFlowTemplatepersonalization.personalizationScore > 50 ? 'premium' : personalization.personalizationScore > 30 ? 'enhanced' : personalization.personalizationScore > 10 ? 'standard' : 'basic'
allFeaturesflatten([personalization.uiElements, personalization.loyaltyFeatures])

Make this template
your own.

Load Booking Personalization System into GoRules, adjust the rules to your policy, and ship it behind your own API.