> ## 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 hotels

> Returns hotels matching the supplied filters.

`lowest_price` is the cheapest matching room price per night per guest. When a two-bed room is priced per room, the API returns the per-guest display price.

`lowest_price.<lang>.amount_per_night` includes any active discount promotions. `original_amount_per_night` is the price before any discount — equal to `amount_per_night` when no promotion applies.

`stars`, `image`, and `thumbnail` can be `null`. Set `include_room_types=false` when you do not need nested room type data.




## OpenAPI

````yaml /api/v1/openapi.yaml get /hotels
openapi: 3.0.3
info:
  title: SpaPortal API v1
  version: '1.0'
  description: Public API for booking clients that integrate with SpaPortal.
servers:
  - url: https://spaportal.cz/api/v1
    description: Production
security:
  - bearerAuth: []
  - accessTokenQuery: []
tags:
  - name: System
  - name: Catalog
  - name: Availability
  - name: Pricing
  - name: Booking
paths:
  /hotels:
    get:
      tags:
        - Catalog
      summary: Get hotels
      description: >
        Returns hotels matching the supplied filters.


        `lowest_price` is the cheapest matching room price per night per guest.
        When a two-bed room is priced per room, the API returns the per-guest
        display price.


        `lowest_price.<lang>.amount_per_night` includes any active discount
        promotions. `original_amount_per_night` is the price before any discount
        — equal to `amount_per_night` when no promotion applies.


        `stars`, `image`, and `thumbnail` can be `null`. Set
        `include_room_types=false` when you do not need nested room type data.
      operationId: getHotels
      parameters:
        - $ref: '#/components/parameters/AcceptLanguage'
        - $ref: '#/components/parameters/Max'
        - $ref: '#/components/parameters/Offset'
        - name: destination_id
          in: query
          schema:
            type: integer
          description: Filter by destination ID.
        - name: visit_type_id
          in: query
          schema:
            type: integer
          description: Filter by visit type ID.
        - name: number_of_beds
          in: query
          schema:
            type: integer
            minimum: 1
          description: Filter by room occupancy.
        - $ref: '#/components/parameters/DateFrom'
        - $ref: '#/components/parameters/DateTo'
        - name: include_room_types
          in: query
          schema:
            type: boolean
            default: true
          description: Include room types in the hotel response.
      responses:
        '200':
          description: Hotels matching the filters.
          headers:
            X-Total-Count:
              $ref: '#/components/headers/XTotalCount'
            Content-Language:
              $ref: '#/components/headers/ContentLanguage'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Hotel'
              examples:
                default:
                  $ref: '#/components/examples/HotelsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
components:
  parameters:
    AcceptLanguage:
      name: Accept-Language
      in: header
      schema:
        type: string
        example: cs_CZ,de
      description: >-
        Comma-separated list of languages to include. See
        [Localization](/api/v1/localization) for details.
    Max:
      name: max
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 10
      description: Number of records to return.
    Offset:
      name: offset
      in: query
      schema:
        type: integer
        minimum: 0
        default: 0
      description: Number of records to skip.
    DateFrom:
      name: date_from
      in: query
      schema:
        type: string
        format: date
      description: Start date in `YYYY-MM-DD` format.
    DateTo:
      name: date_to
      in: query
      schema:
        type: string
        format: date
      description: End date in `YYYY-MM-DD` format.
  headers:
    XTotalCount:
      description: Total number of matching records.
      schema:
        type: integer
    ContentLanguage:
      description: Languages included in the response.
      schema:
        type: string
        example: cs_CZ,de
  schemas:
    Hotel:
      type: object
      properties:
        _id:
          $ref: '#/components/schemas/ObjectId'
        id:
          type: integer
        name:
          type: string
        stars:
          type: integer
          nullable: true
        address:
          $ref: '#/components/schemas/Address'
        phone_number:
          type: string
        email:
          $ref: '#/components/schemas/LocalizedString'
        description:
          $ref: '#/components/schemas/LocalizedString'
        equipment:
          $ref: '#/components/schemas/LocalizedString'
        services:
          $ref: '#/components/schemas/LocalizedString'
        lowest_price:
          $ref: '#/components/schemas/LowestPriceByLanguage'
        commercial_slogan:
          $ref: '#/components/schemas/LocalizedString'
        image:
          type: string
          nullable: true
        thumbnail:
          type: string
          nullable: true
        booking_url:
          $ref: '#/components/schemas/LocalizedString'
        destination:
          $ref: '#/components/schemas/Destination'
        roomTypes:
          type: array
          items:
            $ref: '#/components/schemas/RoomType'
    ObjectId:
      type: string
      pattern: ^[0-9a-fA-F]{24}$
      description: Object id (24-character hex string) for the same entity.
      example: 66f16191f739705faa020001
    Address:
      type: object
      properties:
        address_line:
          type: string
          nullable: true
        city:
          type: string
          nullable: true
        postal_code:
          type: string
          nullable: true
        country_code:
          type: string
          nullable: true
    LocalizedString:
      type: object
      additionalProperties:
        type: string
        nullable: true
      example:
        cs_CZ: Frantiskovy Lazne
        de: Franzensbad
    LowestPriceByLanguage:
      type: object
      additionalProperties:
        $ref: '#/components/schemas/LowestPriceAmount'
    Destination:
      type: object
      required:
        - id
        - name
      properties:
        _id:
          $ref: '#/components/schemas/ObjectId'
        id:
          type: integer
        name:
          $ref: '#/components/schemas/LocalizedString'
    RoomType:
      type: object
      properties:
        _id:
          $ref: '#/components/schemas/ObjectId'
        id:
          type: integer
        category:
          $ref: '#/components/schemas/LocalizedString'
        facilities:
          type: array
          items:
            type: string
        beds:
          type: integer
        image:
          type: string
          nullable: true
        thumbnail:
          type: string
          nullable: true
        booking_url:
          $ref: '#/components/schemas/LocalizedString'
        description:
          $ref: '#/components/schemas/LocalizedString'
        lowest_price:
          $ref: '#/components/schemas/LowestPriceByLanguage'
        hotel:
          type: object
          description: Included on price list room type items.
          properties:
            _id:
              $ref: '#/components/schemas/ObjectId'
            id:
              type: integer
            name:
              type: string
            stars:
              type: integer
              nullable: true
    ErrorResponse:
      type: object
      required:
        - success
        - message
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
    ValidationErrorResponse:
      type: object
      required:
        - success
        - message
        - errors
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
        errors:
          type: array
          items:
            type: object
            additionalProperties: true
    LowestPriceAmount:
      type: object
      properties:
        amount_per_night:
          type: number
          nullable: true
          description: >-
            Lowest per-night, per-guest price, including any active discount
            promotions.
        original_amount_per_night:
          type: number
          nullable: true
          description: >-
            Per-night price before any discount. Equals `amount_per_night` when
            no promotion applies; higher when a promotion is active.
        currency:
          type: string
          enum:
            - CZK
            - EUR
  examples:
    HotelsResponse:
      summary: Hotel list
      value:
        - _id: 66f16191f739705faa020002
          id: 1
          name: Pawlik
          stars: 4
          phone_number: +420 354 201 111
          email:
            cs_CZ: info@frantiskovylazne.cz
            de: info@franzensbad.cz
          description:
            cs_CZ: Kralovska vila mesta Frantiskovy Lazne uprostred lazenskeho parku.
            de: Die Koenigsvilla Franzensbads im Zentrum der Stadt.
          equipment:
            cs_CZ: Hotel je vybaven moderni saunou.
            de: Hotel hat eine Sauna.
          services:
            cs_CZ: Kuryri sluzby v cene pobytu.
            de: DHL included.
          lowest_price:
            cs_CZ:
              amount_per_night: 1024.5
              original_amount_per_night: 1205.29
              currency: CZK
            de:
              amount_per_night: 40
              original_amount_per_night: 47.06
              currency: EUR
          commercial_slogan:
            cs_CZ: Buy it or leave it.
            de: ''
          image: >-
            https://spaportal-files.s3.eu-central-1.amazonaws.com/production/hotels/example/pawlik.jpg
          thumbnail: >-
            https://spaportal-files.s3.eu-central-1.amazonaws.com/production/thumbnails/hotels/example/pawlik.webp
          booking_url:
            cs_CZ: https://rezervace.frantiskovylazne.cz?hotel=Pawlik
            de: https://reservierung.franzensbad.cz?hotel=Pawlik
          destination:
            _id: 66f16191f739705faa020001
            id: 1
            name:
              cs_CZ: Frantiskovy Lazne
              de: Franzensbad
          address:
            address_line: Dr. Pohoreckeho 22
            city: Frantiskovy Lazne
            postal_code: 351 01
            country_code: CZE
          roomTypes:
            - _id: 66f16191f739705faa020003
              id: 1
              category:
                cs_CZ: Prezidentske apartma
                de: App. Aquaforum
              facilities:
                - shower
                - toilet
                - bath
              beds: 2
              image: >-
                https://spaportal-files.s3.eu-central-1.amazonaws.com/production/rooms/example/room.jpg
              thumbnail: >-
                https://spaportal-files.s3.eu-central-1.amazonaws.com/production/thumbnails/rooms/example/room.webp
              booking_url:
                cs_CZ: >-
                  https://rezervace.frantiskovylazne.cz?hotel=Pawlik&roomType=APPARTEMENT
                de: >-
                  https://reservierung.franzensbad.cz?hotel=Pawlik&roomType=APPARTEMENT
              description:
                cs_CZ: Pokoj s koupelnou, sprchou, WC a fenem.
                de: Luxurioeses Appartement.
              lowest_price:
                cs_CZ:
                  amount_per_night: 1024.5
                  original_amount_per_night: 1205.29
                  currency: CZK
                de:
                  amount_per_night: 40
                  original_amount_per_night: 47.06
                  currency: EUR
  responses:
    BadRequest:
      description: Invalid request.
      content:
        application/json:
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorResponse'
              - $ref: '#/components/schemas/ValidationErrorResponse'
    Unauthorized:
      description: Invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    UnprocessableEntity:
      description: Resource exists but cannot be used for this request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        See [Authentication](/api/v1/authentication) for how to obtain and send
        your API key.
    accessTokenQuery:
      type: apiKey
      in: query
      name: access_token
      description: >-
        See [Authentication](/api/v1/authentication) for how to obtain and send
        your API key.

````