openapi: 3.0.0
info:
  title: PMSX Ultra Sync APIs
  description: The endpoints that the PMSX Partner needs to build in order to fully support rate and restrictions updates from SiteMinder.
  version: 1.0.1
  contact:
    name: API Support
    email: pmsteam@siteminder.com

servers:
  - url: https://pmsx-partner.com
    description: Partner server
security:
  - basicAuth: []

paths:
  /pmses/{pmsCode}/hotels/{hotelCode}/rates:
    post:
      parameters:
        - $ref: '#/components/parameters/traceToken'
        - $ref: '#/components/parameters/hotelCode'
        - $ref: '#/components/parameters/pmsCode'
        
      summary: Hotel Room Rate Update (Per day rate)
      description: Endpoint to receive and process hotel room rate rates
      tags:
        - Hotel Rate Update 
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HotelRateUpdate'
      responses:
        '200':
          description: Rates Update received
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
          headers:
            X-PMS-TRACE-TOKEN:
              $ref: '#/components/headers/X-SM-TRACE-TOKEN'
            Time-Stamp:
                $ref: '#/components/headers/Time-Stamp'
        '400':
          $ref: "#/components/responses/BadRequest"
        '401':
          $ref: "#/components/responses/Unauthorized"
        '403':
          $ref: "#/components/responses/AccessDenied"
        '404':
          $ref: "#/components/responses/NotFound"
        '429':
          $ref: "#/components/responses/TooManyRequests"
        '500':
          $ref: "#/components/responses/ServerError"
        '503':
          $ref: "#/components/responses/ServiceUnavailableError"
  /pmses/{pmsCode}/hotels/{hotelCode}/occupancy-based-rates:
      post:
        parameters:
          - $ref: '#/components/parameters/traceToken'
          - $ref: '#/components/parameters/hotelCode'
          - $ref: '#/components/parameters/pmsCode'

        summary: Hotel Room Rate Update (Occupancy based rates)
        description: Endpoint to receive and process hotel room rate rates
        tags:
          - Hotel Rate Update 
        requestBody:
          required: true
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HotelOccupancyBasedRateUpdate'
        responses:
          '200':
            description: Rates Update received
            headers:
              X-PMS-TRACE-TOKEN:
                $ref: '#/components/headers/X-SM-TRACE-TOKEN'
              Time-Stamp:
                $ref: '#/components/headers/Time-Stamp'
          '400':
            $ref: "#/components/responses/BadRequest"
          '401':
            $ref: "#/components/responses/Unauthorized"
          '403':
            $ref: "#/components/responses/AccessDenied"
          '404':
            $ref: "#/components/responses/NotFound"
          '429':
            $ref: "#/components/responses/TooManyRequests"
          '500':
            $ref: "#/components/responses/ServerError"
          '503':
            $ref: "#/components/responses/ServiceUnavailableError"
 
  /pmses/{pmsCode}/hotels/{hotelCode}/restrictions:
    post:
      parameters:
        - $ref: '#/components/parameters/traceToken'
        - $ref: '#/components/parameters/hotelCode'
        - $ref: '#/components/parameters/pmsCode'

      summary: Hotel Room Rate Update (Restrictions)
      description: Endpoint to receive and process hotel room rate restrictions 
      tags:
        - Hotel Rate Update 
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HotelRestrictionsUpdate'
      responses:
        '200':
          description: Restrictions Update received
          headers:
            X-PMS-TRACE-TOKEN:
              $ref: '#/components/headers/X-SM-TRACE-TOKEN'
            Time-Stamp:
                $ref: '#/components/headers/Time-Stamp'
        '400':
          $ref: "#/components/responses/BadRequest"
        '401':
          $ref: "#/components/responses/Unauthorized"
        '403':
          $ref: "#/components/responses/AccessDenied"
        '404':
          $ref: "#/components/responses/NotFound"
        '429':
          $ref: "#/components/responses/TooManyRequests"
        '500':
          $ref: "#/components/responses/ServerError"
        '503':
          $ref: "#/components/responses/ServiceUnavailableError"
  /pmses/{pmsCode}/hotels/{hotelCode}/room-rates:
    get:
      summary: Retrieve room rate mappings for a hotel
      description: Returns the current room rate mapping configuration for the specified hotel
      parameters:
        - $ref: '#/components/parameters/traceToken'
        - $ref: '#/components/parameters/hotelCode'
        - $ref: '#/components/parameters/pmsCode'
      responses:
        '200':
          description: PMS RoomRate Mapping Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoomRateMappingList'
          headers:
            X-PMS-TRACE-TOKEN:
              $ref: '#/components/headers/X-SM-TRACE-TOKEN'
            Time-Stamp:
                $ref: '#/components/headers/Time-Stamp'
        '400':
          $ref: "#/components/responses/BadRequest"
        '401':
          $ref: "#/components/responses/Unauthorized"
        '403':
          $ref: "#/components/responses/AccessDenied"
        '404':
          $ref: "#/components/responses/NotFound"
        '429':
          $ref: "#/components/responses/TooManyRequests"
        '500':
          $ref: "#/components/responses/ServerError"
        '503':
          $ref: "#/components/responses/ServiceUnavailableError"
components:
  headers:
    X-SM-TRACE-TOKEN:
      schema:
        type: string
        description: "The unique identifier of the request (UUID), this traceToken is logged with this request."
        example: "8bf21e96-e6c7-4bf9-a377-a5763e053538"    
    Time-Stamp:
      schema:
        type: string
        format: date-time
        example: '2024-01-26T18:25:43.511Z'
        description: Response Timestamp.
  parameters:
    traceToken:
      name: X-SM-TRACE-TOKEN
      in: header
      description: "The unique identifier of the request (UUID), this traceToken is logged with this request."
      required: true
      schema:
        type: string
        example: "8bf21e96-e6c7-4bf9-a377-a5763e053538"    
    hotelCode:
      name: hotelCode
      in: path
      required: true
      description: Hotel identifier code
      schema:
        type: string
    pmsCode:
      name: pmsCode
      in: path
      required: true
      description: PMSX partner code
      schema:
        type: string
  responses:
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseList'
      headers:
          X-PMS-TRACE-TOKEN:
            $ref: '#/components/headers/X-SM-TRACE-TOKEN'
          Time-Stamp:
            $ref: '#/components/headers/Time-Stamp'
    BadRequest:
      description: Bad request 
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseList'
      headers:
          X-PMS-TRACE-TOKEN:
            $ref: '#/components/headers/X-SM-TRACE-TOKEN'
          Time-Stamp:
            $ref: '#/components/headers/Time-Stamp'
    NotFound:
      description: Not Found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseList'
      headers:
          X-PMS-TRACE-TOKEN:
            $ref: '#/components/headers/X-SM-TRACE-TOKEN'
          Time-Stamp:
            $ref: '#/components/headers/Time-Stamp'
    AccessDenied:
      description: Access Denied
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseList'
      headers:
        X-PMS-TRACE-TOKEN:
          $ref: '#/components/headers/X-SM-TRACE-TOKEN'
        Time-Stamp:
          $ref: '#/components/headers/Time-Stamp'
    TooManyRequests:
      description: Too Many Requests
      headers:
        Retry-After:
          description: Number of seconds before SM should retry.
          required: true  
          schema:
            type: integer
            minimum: 1
            example: 60
        X-PMS-TRACE-TOKEN:
          $ref: '#/components/headers/X-SM-TRACE-TOKEN'
        Time-Stamp:
          $ref: '#/components/headers/Time-Stamp'
    ServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseList'
      headers:
        X-PMS-TRACE-TOKEN:
          $ref: '#/components/headers/X-SM-TRACE-TOKEN'
        Time-Stamp:
          $ref: '#/components/headers/Time-Stamp'
    ServiceUnavailableError:
      description: Service Unavailable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponseList'
      headers:
        X-PMS-TRACE-TOKEN:
          $ref: '#/components/headers/X-SM-TRACE-TOKEN'
        Time-Stamp:
          $ref: '#/components/headers/Time-Stamp'
  schemas:
    HotelRateUpdate:
      type: object
      required:
        - invTypeCode
        - ratePlanCode
        - currencyCode
        - rates
      properties:
        invTypeCode:
          type: string
          description: Inventory type code
          example: "ABC"
        ratePlanCode:
          type: string
          description: Rate plan code
          example: "CBA"
        currencyCode:
          type: string
          description: Three-letter currency code
          pattern: "^[A-Z]{3}$"
          example: "USD"
        rates:
          type: array
          description: A list per day rate updates for the hotel
          items:
            $ref: '#/components/schemas/RateUpdate'
    
    RateUpdate:
      type: object
      required:
        - date
      properties:
        date:
          type: string
          format: date
          description: Date for which the update applies
          example: "2025-01-01"
        rate:
           $ref: '#/components/schemas/OccupancyRateAmount'
        extraAdultAmount:
           $ref: '#/components/schemas/RateAmount'
        extraChildAmount:
           $ref: '#/components/schemas/RateAmount' 
      example: { 
        "date": "2025-01-01",
        "rate": {
          "amountAfterTax": 355.5,
          "numberOfAdults": 2
          },
        "extraAdultAmount": {
          "amountAfterTax": 65.5,
        },
        "extraChildAmount": {
          "amountAfterTax": 65.5,
        }
      } 

    HotelOccupancyBasedRateUpdate:
      type: object
      required:
        - invTypeCode
        - ratePlanCode
        - currencyCode
        - occupancyBasedRates
      properties:
        invTypeCode:
          type: string
          description: Inventory type code
          example: "ABC"
        ratePlanCode:
          type: string
          description: Rate plan code
          example: "CBA"
        currencyCode:
          type: string
          description: Three-letter currency code
          pattern: "^[A-Z]{3}$"
          example: "USD"
        occupancyBasedRates:
          type: array
          description: A list of occupancy based rate updates for the hotel
          items:
            $ref: '#/components/schemas/OccupancyBasedRateUpdate'
      example: {
        "invTypeCode": "ABC",
        "ratePlanCode": "CBA",
        "currencyCode": "USD",
        "occupancyBasedRates": [
          {
            "date": "2025-01-01",
            "occupancyBasedRates": [
            {
              "amountAfterTax": 300,
              "numberOfAdults": 1
            }
            ,
            {
              "amountAfterTax": 355.5,
              "numberOfAdults": 2
            }
            ,{
              "amountAfterTax": 425,
              "numberOfAdults": 3
            }
            ,{
              "amountAfterTax": 492.5,
              "numberOfAdults": 4
            }
          ],
          "extraChildAmount": {
            "amountAfterTax": 65.5,
        }
        }
        ]
      }
    OccupancyBasedRateUpdate:
      type: object
      required:
        - date
      properties:
        date:
          type: string
          format: date
          description: Date for which the update applies
          example: "2025-01-01"
        occupancyBasedRates:
          type: array
          description: All occupancy based rates for this date (IE 1-5 pax)
          items:
            $ref: '#/components/schemas/OccupancyRateAmount'
        extraChildAmount:
           $ref: '#/components/schemas/RateAmount' 

    OccupancyRateAmount:
      type: object 
      required:
        - amountAfterTax
        - numberOfAdults
      properties:
        amountAfterTax:
          type: number
          description: Rate amount after tax 
          example: 355.50
        amountBeforeTax:
          type: number
          description: Rate amount before tax 
          example: 350.00
        numberOfAdults:
          type: number
          description: Number of included adults the rate is for
          example : 2

    RateAmount:
      type: object 
      required:
        - amountAfterTax
      properties:
        amountAfterTax:
          type: number
          description: Rate amount after tax 
          example: 65.50
        amountBeforeTax:
          type: number
          description: Currently unsupported, rate amount before tax 
          example: 50.00

    HotelRestrictionsUpdate:
      type: object
      required:
        - invTypeCode
        - ratePlanCode
        - restrictions
      properties:
        invTypeCode:
          type: string
          description: Inventory type code
          example: "ABC"
        ratePlanCode:
          type: string
          description: Rate plan code
          example: "CBA"
        restrictions:
          type: array
          description: List of inventory and rate updates for the hotel
          items:
            $ref: '#/components/schemas/RestrictionsUpdate'
      example: {
        "invTypeCode": "ABC",
        "ratePlanCode": "CBA",
        "restrictions": [
        {
          "date": "2025-01-01",
          "minLOS": 2,
          "maxLOS": 7,
          "close": false,
          "closeToArrival": false,
          "closeToDeparture": false
        }]
      }

    RestrictionsUpdate:
      type: object
      required:
        - date
      properties:
        date:
          type: string
          format: date
          description: Date for which the update applies
          example: "2025-01-01"
        minLOS:
          type: number
          description: Minimum length of stay
          example: 2
        maxLOS:
          type: number
          description: Maximum length of stay
          example: 7
        forwardMinStay:
          type: number
          description: Minimum length of stay through
          example: 3
        forwardMaxStay:
          type: number
          description: Maximum length of stay through
          example: 5
        close:
          type: boolean
          description: Room rate closed 
          example: false
        closeToArrival:
          type: boolean
          description: Room rate closed to arrival
          example: false
        closeToDeparture:
          type: boolean
          description: Room rate closed to departure
          example: false

    RoomRateMapping:
      type: object
      required:
        - roomTypeCode
        - ratePlanCode
        - roomTypeName
        - ratePlanName
        - includedAdultOccupancy
        - rateSetupType
      properties:
        roomTypeCode:
          type: string
          description: Unique code identifying the room type
          example: "ABC"
        ratePlanCode:
          type: string
          description: Unique code identifying the rate plan
          example: "CBA"
        roomTypeName:
          type: string
          description: Human-readable name of the room type
          example: "Single Room"
        ratePlanName:
          type: string
          description: Human-readable name of the rate plan
          example: "Best Available Rate"
        includedAdultOccupancy:
          type: integer
          minimum: 1
          description: Number of adults included in this rate
          example: 2
        rateSetupType:
          type: string
          enum:
            - Derived
            - Manual
          description: Indicates how the rate is configured in the PMS. If the rate is 'Derived' in the PMS, we would expect that you would also include 'NO_RATES' in unsupportedData as the rate is not updatable.
          example: "Derived"
        unsupportedData:
          type: array
          description: List of unsupported data or limitations for this mapping
          items:
            $ref: '#/components/schemas/UnsupportedDataItem'
    
    UnsupportedDataItem:
      type: object
      required:
        - code
      properties:
        code:
          type: string
          description: Code indicating the type of unsupported data. 'NO_UPDATES' will result in no updates pushed to this room rate. 'NO_RATES' will result in no rate updates pushed to this room rate.
          example: "NO_RATES"
          enum:
            - NO_RATES
            - NO_UPDATES
    
    RoomRateMappingList:
      type: array
      description: List of room rate mappings
      items:
        $ref: '#/components/schemas/RoomRateMapping'

    ErrorResponseList:
      type: object
      properties:
        errors:
          type: array
          description: List errors
          items:
            $ref: '#/components/schemas/ErrorResponse'
      
    ErrorResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code
          example: "INVALID_REQUEST"
        message:
          type: string
          description: Error message
          example: "Invalid request payload"
  
    SuccessResponse:
      type: object
      properties:
        result:
          type: string
          description: Result
          example: "Success"
      

  securitySchemes:
    basicAuth:
      type: http
      scheme: basic

      
