GoRules Version 2 is here - redesigned, now with managed cloud.GoRules Version 2 is here!
Watch the launch videoWatchFlight Ancillary Recommendations
Data-driven system that personalizes travel add-on recommendations based on customer profile, route details, and previous purchasing behavior.
Solution
This intelligent recommendation engine helps airlines boost ancillary revenue by delivering personalized product suggestions that match each traveler's specific journey context. The system analyzes multiple factors including loyalty tier status, flight duration, travel purpose, and destination type to recommend the most relevant add-ons like lounge access, priority boarding, or extra baggage.
For business travelers, it prioritizes productivity-enhancing services such as WiFi and fast-track security, especially for frequent flyers on medium to long routes. Leisure travelers receive suggestions focused on comfort and experience enhancement, while family groups see recommendations for practical needs like family seating and entertainment packages. The system also examines previous purchase history to avoid redundant recommendations, ensuring travelers only see relevant new offerings they haven't already bought.
How it works
The recommendation engine follows a structured evaluation process:
- Flight Classification: Categorizes flights as short, medium, or long based on duration in minutes.
- Customer Analysis: Evaluates loyalty status and examines previous purchase patterns to identify premium customers and product preferences.
- Base Recommendations: Generates initial suggestions by matching travel purpose (business, leisure, family) with flight duration and customer attributes.
- Contextual Enhancement: Adds specialized recommendations based on route characteristics (international, beach destinations) and airport facilities.
- Priority Assignment: Ranks all recommendations by relevance score to highlight the most valuable suggestions first.
- Recommendation Consolidation: Merges all suggestions into a unified, prioritized list for presentation to the customer.
Where teams use it
- Post-booking ancillary upsell campaigns
- Real-time recommendations during web/mobile booking flow
- Personalized preflight email marketing
- Airport check-in kiosk offers
- Airline mobile app targeted promotions
- Call center agent suggestion tools
Inside the decision model
Flight Ancillary Recommendations ships as a JDM decision graph with 6 nodes, 3 decision tables and 17 rules. Download it, load it into GoRules, and run it as-is on Zen Engine.
Request
inputFour request blocks feed the engine: customerProfile with loyaltyTier and travelFrequency, route with flightDurationMinutes and destination, the travelPurpose flag, and a previousPurchases list used to suppress products the traveler already bought.
Sample requestJSON
{
"customerProfile": {
"id": "cust-12345",
"loyaltyTier": "gold",
"travelFrequency": "frequent",
"preferredLanguage": "en",
"preferredCurrency": "USD"
},
"route": {
"origin": "JFK",
"destination": "international",
"flightDurationMinutes": 480,
"hasAirportLounge": true,
"departureTime": "2025-04-15T08:30:00Z",
"returnTime": "2025-04-22T15:45:00Z"
},
"travelPurpose": "business",
"tripDetails": {
"passengers": 1,
"cabinClass": "economy",
"dateFlexibility": "fixed"
},
"previousPurchases": [
{
"bookingId": "bkg-9876",
"productType": "seat",
"purchaseDate": "2024-12-10T14:22:00Z",
"productDetails": {
"seatType": "extra_legroom",
"amount": 35
}
},
{
"bookingId": "bkg-8765",
"productType": "wifi",
"purchaseDate": "2024-11-05T09:15:00Z",
"productDetails": {
"packageType": "full_flight",
"amount": 19.99
}
}
]
}Categorize Flight Duration
tableDuration bucketing comes first: a route.flightDurationMinutes of 240 or more classifies the flight as 'long', 120 up to 240 as 'medium', and anything under 120 as 'short', resolved under a first hit policy.
A four-hour break for long flights and a two-hour break for medium roughly tracks how airlines segment ancillary relevance: meal and entertainment products only sell on longer sectors, while short hops leave little worth offering beyond seats and bags. The exact minute thresholds are a merchandising choice, not an official haul classification.
| Flight Duration Minutesroute.flightDurationMinutes | Duration CategoryflightDurationCategory |
|---|---|
| >= 240 | 'long' |
| >= 120 and < 240 | 'medium' |
| < 120 | 'short' |
Calculate Customer Attributes
expressionPurchase history gets condensed into flags before anything is recommended: isPremiumCustomer is true for a 'gold' or 'platinum' customerProfile.loyaltyTier, and hasBoughtBaggage, hasBoughtMeals, hasBoughtSeats, and hasBoughtLounge each scan previousPurchases for a matching productType. These booleans are what let later rules skip products the traveler already owns.
customerProfile.loyaltyTier == 'gold' or customerProfile.loyaltyTier == 'platinum'some(previousPurchases ?? [], #.productType == 'baggage')some(previousPurchases ?? [], #.productType == 'meal')some(previousPurchases ?? [], #.productType == 'seat')some(previousPurchases ?? [], #.productType == 'lounge')Base Recommendations
tableEvery matching row fires here because the hit policy is collect, writing productType and priority pairs into recommendations.base. Business travelers on 'long' flights who satisfy isPremiumCustomer collect 'lounge' at priority 5, 'priority_boarding' on 'medium' or 'long' sectors at 4, and 'wifi' at 3 regardless of duration; leisure rows push 'extra_baggage', a 'meal' guarded by !hasBoughtMeals, and 'seat_selection' guarded by !hasBoughtSeats; family rows add 'family_seating', 'extra_baggage', and an 'entertainment_package' on long flights.
Matching product to travel purpose is the standard ancillary merchandising play: productivity items for business, comfort and experience items for leisure, practical items for families. The negative guards on prior purchases prevent redundant offers, basic hygiene in upsell campaigns since pitching a product someone already owns depresses conversion.
| Travel PurposetravelPurpose | Flight DurationflightDurationCategory | Customer Attributes | ProductproductType | Prioritypriority |
|---|---|---|---|---|
| 'business' | 'long' | isPremiumCustomer | 'lounge' | 5 |
| 'business' | 'medium', 'long' | - | 'priority_boarding' | 4 |
| 'business' | - | - | 'wifi' | 3 |
| 'leisure' | 'long' | - | 'extra_baggage' | 5 |
| 'leisure' | 'medium', 'long' | !hasBoughtMeals | 'meal' | 4 |
| 'leisure' | - | !hasBoughtSeats | 'seat_selection' | 3 |
+3 more rows in the downloadable template
Additional Recommendations
tableContext stacks on top of purpose in this second collect table, which appends route-driven offers into recommendations.additional. A lounge-equipped airport (route.hasAirportLounge and !hasBoughtLounge) plus premium status yields 'lounge' at priority 4, route.destination == 'international' adds 'travel_insurance', a 'long' flight without prior meal purchases adds 'premium_meal', frequent business flyers get 'fast_track_security', and 'beach' or 'resort' destinations paired with leisure travel add an 'excursion_package'.
Attaching insurance to international itineraries and excursions to resort destinations follows observable purchase propensity rather than any rule; travel insurance in particular converts far better on international trips where medical cover matters. Gating the lounge offer on the airport actually having one keeps the recommendation credible.
| Route Attributes | Customer Context | Additional ProductproductType | Prioritypriority |
|---|---|---|---|
| route.hasAirportLounge and !hasBoughtLounge | isPremiumCustomer | 'lounge' | 4 |
| route.destination == 'international' | - | 'travel_insurance' | 3 |
| flightDurationCategory == 'long' and !hasBoughtMeals | - | 'premium_meal' | 2 |
| customerProfile.travelFrequency == 'frequent' and travelPurpose == 'business' | - | 'fast_track_security' | 4 |
| route.destination == 'beach' or route.destination == 'resort' | travelPurpose == 'leisure' | 'excursion_package' | 3 |
Join Recommendations
expressionOne flat list leaves the graph: flatten(values(recommendations)) merges the base and additional buckets into a single recommendations array, each entry keeping its productType and priority. Downstream channels can then sort by priority without caring which table produced a suggestion.
flatten(values(recommendations))Other Aviation templates
View all templatesFlight Dispatch Decision System
Rules-based aviation system that evaluates weather, aircraft, crew, and weight factors to ensure regulatory compliance and safe flight operations.
AviationDynamic Airline Ticket Pricing Engine
Automated fare optimization system that sets ticket prices based on time to departure, seat availability, market demand, and competitor pricing.
AviationBooking Personalization System
Dynamic flight booking platform that tailors UI, discounts, and features based on customer loyalty status, device type, booking history, and traffic source.
Make this template
your own.
Load Flight Ancillary Recommendations into GoRules, adjust the rules to your policy, and ship it behind your own API.