Skip to main content

Multi-Listing Combinations

When no single listing can accommodate all guests, the system groups nearby listings together.

When Combinations Trigger

if (allowCombination == true AND singleFitCount < minSingleResults):
build combinations
  • minSingleResults defaults to 3 — combinations only activate if fewer than 3 listings can fit everyone alone

How It Works

  1. Candidates: All processed listings with maxAdults > 0, capped at 30
  2. Generate groups: Sizes 2 to maxListingsInGroup (default 3)
  3. Capacity check: Combined totalAdults >= required AND totalChildren >= required
  4. Proximity filter (optional):
    • If anchorLat/anchorLon set: all listings must be within proximityMeters of anchor
    • If no anchor: all pairwise distances must be within proximityMeters
  5. Score each group:
score = discountWeight (capped at 40)
+ 30 × (1 - min(maxPairwiseDistance / 1000, 1))
+ 20 / listingCount
  • Higher discount % → higher score
  • Closer together → higher score
  • Fewer listings in group → higher score (prefer 2 over 3)
  1. Sort by score (best first)

Group ID

Combined groups get a composite ID:

lst_abc+lst_def+lst_ghi

This ID is used for the detail API to fetch the combined breakup.

Proximity Labels

DistanceLabel
< 500m"Within 500m"
500m - 1km"500m - 1km"
1km - 2km"1-2km"
2km - 5km"2-5km"
> 5km"5km+"

Response

{
"combinedGroups": [
{
"groupId": "lst_abc+lst_def",
"listings": [ ... full listing cards ... ],
"totalAdultCapacity": 12,
"totalChildrenCapacity": 6,
"maxPairwiseDistanceMeters": 350.0,
"proximityLabel": "Within 500m",
"price": {
"total": 45000,
"perNight": 22500,
"totalBeforeDiscount": 52000,
"totalSaving": 7000,
"discountPercent": 13
}
}
]
}