Frontend API Guide: Import Preview + Bundle Pricing Flow

Change summary for frontend migration: docs/frontend-api-change-impact.md

This document lists the APIs required by frontend for:

Base Notes


1) Location APIs

1.1 Check Cities by Name (bulk exact check)

Request

{
  "cityNames": ["Gangtok", "Darjeeling", "Pelling"]
}

Response

{
  "message": "SUC_CITY_NAME_CHECKED",
  "data": {
    "Gangtok": { "id": 101, "name": "Gangtok", "stateName": "Sikkim" },
    "Darjeeling": {
      "id": 102,
      "name": "Darjeeling",
      "stateName": "West Bengal"
    }
  }
}

1.2 Search Cities by Name (ILIKE)

Response

{
  "message": "SUC_CITIES_FETCHED",
  "data": [
    { "id": 101, "name": "Gangtok", "state": { "id": 11, "name": "Sikkim" } }
  ]
}

1.3 Search States by Name (ILIKE)

Response

{
  "message": "SUC_STATES_FETCHED",
  "data": [{ "id": 11, "name": "Sikkim" }]
}

1.4 Create City / Location

Request

{
  "name": "Lachung",
  "stateId": 11,
  "latitude": 27.6892,
  "longitude": 88.742
}

Response

{
  "message": "SUC_CITY_CREATED",
  "data": {
    "id": 501,
    "name": "Lachung",
    "stateId": 11,
    "countryId": 1,
    "latitude": 27.6892,
    "longitude": 88.742
  }
}

2) Hotel Inventory APIs

2.1 Check Hotel Inventory (bulk)

Request

{
  "items": [
    {
      "category": "standard",
      "locationId": 101,
      "priorityHotelNames": ["Maple Residency", "Delight The Fortuna"]
    },
    {
      "category": "premium",
      "locationId": 101
    }
  ]
}

Response

{
  "message": "SUC_HOTEL_INVENTORY_CHECKED",
  "data": [
    {
      "inputIndex": 0,
      "matched": true,
      "matchType": "priority_name",
      "hotel": {
        "id": 9001,
        "name": "Maple Residency",
        "cityId": 101,
        "category": "standard",
        "address": "MG Road",
        "description": "Sample standard hotel",
        "starRating": 4,
        "checkInTime": "14:00:00",
        "checkOutTime": "11:00:00",
        "roomType": "Suite"
      },
      "hotels": [
        {
          "id": 9001,
          "name": "Maple Residency",
          "cityId": 101,
          "category": "standard",
          "address": "MG Road",
          "description": "Sample standard hotel",
          "starRating": 4,
          "checkInTime": "14:00:00",
          "checkOutTime": "11:00:00",
          "roomType": "Suite"
        },
        {
          "id": 9003,
          "name": "Delight The Fortuna",
          "cityId": 101,
          "category": "standard",
          "address": "Central Avenue",
          "description": "Sample standard hotel",
          "starRating": 4,
          "checkInTime": "13:00:00",
          "checkOutTime": "10:00:00",
          "roomType": "Deluxe"
        }
      ]
    },
    {
      "inputIndex": 1,
      "matched": true,
      "matchType": "fallback_category_location",
      "hotel": {
        "id": 9007,
        "name": "Lemon Tree",
        "cityId": 101,
        "category": "premium",
        "address": "Hill View",
        "description": "Sample premium hotel",
        "starRating": 5,
        "checkInTime": "14:00:00",
        "checkOutTime": "11:00:00",
        "roomType": "Suite"
      },
      "hotels": [
        {
          "id": 9007,
          "name": "Lemon Tree",
          "cityId": 101,
          "category": "premium",
          "address": "Hill View",
          "description": "Sample premium hotel",
          "starRating": 5,
          "checkInTime": "14:00:00",
          "checkOutTime": "11:00:00",
          "roomType": "Suite"
        }
      ]
    }
  ]
}

2.2 Search Hotel Inventory

Response

{
  "message": "SUC_HOTELS_FETCHED",
  "data": [
    {
      "id": 9001,
      "name": "Maple Residency",
      "cityId": 101,
      "category": "standard",
      "address": "MG Road",
      "description": "Sample standard hotel",
      "starRating": 4,
      "checkInTime": "14:00:00",
      "checkOutTime": "11:00:00",
      "roomType": "Suite"
    }
  ]
}

2.3 Create Hotel Inventory

Request

{
  "name": "Delight The Fortuna",
  "cityId": 101,
  "category": "standard",
  "address": "MG Road, Gangtok",
  "description": "Comfort stay near city center",
  "starRating": 4.5,
  "checkInTime": "14:00:00",
  "checkOutTime": "11:00:00",
  "roomType": 4,
  "mediaLinks": [
    "https://cdn.example.com/hotels/delight-1.jpg",
    "https://cdn.example.com/hotels/delight-2.jpg"
  ]
}

Required fields:

Optional fields:

Response

{
  "message": "SUC_HOTEL_CREATED",
  "data": {
    "id": 9010,
    "name": "Delight The Fortuna",
    "cityId": 101,
    "category": "standard",
    "address": "MG Road, Gangtok",
    "description": null,
    "starRating": null,
    "checkInTime": null,
    "checkOutTime": null,
    "roomType": null,
    "media": [
      {
        "id": 30001,
        "fileType": 1,
        "link": "https://cdn.example.com/hotels/delight-1.jpg"
      }
    ]
  }
}

3) Transfer Inventory APIs

3.1 Check Transfer by Name

Request

{
  "items": [{ "name": "Wagon R / Similar" }, { "name": "Innova / Similar" }]
}

Response

{
  "message": "SUC_TRANSFER_CHECKED",
  "data": [
    {
      "requestedName": "Wagon R / Similar",
      "matched": true,
      "transfer": {
        "id": 3001,
        "vehicleName": "Wagon R / Similar",
        "vehicleType": "Car",
        "seater": 3,
        "description": "Airport and local transfers",
        "notes": "Night surcharge excluded",
        "isActive": true,
        "createdAt": "2026-03-20T10:10:10.000Z",
        "updatedAt": "2026-03-20T10:10:10.000Z"
      }
    },
    {
      "requestedName": "Innova / Similar",
      "matched": false,
      "transfer": null
    }
  ]
}

3.2 Search Transfer by Name

Response

{
  "message": "SUC_TRANSFERS_FETCHED",
  "data": [
    {
      "id": 3002,
      "vehicleName": "Innova / Xylo / Similar",
      "vehicleType": "Car",
      "seater": 6,
      "description": "Airport and local transfers",
      "notes": "Night surcharge excluded",
      "isActive": true,
      "createdAt": "2026-03-20T10:10:10.000Z",
      "updatedAt": "2026-03-20T10:10:10.000Z"
    }
  ]
}

3.3 Create Transfer Inventory

Request

{
  "vehicleType": "Car",
  "vehicleName": "Innova / Xylo / Similar",
  "seater": 6,
  "description": "Airport and local transfers",
  "notes": "Night surcharge excluded"
}

Required fields:

Optional fields:

Response

{
  "message": "SUC_TRANSFER_CREATED",
  "data": {
    "id": 3010,
    "vehicleName": "Innova / Xylo / Similar",
    "vehicleType": "Car",
    "seater": 6,
    "description": "Airport and local transfers",
    "notes": null,
    "isActive": true,
    "media": [
      {
        "id": 40001,
        "fileType": 1,
        "link": "https://cdn.example.com/transfers/innova-1.jpg"
      }
    ],
    "createdAt": "2026-03-20T10:10:10.000Z",
    "updatedAt": "2026-03-20T10:10:10.000Z"
  }
}

3.4 Activity create API (full + media upload)

Notes:


4) Full Import API

4.1 Import Full Itinerary in One Call

Request (shape)

{
  "itinerary": { "...": "CreateItineraryDto" },
  "transferIds": [3010, 3011],
  "hotelIds": [901, 905],
  "hotelDayMappings": [
    { "hotelId": 901, "dayOrder": 1 },
    { "hotelId": 905, "dayOrder": 2 }
  ],
  "activities": [
    {
      "dayOrder": 1,
      "title": "Gangtok local sightseeing",
      "startTime": "2026-03-20 10:00:00",
      "duration": 120,
      "description": "MG Road and nearby viewpoints"
    },
    {
      "dayOrder": 2,
      "title": "Tsomgo Lake excursion",
      "startTime": "2026-03-21 09:30:00"
    }
  ],
  "bundlePricing": [
    {
      "category": "standard",
      "plan": "CP",
      "extraBedPrice": 4050,
      "childWithoutBedPrice": 2100,
      "dinnerSupplementPrice": 1950,
      "vehiclePricing": [
        {
          "transferId": 3001,
          "capacityMin": 1,
          "capacityMax": 3,
          "pricePerPerson": 15100
        },
        {
          "transferId": 3002,
          "capacityMin": 1,
          "capacityMax": 3,
          "pricePerPerson": 18400
        },
        {
          "transferId": 3002,
          "capacityMin": 4,
          "capacityMax": 6,
          "pricePerPerson": 12350
        }
      ]
    }
  ]
}

Notes:

Response

{
  "message": "SUC_ITN_IMPORTED",
  "data": {
    "id": 948,
    "name": "THE LAST SHANGRI-LA"
  }
}

5) Existing APIs Still Reusable

For import-preview UX, prefer the new lightweight check/search endpoints documented above.


6) Category Alignment + Publish Rules

6.1 B2C default display order

6.2 Publish pre-validation matrix

Validation runs only when publishing (not unpublishing). Checked in validatePublishReadiness() (src/modules/itinerary/utils/publish-validation.util.ts).