Frontend integration contract for itinerary pricing flows.
PUT /v1/itinerary/:id/pricing-selection (admin) is deprecated/removed from admin flow.PUT /v1/itinerary/:id/pricing-table for pricing updates.POST /v1/bookings via required pricingSelection payload.PUT /v1/itinerary/:id/customer-pricing-selection has been removed.POST /v1/bookings under pricingSelection./v1/itineraryPricing categories use HotelCategoryEnum numeric values:
1 = LUXURY2 = PREMIUM3 = SUPER_DELUXE4 = DELUXE5 = STANDARDDiscount type values (when present in summary):
1 = FLAT2 = PERCENTAGE/v1/itinerary/:id/price-detailsSource of truth for pricing table mode, defaults, and summary.
adults (number)children (number)extraMattressCount (number; pricing-only, excluded from traveler/slab count)selectedCategory (number enum value; applied in customer/b2c flow)selectedTransferId (number)selectedVehicleName (string)selectedCapacityMin (number)selectedCapacityMax (number)includeDinnerSupplement (true/false)channel (b2b or b2c)GET /price-details recalculates summary from the supplied query params (selection context) in real time.
Compatibility: legacy query params childrenWithoutBed and childrenWithBed are still accepted as aliases for children and extraMattressCount.
{
"message": "SUC_PRICE_DETAILS_FETCHED",
"data": {
"itineraryId": 958,
"pricingTableType": "hotel_transfer",
"mappingSnapshot": {
"hasActivities": true,
"hasHotels": true,
"hasTransfers": true
},
"defaultCategory": 5,
"availableCategories": [5, 2, 1],
"selection": {
"selectedCategory": 5,
"selectedVehicleSlab": {
"transferId": 3002,
"vehicleName": "Innova / Xylo / Similar",
"capacityMin": 1,
"capacityMax": 3
},
"travelerDetails": {
"adults": 2,
"children": 1,
"infants": 0
},
"extraMattressCount": 0,
"includeDinnerSupplement": false,
"displayMode": 1
},
"pricingTable": {},
"summary": {
"channel": "b2b",
"currency": "INR",
"baseCost": 0,
"markupPercent": 5,
"markupAmount": 0,
"gstPercent": 5,
"gstAmount": 0,
"tcsPercent": 0,
"tcsAmount": 0,
"discountType": 1,
"discountValue": 0,
"discountAmount": 0,
"grandTotal": 0,
"tcsApplicable": false
}
}
}
pricingTable by scenarioactivities_only{
"pricingTableType": "activities_only",
"pricingTable": {
"activitiesOnly": {
"adultPrice": 5000,
"childPrice": 2000
}
}
}
hotel_only{
"pricingTableType": "hotel_only",
"pricingTable": {
"categoryPerPersonPrices": [
{
"category": 5,
"perPersonPrice": 15100,
"primaryMappedHotelName": "Taj City Center"
},
{
"category": 2,
"perPersonPrice": 18400,
"primaryMappedHotelName": null
}
],
"hotelRows": [
{
"category": 5,
"plan": "CP",
"extraBedPrice": 4050,
"childWithoutBedPrice": 2100,
"dinnerSupplementPrice": 1950
},
{
"category": 2,
"plan": "CP",
"extraBedPrice": 5500,
"childWithoutBedPrice": 3800,
"dinnerSupplementPrice": 2400
}
]
}
}
transfer_only{
"pricingTableType": "transfer_only",
"pricingTable": {
"transferRows": [
{
"transferId": 3001,
"vehicleName": "Wagon R / Similar",
"capacityMin": 1,
"capacityMax": 3,
"pricePerPerson": 15100
},
{
"transferId": 3002,
"vehicleName": "Innova / Xylo / Similar",
"capacityMin": 1,
"capacityMax": 3,
"pricePerPerson": 18400
},
{
"transferId": 3002,
"vehicleName": "Innova / Xylo / Similar",
"capacityMin": 4,
"capacityMax": 6,
"pricePerPerson": 12350
}
]
}
}
hotel_transfer{
"pricingTableType": "hotel_transfer",
"pricingTable": {
"categoryPerPersonPrices": [
{
"category": 5,
"perPersonPrice": 15100,
"primaryMappedHotelName": "Taj City Center"
}
],
"rows": [
{
"category": 5,
"plan": "CP",
"extraBedPrice": 4050,
"childWithoutBedPrice": 2100,
"dinnerSupplementPrice": 1950,
"vehiclePricing": [
{
"transferId": 3001,
"vehicleName": "Wagon R / Similar",
"capacityMin": 1,
"capacityMax": 3,
"pricePerPerson": 15100
},
{
"transferId": 3002,
"vehicleName": "Innova / Xylo / Similar",
"capacityMin": 1,
"capacityMax": 3,
"pricePerPerson": 18400
},
{
"transferId": 3002,
"vehicleName": "Innova / Xylo / Similar",
"capacityMin": 4,
"capacityMax": 6,
"pricePerPerson": 12350
}
]
}
]
}
}
Customer write path:
POST /v1/bookings (booking-jwt)pricingSelection payloadbooking.priceDetails)pricingSelection block inside booking payload){
"channel": "b2b",
"selectedCategory": 5,
"selectedVehicleSlab": {
"transferId": 3002,
"vehicleName": "Innova / Xylo / Similar",
"capacityMin": 1,
"capacityMax": 3
},
"travelerDetails": {
"adults": 2,
"children": 1,
"infants": 0
},
"extraMattressCount": 0,
"includeDinnerSupplement": true,
"displayMode": 1
}
Booking response includes booking.priceDetails in same structure as GET /price-details with recalculated summary.
Notes:
selectedCategory is meaningful for hotel-involved flows.selectedVehicleSlab is meaningful for transfer-involved flows.pricingSelection.travelerDetails.childrenWithoutBed and pricingSelection.travelerDetails.childrenWithBed are accepted as legacy aliases.vehiclePricing[] and transferRows[] include transferId for transfer reference binding.pricingSelection.travelerDetails, children and infants are optional; pricing computation uses adults + children for traveler/slab count.extraMattressCount is pricing-only and must be sent outside travelerDetails.hotel_transfer and hotel_only, pricingTable.categoryPerPersonPrices provides category-wise per-person prices (markup included, dinner supplement excluded) for category card display, plus primaryMappedHotelName for that category.primaryMappedHotelName is null.transferId; vehicle name is resolved from transfer master.1-34-seateractivities_only, customer selection does not accept activity prices; prices come from admin pricing-table config.pricingTable.rows (or any rows) in pricingSelection; selection inputs only./v1/itinerary/:id/pricing-table (admin only)Upsert pricing master rows (rate card) for each scenario.
TRIP permissionhotel_transfer payload{
"scenario": "hotel_transfer",
"rows": [
{
"category": 5,
"plan": "CP",
"extraBedPrice": 4050,
"childWithoutBedPrice": 2100,
"dinnerSupplementPrice": 1950,
"vehiclePricing": [
{
"transferId": 3001,
"capacityMin": 1,
"capacityMax": 3,
"pricePerPerson": 15100
}
]
}
]
}
hotel_only payload{
"scenario": "hotel_only",
"hotelRows": [
{
"category": 5,
"plan": "CP",
"extraBedPrice": 4050,
"childWithoutBedPrice": 2100,
"dinnerSupplementPrice": 1950
}
]
}
transfer_only payload{
"scenario": "transfer_only",
"category": 5,
"transferRows": [
{
"transferId": 3001,
"capacityMin": 1,
"capacityMax": 3,
"pricePerPerson": 12000
}
]
}
category is optional for transfer_only; if omitted, backend uses itinerary default category (fallback standard).
activities_only payload{
"scenario": "activities_only",
"displayMode": 1,
"activitiesOnly": {
"adultPrice": 5000,
"childPrice": 2000
}
}
{
"message": "SUC_PRICING_TABLE_SAVED",
"data": {
"itineraryId": 958,
"pricingTableType": "hotel_transfer",
"pricingTable": {},
"selection": {},
"summary": {}
}
}
Notes:
POST /bookings pricingSelection updates customer selection inputs and recalculates totals.channel = "b2b"tripType (admin cannot override category in summary calculation)selectedCategory input is ignored for b2b summary computationsummary shows markupAmount, gstAmount, tcsAmount, discountAmount separately.channel = "b2c"hotel_transfer, selected category also drives transfer slab selection from that category bundle when availableselectedCategory can change summary totals based on selected bundle pricessummarygstAmount, tcsAmount, discountAmount separately./v1/itinerary/price-details/:leadId/:tripIdPublic lead pricing endpoint.
/v1/itinerary/:id/customer-price-detailsCustomer-token variant of itinerary price-details endpoint.
/v1/itinerary/:id/travelersLegacy compatibility endpoint.
New UI should use POST /bookings with pricingSelection.
tripType is the canonical category source.adults + children count (infants and extraMattressCount excluded from slab banding).<= 3 selects 1-3 slab> 3 selects 4-6 slab (or matching higher slab)hotel + transfer: selected/default category hotel bundle + primary transfer pricing.transfer-only: primary transfer pricing.activities-only: adultPrice default.hotel + transfer (+activities):hotel-only:transfer-only:activities-only:adultPrice is mandatory