openapi: 3.0.0
info:
  title: Skyscanner Hotels API
  description: |
    Search Skyscanner hotels for a place or a hotel and dates.

    Properties come with their stars, rating, address, photos and price per night and in total, with and without taxes, and every partner's rate with its room, meals, payment terms and booking link. Prices cover every room searched. A property's prices are those of the rate Skyscanner lists as its cheapest by the price it displays, which includes fees and leaves taxes out, so one of the property's own rates can cost less with all taxes. A discounted rate also carries its prices before the discount. Properties come in Skyscanner's recommended order, as on its first page of results. Prices are in US dollars.

    A property's `entity_id` can be passed back as `entity_id` to search around that property.
  version: 1.0.0
servers:
  - url: https://www.searchapi.io/api/v1
paths:
  /search:
    get:
      summary: Skyscanner Hotels Search
      security:
        - ApiKeyAuth: []
        - ApiKeyQuery: []
      parameters:
        - name: engine
          in: query
          required: true
          description: 'Search engine. Must be set to: `skyscanner_hotels`'
          schema:
            type: string
            enum: ["skyscanner_hotels"]
        - name: q
          in: query
          required: false
          description: Place or hotel to search, such as `London` or `Hilton London Metropole`. English names work best, for example `Athens` rather than `Αθήνα`. The search runs on the first place Skyscanner suggests for it. Up to 256 characters, fewer in non-Latin scripts. Cannot contain `/`, `%`, `\` or control characters such as line breaks. Required unless `entity_id` is set.
          schema:
            type: string
            maxLength: 256
            pattern: '^(?!\.+$)[^/%\\\x00-\x1F\x7F]*$'
        - name: entity_id
          in: query
          required: false
          description: Skyscanner id of the place or hotel to search, such as `27544008` for London. A hotel searched comes first, without prices when it has no rate for the dates. Cannot be used with `q`.
          schema:
            type: string
            pattern: '^\d{1,12}$'
        - name: check_in_date
          in: query
          required: true
          description: Check-in date in YYYY-MM-DD format, from today up to 730 days ahead.
          schema:
            type: string
            format: date
        - name: check_out_date
          in: query
          required: true
          description: Check-out date in YYYY-MM-DD format, after `check_in_date` and at most 90 nights later.
          schema:
            type: string
            format: date
        - name: adults
          in: query
          required: false
          description: Number of adults, from 1 to 10. A search without it is for 2 adults.
          schema:
            type: integer
            minimum: 1
            maximum: 10
        - name: rooms
          in: query
          required: false
          description: Number of rooms, from 1 to 10 and no more than `adults`. A search without it is for 1 room.
          schema:
            type: integer
            minimum: 1
            maximum: 10
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          description: Validation Error. There is an issue with query parameters, such as missing required parameters or invalid values.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication Error. The API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate Limit Exceeded. The number of allowed requests has been exceeded. Consider upgrading your plan or waiting for the limit to reset.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Server Error. Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Timeout. We could not retrieve results in 90 seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Use Bearer authentication. Format: "Bearer YOUR_API_KEY"'
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key
      description: Pass API key as query parameter
  schemas:
    SearchResponse:
      type: object
      properties:
        search_metadata:
          $ref: '#/components/schemas/SearchMetadata'
        search_parameters:
          $ref: '#/components/schemas/SearchParameters'
        search_information:
          $ref: '#/components/schemas/SearchInformation'
        properties:
          type: array
          items:
            $ref: '#/components/schemas/Property'
          description: "Properties for the search, in Skyscanner's recommended order"
        error:
          type: string
          description: "Error message describing what went wrong"
    SearchMetadata:
      type: object
      required: [id, status, created_at]
      properties:
        id:
          type: string
          description: "Unique identifier for the search request"
        status:
          type: string
          description: "Status of the search request"
        created_at:
          type: string
          format: date-time
          description: "Timestamp when the search was created"
        request_time_taken:
          type: number
          description: "Time taken to make the request in seconds"
        parsing_time_taken:
          type: number
          description: "Time taken to parse the results in seconds"
        total_time_taken:
          type: number
          description: "Total time taken for the search in seconds"
        request_url:
          type: string
          description: "Skyscanner results page for this search"
        html_url:
          type: string
          description: "URL to view the raw results"
        json_url:
          type: string
          description: "URL to view JSON results"
    SearchParameters:
      type: object
      properties:
        engine:
          type: string
          description: "Search engine used"
        q:
          type: string
          description: "Place or hotel searched"
        entity_id:
          type: string
          description: "Skyscanner id of the place or hotel searched"
        check_in_date:
          type: string
          description: "Check-in date searched"
        check_out_date:
          type: string
          description: "Check-out date searched"
        adults:
          type: string
          description: "Number of adults searched"
        rooms:
          type: string
          description: "Number of rooms searched"
    SearchInformation:
      type: object
      required: [total_results, destination]
      properties:
        total_results:
          type: integer
          description: "Number of properties Skyscanner found for the search"
        destination:
          $ref: '#/components/schemas/Destination'
        currency:
          type: string
          description: "Currency of every price, such as USD"
    Destination:
      type: object
      required: [entity_id, type, name, gps_coordinates]
      properties:
        entity_id:
          type: string
          description: "Skyscanner id of the place searched"
        type:
          type: string
          description: "Kind of place searched, such as city, district or hotel"
        name:
          type: string
          description: "Name of the place searched"
        gps_coordinates:
          $ref: '#/components/schemas/GpsCoordinates'
    GpsCoordinates:
      type: object
      required: [latitude, longitude]
      properties:
        latitude:
          type: number
          description: "Latitude"
        longitude:
          type: number
          description: "Longitude"
    Property:
      type: object
      required: [position, entity_id, title, type, accommodation_type, address, gps_coordinates]
      properties:
        position:
          type: integer
          description: "Position of the property in Skyscanner's order"
        entity_id:
          type: string
          description: "Skyscanner id of the property, usable as entity_id"
        title:
          type: string
          description: "Name of the property"
        link:
          type: string
          description: "Skyscanner page of the property"
        type:
          type: string
          enum: ["hotel", "vacation_rental"]
          description: "Kind of property"
        accommodation_type:
          type: string
          description: "Skyscanner's category for the property, such as hotels or homes_and_apartments"
        hotel_class:
          type: string
          description: "Star rating, such as 4-star hotel"
        extracted_hotel_class:
          type: integer
          description: "Number of stars"
        rating:
          type: number
          description: "Guest rating, out of 5"
        max_rating:
          type: integer
          description: "Highest possible rating"
        rating_word:
          type: string
          description: "Skyscanner's word for the rating, such as Very Good"
        reviews:
          type: integer
          description: "Number of reviews behind the rating"
        address:
          type: string
          description: "Address of the property"
        neighborhood:
          type: string
          description: "District the property is in"
        gps_coordinates:
          $ref: '#/components/schemas/GpsCoordinates'
        images:
          type: array
          items:
            $ref: '#/components/schemas/Image'
          description: "Photos of the property"
        price_per_night:
          $ref: '#/components/schemas/Price'
        total_price:
          $ref: '#/components/schemas/Price'
        original_price_per_night:
          $ref: '#/components/schemas/Price'
        original_total_price:
          $ref: '#/components/schemas/Price'
        offers:
          type: array
          items:
            $ref: '#/components/schemas/Offer'
          description: "Every partner's rate for the property"
    Image:
      type: object
      required: [original]
      properties:
        original:
          type: string
          description: "URL of the full-size photo"
    Price:
      type: object
      required: [extracted_price, extracted_price_before_taxes]
      description: "A price for every room searched, with and without taxes and fees"
      properties:
        extracted_price:
          type: number
          description: "Price with all taxes and fees"
        extracted_price_before_taxes:
          type: number
          description: "Price before taxes and fees"
    Offer:
      type: object
      required: [source, room_type, price_per_night, total_price, tracking_link]
      properties:
        source:
          type: string
          description: "Partner that sells the rate, such as Booking.com"
        logo:
          type: string
          description: "Logo of the partner"
        is_official:
          type: boolean
          description: "Whether Skyscanner marks the partner as the property's official website"
        room_name:
          type: string
          description: "Room as the partner names it"
        room_type:
          type: string
          description: "Kind of room, such as double_room or suite_room"
        price_per_night:
          $ref: '#/components/schemas/Price'
        total_price:
          $ref: '#/components/schemas/Price'
        original_price_per_night:
          $ref: '#/components/schemas/Price'
        original_total_price:
          $ref: '#/components/schemas/Price'
        has_free_cancellation:
          type: boolean
          description: "Whether the rate can be cancelled for free"
        meal_plan:
          type: string
          description: "Meals in the rate, such as breakfast_included or meals_not_included"
        payment_type:
          type: string
          description: "When the stay is paid, pay_now or pay_on_arrival"
        tracking_link:
          type: string
          description: "Skyscanner link that sends the traveller on to book with the partner"
    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: string
          description: Error message describing what went wrong
