Pricing APIs

Frontend integration contract for itinerary pricing flows.

⚠️ Deprecation Note

Removed in current release

Base

Category enum values

Pricing categories use HotelCategoryEnum numeric values (src/shared/enums/hotel-category.enum.ts):

Markup type values (MarkupTypeEnum):

Discount type values (DiscountTypeEnum, when present in summary):


1) GET /v1/itinerary/:id/price-details

Source of truth for pricing table mode, defaults, and summary.

Supported query params

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.

Common response envelope

{
  "message": "SUC_PRICE_DETAILS_FETCHED",
  "data": {
    "itineraryId": 958,
    "pricingTableType": "hotel_transfer",
    "mappingSnapshot": {
      "hasActivities": true,
      "hasHotels": true,
      "hasTransfers": true
    },
    "defaultCategory": 5,
    "availableCategories": [1, 2, 3, 4, 5],
    "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,
      "gstPercent": 5,
      "gstAmount": 0,
      "tcsPercent": 0,
      "tcsAmount": 0,
      "discountType": 1,
      "discountValue": 0,
      "discountAmount": 0,
      "grandTotal": 0,
      "tcsApplicable": false,
      "markupPercent": 5,
      "markupType": 2,
      "markupValue": 5,
      "markupAmount": 0
    }
  }
}

2) pricingTable by scenario

A) activities_only

{
  "pricingTableType": "activities_only",
  "pricingTable": {
    "activitiesOnly": {
      "adultPrice": 5000,
      "childPrice": 2000
    }
  }
}

B) hotel_only

{
  "pricingTableType": "hotel_only",
  "pricingTable": {
    "categoryPerPersonPrices": [
      {
        "category": 5,
        "perPersonPrice": 15100,
        "primaryMappedHotelName": "Taj City Center"
      },
      {
        "category": 2,
        "perPersonPrice": 18400,
        "primaryMappedHotelName": null
      }
    ],
    "hotelRows": [
      {
        "category": 5,
        "pricePerPerson": 15100,
        "plan": "CP",
        "extraBedPrice": 4050,
        "childWithoutBedPrice": 2100,
        "dinnerSupplementPrice": 1950
      },
      {
        "category": 2,
        "pricePerPerson": 18400,
        "plan": "CP",
        "extraBedPrice": 5500,
        "childWithoutBedPrice": 3800,
        "dinnerSupplementPrice": 2400
      }
    ]
  }
}

C) 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
      }
    ]
  }
}

D) 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
          }
        ]
      }
    ]
  }
}

3) Customer pricing selection via booking create

Customer write path:

Request (pricingSelection block inside booking payload)

{
  "channel": "b2c",
  "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
}

Response

Booking response includes booking.priceDetails in same structure as GET /price-details with recalculated summary.

Notes:


4) PUT /v1/itinerary/:id/pricing-table (admin only)

Upsert pricing master rows (rate card) for each scenario.

A) hotel_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
        }
      ]
    }
  ]
}

B) hotel_only payload

{
  "scenario": "hotel_only",
  "hotelRows": [
    {
      "category": 5,
      "pricePerPerson": 15100,
      "plan": "CP",
      "extraBedPrice": 4050,
      "childWithoutBedPrice": 2100,
      "dinnerSupplementPrice": 1950
    }
  ]
}

C) 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 resolves category from: dto.categorybasePriceDetails.defaultCategorybasePriceDetails.availableCategories[0]HotelCategoryEnum.STANDARD (5).

D) activities_only payload

{
  "scenario": "activities_only",
  "displayMode": 1,
  "activitiesOnly": {
    "adultPrice": 5000,
    "childPrice": 2000
  }
}

Response (all scenarios)

{
  "message": "SUC_PRICING_TABLE_SAVED",
  "data": {
    "itineraryId": 958,
    "pricingTableType": "hotel_transfer",
    "pricingTable": {},
    "selection": {},
    "summary": {}
  }
}

Notes:


5) B2B/B2C summary behavior


6) Other related pricing endpoints

A) GET /v1/itinerary/price-details/:leadId/:tripId

Public lead pricing endpoint.

B) GET /v1/itinerary/:id/customer-price-details

Customer-token variant of itinerary price-details endpoint.

C) PUT /v1/itinerary/:id/travelers

Saves the default traveler/pax configuration on the itinerary (adults, children, infants, selectedCategory, selectedVehicleSlab, extraMattressCount, includeDinnerSupplement, displayMode). These defaults are used when displaying a trip with no customer-supplied selection context.

This endpoint remains active. For customer booking price snapshots, use POST /bookings with pricingSelection.


7) Rules for frontend consumers


8) Publish validation matrix