openapi: 3.0.0
info:
  title: Airbnb Experiences Search API
  description: |
    Search for Airbnb experiences with filters including location, dates, pricing, guest counts, experience types, time of day, duration, and language.

    Returns detailed experience information including pricing, ratings, duration, categories, badges, and images.
  version: 1.0.0
servers:
  - url: https://www.searchapi.io/api/v1
paths:
  /search:
    get:
      summary: Airbnb Experiences Search
      security:
        - ApiKeyAuth: []
        - ApiKeyQuery: []
      parameters:
        - name: engine
          in: query
          required: true
          description: Search engine identifier
          schema:
            type: string
            enum: ["airbnb_experiences"]
            default: "airbnb_experiences"
        - name: q
          in: query
          required: true
          description: 'Search query for location (e.g., "New York", "Tokyo").'
          schema:
            type: string
        - name: check_in_date
          in: query
          required: false
          description: 'Check-in date in YYYY-MM-DD format. Must be a future date.'
          schema:
            type: string
            pattern: '^\d{4}-\d{2}-\d{2}$'
        - name: check_out_date
          in: query
          required: false
          description: Check-out date in YYYY-MM-DD format. Must be after check-in date. Requires check_in_date to be set.
          schema:
            type: string
            pattern: '^\d{4}-\d{2}-\d{2}$'
        - name: adults
          in: query
          required: false
          description: Number of adult guests
          schema:
            type: integer
            minimum: 0
            maximum: 16
        - name: children
          in: query
          required: false
          description: Number of children guests
          schema:
            type: integer
            minimum: 0
            maximum: 15
        - name: infants
          in: query
          required: false
          description: Number of infant guests
          schema:
            type: integer
            minimum: 0
            maximum: 5
        - name: price_min
          in: query
          required: false
          description: Minimum price filter for experiences
          schema:
            type: number
            format: float
            minimum: 0
        - name: price_max
          in: query
          required: false
          description: Maximum price filter for experiences
          schema:
            type: number
            format: float
            minimum: 0
        - name: experience_type
          in: query
          required: false
          description: 'Comma-separated list of experience type keys to filter by (e.g., "cooking", "outdoors,wellness"). Valid values: `architecture`, `art_workshops`, `beauty`, `cooking`, `cultural_tours`, `dining`, `flying`, `food_tours`, `galleries`, `landmarks`, `museums`, `outdoors`, `performances`, `shopping_and_fashion`, `tastings`, `water_sports`, `wellness`, `wildlife`, `workouts`.'
          schema:
            type: string
        - name: traveler_type
          in: query
          required: false
          description: 'Filter experiences by traveler type. Comma-separated list of tags. Valid values: `kids`, `big_groups`, `solo`, `date_night`.'
          schema:
            type: string
        - name: time_of_day
          in: query
          required: false
          description: 'Comma-separated list of time of day filters (e.g., "morning", "morning,afternoon"). Valid values: `morning`, `afternoon`, `evening`.'
          schema:
            type: string
        - name: min_duration
          in: query
          required: false
          description: Minimum experience duration in minutes
          schema:
            type: integer
            minimum: 0
        - name: max_duration
          in: query
          required: false
          description: Maximum experience duration in minutes
          schema:
            type: integer
            minimum: 0
        - name: language_offered
          in: query
          required: false
          description: 'Comma-separated list of languages the experience is offered in (e.g., "english", "english,spanish"). Valid values: `english`, `french`, `german`, `japanese`, `italian`, `russian`, `spanish`, `chinese`, `arabic`, `hindi`, `portuguese`, `turkish`, `indonesian`, `dutch`, `korean`, `bengali`, `thai`, `punjabi`, `greek`, `sign_language`, `hebrew`, `polish`, `malay`, `tagalog`, `danish`, `swedish`, `norwegian`, `finnish`, `czech`, `hungarian`, `ukrainian`.'
          schema:
            type: string
        - name: currency
          in: query
          required: false
          description: Currency code for pricing. When omitted, Airbnb returns prices in the default currency for the selected `airbnb_domain`.
          schema:
            type: string
            enum: ["USD", "AUD", "BRL", "BGN", "BAM", "CAD", "CLP", "CNY", "COP", "CRC", "CZK", "DKK", "EGP", "AED", "EUR", "GHS", "GTQ", "HNL", "HKD", "HUF", "INR", "IDR", "ILS", "JPY", "KZT", "KES", "MYR", "MXN", "MAD", "TWD", "NZD", "NOK", "PEN", "PHP", "PLN", "GBP", "QAR", "RON", "RUB", "SAR", "SGD", "ZAR", "KRW", "SEK", "CHF", "THB", "TRY", "UGX", "UAH", "UYU", "VND"]
        - name: airbnb_domain
          in: query
          required: false
          description: Airbnb domain to search (affects language and regional results)
          schema:
            type: string
            enum: ["airbnb.com", "sw.airbnb.com", "sq.airbnb.com", "ar.airbnb.com", "airbnb.com.ar", "airbnb.am", "airbnb.com.au", "airbnb.at", "airbnb.az", "airbnb.be", "fr.airbnb.be", "airbnb.com.bz", "airbnb.com.bo", "airbnb.ba", "airbnb.com.br", "bg.airbnb.com", "airbnb.ca", "fr.airbnb.ca", "airbnb.cl", "airbnb.cn", "airbnb.com.co", "airbnb.co.cr", "hr.airbnb.com", "airbnb.cz", "airbnb.dk", "airbnb.com.ec", "airbnb.com.sv", "airbnb.com.ee", "airbnb.fi", "airbnb.fr", "ka.airbnb.com", "airbnb.de", "airbnb.gr", "airbnb.com.gt", "airbnb.gy", "airbnb.com.hn", "airbnb.com.hk", "airbnb.hu", "airbnb.is", "airbnb.co.in", "hi.airbnb.co.in", "kn.airbnb.co.in", "mr.airbnb.co.in", "airbnb.co.id", "airbnb.ie", "ga.airbnb.ie", "he.airbnb.com", "airbnb.it", "airbnb.jp", "airbnb.lv", "airbnb.lt", "airbnb.lu", "de.airbnb.lu", "airbnb.com.my", "mt.airbnb.com.mt", "airbnb.mx", "airbnb.me", "airbnb.nl", "airbnb.co.nz", "airbnb.com.ni", "mk.airbnb.com", "airbnb.no", "airbnb.com.pa", "airbnb.com.py", "airbnb.com.pe", "airbnb.com.ph", "airbnb.pl", "airbnb.pt", "airbnb.com.ro", "airbnb.ru", "airbnb.rs", "airbnb.com.sg", "sk.airbnb.com", "airbnb.si", "xh.airbnb.co.za", "zu.airbnb.co.za", "airbnb.co.kr", "airbnb.cat", "airbnb.es", "airbnb.se", "fr.airbnb.ch", "airbnb.ch", "it.airbnb.ch", "airbnb.com.tw", "th.airbnb.com", "airbnb.com.tr", "airbnb.com.ua", "airbnb.ae", "airbnb.co.uk", "zh.airbnb.com", "zh-t.airbnb.com", "es.airbnb.com", "airbnb.co.ve", "airbnb.com.vn"]
            default: "airbnb.com"
        - name: next_page_token
          in: query
          required: false
          description: Fetches the next batch of experiences that Airbnb lazy-loads on scroll. Pass the `next_page_token` from the previous response. `sections` are only returned on the first page.
          schema:
            type: string
      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'
        experiences:
          type: array
          description: Primary list of experience results. Paginates via `next_page_token`.
          items:
            $ref: '#/components/schemas/Experience'
        sections:
          type: array
          description: Curated thematic sections (e.g., "Get outside", "The best in local flavours", "Local culture and history"). Only present on the first page; subsequent paginated requests return experiences without sections.
          items:
            $ref: '#/components/schemas/Section'
        pagination:
          $ref: '#/components/schemas/Pagination'
        error:
          type: string
          description: Error message when no results are found

    SearchMetadata:
      type: object
      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: Airbnb URL for this search
        html_url:
          type: string
          description: URL to view HTML results
        json_url:
          type: string
          description: URL to view JSON results

    SearchParameters:
      type: object
      properties:
        engine:
          type: string
          description: Search engine used
        airbnb_domain:
          type: string
          description: Airbnb domain searched
        currency:
          type: string
          description: Currency code for pricing
        q:
          type: string
          description: Search query location
        check_in_date:
          type: string
          description: Check-in date
        check_out_date:
          type: string
          description: Check-out date
        adults:
          type: integer
          description: Number of adults
        children:
          type: integer
          description: Number of children
        infants:
          type: integer
          description: Number of infants
        price_min:
          type: number
          format: float
          description: Minimum price filter
        price_max:
          type: number
          format: float
          description: Maximum price filter
        experience_type:
          type: string
          description: Experience type filter
        traveler_type:
          type: string
          description: Traveler type filter
        time_of_day:
          type: string
          description: Time of day filter
        min_duration:
          type: integer
          description: Minimum duration filter in minutes
        max_duration:
          type: integer
          description: Maximum duration filter in minutes
        language_offered:
          type: string
          description: Language offered filter
        next_page_token:
          type: string
          description: Pagination token

    SearchInformation:
      type: object
      properties:
        query_displayed:
          type: string
          description: Location query as displayed by Airbnb
        results:
          type: string
          description: Results summary text
        time_period:
          type: string
          description: Time period display text
        check_in_date:
          type: string
          description: Check-in date from search
        check_out_date:
          type: string
          description: Check-out date from search
        guests:
          type: string
          description: Guest count display text
        adults:
          type: integer
          description: Number of adult guests
        children:
          type: integer
          description: Number of child guests
        infants:
          type: integer
          description: Number of infant guests

    Experience:
      type: object
      required: [position, id, title, link, price, images]
      properties:
        position:
          type: integer
          description: Position in search results
        id:
          type: integer
          description: Unique experience listing ID
        title:
          type: string
          description: Experience title
        description:
          type: string
          description: Experience description or byline
        link:
          type: string
          description: URL to experience details page
        rating:
          type: number
          format: float
          description: Average rating score
        reviews:
          type: integer
          description: Number of reviews
        duration:
          type: string
          description: 'Formatted duration (e.g., "2h", "1h 30m", "45m")'
        category:
          type: string
          description: Primary experience category
        price:
          $ref: '#/components/schemas/Price'
        badges:
          type: array
          description: Experience badges (e.g., Bestseller, Great value)
          items:
            type: string
        images:
          type: array
          description: Experience image URLs
          items:
            type: string

    Price:
      type: object
      properties:
        price_label:
          type: string
          description: Accessibility label for the full price display
        price:
          type: string
          description: Discounted or current price display text
        extracted_price:
          type: number
          format: float
          description: Numeric current price value
        qualifier:
          type: string
          description: 'Price qualifier text (e.g., "/ person")'
        original_price:
          type: string
          description: Original price before discount
        extracted_original_price:
          type: number
          format: float
          description: Numeric original price value

    Section:
      type: object
      required: [title, experiences]
      properties:
        title:
          type: string
          description: Section heading (e.g., "Get outside", "The best in local flavours", "Local culture and history")
        experiences:
          type: array
          description: Experiences grouped under this section
          items:
            $ref: '#/components/schemas/Experience'

    Pagination:
      type: object
      required: [next_page_token]
      properties:
        next_page_token:
          type: string
          description: Pass this back as `next_page_token` to fetch the next batch of lazy-loaded experiences.

    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: string
          description: Error message describing what went wrong
