> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spaportal.cz/llms.txt
> Use this file to discover all available pages before exploring further.

# Get a hotel

> Returns a single hotel with its localized content, complete structured
profile, and amenities by id.

See the [Hotel](/api/objects/hotel) object for the full field
reference, including the allowed values for `serviceMethod`,
`indications`, and `staffLanguages`.


<Warning>
  **Draft:** The `roomTypes` response field and `expand=roomTypes`
  behavior are still in progress. Their response shape may change
  before they are finalized.
</Warning>


## OpenAPI

````yaml /api/v2/openapi.yaml get /hotels/{hotelId}
openapi: 3.0.3
info:
  title: SpaPortal API v2
  version: '2.0'
  description: The current SpaPortal public API.
servers:
  - url: https://spaportal.cz/api/v2
    description: Production
security:
  - spaPortalPublicKey: []
tags:
  - name: Hotels
  - name: Room types
  - name: Amenity categories
paths:
  /hotels/{hotelId}:
    get:
      tags:
        - Hotels
      summary: Get a hotel
      description: |
        Returns a single hotel with its localized content, complete structured
        profile, and amenities by id.

        See the [Hotel](/api/objects/hotel) object for the full field
        reference, including the allowed values for `serviceMethod`,
        `indications`, and `staffLanguages`.
      operationId: getHotel
      parameters:
        - $ref: '#/components/parameters/AcceptLanguage'
        - $ref: '#/components/parameters/RequestId'
        - name: hotelId
          in: path
          required: true
          schema:
            type: string
            pattern: ^[0-9a-fA-F]{24}$
          description: Hotel id.
        - name: expand
          in: query
          style: form
          explode: false
          schema:
            type: array
            items:
              type: string
              enum:
                - roomTypes
                - amenityLabels
          description: >-
            Comma-separated list of expansions (for example
            `expand=amenityLabels` or `expand=roomTypes,amenityLabels`).
            `amenityLabels` inlines the localized category, amenity, and option
            labels in `amenityCategories`, so no dictionary lookup is needed.
            `roomTypes` (**draft**, response shape may change) embeds the
            hotel's room types (otherwise fetch them via `GET
            /room-types?hotelId={hotelId}`).
      responses:
        '200':
          description: The hotel.
          headers:
            Content-Language:
              $ref: '#/components/headers/ContentLanguage'
            X-SpaPortal-Amenities-Version:
              $ref: '#/components/headers/AmenitiesVersion'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Hotel'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  parameters:
    AcceptLanguage:
      name: Accept-Language
      in: header
      required: false
      schema:
        type: string
        example: cs-CZ,de
      description: >-
        Comma-separated BCP 47 language tags selecting which locale keys
        localized fields return. When omitted, all locale keys are returned. See
        [Localization](/api/localization) for details.
    RequestId:
      name: X-Request-Id
      in: header
      required: false
      schema:
        type: string
      description: Optional client-provided request identifier echoed in error responses.
  headers:
    ContentLanguage:
      description: Comma-separated locale keys included in localized fields.
      schema:
        type: string
        example: cs-CZ,de
    AmenitiesVersion:
      description: >-
        Current amenity dictionary version. The value changes only when the
        dictionary content changes. Refetch `GET /amenity-categories` when it
        differs from the version you cached.
      schema:
        type: string
        example: 9f3c2a7d81b04e55
    RequestId:
      description: Request identifier for support and debugging.
      schema:
        type: string
  schemas:
    Hotel:
      type: object
      required:
        - id
        - name
        - shortDescription
        - channelContent
        - stars
        - address
        - email
        - phoneNumber
        - url
        - images
        - accommodationRules
        - mealServices
        - indications
        - staffLanguages
        - amenityCategories
        - priceFrom
      properties:
        id:
          type: string
          pattern: ^[0-9a-fA-F]{24}$
          example: 66f16191f739705faa020001
        name:
          allOf:
            - $ref: '#/components/schemas/HotelNameLocalizedString'
          description: >-
            Localized hotel name (plain text). Falls back to the default locale
            (cs-CZ) when a requested locale has no value, so it is never null.
          example:
            cs-CZ: Pawlik
            de: Pawlik-Aquaforum
        shortDescription:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: >-
            Localized short hotel description (plain text). Each locale value is
            at most 400 characters.
        channelContent:
          $ref: '#/components/schemas/HotelChannelContent'
        stars:
          type: integer
          nullable: true
          minimum: 1
          maximum: 5
          example: 4
        address:
          $ref: '#/components/schemas/HotelAddress'
        email:
          type: string
          format: email
          nullable: true
        phoneNumber:
          type: string
          nullable: true
        url:
          type: string
          format: uri
          nullable: true
        images:
          type: array
          items:
            $ref: '#/components/schemas/Image'
        accommodationRules:
          $ref: '#/components/schemas/HotelAccommodationRules'
        mealServices:
          $ref: '#/components/schemas/HotelMealServices'
        indications:
          type: array
          description: Medical indications the hotel specializes in, in display order.
          items:
            type: string
            enum:
              - musculoskeletal
              - cardiovascular
              - dermatology
              - digestion_metabolism
              - nervous_system
              - prevention
              - gynecology
              - oncology_aftercare
              - diabetes
        staffLanguages:
          type: array
          description: Languages spoken by hotel staff.
          items:
            type: string
            enum:
              - cs
              - en
              - de
              - ru
        amenityCategories:
          type: array
          description: >-
            Structured amenities assigned to this hotel, grouped by category.
            Categories without assigned amenities are omitted. Category,
            amenity, and option are returned by `code` only — resolve their
            localized labels and supported detail kinds against the [amenity
            dictionary](/api/amenities) (`GET /amenity-categories`).
          items:
            $ref: '#/components/schemas/HotelAmenityCategoryGroup'
          example:
            - category:
                code: wellness
              amenities:
                - code: aquapark
                  proximity: nearby
                  proximityMeters: 250
                  access: included
                  openingHours:
                    continuous: false
                    blocks:
                      - days:
                          - monday
                          - tuesday
                          - wednesday
                        from: '09:00'
                        to: '21:00'
        priceFrom:
          allOf:
            - $ref: '#/components/schemas/PriceFrom'
          nullable: true
          description: >-
            Cheapest available current or future room price for the room's
            standard occupancy, including an applicable public-channel
            promotion, or null when no usable price is available.
        roomTypes:
          type: array
          description: |
            **Draft:** This field and its response shape are still in progress
            and may change before they are finalized.

            Embedded only when `expand=roomTypes`;
            otherwise fetch them via `GET /room-types?hotelId={hotelId}`. Each
            item omits the nested `hotel` block (it is this hotel).
          items:
            $ref: '#/components/schemas/RoomType'
      example:
        id: 66f16191f739705faa020001
        name:
          cs-CZ: Spa Resort Pawlik
          de: Kurhotel Pawlik
          en: Spa Resort Pawlik
          ru: Spa Resort Pawlik
        shortDescription:
          cs-CZ: Lázeňský hotel s přímým vstupem do aquaparku.
          de: Kurhotel mit direktem Zugang zum Aquapark.
          en: Spa hotel with direct access to the aquapark.
          ru: Спа-отель с прямым доступом в аквапарк.
        channelContent:
          tagline:
            cs-CZ: Lázeňská péče pod jednou střechou
            de: Kurbehandlungen unter einem Dach
            en: Spa care under one roof
            ru: Санаторно-курортное лечение под одной крышей
        stars: 4
        address:
          addressLine: Národní 25
          city: Františkovy Lázně
          postalCode: 351 01
          country: cze
        email: hotel@example.com
        phoneNumber: +420 123 456 789
        url: https://hotel.example.com
        images:
          - url: https://files.example.com/hotel.jpg
            thumbnailUrl: https://files.example.com/hotel-thumbnail.webp
        accommodationRules:
          checkIn:
            from: '14:00'
            to: '20:00'
          checkOut:
            from: '07:00'
            to: '10:00'
          children:
            allowed: true
            minimumAge: 6
          pets:
            allowed: true
            minimumNights: 2
            feePerNight:
              czk: 500
              eur: 20
            conditions:
              cs-CZ: Mazlíčci jsou povoleni ve vybraných pokojích.
              de: Haustiere sind in ausgewählten Zimmern erlaubt.
              en: Pets are allowed in selected rooms.
              ru: Размещение с домашними животными разрешено в отдельных номерах.
        mealServices:
          breakfast:
            enabled: true
            servingTime:
              from: '07:00'
              to: '10:00'
            serviceMethod: buffet
            drinksIncluded: true
            drinksNote:
              cs-CZ: Nealkoholické nápoje jsou v ceně.
              de: Alkoholfreie Getränke sind inklusive.
              en: Soft drinks are included.
              ru: Безалкогольные напитки включены в стоимость.
          lunch:
            enabled: true
            servingTime:
              from: '11:30'
              to: '14:30'
            serviceMethod: buffet
            drinksIncluded: true
            drinksNote:
              cs-CZ: Voda je zahrnuta v ceně oběda.
              de: Wasser ist im Mittagessen inbegriffen.
              en: Water is included with lunch.
              ru: Вода включена в стоимость обеда.
          dinner:
            enabled: true
            servingTime:
              from: '18:00'
              to: '21:00'
            serviceMethod: served
            drinksIncluded: false
            drinksNote:
              cs-CZ: Nápoje se hradí samostatně.
              de: Getränke werden separat berechnet.
              en: Drinks are charged separately.
              ru: Напитки оплачиваются отдельно.
        indications:
          - musculoskeletal
          - cardiovascular
          - diabetes
        staffLanguages:
          - cs
          - de
          - en
        amenityCategories:
          - category:
              code: wellness
            amenities:
              - code: aquapark
                proximity: nearby
                proximityMeters: 250
                access: included
                openingHours:
                  continuous: false
                  blocks:
                    - days:
                        - monday
                        - tuesday
                        - wednesday
                        - thursday
                        - friday
                      from: '09:00'
                      to: '21:00'
              - code: sauna
                proximity: in-hotel
                proximityMeters: null
                access: included
                options:
                  - code: finnish
                  - code: steam
                openingHours:
                  continuous: false
                  blocks:
                    - days:
                        - monday
                        - tuesday
                        - wednesday
                        - thursday
                        - friday
                      from: '09:00'
                      to: '21:00'
          - category:
              code: parking
              label:
                cs-CZ: Parkování
                de: Parken
                en: Parking
                ru: Парковка
            amenities:
              - code: parking
                access: paid
                options:
                  - code: covered
                    label:
                      cs-CZ: Kryté
                      de: Überdacht
                      en: Covered
                      ru: Крытая
                  - code: guarded
                    label:
                      cs-CZ: Hlídané
                      de: Bewacht
                      en: Guarded
                      ru: Охраняемая
                note:
                  cs-CZ: Hlídané parkoviště je přímo u hotelu.
                  de: Der bewachte Parkplatz befindet sich direkt am Hotel.
                  en: Guarded parking is available next to the hotel.
                  ru: Охраняемая парковка находится рядом с отелем.
        priceFrom:
          CZK:
            perNight:
              amountMinor: 288000
              currency: CZK
              currencyExponent: 2
            perNightOriginal:
              amountMinor: 320000
              currency: CZK
              currencyExponent: 2
            minimumStay:
              amountMinor: 576000
              currency: CZK
              currencyExponent: 2
            minimumStayOriginal:
              amountMinor: 640000
              currency: CZK
              currencyExponent: 2
            guests: 2
            minimumNights: 2
          EUR:
            perNight:
              amountMinor: 11340
              currency: EUR
              currencyExponent: 2
            perNightOriginal:
              amountMinor: 12600
              currency: EUR
              currencyExponent: 2
            minimumStay:
              amountMinor: 22680
              currency: EUR
              currencyExponent: 2
            minimumStayOriginal:
              amountMinor: 25200
              currency: EUR
              currencyExponent: 2
            guests: 2
            minimumNights: 2
    HotelNameLocalizedString:
      type: object
      additionalProperties: false
      properties:
        cs-CZ:
          type: string
          minLength: 1
        de:
          type: string
          minLength: 1
        en:
          type: string
          minLength: 1
        ru:
          type: string
          minLength: 1
      description: >-
        Localized hotel name keyed by supported response locale (`cs-CZ`, `de`,
        `en`, `ru`). Missing requested translations fall back to the Czech name,
        so every returned value is a non-empty string.
      example:
        cs-CZ: Spa Resort Pawlik
        de: Kurhotel Pawlik
    LocalizedString:
      type: object
      additionalProperties: false
      properties:
        cs-CZ:
          type: string
          nullable: true
        de:
          type: string
          nullable: true
        en:
          type: string
          nullable: true
        ru:
          type: string
          nullable: true
      description: >-
        Localized field keyed by supported response locale (`cs-CZ`, `de`, `en`,
        `ru`). When `Accept-Language` is set, only the matched keys are
        returned.
      example:
        cs-CZ: Český text
        de: Deutscher Text
    HotelChannelContent:
      type: object
      required:
        - tagline
      properties:
        tagline:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: >-
            Localized tagline intended for sales channels. Each locale value is
            at most 100 characters.
    HotelAddress:
      type: object
      required:
        - addressLine
        - city
        - postalCode
        - country
      properties:
        addressLine:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        postalCode:
          type: string
          nullable: true
        country:
          type: string
          nullable: true
          pattern: ^[a-z]{3}$
          description: Lowercase ISO 3166-1 alpha-3 country code.
          example: cze
    Image:
      type: object
      required:
        - url
        - thumbnailUrl
      properties:
        url:
          type: string
          description: Original image URL.
        thumbnailUrl:
          type: string
          nullable: true
          description: Generated preview image URL, or null when unavailable.
    HotelAccommodationRules:
      type: object
      required:
        - checkIn
        - checkOut
        - children
        - pets
      properties:
        checkIn:
          $ref: '#/components/schemas/HotelTimeRange'
        checkOut:
          $ref: '#/components/schemas/HotelTimeRange'
        children:
          $ref: '#/components/schemas/HotelChildrenPolicy'
        pets:
          $ref: '#/components/schemas/HotelPetPolicy'
    HotelMealServices:
      type: object
      required:
        - breakfast
        - lunch
        - dinner
      properties:
        breakfast:
          $ref: '#/components/schemas/HotelMealService'
        lunch:
          $ref: '#/components/schemas/HotelMealService'
        dinner:
          $ref: '#/components/schemas/HotelMealService'
      example:
        breakfast:
          enabled: true
          servingTime:
            from: '07:00'
            to: '10:00'
          serviceMethod: buffet
          drinksIncluded: true
          drinksNote:
            cs-CZ: Nealkoholické nápoje jsou v ceně.
            de: Alkoholfreie Getränke sind inklusive.
            en: Soft drinks are included.
            ru: Безалкогольные напитки включены в стоимость.
        lunch:
          enabled: true
          servingTime:
            from: '11:30'
            to: '14:30'
          serviceMethod: buffet
          drinksIncluded: true
          drinksNote:
            cs-CZ: Voda je zahrnuta v ceně oběda.
            de: Wasser ist im Mittagessen inbegriffen.
            en: Water is included with lunch.
            ru: Вода включена в стоимость обеда.
        dinner:
          enabled: true
          servingTime:
            from: '18:00'
            to: '21:00'
          serviceMethod: served
          drinksIncluded: false
          drinksNote:
            cs-CZ: Nápoje se hradí samostatně.
            de: Getränke werden separat berechnet.
            en: Drinks are charged separately.
            ru: Напитки оплачиваются отдельно.
    HotelAmenityCategoryGroup:
      type: object
      required:
        - category
        - amenities
      description: >-
        One amenity category containing the values assigned to a hotel.
        Categories without assigned amenities are omitted from hotel responses.
      properties:
        category:
          $ref: '#/components/schemas/AmenityCategoryRef'
        amenities:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/AmenityValue'
    PriceFrom:
      type: object
      description: >-
        Cheapest available current or future room price for a hotel, keyed by
        currency. Prices are room totals for the room's standard occupancy and
        include an applicable public-channel promotion. They are not affected by
        query parameters. The cheapest room may differ by currency. A currency
        key is present only when the hotel has a usable price in that currency.
      properties:
        CZK:
          $ref: '#/components/schemas/PriceFromCurrency'
        EUR:
          $ref: '#/components/schemas/PriceFromCurrency'
      example:
        CZK:
          perNight:
            amountMinor: 288000
            currency: CZK
            currencyExponent: 2
          perNightOriginal:
            amountMinor: 320000
            currency: CZK
            currencyExponent: 2
          minimumStay:
            amountMinor: 576000
            currency: CZK
            currencyExponent: 2
          minimumStayOriginal:
            amountMinor: 640000
            currency: CZK
            currencyExponent: 2
          guests: 2
          minimumNights: 2
        EUR:
          perNight:
            amountMinor: 11340
            currency: EUR
            currencyExponent: 2
          perNightOriginal:
            amountMinor: 12600
            currency: EUR
            currencyExponent: 2
          minimumStay:
            amountMinor: 22680
            currency: EUR
            currencyExponent: 2
          minimumStayOriginal:
            amountMinor: 25200
            currency: EUR
            currencyExponent: 2
          guests: 2
          minimumNights: 2
    RoomType:
      type: object
      description: >-
        **Draft:** The room-type resource is still in progress. Its response
        shape may change before it is finalized.
      required:
        - id
        - hotelId
        - code
        - category
        - beds
        - facilities
        - images
        - description
      properties:
        id:
          type: string
          pattern: ^[0-9a-fA-F]{24}$
          example: 66f16191f739705faa020003
        hotelId:
          type: string
          pattern: ^[0-9a-fA-F]{24}$
          example: 66f16191f739705faa020001
        code:
          type: string
          nullable: true
          example: SUPERIOR-DBL
        category:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: Localized category name (plain text).
        beds:
          type: integer
          example: 2
        facilities:
          type: array
          items:
            type: string
          example:
            - shower
            - toilet
        images:
          type: array
          items:
            $ref: '#/components/schemas/Image'
        description:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: Localized description (Markdown).
        hotel:
          type: object
          description: Embedded only when `expand=hotel`.
          required:
            - id
            - name
            - stars
          properties:
            id:
              type: string
              pattern: ^[0-9a-fA-F]{24}$
              example: 66f16191f739705faa020001
            name:
              allOf:
                - $ref: '#/components/schemas/HotelNameLocalizedString'
              description: >-
                Localized hotel name. Falls back to the default locale (cs-CZ),
                so it is never null.
              example:
                cs-CZ: Pawlik
                de: Pawlik-Aquaforum
            stars:
              type: integer
              nullable: true
              minimum: 1
              maximum: 5
              example: 4
      example:
        id: 66f16191f739705faa020003
        hotelId: 66f16191f739705faa020001
        code: SUPERIOR-DBL
        category:
          cs-CZ: Superior dvoulůžkový pokoj
          de: Superior Doppelzimmer
          en: Superior double room
          ru: Улучшенный двухместный номер
        beds: 2
        facilities:
          - shower
          - toilet
        images:
          - url: https://cdn.example.com/rooms/superior.jpg
            thumbnailUrl: https://cdn.example.com/rooms/superior-thumbnail.jpg
        description:
          cs-CZ: Prostorný pokoj s vlastní koupelnou.
          de: Geräumiges Zimmer mit eigenem Bad.
          en: Spacious room with a private bathroom.
          ru: Просторный номер с собственной ванной комнатой.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - requestId
          properties:
            code:
              type: string
              enum:
                - invalid_request
                - missing_authentication
                - invalid_authentication
                - insufficient_scope
                - not_found
                - conflict
                - rate_limited
                - internal_error
            message:
              type: string
            details:
              type: array
              items:
                type: object
                additionalProperties: true
            requestId:
              type: string
    HotelTimeRange:
      type: object
      required:
        - from
        - to
      properties:
        from:
          type: string
          nullable: true
          pattern: ^([01]\d|2[0-3]):[0-5]\d$
          example: '14:00'
        to:
          type: string
          nullable: true
          pattern: ^([01]\d|2[0-3]):[0-5]\d$
          example: '22:00'
    HotelChildrenPolicy:
      type: object
      required:
        - allowed
        - minimumAge
      properties:
        allowed:
          type: boolean
        minimumAge:
          type: integer
          minimum: 0
          maximum: 18
          nullable: true
    HotelPetPolicy:
      type: object
      required:
        - allowed
        - minimumNights
        - feePerNight
        - conditions
      properties:
        allowed:
          type: boolean
        minimumNights:
          type: integer
          minimum: 0
          nullable: true
        feePerNight:
          $ref: '#/components/schemas/HotelPetFee'
        conditions:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: >-
            Localized supplementary conditions for guests with pets. Each locale
            value is at most 300 characters.
    HotelMealService:
      type: object
      required:
        - enabled
        - servingTime
        - serviceMethod
        - drinksIncluded
        - drinksNote
      properties:
        enabled:
          type: boolean
        servingTime:
          $ref: '#/components/schemas/HotelTimeRange'
        serviceMethod:
          type: string
          nullable: true
          enum:
            - buffet
            - served
        drinksIncluded:
          type: boolean
        drinksNote:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: >-
            Localized note about included drinks. Each locale value is at most
            200 characters.
      example:
        enabled: true
        servingTime:
          from: '07:00'
          to: '10:00'
        serviceMethod: buffet
        drinksIncluded: true
        drinksNote:
          cs-CZ: Nealkoholické nápoje jsou v ceně.
          de: Alkoholfreie Getränke sind inklusive.
          en: Soft drinks are included.
          ru: Безалкогольные напитки включены в стоимость.
    AmenityCategoryRef:
      type: object
      required:
        - code
      description: >-
        A category on a hotel response. Identified by `code`; its localized
        `label` is included only with `expand=amenityLabels`. Otherwise resolve
        the label against the [amenity dictionary](/api/amenities) (`GET
        /amenity-categories` `data[].category`).
      properties:
        code:
          type: string
          enum:
            - health
            - wellness
            - dining
            - services
            - accessibility
            - parking
            - sport
            - children
        label:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: Localized category label. Present only with `expand=amenityLabels`.
    AmenityValue:
      type: object
      required:
        - code
      description: >-
        A structured amenity assigned to a hotel. Hotel responses contain only
        assigned amenities. Apart from `code` (and `label` with
        `expand=amenityLabels`), only the fields mapped from the corresponding
        entry under the amenity dictionary response `data[].amenities[]` are
        present.
      properties:
        code:
          type: string
          description: References an `Amenity.code`.
          example: sauna
        label:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: Localized amenity label. Present only with `expand=amenityLabels`.
        proximity:
          type: string
          nullable: true
          enum:
            - in-hotel
            - connecting
            - nearby
          description: >-
            Where the amenity is located relative to the hotel. Present when
            `detailKinds` includes `proximity`; null when supported but not
            filled. `in-hotel` is inside the hotel building, `connecting` is an
            adjacent building linked by an internal passage, and `nearby` is a
            short distance away (see `proximityMeters`).
        proximityMeters:
          type: number
          minimum: 0
          maximum: 1000000
          nullable: true
          description: >-
            Present with `proximity`. Contains a distance when `proximity` is
            `nearby`; otherwise null.
        access:
          type: string
          nullable: true
          enum:
            - included
            - conditional
            - paid
          description: >-
            Present when `detailKinds` includes `access`. Null when supported
            but not filled. `included` means no additional charge, `conditional`
            means inclusion depends on stated conditions, and `paid` means an
            additional charge applies.
        options:
          type: array
          description: >-
            Amenity-specific choices selected for this hotel, by `code` only.
            Present when `detailKinds` includes `options`. Empty when the
            amenity supports choices but none are selected. Resolve labels
            against the dictionary.
          items:
            $ref: '#/components/schemas/AmenityOptionRef'
        openingHours:
          allOf:
            - $ref: '#/components/schemas/AmenityOpeningHours'
          description: >-
            Present when `detailKinds` includes `opening_hours`. When supported
            but not filled, returns `continuous: false` with an empty `blocks`
            array.
        note:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: >-
            Present when `detailKinds` includes `note`. Localized supplementary
            information for guests. Locale values are at most 200 characters and
            are null when the requested translation is not filled.
      example:
        code: aquapark
        proximity: nearby
        proximityMeters: 250
        access: included
        openingHours:
          continuous: false
          blocks:
            - days:
                - monday
                - tuesday
                - wednesday
              from: '09:00'
              to: '21:00'
    PriceFromCurrency:
      type: object
      required:
        - perNight
        - perNightOriginal
        - minimumStay
        - minimumStayOriginal
        - guests
        - minimumNights
      properties:
        perNight:
          allOf:
            - $ref: '#/components/schemas/Money'
          description: >-
            Current nightly room price for the standard occupancy, after any
            active promotion.
        perNightOriginal:
          allOf:
            - $ref: '#/components/schemas/Money'
          nullable: true
          description: >-
            Pre-discount nightly price (the original price before a promotion),
            or null when the offer has no active discount.
        minimumStay:
          allOf:
            - $ref: '#/components/schemas/Money'
          description: Current total for the required stay (`perNight` × `minimumNights`).
        minimumStayOriginal:
          allOf:
            - $ref: '#/components/schemas/Money'
          nullable: true
          description: >-
            Pre-discount total for the minimum stay, or null when there is no
            discount.
        guests:
          type: integer
          minimum: 1
          description: >-
            Number of guests this "from" price is for (the occupancy with the
            cheapest offer).
          example: 2
        minimumNights:
          type: integer
          minimum: 1
          description: Minimum number of nights the offer requires.
          example: 2
    HotelPetFee:
      type: object
      required:
        - czk
        - eur
      properties:
        czk:
          type: number
          minimum: 0
          nullable: true
          description: Per-night fee in Czech koruna major units.
        eur:
          type: number
          minimum: 0
          nullable: true
          description: Per-night fee in euro major units.
    AmenityOptionRef:
      type: object
      required:
        - code
      description: >-
        A selected amenity option on a hotel response. Identified by `code`; its
        localized `label` is included only with `expand=amenityLabels`.
        Otherwise resolve the label against the amenity's `options` in the
        [amenity dictionary](/api/amenities).
      properties:
        code:
          type: string
          description: References an option `code` from the dictionary.
          example: finnish
        label:
          allOf:
            - $ref: '#/components/schemas/LocalizedString'
          description: Localized option label. Present only with `expand=amenityLabels`.
    AmenityOpeningHours:
      type: object
      required:
        - continuous
        - blocks
      properties:
        continuous:
          type: boolean
          description: True when the amenity operates continuously (24/7).
        blocks:
          type: array
          description: Weekly opening-hour blocks. Empty when `continuous` is true.
          items:
            $ref: '#/components/schemas/AmenityOpeningHoursBlock'
    Money:
      type: object
      required:
        - amountMinor
        - currency
        - currencyExponent
      properties:
        amountMinor:
          type: integer
          description: Amount in the smallest currency unit.
          example: 180000
        currency:
          type: string
          enum:
            - CZK
            - EUR
        currencyExponent:
          type: integer
          enum:
            - 2
          description: Decimal exponent for the currency.
    AmenityOpeningHoursBlock:
      type: object
      required:
        - days
        - from
        - to
      properties:
        days:
          type: array
          minItems: 1
          items:
            type: string
            enum:
              - monday
              - tuesday
              - wednesday
              - thursday
              - friday
              - saturday
              - sunday
        from:
          type: string
          pattern: ^([01]\d|2[0-3]):[0-5]\d$
          example: '07:00'
        to:
          type: string
          pattern: ^([01]\d|2[0-3]):[0-5]\d$
          example: '15:00'
  responses:
    BadRequest:
      description: Invalid request.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Invalid API key.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: Resource not found.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalServerError:
      description: Unexpected server error.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    spaPortalPublicKey:
      type: apiKey
      in: header
      name: X-SpaPortal-Public-Key
      description: >-
        See [Authentication](/api/authentication) for how to obtain and send
        your public key.

````