Skip to main content

Listing Search API

Search listings with structured filters. Context-aware pricing applied automatically.


POST /api/v1/crs/listings
Content-Type: application/json
{
"rawParams": [
{ "filterName": "channelId", "filterValues": ["B2C"] },
{ "filterName": "city", "filterValues": ["Goa"] },
{ "filterName": "checkInDate", "filterValues": ["2026-05-15"] },
{ "filterName": "checkOutDate", "filterValues": ["2026-05-17"] },
{ "filterName": "adults", "filterValues": ["4"] },
{ "filterName": "children", "filterValues": ["2"] },
{ "filterName": "propertyType", "filterValues": ["Villa"] },
{ "filterName": "petFriendly", "filterValues": ["true"] },
{ "filterName": "maxPrice", "filterValues": ["20000"] }
]
}

Response

{
"singleListings": [
{
"listingId": "lst_abc",
"title": "Nimishka Villa",
"coverPicture": "https://cdn.elivaas.com/villa.jpg",
"propertyType": "VILLA",
"brand": "priv\u00e9",
"badges": [
{ "label": "Best Seller", "type": "BEST_SELLER", "placement": null },
{ "label": "In Demand", "type": "IN_DEMAND", "placement": null },
{ "label": "High Margin", "type": "HIGH_MARGIN", "placement": null }
],
"adults": 6,
"bedrooms": 3,
"bathrooms": 2,
"unitCount": 4,
"locality": "Chattyan",
"city": "Kasauli",
"state": "Himachal Pradesh",
"rating": 4.6,
"tags": ["Pvt Pool", "Garden Area", "Scenic Views", "Game Room"],
"selectedProperties": [
{ "propertyId": "prop_1", "title": "Deluxe Room", "quantity": 2 }
],
"price": {
"total": 32800,
"perNight": 16400,
"totalBeforeDiscount": 38000,
"totalSaving": 5200,
"discountPercent": 14
},
"offerTitles": ["10% off with Visa"],
"cancellationPlans": [
{
"id": "plan_flex",
"name": "Flexible",
"planType": "FLEXIBLE",
"cancellationSummary": "Free cancellation till 7 days before check-in",
"hasDiscount": false,
"totalAfterDiscount": 32800,
"perNightAfterDiscount": 16400
}
]
}
],
"combinations": []
}

Available Filters

Generated from com.elivaas.common.dto.listing.FilterCatalog \u2014 do not edit by hand. Run ./gradlew :common:generateFilterDocs after adding a filter.

filterNameTypeExampleDescription
channelIdstringB2CSales channel (B2C, B2B)
citystring[]["Goa"]Filter by city (case-insensitive)
statestring[]["Himachal Pradesh"]Filter by state (case-insensitive)
countrystring[]["India"]Filter by country (case-insensitive)
localitystring[]["Kasauli"]Filter by locality (case-insensitive)
listingIdstring[]["lst_abc"]Specific listing IDs (case-sensitive, opaque)
brandstring[]["privé"]Filter by brand (case-insensitive)
propertyTypestring[]["Villa"]Villa, Apartment, Resort (case-insensitive)
tagsstring[]["Scenic Views"]Required tags (post-filter, in-memory)
amenitiesstring[]["Pool","Wifi"]Required amenities (post-filter)
roomViewstring[]["Sea View","Mountain View"]Matches property_views.view_name via property_view_mappings (case-insensitive)
bhkstring[]["2 BHK","3"]Leading int parsed; matches properties.total_bedrooms
houseRulesstring[]["smoking","alcohal"]Matches property_rules.name via property_rule_mappings (case-insensitive). status not yet applied
searchQuerystringNimishkaText search on listing/property name (ILIKE)
querystringvilla in goa for 4 adults next weekendNatural-language query. Triggers AI intent extraction in the search controller, which synthesizes additional rawParam filters (city, dates, propertyType, etc.) and merges them into this request. Echoed back via response.rawParams so the UI can render selected filters.
minPriceint5000Min per-night price
maxPriceint20000Max per-night price
minBedroomsint2Min total bedrooms (sum of properties.total_bedrooms weighted by quantity)
maxBedroomsint5Max total bedrooms
minBathroomsint1Min bathrooms (column pending — currently no-op)
maxBathroomsint4Max bathrooms (column pending — currently no-op)
minAdultsint2Min adult capacity (sum-weighted)
maxAdultsint10Max adult capacity
minRatingdouble4.0Min rating (column pending — currently no-op)
adultsint4Required adults
childrenint2Required children
infantsint1Required infants
petsint1Required pets
checkInDatestring2026-06-01YYYY-MM-DD
checkOutDatestring2026-06-04YYYY-MM-DD
petFriendlybooleantruePet-friendly only
stressPropertiesbooleantrueStressed/deal properties
allowCombinationbooleantrueEnable multi-listing groups
maxListingsInGroupint3Max listings per group (default 3)
includeSingleListingsbooleantrueInclude single-fit listings in result
proximityMetersdouble500Radius for combination grouping
anchorLatdouble15.5Anchor latitude for proximity
anchorLondouble73.7Anchor longitude for proximity
minSingleResultsint3Trigger combinations only below this many singles
pageint11-based page index for singleListings
sizeint10Page size for singleListings
bevstringv_abc123Visitor cookie (auto-injected)
partner_idstringptn_xyzPartner (auto-injected or explicit)
utm_sourcestringgoogleUTM source
utm_mediumstringcpcUTM medium
utm_campaignstringsummer-saleUTM campaign

Pagination

page and size are filters like any other — pass them inside rawParams and the response gains four pagination fields next to singleListings. Omit them and the response is byte-identical to a pre-pagination caller.

{
"rawParams": [
{ "filterName": "city", "filterValues": ["Goa"] },
{ "filterName": "checkInDate", "filterValues": ["2026-06-01"] },
{ "filterName": "checkOutDate", "filterValues": ["2026-06-04"] },
{ "filterName": "adults", "filterValues": ["5"] },
{ "filterName": "page", "filterValues": ["1"] },
{ "filterName": "size", "filterValues": ["10"] }
]
}

Response (additions only):

{
"singleListings": [ /* sliced to the requested window */ ],
"page": 1,
"size": 10,
"totalSingleListings": 42,
"totalPages": 5
}
  • page is 1-based. Values < 1 are coerced to 1.
  • size is required alongside page to enable pagination. If either is missing, the legacy unpaged behavior runs and the four pagination fields are omitted from the response.
  • Pagination is purely presentational — it slices the sorted singleListings after sorting, and never changes whether combinedGroups are built. The combination fallback still triggers on the total number of single fits, not the paginated slice.
  • Out-of-range pages return an empty singleListings with accurate totalPages / totalSingleListings, never a 4xx.

Sorting

Single-fit listings are sorted by:

  1. Occupancy fit (primary) \u2014 total selected adult+child capacity minus required, smallest first. A 2-adult villa beats a 10-adult villa for an adults=2 query.
  2. Static cost (tie-breaker) \u2014 price/100 + (10 - rating) * 20. Cheaper, higher-rated wins.

Listing badges

Listings carry an array of Badge { label, type, placement }. Types are populated from the listing_badge table by background jobs (e.g. BEST_SELLER, IN_DEMAND, HIGH_MARGIN). Rows past expires_at are excluded automatically. placement is reserved for future server-driven UI placement; currently null.

Website API

On the website (POST /api/v1/listings/search), traffic context is auto-injected from the bev cookie. You don't need to pass partner_id or utm_source — the backend resolves it automatically.