# ScraperCompany public OpenAPI spec. GENERATED by scripts/gen_public_openapi.py from the backend's app.openapi() export.
# Do not edit by hand: change the generator and re-run it.
openapi: 3.1.0
info:
  title: ScraperCompany Hotel Rate API
  version: 1.0.0
  description: |
    Live hotel rates from Google Hotels, the major OTAs (Booking.com, Hotels.com, Expedia, Agoda, Tripadvisor, Hostelworld), vacation rentals (Airbnb, Vrbo), Google Flights and hotels' own official booking engines, normalized into consistent JSON with per-rate provenance. The same data is available to AI agents through the MCP server at `https://api.scrapercompany.com/mcp`.

    ## Base URL

    All requests go to `https://api.scrapercompany.com`. Every path in this reference is relative to it, for example `POST https://api.scrapercompany.com/v1/calendar`.

    ## Authentication

    Send your API key in the `x-api-key` header:

    ```bash
    curl https://api.scrapercompany.com/v1/markets \
      -H "x-api-key: sk_your_key"
    ```

    The API also accepts `Authorization: Bearer <key>` and an `api_key` query parameter (handy for SearchAPI-style GET integrations). Prefer the header: query strings tend to end up in logs and browser history.

    Keys look like `sk_` followed by random characters. There is a single key type, with no separate live and test keys. During the beta, keys are issued by the ScraperCompany team: [contact sales or support](https://scrapercompany.com/contact) to get one. Keys cannot yet be created or rotated from the dashboard.

    ## Errors

    Errors return a non-2xx status and a JSON body with a `detail` field:

    ```json
    {"detail": "missing or invalid API key"}
    ```

    Request-validation failures (`422`) usually return `detail` as a list of problems, each with `loc`, `msg` and `type`; a few semantic checks return a plain string instead. Status codes used: `400` bad request, `401` missing or invalid key, `402` insufficient credits (only once credit enforcement is on), `404` not found, `409` conflict, `422` validation error, `429` rate or concurrency limit exceeded, `502` the upstream source failed or blocked the request, `503` temporarily unavailable. Responses carry an `x-request-id` header (`req_...`); for calls recorded in your request history it is also the `id` used by `GET /v1/requests/{request_id}`, so quote it when contacting support.

    ## Rate limits

    Each key has a requests-per-minute limit, enforced over a sliding 60-second window. The default is 60 requests per minute; your key's limit is returned as `key.rate_limit_per_min` by `GET /v1/usage`. Going over it returns `429` with `{"detail": "rate limit 60/min exceeded"}`. No rate-limit or `Retry-After` headers are sent, so back off (for example exponentially) and retry. Once credit enforcement is switched on, a `429` can also mean the plan's concurrent-request limit was reached (`concurrency limit N reached for the <plan> plan`).

    ## Credits

    Credit metering is in beta and paid plans are not on sale yet. Metering runs in *shadow* mode: every request is metered and recorded, and nothing is blocked. Each operation states its cost in its description ("Credits: N") and in the `x-credits` extension. Failed, blocked and empty results are free.

    Metered responses carry `x-credits-charged` (credits charged for the request) and `x-credits-remaining` (credits left on the account). `GET /v1/billing` returns your plan, balance and period, `GET /v1/billing/ledger` every credit movement, and `GET /v1/billing/plans` the plan catalogue and full cost table. Once enforcement is on, a request that needs more credits than are available gets `402`.

    | Operation | Credits |
    |---|---|
    | Property search / resolve: `POST /v1/search`, `POST /v1/ota/{booking,hotels,agoda,expedia,vrbo}/search` | 1 |
    | Google Hotels destination search: `POST /v1/hotels/search`, `POST /v1/serp/google_hotels` | 3 per page (an empty page is free) |
    | Google Hotels calendar: `POST /v1/calendar`, `POST /v1/serp/google_hotels_calendar` (calendar adds 3 per night with `basis: mainstream` and 3 per `verify_sources` spot-check) | 5 |
    | Calendar batch: `POST /v1/jobs` | each succeeded item priced like `POST /v1/calendar` (5 by default) |
    | Google property, offers, rooms and stay: `POST /v1/offers`, `POST /v1/rooms`, `POST /v1/stay`, `POST /v1/serp/google_hotels_property` | 3 |
    | Single OTA source: Booking.com, Hotels.com, Expedia, Vrbo, Agoda, Tripadvisor, Hostelworld, Airbnb (`POST /v1/serp/airbnb`, `GET /api/v1/search`) | 8 |
    | Airbnb priced calendar: `POST /v1/airbnb/calendar`, `POST /v1/serp/airbnb_property_availability_calendar` | 8, plus 1 per night actually priced (at most 92) |
    | Official hotel site: `POST /v1/official` | 4 |
    | OTA compare: `POST /v1/ota/compare` | 20 |
    | Google Flights search, return leg and booking options: `POST /v1/serp/google_flights`, `POST /v1/serp/google_flights_return`, `POST /v1/serp/google_flights_booking` | 3 |
    | Google Flights location search: `POST /v1/serp/google_flights_location_search` | 1 |
    | Google Flights calendar: `POST /v1/serp/google_flights_calendar` | 5 |
    | Metadata, billing and stored reads: usage, request history, billing, markets, OTA sources, official engines, storage status, stored rates, job submission and polling | 0 |

    ## Coverage

    - **Google Hotels calendar**: `POST /v1/calendar` returns up to 330 nights per call (90 by default).
    - **Official hotel sites**: `POST /v1/official` covers 31 official booking engines, detected automatically from the hotel's website.
    - **SearchAPI compatibility**: `/v1/serp/*` and `GET /api/v1/search` accept SearchAPI's parameter names and return its response shapes, so existing integrations only change their base URL.
    - **MCP server**: `POST /mcp` exposes 18 read-only tools (hotel rates, flights, vacation rentals, credit balance) to Model Context Protocol clients, authenticated with the same API key and metered like the REST call each tool wraps.
  contact:
    name: ScraperCompany Support
    url: https://scrapercompany.com/contact
  termsOfService: https://scrapercompany.com/terms
servers:
- url: https://api.scrapercompany.com
  description: Production
security:
- ApiKeyAuth: []
- BearerAuth: []
- ApiKeyQuery: []
tags:
- name: Discovery
  description: Start here. Turn a hotel name into the property token every Google endpoint keys off.
- name: Google News
  description: 'Google''s own RSS wire: keyword search and section headlines, newest first, one page of up to 100 stories per call.'
- name: Indeed
  description: 'Indeed job search over plain HTTP: the embedded job-cards model with salary, posting age, company ratings and Indeed''s own redirect links.'
- name: Walmart
  description: 'Walmart product search and reviews over plain HTTP: the store''s own __NEXT_DATA__ JSON, no browser.'
- name: Amazon
  description: Amazon product search (without a browser; prices follow the local point-of-sale) and a product's ratings histogram with featured reviews.
- name: Google Shopping
  description: 'Google Shopping cards rendered in a real browser: title, price, merchant, condition, and Google''s data-pid per product.'
- name: Google Jobs
  description: 'Google Jobs listings rendered in a real browser: title, company, location, publisher, posting age, employment type and apply links per card.'
- name: Google Maps
  description: 'Places search and place detail from the maps RPC: name, address, coordinates, rating, phone, website, category, and the review count on detail.'
- name: Google Trends
  description: 'Interest over time and related queries from Google''s explore API: 0-100 relative values and rising queries with growth percentages.'
- name: Google Search
  description: Google's web results with People Also Ask and the AI Overview, rendered in a real browser (Google serves a JS shell to plain HTTP).
- name: Bing
  description: 'Bing organic web search over plain HTTP: title, destination URL, display URL and snippet per result, with Bing''s related-search suggestions.'
- name: Google Hotels
  description: Google Hotels' destination search, property page and price calendar. `/v1/hotels/search` lists a destination's hotels with prices; `/v1/calendar` is the cheap one — a whole horizon in a single ~30 KB call; `/v1/offers` is per-OTA detail for one night.
- name: Jobs
  description: Durable asynchronous calendar batches. Submit up to 50 properties with an Idempotency-Key, poll per-item status, and optionally receive a signed completion webhook.
- name: Booking.com
  description: Resolve a hotel name to its Booking.com URL slug, then query Booking.com's own inventory. The calendar returns 61 priced dates for ~5.5 KB; rooms come from the property page's room grid.
- name: Hotels.com
  description: Resolve a hotel name to its numeric Hotels.com property id, then query Expedia Group inventory. No calendar exists here, so it is one call per date. Prices are NOT comparable across points-of-sale.
- name: Expedia
  description: Resolve a hotel name to its numeric Expedia property id, then query Expedia's own rooms and rate plans for one stay. The point-of-sale (`market`, US or CA) decides the currency.
- name: Vrbo
  description: 'Search vacation rentals by destination and dates, then quote one rental''s stay: nightly price, total, whether fees are included and the payment model.'
- name: Agoda
  description: Resolve a hotel name to its Agoda property id, then query Agoda's own rooms and rate plans. Its 23 currencies are genuine conversions of one rate.
- name: Tripadvisor
  description: 'Metasearch prices from Booking.com, Hotels.com, Expedia and others for one stay window, by Tripadvisor locationId. Name search is not available yet: take the locationId from the hotel''s Tripadvisor URL.'
- name: Hostelworld
  description: Query Hostelworld's own rooms and rate plans using numeric property ids. Returns per-bed pricing for dorms and per-room pricing for privates. Currency is property-specific (not selectable).
- name: Airbnb
  description: Destination and map-area vacation-rental search in SearchAPI's `engine=airbnb` parameter and response shape. One guest page returns listing ids, prices, breakdowns, ratings, coordinates, images and cursor pagination. `/v1/airbnb/calendar` adds a day-by-day availability calendar with Airbnb's own quoted nightly prices.
- name: Cross-source
  description: Queries that span providers — rate parity, and the capability matrix describing what each source can do.
- name: Official site
  description: The rate the hotel sells at itself, through whichever of 31 booking engines it runs, detected automatically.
- name: SearchAPI compatibility
  description: Drop-in shapes for callers already written against SearchAPI's Google Hotels and Google Flights engines (Google Flights follows SerpApi's `departure_token` / `booking_token` flow) — repointing is a base-URL change.
- name: Stored rates
  description: Fast reads over the latest stored, normalized rates. These endpoints never collect live from an upstream source.
- name: Usage
  description: Customer-scoped request history and aggregate usage. Every result is isolated to the authenticated API key; credentials and response bodies are never stored.
- name: Billing
  description: Your plan, credit balance and credit ledger, and the plan catalogue with the cost of every operation. Metered responses carry `x-credits-charged` and `x-credits-remaining`; failed or empty results are free.
paths:
  /v1/markets:
    get:
      tags:
      - Discovery
      summary: List configured markets
      description: 'Credits: 0 (failed requests are free)'
      operationId: list_markets
      x-credits: 0
      responses:
        '200':
          description: Configured markets, each with its verified currency, gl and default tax basis
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MarketsResponse'
              example:
                markets:
                - code: US
                  currency: USD
                  label: United States
                  rates_include_tax: false
                - code: CA
                  currency: CAD
                  label: Canada
                  rates_include_tax: false
                - code: MX
                  currency: MXN
                  label: Mexico
                  rates_include_tax: false
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v1/search:
    post:
      tags:
      - Discovery
      summary: Find a property token by name
      description: |-
        Resolve a hotel name to candidate property tokens.

        Verification is on by default: each candidate is checked with a calendar lookup (slower, but no extra credits; a search costs 1 credit).
        That is the right default for onboarding: a wrong token yields rates that
        are entirely plausible and belong to a different hotel. Turn it off only
        when a human is going to confirm the choice anyway.

        Not a hot path — tokens are stable, so resolve once and store the result.
        Google rate-limits search more aggressively than the calendar.

        Credits: 1 (failed requests are free)
      operationId: search_properties
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
        required: true
      responses:
        '200':
          description: Candidate properties, best match first
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
              example:
                query: Blue Horizons Garden Resort St George's
                gl: us
                requested_market: GD
                attempted_markets:
                - GD
                - US
                matched_market: US
                market_fallback_used: true
                search_status: matched
                external_fallback_recommended: false
                matches:
                - token: ChcI7LnnsZLasKYOGgsvZy8xdHJzejFiORAB
                  rank: 0
                  verified: true
                  name: Blue Horizons Garden Resort
                  name_score: 1.0
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/rates/stored:
    get:
      tags:
      - Stored rates
      summary: Read current stored rates without scraping
      description: |-
        Stored-rate lookup with explicit freshness metadata.

        Credits: 0 (failed requests are free)
      operationId: stored_rates
      x-credits: 0
      parameters:
      - name: token
        in: query
        required: true
        schema:
          type: string
          minLength: 8
          description: Google property token whose rates have already been collected into stored rates (for example by a `POST /v1/jobs` batch).
          title: Token
        description: Google property token whose rates have already been collected into stored rates (for example by a `POST /v1/jobs` batch).
      - name: start
        in: query
        required: false
        schema:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          description: Inclusive first stay date.
          title: Start
        description: Inclusive first stay date.
      - name: end
        in: query
        required: false
        schema:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          description: Inclusive last stay date.
          title: End
        description: Inclusive last stay date.
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 2000
          minimum: 1
          default: 500
          title: Limit
      responses:
        '200':
          description: Latest stored rates; this endpoint performs no live collection
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StoredRatesResponse'
              example:
                source: google_hotels
                source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                count: 1
                last_observed_at: '2026-08-07 03:08:24.123+00'
                last_success_at: '2026-08-07 03:08:25.456+00'
                age_seconds: 42
                freshness: fresh
                rates:
                - property_name: Hilton Chicago
                  stay_date: '2028-12-30'
                  occupancy_key: adults=2
                  los: 1
                  rate: 332.01
                  rate_base: 307.01
                  rate_before_taxes_with_fees: 332.01
                  rate_total: 399.48
                  tax: 67.47
                  fees: 25.0
                  currency: USD
                  market: US
                  rates_include_tax: false
                  observed_at: '2026-08-07 03:08:24.123+00'
                  last_changed_at: '2026-08-07 03:08:24.123+00'
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observation_id: rateobs_0123456789abcdef0123456789abcdef
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: google_hotels_calendar
                    source_kind: calendar
                    collector: scrapingme.google_calendar
                    source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: room_base_before_taxes_and_fees
                    derivation: normalized_upstream
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/storage/status:
    get:
      tags:
      - Stored rates
      summary: Inspect stored-rates service status
      description: |-
        Operational status and record counts for the stored-rates service.

        Credits: 0 (failed requests are free)
      operationId: storage_status
      x-credits: 0
      responses:
        '200':
          description: Stored-rates service status and record counts
          content:
            application/json:
              schema: {}
              example:
                database:
                  tables:
                    properties: 4
                    property_source_identifiers: 4
                    scrape_runs: 3
                    rate_current: 51
                    rate_history: 76
                    refresh_jobs: 8
                    refresh_job_items: 12
                    request_history: 1842
                  latest_run:
                    run_id: scraperun_0123456789abcdef0123456789abcdef
                    status: succeeded
                    rows_written: 51
                    rows_changed: 6
                    rows_removed: 1
                    finished_at: '2026-08-07 03:08:25.456+00'
                r2_configured: true
                shared_cache_configured: true
                worker_archiving_enabled: true
                worker_persistence_enabled: true
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/usage:
    get:
      tags:
      - Usage
      summary: Read this API key's usage
      description: |-
        Request counts, errors, bytes, and latency for the calling key only.

        Credits: 0 (failed requests are free)
      operationId: customer_usage
      x-credits: 0
      parameters:
      - name: period
        in: query
        required: false
        schema:
          type: string
          pattern: ^(24h|7d|30d|90d)$
          description: 'Aggregation window: 24 hours, 7, 30, or 90 days.'
          default: 30d
          title: Period
        description: 'Aggregation window: 24 hours, 7, 30, or 90 days.'
      responses:
        '200':
          description: Customer-scoped request volume, error rate, bytes, and latency
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UsageResponse'
              example:
                key:
                  name: example-production
                  prefix: sk_example1
                  rate_limit_per_min: 600
                  role: customer
                period:
                  name: 30d
                  start: '2026-07-11T19:00:00+00:00'
                  end: '2026-08-10T19:00:00+00:00'
                totals:
                  requests: 1842
                  successful: 1804
                  errors: 38
                  rate_limited: 2
                  response_bytes: 18742311
                  avg_duration_ms: 482
                  p95_duration_ms: 2210
                by_status:
                - status: 200
                  requests: 1804
                - status: 422
                  requests: 36
                - status: 429
                  requests: 2
                by_endpoint:
                - method: POST
                  path: /v1/calendar
                  requests: 1290
                  errors: 12
                  avg_duration_ms: 391
                  p95_duration_ms: 884
                by_day:
                - date: '2029-01-01'
                  requests: 74
                  errors: 1
                  response_bytes: 812204
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/requests:
    get:
      tags:
      - Usage
      summary: List this API key's request history
      description: |-
        Newest-first metadata with keyset pagination and optional filters.

        Credits: 0 (failed requests are free)
      operationId: customer_request_history
      x-credits: 0
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 200
          minimum: 1
          default: 50
          title: Limit
      - name: cursor
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Opaque `next_cursor` from the previous page.
          title: Cursor
        description: Opaque `next_cursor` from the previous page.
      - name: status
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            maximum: 599
            minimum: 100
          - type: 'null'
          title: Status
      - name: method
        in: query
        required: false
        schema:
          anyOf:
          - type: string
            pattern: ^(GET|POST|PUT|PATCH|DELETE)$
          - type: 'null'
          title: Method
      - name: path
        in: query
        required: false
        schema:
          anyOf:
          - type: string
            maxLength: 300
          - type: 'null'
          description: Exact normalized route path, such as `/v1/calendar`.
          title: Path
        description: Exact normalized route path, such as `/v1/calendar`.
      responses:
        '200':
          description: Newest-first request metadata for the authenticated API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestHistoryResponse'
              example:
                requests:
                - id: req_0123456789abcdef0123456789abcdef
                  method: POST
                  path: /v1/calendar
                  status: 200
                  duration_ms: 391
                  response_bytes: 18342
                  request:
                    body:
                      token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                      market: US
                      currency: USD
                      days: 90
                  created_at: '2026-08-10 18:51:06.724001+00'
                count: 1
                has_more: true
                next_cursor: WyIyMDI2LTA4LTEwIDE4OjUxOjA2LjcyNDAwMSswMCIsInJlcV8wMTIzIl0
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/requests/{request_id}:
    get:
      tags:
      - Usage
      summary: Read one request-history record
      description: |-
        Return 404 for missing records and records owned by another key.

        Credits: 0 (failed requests are free)
      operationId: customer_request_detail
      x-credits: 0
      parameters:
      - name: request_id
        in: path
        required: true
        schema:
          type: string
          title: Request Id
      responses:
        '200':
          description: One request record; records belonging to another API key return 404
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestRecord'
              example:
                id: req_0123456789abcdef0123456789abcdef
                method: GET
                path: /v1/rates/stored
                status: 200
                duration_ms: 46
                response_bytes: 9271
                request:
                  query:
                    token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    start: '2029-01-02'
                    end: '2029-02-01'
                created_at: '2026-08-10 18:52:11.104922+00'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/jobs:
    post:
      tags:
      - Jobs
      summary: Submit a durable calendar batch
      description: |-
        Persist before returning 202; execution can survive API restarts.

        Credits: each succeeded item is priced like POST /v1/calendar, surcharges included (5 for a default item); failed items are free
      operationId: submit_calendar_job
      x-credits: 5
      x-credits-variable: true
      parameters:
      - name: Idempotency-Key
        in: header
        required: true
        schema:
          type: string
          minLength: 1
          maxLength: 200
          description: Unique per logical submission. Reusing it with the same body returns the original job; a different body is 409.
          title: Idempotency-Key
        description: Unique per logical submission. Reusing it with the same body returns the original job; a different body is 409.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CalendarJobRequest'
      responses:
        '202':
          description: Durably queued; poll the returned URL for progress
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalendarJob'
              example:
                id: refreshjob_0123456789abcdef0123456789abcdef
                job_id: refreshjob_0123456789abcdef0123456789abcdef
                poll_url: /v1/jobs/refreshjob_0123456789abcdef0123456789abcdef
                status: queued
                priority: 5
                callback_url: https://example.com/webhooks/scrapercompany
                callback_status: pending
                callback_attempts: 0
                result_summary: {}
                items_total: 1
                items_succeeded: 0
                items_failed: 0
                created_at: '2026-08-10T14:05:00Z'
                updated_at: '2026-08-10T14:05:00Z'
                items:
                - id: refreshitem_0123456789abcdef0123456789abcdef
                  item_index: 0
                  token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  label: Boston Marriott Copley Place
                  status: queued
                  request:
                    token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    label: Boston Marriott Copley Place
                    market: US
                    currency: USD
                    days: 90
                    adults: 2
                    los: 1
                    basis: cheapest
                    is_hostel: false
                    probe_min_stay: true
                    verify_sources: 0
                  attempts: 0
                  updated_at: '2026-08-10T14:05:00Z'
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/jobs/{job_id}:
    get:
      tags:
      - Jobs
      summary: Poll a calendar batch and its per-item status
      description: 'Credits: 0 (failed requests are free)'
      operationId: get_calendar_job
      x-credits: 0
      parameters:
      - name: job_id
        in: path
        required: true
        schema:
          type: string
          title: Job Id
      - name: include_results
        in: query
        required: false
        schema:
          type: boolean
          description: Include each completed calendar payload. Leave false for a small status-only response.
          default: false
          title: Include Results
        description: Include each completed calendar payload. Leave false for a small status-only response.
      responses:
        '200':
          description: Current job and per-property progress
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalendarJob'
              example:
                id: refreshjob_0123456789abcdef0123456789abcdef
                job_id: refreshjob_0123456789abcdef0123456789abcdef
                poll_url: /v1/jobs/refreshjob_0123456789abcdef0123456789abcdef
                status: succeeded
                priority: 5
                callback_url: https://example.com/webhooks/scrapercompany
                callback_status: delivered
                callback_attempts: 1
                artifact_uri: r2://example-bucket/jobs/example.json.gz
                artifact_sha256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
                result_summary:
                  rates: 90
                  wire_bytes: 29804
                  database:
                    run_id: scraperun_0123456789abcdef
                    rows_written: 90
                    rows_changed: 82
                    rows_removed: 1
                items_total: 1
                items_succeeded: 1
                items_failed: 0
                created_at: '2026-08-10T14:05:00Z'
                started_at: '2026-08-10T14:05:01Z'
                finished_at: '2026-08-10T14:05:02Z'
                updated_at: '2026-08-10T14:05:02Z'
                items:
                - id: refreshitem_0123456789abcdef0123456789abcdef
                  item_index: 0
                  token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  label: Boston Marriott Copley Place
                  status: succeeded
                  request:
                    token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    label: Boston Marriott Copley Place
                    market: US
                    currency: USD
                    days: 90
                    adults: 2
                    los: 1
                    basis: cheapest
                    is_hostel: false
                    probe_min_stay: true
                    verify_sources: 0
                  attempts: 1
                  started_at: '2026-08-10T14:05:01Z'
                  finished_at: '2026-08-10T14:05:02Z'
                  updated_at: '2026-08-10T14:05:02Z'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/calendar:
    post:
      tags:
      - Google Hotels
      summary: Price a forward horizon in one call
      description: |-
        Forward horizon of nightly rates — the cheap bulk path.

        Credits: 5, plus 3 per night with `basis: mainstream` and 3 per `verify_sources` spot-check (failed requests are free)
      operationId: google_calendar
      x-credits: 5
      x-credits-variable: true
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CalendarRequest'
        required: true
      responses:
        '200':
          description: One row per stay date. ~30 KB for a 90-night window
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalendarResponse'
              example:
                token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                market: US
                collection_id: ratecol_0123456789abcdef0123456789abcdef
                observed_at: '2026-08-07T01:23:45.678Z'
                requested_days: 90
                coverage: 0.9333
                wire_bytes: 29804
                elapsed_s: 0.31
                calendar_elapsed_s: 0.14
                unpriced_dates:
                - '2029-01-10'
                validation:
                  ok: true
                  errors: []
                  warnings: []
                tax_profile:
                  rate: 0.2032
                  confidence: high
                  itemised: 84
                  derived: 0
                rates:
                - stay_date: '2028-12-26'
                  rate: 332.01
                  rate_base: 332.01
                  rate_total: 424.48
                  tax: 67.47
                  fees: 25.0
                  currency: USD
                  market: US
                  rates_include_tax: false
                  adults: 2
                  los: 1
                  implied_tax_rate: 0.203217
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: google_hotels_calendar
                    source_kind: calendar
                    collector: scrapingme.google_calendar
                    source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: room_base_before_taxes_and_fees
                    derivation: normalized_upstream
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/stay:
    post:
      tags:
      - Google Hotels
      summary: Price one explicit stay window
      description: |-
        One explicit stay window. `rate` is the WHOLE-STAY figure — length of
        stay moves the nightly price, so dividing it out would misrepresent it.

        Credits: 3 (failed requests are free)
      operationId: google_stay
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StayRequest'
        required: true
      responses:
        '200':
          description: One priced stay window, tax split out
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StayResponse'
              example:
                nights: 3
                token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                rate: 2492.73
                rate_base: 2492.73
                rate_before_taxes_with_fees: 2567.73
                rate_total: 3053.03
                tax: 485.3
                fees: 75
                currency: USD
                market: US
                rates_include_tax: false
                adults: 2
                los: 3
                stay_date: '2029-02-05'
                implied_tax_rate: 0.1947
                provenance:
                  schema_version: 1
                  observation_id: rateobs_0123456789abcdef0123456789abcdef
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
                  source: google_hotels_calendar
                  source_kind: calendar
                  collector: scrapingme.google_calendar
                  source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  requested_market: US
                  requested_currency: USD
                  returned_currency: USD
                  egress_mode: direct
                  price_basis: room_base_before_taxes_and_fees
                  derivation: normalized_upstream
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/offers:
    post:
      tags:
      - Google Hotels
      summary: Per-OTA offers for one night
      description: |-
        Per-OTA breakdown for one night. Heavier than /v1/calendar (~365 KB on
        the wire vs ~30 KB), so use it for the dates that matter, not all of them.

        Credits: 3 (failed requests are free)
      operationId: google_offers
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OffersRequest'
        required: true
      responses:
        '200':
          description: Every OTA on the property for one night, with per-room detail
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OffersResponse'
              example:
                token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                check_in: '2029-02-05'
                check_out: '2029-02-06'
                nights: 1
                adults: 2
                device: iphone
                coverage: 2
                currency: USD
                currency_matches_request: true
                rates_include_tax: false
                requested_market: US
                egress_market: US
                egress_geo_locked_ok: true
                price_insights_market_verified: true
                lowest_price_per_night: 303.67
                rooms_total: 173
                name: Hilton Chicago
                hotel_class: 4-star hotel
                hotel_class_stars: 4
                rating: 4.3
                reviews: 10686
                deal: 25% less than usual
                has_deal: true
                deal_description: Great Deal
                price_insights:
                  lowest_price: $304
                  price_level: typical
                  typical_price_range:
                    low_price: $304
                    high_price: $521
                sources:
                - Official site
                - Booking.com
                - Expedia
                - Hotels.com
                missing_sources: []
                refundable_offers: 2
                wire_bytes: 4381263
                elapsed_s: 1.14
                warnings: []
                offers:
                - source: Official site
                  raw_source: Hilton Chicago
                  is_official: true
                  nights: 1
                  currency: USD
                  price_per_night: 499.44
                  price_per_night_before_taxes: 420.05
                  tax: 79.39
                  total: 499.44
                  has_free_cancellation: true
                  free_cancellation_until: '2029-02-01'
                  free_cancellation_time: '23:59'
                  room_id: rate-plan-42
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: google_hotels_property_offers
                    source_kind: offer
                    collector: scrapingme.google_property
                    source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: market_proxy
                    price_basis: room_base_before_taxes_and_fees
                    derivation: normalized_upstream
                  rooms:
                  - name: 1 KING BED
                    description: 1 bed
                    beds: 1
                    is_suite: false
                    price_before_taxes: 420.06
                    price_total: 499.45
                    has_free_cancellation: true
                    free_cancellation_until: '2029-02-01'
                    free_cancellation_time: '23:59'
                    link: https://www.google.com/aclk?...
                    thumbnail: https://lh3.googleusercontent.com/...
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/rooms:
    post:
      tags:
      - Google Hotels
      summary: Room types by OTA, aligned on one signature
      description: |-
        Room types by OTA, aligned onto a comparable signature.

        Each OTA names the same room its own way — on one property the official
        site and Expedia shared **zero** names verbatim — so a pivot on the raw
        name shows every row filled by one source. Rows here are keyed on a
        normalised signature and every cell keeps the source's own wording.

        Room detail rides on Google's featured-offer blocks, which the thin
        variant of the page omits entirely. A source with `rooms: 0` means this
        render carried none for it, NOT that the OTA has no inventory.

        Credits: 3 (failed requests are free)
      operationId: google_room_matrix
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoomMatrixRequest'
        required: true
      responses:
        '200':
          description: Room signature x source. An empty cell means the render carried no detail for that source, NOT that the room is unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoomMatrixResponse'
              example:
                search_parameters:
                  engine: google_hotels_rooms
                  token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  check_in_date: '2029-02-05'
                  check_out_date: '2029-02-06'
                  adults: 2
                  currency: USD
                  sources:
                  - Official site
                  - Booking.com
                  - Hotels.com
                  - Expedia
                property:
                  name: Hilton Chicago
                  currency: USD
                  currency_matches_request: true
                  requested_market: US
                  egress_market: US
                  egress_geo_locked_ok: true
                render:
                  wire_bytes: 4416000
                  carried_room_detail: true
                sources:
                - source: Official site
                  rooms: 23
                  cheapest: 420.06
                  dearest: 527.98
                  currency: USD
                  is_official: true
                - source: Hotels.com
                  rooms: 28
                  cheapest: 419.51
                  dearest: 1974.23
                  currency: USD
                  is_official: false
                  duplicate_of: Expedia
                rows:
                - signature: 1 king
                  cells:
                    Official site:
                      name: 1 KING BED
                      price: 420.06
                      total: 499.45
                    Expedia:
                      name: Room, 1 King Bed
                      price: 419.51
                      total: 498.79
                totals:
                  sources_present: 4
                  sources_with_rooms: 3
                  distinct_signatures: 32
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/news:
    post:
      tags:
      - Google News
      summary: Google News results or section headlines
      description: |-
        One page (up to 100) of Google News results.

        This is Google's own published RSS wire — the same feed reader apps
        consume — so it carries the feed's semantics: newest first, one page per
        request, a `when:` freshness operator instead of a date range, and
        `link` values that are Google's canonical redirects to the publisher.
        `q` searches; `topic` reads a section feed; with neither the edition's
        top stories answer.

        Credits: 1 (failed requests are free)
      operationId: google_news
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleNewsRequest'
        required: true
      responses:
        '200':
          description: One page of Google News results with the publisher of each story
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: google_news
                  q: Hilton Chicago
                  gl: US
                  hl: en
                news_results:
                - position: 1
                  title: 'Sleep in history: Inside Hilton Chicago, the city''s grandest hotel'
                  link: https://news.google.com/rss/articles/CBMigAFBVV95cUxOTFVQSS1SaXdVWjNMdUR6WWk1SUk5LTdFSm44bW1xOEtTMko3bDJ0ZlBfaEY0eUlSWGZUV2tOTUZxWmU5Rzg2RVRRQ2RzR243UnJ4UEwwMFR5MzRiSEtnOEFWa2I0M0ZoU1lzYlpBNVhWRHl2d2JqanZrM2xsRkNxag?oc=5
                  story_token: CBMigAFBVV95cUxOTFVQSS1SaXdVWjNMdUR6WWk1SUk5LTdFSm44bW1xOEtTMko3bDJ0ZlBfaEY0eUlSWGZUV2tOTUZxWmU5Rzg2RVRRQ2RzR243UnJ4UEwwMFR5MzRiSEtnOEFWa2I0M0ZoU1lzYlpBNVhWRHl2d2JqanZrM2xsRkNxag
                  published: '2025-10-31T07:00:00Z'
                  source:
                    name: Time Out Worldwide
                    url: https://www.timeout.com
                - position: 2
                  title: Second story title from the same feed
                  link: https://news.google.com/rss/articles/CBMiWhFDQUlRQUNvZENodHljRjlvT25SZmJHOVBVMHh0VTJkSlNsa3lMVmMxZVMxMWVtYxAB?oc=5
                  story_token: CBMiWhFDQUlRQUNvZENodHljRjlvT25SZmJHOVBVMHh0VTJkSlNsa3lMVmMxZVMxMWVtYxAB
                  published: '2026-09-28T22:45:10Z'
                  source:
                    name: Chicago Tribune
                    url: https://www.chicagotribune.com
                total: 2
                meta:
                  source: google_news
                  wire_bytes: 8678
                  elapsed_s: 0.412
                  egress_mode: direct
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/bing/search:
    post:
      tags:
      - Bing
      summary: Bing organic web search over plain HTTP
      description: |-
        One page of Bing organic results, up to 35 per request.

        Bing answers plain HTTP with no JS and no tokens. Each result keeps the
        title, the destination URL (Bing's click tracker is decoded back to the
        destination; an undecodable tracker is returned as-is rather than
        dropped), the display URL and the snippet. `related_searches` carries
        Bing's own refinement suggestions when the page shows them.

        Credits: 1 (failed requests are free)
      operationId: bing_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BingSearchRequest'
        required: true
      responses:
        '200':
          description: One page of Bing organic results with the trackers decoded
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: bing_search
                  q: Hilton Chicago
                  first: 1
                organic_results:
                - position: 1
                  title: Hotels by Hilton - Book the Best Rates Across All Brands
                  url: https://www.hilton.com/en/
                  snippet: Explore Hilton's portfolio of hotels and distinct brands across the globe. Book directly for the best rates during your next stay. Expect …
                  display_url: https://www.hilton.com
                - position: 2
                  title: Hilton Chicago, IL - Hotel Overview, Reviews & Rates
                  url: https://www.hilton.com/en/hotels/chichhx-hilton-chicago/
                  snippet: Stay at Hilton Chicago, a landmark hotel on Michigan Avenue with direct access to McCormick Place…
                  display_url: https://www.hilton.com › en › hotels
                related_searches:
                - query: hilton chicago magnificent mile
                  link: /search?q=hilton+chicago+magnificent+mile
                total: 2
                meta:
                  source: bing_search
                  wire_bytes: 19420
                  elapsed_s: 0.388
                  egress_mode: direct
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/google/search:
    post:
      tags:
      - Google Search
      summary: Google organic results with PAA and AI overview
      description: |-
        One rendered page of Google web results.

        Google serves a JavaScript shell to plain HTTP, so this renders the page
        in a real browser — seconds per call, the honest cost of the flagship.
        The answer carries the organic list, the People Also Ask questions (the
        questions only: answers load on expansion and are not in the DOM), the
        AI Overview text when Google generates one, and related searches.
        `link` is Google's `/goto` redirect unless `resolve=true`, which follows
        each one (one HTTP request per result).

        Credits: 5 (failed requests are free)
      operationId: google_search
      x-credits: 5
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleSearchRequest'
        required: true
      responses:
        '200':
          description: One rendered page of Google organic results with PAA and AI overview
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: google_search
                  q: best time to visit japan
                  page: 1
                organic_results:
                - position: 1
                  title: 'Best Time to Visit Japan: Seasons, Months, Weather & Events'
                  link: https://www.google.com/goto?url=CAESeQHrOzAVJE8lGsYKYT
                  display_url: https://en.japantravel.com › Culture
                  snippet: Mar 25, 2026 — If we're going by popular opinion, spring (March to May) is the best time to visit Japan…
                - position: 2
                  title: The Best Time to Visit Japan
                  link: https://www.google.com/goto?url=CAESdAHrOzAVksx1otYJyS
                  display_url: https://www.japan-guide.com › travel-essentials
                  snippet: The best time to visit Japan is in spring (March to May) for cherry blossoms, or autumn (October to November) for foliage…
                people_also_ask:
                - Is $5000 enough for a week in Japan?
                - What is the cheapest month to go to Japan?
                - What month is best for cherry blossoms in Japan?
                - What is Japan's rainy season?
                related_searches: []
                ai_overview: |-
                  Spring: Cherry Blossoms (March – May)
                  Highlights: Mild temperatures (45–70°F) and famous cherry blossoms (sakura) peaking in late March to early April.
                  Drawbacks: Extremely crowded and expensive.
                ai_overview_sources: []
                total: 2
                meta:
                  source: google_search
                  wire_bytes: 662725
                  elapsed_s: 8.2
                  rendered: true
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/trends/interest:
    post:
      tags:
      - Google Trends
      summary: Interest over time for a keyword
      description: |-
        Google Trends interest over time, one 0-100 timeline.

        Values are relative to the keyword's own peak in the window (100 =
        busiest point) — not absolute volume, exactly as Google's charts state.
        `time_range` uses Google's own grammar.

        Credits: 1 (failed requests are free)
      operationId: google_trends_interest
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TrendsInterestRequest'
        required: true
      responses:
        '200':
          description: 'Interest over time: 0-100 relative to the keyword''s own peak'
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: google_trends_interest
                  keyword: Hilton
                  geo: US
                  time_range: today 1-m
                series:
                - points:
                  - date: '2029-01-23'
                    value: 41
                  - date: '2029-01-24'
                    value: 38
                  - date: '2029-01-25'
                    value: 47
                  - date: '2029-01-26'
                    value: 52
                total: 4
                meta:
                  source: google_trends
                  wire_bytes: 8456
                  elapsed_s: 0.612
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/trends/related:
    post:
      tags:
      - Google Trends
      summary: 'Related queries: top and rising'
      description: |-
        Google Trends related queries, split top and rising.

        Top values are 0-100 relative to the top query; rising values are
        growth percentages, and above 5000% Google answers "Breakout", carried
        as `breakout: true` with a null value.

        Credits: 1 (failed requests are free)
      operationId: google_trends_related
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TrendsRelatedRequest'
        required: true
      responses:
        '200':
          description: 'Related queries: top (0-100) and rising (growth %, or Breakout)'
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: google_trends_related
                  keyword: Hilton
                  geo: US
                  time_range: today 1-m
                top:
                - query: hilton honors
                  kind: top
                  value: 100
                  breakout: false
                - query: hilton head
                  kind: top
                  value: 87
                  breakout: false
                rising:
                - query: hilton giveaway 2026
                  kind: rising
                  value: 300
                  breakout: false
                - query: hilton points exploit
                  kind: rising
                  breakout: true
                meta:
                  source: google_trends
                  wire_bytes: 6421
                  elapsed_s: 0.538
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/maps/search:
    post:
      tags:
      - Google Maps
      summary: Places matching a Maps query
      description: |-
        One page of Google Maps place cards.

        `q` is whatever the Maps search box takes — a business name, a
        category in a place, a landmark. Each card carries name, address,
        coordinates, rating, phone, website, category and the `place_token`
        the detail call keys off. The review count is only on the detail
        record.

        Credits: 3 (failed requests are free)
      operationId: google_maps_search
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MapsSearchRequest'
        required: true
      responses:
        '200':
          description: Places matching a Maps query, with tokens for the detail call
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: google_maps_search
                  q: Hilton Chicago
                  gl: us
                  hl: en
                places:
                - place_token: 0x880e2c99242c7a2f:0x4de3d4bb09dba1
                  name: Hilton Chicago
                  address: 720 S Michigan Ave, Chicago, IL 60605
                  gps_coordinates:
                    latitude: 41.872259199999995
                    longitude: -87.624696
                  rating: 4.3
                  phone: (312) 922-4400
                  website: https://www.hilton.com/en/hotels/chichhh-hilton-chicago/
                  category: Hotel
                - place_token: 0x880e2c99242c7a2f:0x31660dda0c86665
                  name: The Chicago Hotel Collection Wrigleyville
                  address: 844 W Addison St, Chicago, IL 60613
                  gps_coordinates:
                    latitude: 41.945531
                    longitude: -87.654866
                  rating: 4.1
                  phone: (773) 525-4700
                  website: https://www.chicago-hotel-collection.com/
                  category: Hotel
                total: 2
                meta:
                  source: google_maps
                  wire_bytes: 270014
                  elapsed_s: 0.712
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/maps/detail:
    post:
      tags:
      - Google Maps
      summary: One place's detail record
      description: |-
        One place's detail card: the search fields plus the review count.

        Token and name come from the same `POST /v1/maps/search` row — the
        token pin answers only when the query names the same place.

        Credits: 3 (failed requests are free)
      operationId: google_maps_detail
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MapsDetailRequest'
        required: true
      responses:
        '200':
          description: 'One place''s detail record: the search fields plus the review count'
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: google_maps_detail
                  place_token: 0x880e2c99242c7a2f:0x4de3d4bb09dba1
                  name: Hilton Chicago
                  gl: us
                  hl: en
                place:
                  place_token: 0x880e2c99242c7a2f:0x4de3d4bb09dba1
                  name: Hilton Chicago
                  address: 720 S Michigan Ave, Chicago, IL 60605
                  gps_coordinates:
                    latitude: 41.872259199999995
                    longitude: -87.624696
                  rating: 4.3
                  reviews: 10999
                  phone: (312) 922-4400
                  website: https://www.hilton.com/en/hotels/chichhh-hilton-chicago/
                  category: Hotel
                meta:
                  source: google_maps
                  wire_bytes: 310583
                  elapsed_s: 0.664
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/jobs/search:
    post:
      tags:
      - Google Jobs
      summary: Google Jobs listings for a query
      description: |-
        One rendered page of Google Jobs cards.

        Google serves a JavaScript shell to plain HTTP, so this renders the
        jobs panel in a real browser — seconds per call. Each card carries the
        title, company, location, the upstream publisher (`via`), the relative
        posting age (Google publishes no absolute dates here), the employment
        type, and the apply links with their sources.

        Credits: 3 (failed requests are free)
      operationId: google_jobs_search
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleJobsRequest'
        required: true
      responses:
        '200':
          description: One rendered page of Google Jobs cards with apply sources
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: google_jobs
                  q: hotel jobs chicago
                jobs_results:
                - title: Housekeeping Supervisor - Part Time
                  company: Sonesta International Hotels
                  location: Chicago, IL, United States
                  via: LinkedIn
                  posted: 1 day ago
                  employment_type: Part-time
                  apply_options:
                  - source: LinkedIn
                    link: https://www.google.com/goto?url=CAES9wEB6zswFTBT
                  - source: Indeed
                    link: https://www.google.com/goto?url=CAESugEB6zswFdeT
                - title: Assistant Room Operations Manager- Housekeeping
                  company: Marriott
                  location: Chicago, IL, United States
                  via: Marriott Careers
                  posted: 6 days ago
                  employment_type: Full-time
                  apply_options:
                  - source: Marriott Careers
                    link: https://www.google.com/goto?url=CAESugEB6zswFxyz
                total: 2
                meta:
                  source: google_jobs
                  wire_bytes: 474558
                  elapsed_s: 9.8
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/shopping/search:
    post:
      tags:
      - Google Shopping
      summary: Google Shopping products for a query
      description: |-
        One rendered page of Google Shopping cards (~10 per page).

        Google serves a JavaScript shell to plain HTTP, so this renders the
        shopping SERP in a real browser — seconds per call. Each card carries
        the title, price, merchant and condition chips ("Pre-owned"), plus
        Google's `data-pid`. Google renders the same product more than once;
        the answer dedupes by `data-pid`.

        Credits: 3 (failed requests are free)
      operationId: google_shopping_search
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleShoppingRequest'
        required: true
      responses:
        '200':
          description: One rendered page of Google Shopping cards
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: google_shopping
                  q: hilton bathrobe
                shopping_results:
                - title: Paris Hilton Women Robe Blue Size S/m $92
                  price: 39.0
                  merchant: eBay
                  product_id: '15138752771170097272'
                  item_id: '1792340598104035252'
                - title: Paris Hilton lounge robe
                  price: 25.0
                  merchant: Whatnot
                  product_id: '15138752771170097273'
                  item_id: '1792340598104035253'
                - title: Paris Hilton One Size Fits Most White Polyester Bathrobe
                  price: 15.0
                  merchant: eBay
                  condition: Pre-owned
                  product_id: '15138752771170097274'
                  item_id: '1792340598104035254'
                total: 3
                meta:
                  source: google_shopping
                  wire_bytes: 854947
                  elapsed_s: 10.4
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/amazon/search:
    post:
      tags:
      - Amazon
      summary: Amazon product search over plain HTTP
      description: |-
        One page (~48) of Amazon search results.

        Over plain HTTP. Prices follow the local point-of-sale — a
        Canadian exit answers CAD — so `price_text` keeps the display string
        verbatim and `currency` carries the best-effort guess from its symbol.
        Sponsored rows come labelled in `sponsored` rather than dropped.

        Credits: 1 (failed requests are free)
      operationId: amazon_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AmazonSearchRequest'
        required: true
      responses:
        '200':
          description: One page of Amazon search results (prices in the local point-of-sale)
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: amazon_search
                  q: bathrobe
                products:
                - asin: B084PBWBJR
                  title: PAVILIA Premium Womens Plush Soft Robe, Fluffy Warm Fleece Sherpa Bathrobe
                  price: 42.52
                  price_text: CAD 42.52
                  currency: CAD
                  rating: 4.6
                  ratings_count: 13206
                  url: https://www.amazon.com/dp/B084PBWBJR
                  image: https://m.media-amazon.com/images/I/61VOJmplqeL._AC_UL320_.jpg
                  sponsored: false
                - asin: B07FZSP1BR
                  title: Alexander Del Rossa Womens Robe, Long Fleece Bathrobe
                  price: 55.0
                  price_text: CAD 55.00
                  currency: CAD
                  rating: 4.7
                  ratings_count: 8941
                  url: https://www.amazon.com/dp/B07FZSP1BR
                  sponsored: true
                total: 2
                meta:
                  source: amazon_search
                  wire_bytes: 110467
                  elapsed_s: 1.212
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/amazon/reviews:
    post:
      tags:
      - Amazon
      summary: A product's histogram and featured reviews
      description: |-
        A product's ratings histogram and featured reviews.

        The `/product-reviews` list requires sign-in (measured: redirected to
        sign-in over plain HTTP and in a fresh browser), so the answer is the
        product page's own reviews widget, rendered in a real browser: the
        5→1 histogram, the global ratings count, and the featured reviews
        (title, rating, date, author, body, "Verified Purchase", helpful
        votes).

        Credits: 2 (failed requests are free)
      operationId: amazon_reviews
      x-credits: 2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AmazonReviewsRequest'
        required: true
      responses:
        '200':
          description: A product's ratings histogram and featured reviews
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: amazon_reviews
                  asin: B084PBWBJR
                total_ratings: 13206
                histogram:
                  '5': 78
                  '4': 11
                  '3': 6
                  '2': 2
                  '1': 3
                reviews:
                - source: amazon
                  rating: 5.0
                  title: Soft and comfy!!
                  text: Thick, soft, cozy, comfy, warm, good length, good quality, absorbent. Would purchase again.
                  date: '2028-11-12'
                  author: Ms. G.
                  helpful_votes: 3
                  labels:
                  - Verified Purchase
                meta:
                  source: amazon
                  wire_bytes: 54488
                  elapsed_s: 8.9
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/walmart/search:
    post:
      tags:
      - Walmart
      summary: Walmart product search over plain HTTP
      description: |-
        One page (~40) of Walmart search results.

        Walmart's own `__NEXT_DATA__` store over plain HTTP — no browser. Each
        item carries name, brand, price with currency, rating, review count,
        and the item id the reviews call keys off. Sponsored items come
        labelled in `sponsored` rather than dropped.

        Credits: 1 (failed requests are free)
      operationId: walmart_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WalmartSearchRequest'
        required: true
      responses:
        '200':
          description: One page of Walmart search results from the store's own JSON
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: walmart_search
                  q: bathrobe
                products:
                - item_id: '5255687930'
                  name: Black Womens Robe, Fleece Plush Soft Fluffy Bathrobe, S/M
                  brand: Pavilia
                  price: 19.99
                  currency: USD
                  rating: 4.4
                  ratings_count: 2484
                  url: https://www.walmart.com/ip/PAVILIA-Black-Women-Robe-5255687930
                  image: https://i5.walmartimages.com/seo/PAVILIA-Black-Women-Robe_482875EB
                  sponsored: false
                - item_id: '17299362344'
                  name: Mainstays Fleece Bathrobe, Unisex, Adult
                  brand: Mainstays
                  price: 16.98
                  currency: USD
                  rating: 4.5
                  ratings_count: 1290
                  url: https://www.walmart.com/ip/Mainstays-Fleece-Bathrobe-17299362344
                  sponsored: true
                aggregated_count: 387
                total: 2
                meta:
                  source: walmart_search
                  wire_bytes: 181760
                  elapsed_s: 1.344
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/walmart/reviews:
    post:
      tags:
      - Walmart
      summary: One page of Walmart reviews with the summary
      description: |-
        One page (10) of Walmart reviews for an item.

        Plain HTTP — no browser, no tokens. The answer carries the review
        list (rating, title, text, date normalized from Walmart's M/D/YYYY,
        the "Verified Purchase" badge) plus the summary: average, total,
        per-star counts and percentages, recommended percentage, and
        Walmart's own `next_page` url.

        Credits: 2 (failed requests are free)
      operationId: walmart_reviews
      x-credits: 2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WalmartReviewsRequest'
        required: true
      responses:
        '200':
          description: One page of Walmart reviews with the ratings summary
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: walmart_reviews
                  item_id: '5255687930'
                  page: 1
                  sort: relevancy
                total: 2484
                summary:
                  average: 4.4
                  total: 2484
                  counts:
                    '1': 180
                    '2': 74
                    '3': 148
                    '4': 296
                    '5': 1786
                  percentages:
                    '1': 8
                    '2': 3
                    '3': 6
                    '4': 11
                    '5': 72
                  recommended_pct: 81
                reviews:
                - source: walmart
                  review_id: '20669430'
                  rating: 5.0
                  title: Comfortable Robe
                  text: This robe is absolutely beautiful and so comfortable.
                  date: '2027-08-07'
                  author: Rhoda
                  labels:
                  - Verified Purchase
                next_page: sort=relevancy&page=2
                meta:
                  source: walmart
                  wire_bytes: 27192
                  elapsed_s: 1.102
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/indeed/jobs:
    post:
      tags:
      - Indeed
      summary: Indeed job search over plain HTTP
      description: |-
        One page (~45) of Indeed job records.

        Indeed answers plain HTTP with its own embedded job-cards model — no
        browser, no tokens. Each record carries the jobkey, title, company,
        location, salary (verbatim text plus Indeed's extracted min/max and
        period), the relative posting age, the creation date from Indeed's
        epoch, the company's rating, and Indeed's own redirect link.
        Sponsored rows come labelled, not dropped.

        Credits: 1 (failed requests are free)
      operationId: indeed_jobs
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IndeedJobsRequest'
        required: true
      responses:
        '200':
          description: One page of Indeed job records over plain HTTP
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  engine: indeed_jobs
                  q: hotel jobs
                  location: Chicago, IL
                  page: 1
                jobs_results:
                - jobkey: 8f0ec6e87b6ba389
                  title: Front Desk Agent
                  company: Marriott International, Inc
                  location: Chicago, IL 60616
                  salary:
                    text: $27.87 an hour
                    min: 27.87
                    max: 27.87
                    period: HOURLY
                  posted: 6 days ago
                  created: '2029-02-16'
                  company_rating: 4.0
                  company_review_count: 26245
                  job_types: []
                  remote: false
                  sponsored: false
                  link: https://www.indeed.com/rc/clk?jk=8f0ec6e87b6ba389
                  snippet: Process all guest check-ins by confirming reservations, assigning room…
                - jobkey: e3479bc018d43229
                  title: Housekeeping Attendant
                  company: Sonesta International Hotels
                  location: Chicago, IL
                  salary:
                    text: $21.00 an hour
                    min: 21.0
                    max: 21.0
                    period: HOURLY
                  posted: 1 day ago
                  created: '2029-02-21'
                  company_rating: 4.1
                  company_review_count: 402
                  job_types:
                  - PART_TIME
                  remote: false
                  sponsored: false
                  link: https://www.indeed.com/rc/clk?jk=e3479bc018d43229
                  snippet: Clean guest rooms and public areas.
                total: 2
                meta:
                  source: indeed
                  wire_bytes: 1759431
                  elapsed_s: 1.488
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/hotels/search:
    post:
      tags:
      - Google Hotels
      summary: Search a destination for hotels and prices
      description: |-
        One page (~20) of the properties Google Hotels lists for a destination.

        Each property carries its `property_token` (feed it to `/v1/calendar` or
        `/v1/offers`), rating, class, amenities, images, coordinates, deal signal
        and the lowest price for the stay, itemised into base, taxes, fees and
        total with provenance. Vacation rentals add their seller rows. Page on with
        `pagination.next_page_token`, resending the same body.

        One upstream call per page. Prices follow the market Google sees the
        request from; `warnings` says when that market could not be verified.

        Credits: 3 per page of results; an empty page and failed requests are free
      operationId: google_hotels_search
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleHotelsSearchRequest'
        required: true
      responses:
        '200':
          description: One page of destination results; stay totals keep base, taxes and fees apart
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GoogleHotelsSearchResponse'
              example:
                search_parameters:
                  engine: google_hotels_search
                  q: hotels in Montreal
                  check_in_date: '2029-03-14'
                  check_out_date: '2029-03-16'
                  adults: 2
                  currency: CAD
                  gl: ca
                  hl: en
                  sort_by: relevance
                search_information:
                  total_results: 5778
                  location: Montreal
                  location_data_id: 0x4cc91a541c64b70d:0x654e3138211fefef
                  nights: 2
                  returned: 7
                  priced: 7
                  requested_currency: CAD
                  returned_currency: CAD
                  currency_matches_request: true
                  requested_market: CA
                  available_property_types:
                  - id: 19
                    name: Bed and breakfasts
                  - id: 18
                    name: Spa hotels
                  - id: 14
                    name: Hostels
                properties:
                - type: hotel
                  property_token: ChgImtDg_rW5k8iWARoLL2cvMXRzamQ4NncQAQ
                  name: Radisson Hotel Montreal Airport
                  data_id: 0x4cc9178df6e67b8d:0x96904dcb5fd8281a
                  description: Modern lodging with a restaurant & an indoor pool, plus free WiFi & an airport shuttle.
                  link: https://www.choicehotels.com/quebec/montreal/radisson-hotels/cnc37?mc=llgoxxpx
                  gps_coordinates:
                    latitude: 45.4851544
                    longitude: -73.6909316
                  country: CA
                  check_in_time: 3:00 PM
                  check_out_time: 11:00 AM
                  hotel_class: 4-star hotel
                  extracted_hotel_class: 4
                  rating: 3.5
                  reviews: 2535
                  reviews_histogram:
                    '1': 443
                    '2': 220
                    '3': 396
                    '4': 674
                    '5': 802
                  location_rating: 3.1
                  proximity_to_things_to_do_rating: 3.2
                  proximity_to_restaurants_rating: 2.8
                  proximity_to_transit_rating: 2.5
                  airport_access_rating: 4.6
                  reviews_breakdown:
                  - name: Fitness
                    description: Fitness
                    total: 199
                    positive: 119
                    neutral: 13
                    negative: 67
                  - name: Pool
                    description: Pool
                    total: 107
                    positive: 78
                    neutral: 7
                    negative: 22
                  amenities:
                  - Breakfast ($)
                  - Free Wi-Fi
                  - Parking ($)
                  - Pools
                  - Hot tub
                  - Air conditioning
                  amenity_codes:
                  - - 1
                    - 165
                  - - 1
                    - 29
                  - - 1
                    - 17
                  - - 1
                    - 21
                  - - 1
                    - 10
                  - - 1
                    - 2
                  thumbnail: https://lh3.googleusercontent.com/gps-cs-s/AHRPTWk0lycQOr7G_2oWSLSEpBlBBfN0wY5jwgISonycKD0xeg__AHXxCEpS3XqlR9IcD1alML-r6P2EvsCMBx_Lt3KN8sOYNRZU4Jouiz7gc8JcjOskWyeb7HyYDCnqD1bR4L-24cbbvm9TvXHm=s150-w92-h150-n-k-no
                  images:
                  - thumbnail: https://lh3.googleusercontent.com/gps-cs-s/AHRPTWk0lycQOr7G_2oWSLSEpBlBBfN0wY5jwgISonycKD0xeg__AHXxCEpS3XqlR9IcD1alML-r6P2EvsCMBx_Lt3KN8sOYNRZU4Jouiz7gc8JcjOskWyeb7HyYDCnqD1bR4L-24cbbvm9TvXHm=s287-w287-h192-n-k-no-v1
                    original: https://lh3.googleusercontent.com/gps-cs-s/AHRPTWk0lycQOr7G_2oWSLSEpBlBBfN0wY5jwgISonycKD0xeg__AHXxCEpS3XqlR9IcD1alML-r6P2EvsCMBx_Lt3KN8sOYNRZU4Jouiz7gc8JcjOskWyeb7HyYDCnqD1bR4L-24cbbvm9TvXHm=s10000
                  nearby_places:
                  - name: Côte-de-Liesse / No 6400
                    category_code: 2
                    transportations:
                    - type: Walking
                      type_code: 2
                      duration: 2 min
                  deal: 27% less than usual
                  deal_description: Great Deal
                  deal_kind: below_usual_price
                  rate:
                    currency: CAD
                    check_in: '2029-03-14'
                    check_out: '2029-03-16'
                    nights: 2
                    price_per_night: $121
                    price_per_night_before_taxes: $102
                    extracted_price_per_night: 121.0
                    extracted_price_per_night_before_taxes: 101.67969
                    total_price: $242
                    total_price_before_taxes: $203
                    base: 203.35938
                    taxes: 38.640625
                    fees: 0.0
                    total: 242.0
                    before_taxes: 203.36
                    from_display_text: false
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-09-30T22:46:08.123Z'
                    source: google_hotels_search
                    source_kind: search_listing
                    collector: scrapingme.google_hotels_search
                    source_property_id: ChgImtDg_rW5k8iWARoLL2cvMXRzamQ4NncQAQ
                    requested_market: CA
                    requested_currency: CAD
                    returned_currency: CAD
                    egress_mode: direct
                    price_basis: stay_total_including_taxes_and_fees
                    derivation: normalized_upstream
                - type: vacation_rental
                  property_token: ChkQzZioqLvP4IUiGg0vZy8xMXpjZmhoMzJwEAI
                  name: HoMa Loft 206 – Bright, Modern & Easy Parking
                  link: https://www.host-me.ca/properties/69e924482b031c00122c840e
                  gps_coordinates:
                    latitude: 45.54264831542969
                    longitude: -73.53958129882812
                  country: CA
                  check_in_time: 4:00 PM
                  check_out_time: 10:00 AM
                  location_rating: 2.9
                  proximity_to_restaurants_rating: 2.5
                  airport_access_rating: 3.9
                  amenities:
                  - Air conditioning
                  - Kid-friendly
                  - Heating
                  - Ironing board
                  - Kitchen
                  - Microwave
                  excluded_amenities:
                  - No balcony
                  - No crib
                  - No elevator
                  essential_info:
                  - Entire apartment
                  - Sleeps 2
                  - 1 bedroom
                  - 1 bathroom
                  thumbnail: https://lh3.googleusercontent.com/grass-proxy/AIM7gW39AJ5sNUqWYbyQkdBH2YHq7dV63MGIYm0DnOBPevzdmKuKVhPt19sLNF1TWMEzHBW2kN-KopL4tXsF2coEPixiQxcAV6aM2SWxYoWA73riNVMyRVNI3QHt-96hRHLb5couboHdgW6G-tN6pu_pOwPJZdNGqL_RGKM9UOM7G9cUNeoBDdsqXM6hNg=s150-w92-h150-n-k-no
                  images:
                  - thumbnail: https://lh3.googleusercontent.com/grass-proxy/AIM7gW39AJ5sNUqWYbyQkdBH2YHq7dV63MGIYm0DnOBPevzdmKuKVhPt19sLNF1TWMEzHBW2kN-KopL4tXsF2coEPixiQxcAV6aM2SWxYoWA73riNVMyRVNI3QHt-96hRHLb5couboHdgW6G-tN6pu_pOwPJZdNGqL_RGKM9UOM7G9cUNeoBDdsqXM6hNg=s287-w287-h192-n-k-no-v1
                    original: https://lh3.googleusercontent.com/grass-proxy/AIM7gW39AJ5sNUqWYbyQkdBH2YHq7dV63MGIYm0DnOBPevzdmKuKVhPt19sLNF1TWMEzHBW2kN-KopL4tXsF2coEPixiQxcAV6aM2SWxYoWA73riNVMyRVNI3QHt-96hRHLb5couboHdgW6G-tN6pu_pOwPJZdNGqL_RGKM9UOM7G9cUNeoBDdsqXM6hNg=s10000
                  nearby_places:
                  - name: Montréal-Pierre Elliott Trudeau International Airport
                    category_code: 3
                    transportations:
                    - type: Taxi
                      type_code: 0
                      duration: 35 min
                    - type: Public transport
                      type_code: 3
                      duration: 1 hr 30 min
                  rate:
                    currency: CAD
                    check_in: '2029-03-14'
                    check_out: '2029-03-16'
                    nights: 2
                    price_per_night: $152
                    price_per_night_before_taxes: $138
                    extracted_price_per_night: 152.34
                    extracted_price_per_night_before_taxes: 138.49
                    total_price: $305
                    total_price_before_taxes: $277
                    base: 185.0
                    taxes: 27.70375
                    fees: 91.98
                    total: 304.68378
                    before_taxes: 276.98
                    from_display_text: false
                  sources:
                  - source: host-me
                    raw_source: host-me
                    displayed_prices:
                    - $138
                    - $152
                    partner_id: '420480647'
                    logo: //www.gstatic.com/travel-hotels/branding/icon_default.png
                    price_per_night: $152
                    price_per_night_before_taxes: $138
                    extracted_price_per_night: 152.0
                    extracted_price_per_night_before_taxes: 138.0
                    has_free_cancellation: true
                    free_cancellation_until: Oct 16
                    free_cancellation_time: 4:00 PM
                    is_featured: true
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-09-30T22:46:08.123Z'
                    source: google_hotels_search
                    source_kind: search_listing
                    collector: scrapingme.google_hotels_search
                    source_property_id: ChkQzZioqLvP4IUiGg0vZy8xMXpjZmhoMzJwEAI
                    requested_market: CA
                    requested_currency: CAD
                    returned_currency: CAD
                    egress_mode: direct
                    price_basis: stay_total_including_taxes_and_fees
                    derivation: normalized_upstream
                brands:
                - id: 33
                  title: Accor Live Limitless
                  children:
                  - id: 8
                    title: Fairmont Hotels and Resorts
                  - id: 47
                    title: Novotel
                  - id: 84
                    title: Sofitel
                - id: 18
                  title: Best Western International
                  children:
                  - id: 155
                    title: Best Western
                  - id: 104
                    title: Best Western Plus
                pagination:
                  records_from: 1
                  records_to: 20
                  next_page_token: CBI=
                warnings:
                - prices reflect this server's egress, not a verified CA exit; configure a market proxy for market-matched results
                meta:
                  wire_bytes: 214986
                  elapsed_s: 1.89
                  egress:
                    mode: direct
                    class: direct
                    pool: direct
                    attempts: 1
                    path:
                    - direct/direct:ok
                  skipped_records: 0
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/serp/google_hotels:
    post:
      tags:
      - SearchAPI compatibility
      summary: google_hotels destination search, drop-in
      description: |-
        Drop-in for SearchAPI's `engine=google_hotels`.

        Same request names and response hierarchy (`search_parameters`,
        `search_information`, `properties[]`, `brands[]`, `pagination`).
        Extracted prices are exact floats rather than rounded integers, and each
        property adds `prices[]` where Google attached seller rows. Filters this
        source cannot honour are refused with 422 instead of being ignored.

        Credits: 3 per page of results; an empty page and failed requests are free
      operationId: serp_google_hotels
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SerpGoogleHotelsRequest'
        required: true
      responses:
        '200':
          description: SearchAPI google_hotels shape; extracted prices are exact floats
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SerpGoogleHotelsResponse'
              example:
                search_metadata:
                  status: Success
                  created_at: '2026-09-30T22:46:08Z'
                  request_time_taken: 1.89
                  total_time_taken: 1.89
                search_parameters:
                  engine: google_hotels
                  q: hotels in Montreal
                  check_in_date: '2029-03-14'
                  check_out_date: '2029-03-16'
                  adults: 2
                  currency: CAD
                  gl: ca
                  hl: en
                  sort_by: relevance
                search_information:
                  total_results: 5778
                  location: Montreal
                  currency_matches_request: true
                properties:
                - type: hotel
                  property_token: ChgImtDg_rW5k8iWARoLL2cvMXRzamQ4NncQAQ
                  data_id: 0x4cc9178df6e67b8d:0x96904dcb5fd8281a
                  name: Radisson Hotel Montreal Airport
                  link: https://www.choicehotels.com/quebec/montreal/radisson-hotels/cnc37?mc=llgoxxpx
                  description: Modern lodging with a restaurant & an indoor pool, plus free WiFi & an airport shuttle.
                  gps_coordinates:
                    latitude: 45.4851544
                    longitude: -73.6909316
                  city: Montreal
                  country: CA
                  check_in_time: 3:00 PM
                  check_out_time: 11:00 AM
                  price_per_night:
                    price: $121
                    extracted_price: 121.0
                    price_before_taxes: $102
                    extracted_price_before_taxes: 101.67969
                  total_price:
                    price: $242
                    extracted_price: 242.0
                    price_before_taxes: $203
                    extracted_price_before_taxes: 203.36
                  deal: 27% less than usual
                  deal_description: Great Deal
                  nearby_places:
                  - name: Côte-de-Liesse / No 6400
                    transportations:
                    - type: Walking
                      duration: 2 min
                  hotel_class: 4-star hotel
                  extracted_hotel_class: 4
                  rating: 3.5
                  reviews: 2535
                  reviews_histogram:
                    '1': 443
                    '2': 220
                    '3': 396
                    '4': 674
                    '5': 802
                  location_rating: 3.1
                  proximity_to_things_to_do_rating: 3.2
                  proximity_to_restaurants_rating: 2.8
                  proximity_to_transit_rating: 2.5
                  airport_access_rating: 4.6
                  reviews_breakdown:
                  - name: Fitness
                    description: Fitness
                    total: 199
                    positive: 119
                    neutral: 13
                    negative: 67
                  - name: Pool
                    description: Pool
                    total: 107
                    positive: 78
                    neutral: 7
                    negative: 22
                  amenities:
                  - Breakfast ($)
                  - Free Wi-Fi
                  - Parking ($)
                  - Pools
                  - Hot tub
                  - Air conditioning
                  images:
                  - thumbnail: https://lh3.googleusercontent.com/gps-cs-s/AHRPTWk0lycQOr7G_2oWSLSEpBlBBfN0wY5jwgISonycKD0xeg__AHXxCEpS3XqlR9IcD1alML-r6P2EvsCMBx_Lt3KN8sOYNRZU4Jouiz7gc8JcjOskWyeb7HyYDCnqD1bR4L-24cbbvm9TvXHm=s287-w287-h192-n-k-no-v1
                    original: https://lh3.googleusercontent.com/gps-cs-s/AHRPTWk0lycQOr7G_2oWSLSEpBlBBfN0wY5jwgISonycKD0xeg__AHXxCEpS3XqlR9IcD1alML-r6P2EvsCMBx_Lt3KN8sOYNRZU4Jouiz7gc8JcjOskWyeb7HyYDCnqD1bR4L-24cbbvm9TvXHm=s10000
                  thumbnail: https://lh3.googleusercontent.com/gps-cs-s/AHRPTWk0lycQOr7G_2oWSLSEpBlBBfN0wY5jwgISonycKD0xeg__AHXxCEpS3XqlR9IcD1alML-r6P2EvsCMBx_Lt3KN8sOYNRZU4Jouiz7gc8JcjOskWyeb7HyYDCnqD1bR4L-24cbbvm9TvXHm=s150-w92-h150-n-k-no
                  currency: CAD
                - type: vacation_rental
                  property_token: ChkQzZioqLvP4IUiGg0vZy8xMXpjZmhoMzJwEAI
                  name: HoMa Loft 206 – Bright, Modern & Easy Parking
                  link: https://www.host-me.ca/properties/69e924482b031c00122c840e
                  gps_coordinates:
                    latitude: 45.54264831542969
                    longitude: -73.53958129882812
                  city: Montreal
                  country: CA
                  check_in_time: 4:00 PM
                  check_out_time: 10:00 AM
                  price_per_night:
                    price: $152
                    extracted_price: 152.34
                    price_before_taxes: $138
                    extracted_price_before_taxes: 138.49
                  total_price:
                    price: $305
                    extracted_price: 304.68
                    price_before_taxes: $277
                    extracted_price_before_taxes: 276.98
                  nearby_places:
                  - name: Montréal-Pierre Elliott Trudeau International Airport
                    transportations:
                    - type: Taxi
                      duration: 35 min
                    - type: Public transport
                      duration: 1 hr 30 min
                  location_rating: 2.9
                  proximity_to_restaurants_rating: 2.5
                  airport_access_rating: 3.9
                  amenities:
                  - Air conditioning
                  - Kid-friendly
                  - Heating
                  - Ironing board
                  - Kitchen
                  - Microwave
                  excluded_amenities:
                  - No balcony
                  - No crib
                  - No elevator
                  essential_info:
                  - Entire apartment
                  - Sleeps 2
                  - 1 bedroom
                  - 1 bathroom
                  images:
                  - thumbnail: https://lh3.googleusercontent.com/grass-proxy/AIM7gW39AJ5sNUqWYbyQkdBH2YHq7dV63MGIYm0DnOBPevzdmKuKVhPt19sLNF1TWMEzHBW2kN-KopL4tXsF2coEPixiQxcAV6aM2SWxYoWA73riNVMyRVNI3QHt-96hRHLb5couboHdgW6G-tN6pu_pOwPJZdNGqL_RGKM9UOM7G9cUNeoBDdsqXM6hNg=s287-w287-h192-n-k-no-v1
                    original: https://lh3.googleusercontent.com/grass-proxy/AIM7gW39AJ5sNUqWYbyQkdBH2YHq7dV63MGIYm0DnOBPevzdmKuKVhPt19sLNF1TWMEzHBW2kN-KopL4tXsF2coEPixiQxcAV6aM2SWxYoWA73riNVMyRVNI3QHt-96hRHLb5couboHdgW6G-tN6pu_pOwPJZdNGqL_RGKM9UOM7G9cUNeoBDdsqXM6hNg=s10000
                  thumbnail: https://lh3.googleusercontent.com/grass-proxy/AIM7gW39AJ5sNUqWYbyQkdBH2YHq7dV63MGIYm0DnOBPevzdmKuKVhPt19sLNF1TWMEzHBW2kN-KopL4tXsF2coEPixiQxcAV6aM2SWxYoWA73riNVMyRVNI3QHt-96hRHLb5couboHdgW6G-tN6pu_pOwPJZdNGqL_RGKM9UOM7G9cUNeoBDdsqXM6hNg=s150-w92-h150-n-k-no
                  prices:
                  - source: host-me
                    raw_source: host-me
                    displayed_prices:
                    - $138
                    - $152
                    partner_id: '420480647'
                    logo: //www.gstatic.com/travel-hotels/branding/icon_default.png
                    price_per_night: $152
                    price_per_night_before_taxes: $138
                    extracted_price_per_night: 152.0
                    extracted_price_per_night_before_taxes: 138.0
                    has_free_cancellation: true
                    free_cancellation_until: Oct 16
                    free_cancellation_time: 4:00 PM
                    is_featured: true
                  currency: CAD
                brands:
                - id: 33
                  title: Accor Live Limitless
                  children:
                  - id: 8
                    title: Fairmont Hotels and Resorts
                  - id: 47
                    title: Novotel
                  - id: 84
                    title: Sofitel
                - id: 18
                  title: Best Western International
                  children:
                  - id: 155
                    title: Best Western
                  - id: 104
                    title: Best Western Plus
                pagination:
                  records_from: 1
                  records_to: 20
                  next_page_token: CBI=
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/hotels/property:
    post:
      tags:
      - Google Hotels
      summary: 'One property''s details record: name, address, phone'
      description: |-
        The address-bearing render for one property token.

        The search card omits the mailing address; pinning the token answers
        with the details widget, parsed like any property card: name, mailing
        address, phone, rating, review count, class, times. Use it to confirm a
        `/v1/hotels/search` result is the property you meant before targeting it
        with rate or review calls. The stay dates it prices are transport for
        this call and not its answer.

        Credits: 3 (failed requests are free)
      operationId: google_hotels_property_details
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleHotelsPropertyRequest'
        required: true
      responses:
        '200':
          description: 'One property''s details record: name, mailing address, phone'
          content:
            application/json:
              schema: {}
              example:
                type: hotel
                property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                name: Hilton Chicago
                data_id: 0x880e2c99242c7a2f:0x4de3d4bb09dba1
                description: Modern lodging with a restaurant & an indoor pool.
                gps_coordinates:
                  latitude: 41.8722592
                  longitude: -87.624696
                country: US
                address: 720 S Michigan Ave, Chicago, IL 60605, United States
                phone: +1 312-922-4400
                check_in_time: 3:00 PM
                check_out_time: 11:00 AM
                hotel_class: 3-star hotel
                extracted_hotel_class: 3
                rating: 4.3
                reviews: 10999
                reviews_histogram:
                  '1': 596
                  '2': 428
                  '3': 880
                  '4': 2607
                  '5': 6488
                reviews_breakdown: []
                amenities:
                - Free Wi-Fi
                - Indoor pool
                amenity_codes:
                - - 1
                  - 165
                excluded_amenities: []
                essential_info: []
                thumbnail: https://lh3.googleusercontent.com/gps-cs-s/REDACTED
                images: []
                nearby_places: []
                rate:
                  currency: USD
                  check_in: '2029-03-19'
                  check_out: '2029-03-20'
                  nights: 1
                  from_display_text: false
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/hotels/resolve:
    post:
      tags:
      - Google Hotels
      summary: Find properties by name and place, with addresses
      description: |-
        Look up a hotel by name and place, identify it by address.

        Runs the destination search for `q` (name plus city, region or country;
        `gl` biases the market), then fetches each of the top `limit`
        candidates' details record to attach the mailing address and phone. The
        answer lists the properties with their `property_token`, ready for
        `/v1/calendar`, `/v1/offers` and `/v1/hotels/reviews`, so the lookup
        happens once and the token is stored.

        Credits: 12 (failed requests are free)
      operationId: google_hotels_resolve
      x-credits: 12
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleHotelsResolveRequest'
        required: true
      responses:
        '200':
          description: Properties matching a name and place, each with its property token and mailing address
          content:
            application/json:
              schema: {}
              example:
                search_parameters:
                  q: Hilton Chicago
                  gl: us
                  hl: en
                  currency: USD
                  limit: 3
                location: Chicago
                properties:
                - property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  name: Hilton Chicago
                  rating: 4.3
                  reviews: 10999
                  type: hotel
                  address: 720 S Michigan Ave, Chicago, IL 60605, United States
                  phone: +1 312-922-4400
                - property_token: ChgImtDg_rW5k8iWARoLL2cvMXRzamQ4NncQAQ
                  name: Hilton Chicago/Magnificent Mile Suites
                  rating: 4.2
                  reviews: 2808
                  type: hotel
                  address: 540 N Michigan Ave, Chicago, IL 60611, United States
                  phone: +1 312-661-0640
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/hotels/reviews:
    post:
      tags:
      - Google Hotels
      summary: Guest reviews, aggregated by provider
      description: |-
        Google Hotels guest reviews for one property token.

        Google mixes its own reviews with Tripadvisor's, Priceline's and
        others'; each row names its `provider` and keeps that provider's rating
        scale (5 for Google/Tripadvisor, 10 for Priceline) rather than a silently
        renormalised one. Ten reviews per page; `pages` follows Google's
        continuation token, and `next_page_token` continues past that.

        Credits: 2 (failed requests are free)
      operationId: google_hotels_reviews
      x-credits: 2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoogleHotelsReviewsRequest'
        required: true
      responses:
        '200':
          description: Google Hotels guest reviews, aggregated by provider with each row's own rating scale
          content:
            application/json:
              schema: {}
              example:
                source: google
                property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                offset: 0
                limit: 10
                next_page_token: CjEIARIpCgoAP7_LACnN____EhAgaDet6skqGaNbIqMAAAAAGgn92PwCYGHGd2UYACIA:10
                count: 3
                reviews:
                - source: google
                  review_id: Ci9DQUlRQUNvZENodHljRjlvT25SZmJHOVBVMHh0VTJkSlNsa3lMVmMxZVMxMWVtYxAB
                  rating: 3.0
                  text: We stayed here for one night during a trip to Chicago, and overall, the hotel served its purpose, but I don't think we'd book here again.
                  date: a month ago
                  author: Amber S
                  management_reply: Dear Amber, thank you for choosing us for your stay.
                  provider: Google
                - source: google
                  review_id: ChdDSUhNMG9nS0VQLXBpdUc4aE5peXZ3RRAB
                  rating: 4.0
                  text: It is a magnificent old building with spacious rooms.
                  date: 4 weeks ago
                  author: adflanagan13
                  url: https://www.tripadvisor.com/ShowUserReviews-g35805-d87590-r1075812531
                  provider: Tripadvisor
                - source: google
                  review_id: ChdDSUhNMG9nS0VJYVBqUG1LMGJmZzBnRRAB
                  rating: 9.0
                  text: The location, having access to the pool and fitness center, was just lovely.
                  date: 5 months ago
                  author: Ronald
                  provider: Priceline
                provenance:
                  schema_version: 1
                  observation_id: rateobs_0123456789abcdef0123456789abcdef
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
                  source: google_hotels_calendar
                  source_kind: calendar
                  collector: scrapingme.google_calendar
                  source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  requested_market: US
                  requested_currency: USD
                  returned_currency: USD
                  egress_mode: direct
                  price_basis: room_base_before_taxes_and_fees
                  derivation: normalized_upstream
                wire_bytes: 40175
                elapsed_s: 0.388
                egress_mode: direct
                collection_id: ratecol_0123456789abcdef0123456789abcdef
                observed_at: '2026-08-07T01:23:45.678Z'
                warnings: []
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/ota/sources:
    get:
      tags:
      - Cross-source
      summary: What each source supports, and what it costs
      description: |-
        What each OTA can actually answer.

        Published because the three are not interchangeable — one returns a whole
        horizon, the others one date; only Agoda breaks out rooms — and a caller
        should pick on capability rather than by trial and error.

        Credits: 0 (failed requests are free)
      operationId: ota_source_matrix
      x-credits: 0
      responses:
        '200':
          description: Per-source capability matrix — granularity, identifier type, and whether a browser token is needed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OtaSourcesResponse'
              example:
                sources:
                  booking:
                    engine: booking_calendar
                    primary_operation: calendar
                    identifier: pagename (URL slug) + country
                    granularity: daily lowest rate
                    multi_date: true
                    max_dates_per_call: 61
                    per_room: false
                    currency_selectable: true
                    needs_browser_token: true
                    operations:
                      search:
                        supported: true
                        needs_browser_token: true
                        available: true
                      rates:
                        supported: true
                        needs_browser_token: true
                        available: true
                      rooms:
                        supported: true
                        needs_browser_token: true
                        available: true
                      calendar:
                        supported: true
                        needs_browser_token: true
                        available: true
                    notes: Cheapest horizon sweep. A year costs 6 calls / ~33 KB.
                    available: true
                  hotels:
                    engine: hotels_property
                    primary_operation: rates
                    identifier: numeric property id
                    granularity: headline price for one stay window
                    multi_date: false
                    max_dates_per_call: 1
                    per_room: false
                    currency_selectable: true
                    currency_mechanism: point-of-sale
                    markets:
                    - AU
                    needs_browser_token: true
                    operations:
                      search:
                        supported: true
                        needs_browser_token: false
                        available: true
                      rates:
                        supported: true
                        needs_browser_token: true
                        available: true
                      rooms:
                        supported: true
                        needs_browser_token: true
                        available: true
                      calendar:
                        supported: false
                        needs_browser_token: false
                        available: false
                        unavailable_reason: not supported
                    notes: No calendar exists; one call per date. Prices are NOT comparable across markets …
                    available: true
                  agoda:
                    engine: agoda_property
                    primary_operation: rates
                    identifier: numeric property id
                    granularity: every room type and rate plan
                    multi_date: false
                    max_dates_per_call: 1
                    per_room: true
                    currency_selectable: true
                    currencies:
                    - AED
                    needs_browser_token: false
                    operations:
                      search:
                        supported: true
                        needs_browser_token: false
                        available: true
                      rates:
                        supported: true
                        needs_browser_token: false
                        available: true
                      rooms:
                        supported: true
                        needs_browser_token: false
                        available: true
                      calendar:
                        supported: false
                        needs_browser_token: false
                        available: false
                        unavailable_reason: not supported
                    notes: No anti-bot gate. Richest per-date answer, and its currencies are genuine FX con…
                    available: true
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v1/ota/booking/search:
    post:
      tags:
      - Booking.com
      summary: Find a Booking.com slug by hotel name
      description: |-
        Resolve a hotel name to Booking.com's country/slug identifier.

        Add `city` whenever possible. A slug is stable, so search once during
        onboarding and store `recommended_match` for calendar and room calls.
        It is null when only weak or ambiguous candidates were found; `matches`
        remains available for manual review.

        Credits: 1 (failed requests are free)
      operationId: booking_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookingSearchRequest'
        required: true
      responses:
        '200':
          description: Candidate Booking.com URL slugs, ranked against the requested hotel name
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingSearchResponse'
              example:
                search_parameters:
                  engine: booking_search
                  name: Moxy Boston Downtown
                  city: Boston
                  limit: 5
                search_status: matched
                recommended_match:
                  pagename: moxy-boston-downtown
                  country: us
                  name: Moxy Boston Downtown
                  url: https://www.booking.com/hotel/us/moxy-boston-downtown.html
                  rank: 0
                  name_score: 1.0
                  identity_score: 1.0
                  match_score: 1.0
                  confidence: high
                warnings: []
                matches:
                - pagename: moxy-boston-downtown
                  country: us
                  name: Moxy Boston Downtown
                  url: https://www.booking.com/hotel/us/moxy-boston-downtown.html
                  rank: 0
                  name_score: 1.0
                  identity_score: 1.0
                  match_score: 1.0
                  confidence: high
                meta:
                  source: booking
                  matches: 1
                  selection_method: name_city_confidence
                  match_threshold: 0.8
                  match_margin: 0.12
                  wire_bytes: 1384521
                  elapsed_s: 1.214
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/booking:
    post:
      tags:
      - Booking.com
      summary: Price calendar — 61 dates per call
      description: |-
        Booking.com forward horizon — 61 dates per call.

        Credits: 8 (failed requests are free)
      operationId: booking_calendar
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookingRequest'
        required: true
      responses:
        '200':
          description: Booking's own calendar. Paged past its 61-day cap automatically
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingCalendarResponse'
              example:
                search_parameters:
                  engine: booking_calendar
                  pagename: moxy-boston-downtown
                  country: us
                  start_date: '2029-02-05'
                  days: 3
                  currency: USD
                  adults: 2
                  rooms: 1
                property:
                  pagename: moxy-boston-downtown
                  hotel_id: 5375786
                calendar:
                - stay_date: '2029-02-05'
                  available: true
                  price: 453.0
                  currency: USD
                  min_length_of_stay: 1
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: booking_com
                    source_kind: ota_calendar
                    collector: scrapingme.ota.booking
                    source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: room_base_before_taxes_and_fees
                    derivation: normalized_upstream
                - stay_date: '2029-02-06'
                  available: false
                  price: null
                  currency: USD
                  min_length_of_stay: 1
                unavailable_dates:
                - '2029-02-06'
                - '2029-02-07'
                meta:
                  source: booking
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
                  calls: 1
                  wire_bytes: 454
                  elapsed_s: 2.147
                  dates: 3
                  priced: 1
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/hotels/search:
    post:
      tags:
      - Hotels.com
      summary: Find a Hotels.com property id by hotel name
      description: |-
        Resolve a hotel name to Hotels.com's numeric property identifier.

        This uses Hotels.com's lightweight typeahead response. Add `city` to disambiguate common brands,
        then store `recommended_match.property_id` for headline-price and room
        calls. It is null when only weak or ambiguous candidates were found.

        Credits: 1 (failed requests are free)
      operationId: hotels_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HotelsSearchRequest'
        required: true
      responses:
        '200':
          description: Candidate Hotels.com numeric property ids, with city-aware ranking
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HotelsSearchResponse'
              example:
                search_parameters:
                  engine: hotels_search
                  name: Moxy Boston Downtown
                  city: Boston
                  market: US
                  limit: 5
                search_status: matched
                recommended_match:
                  property_id: '38766175'
                  name: Moxy Boston Downtown
                  city: Boston
                  address: 240 TREMONT STREET, Boston, MA
                  country: USA
                  url: https://www.hotels.com/ho38766175
                  rank: 0
                  score: 1.0
                  name_score: 1.0
                  identity_score: 1.0
                  match_score: 1.0
                  confidence: high
                  city_score: 1.0
                  winner_reason: EXACT_MATCH
                  coordinates:
                    latitude: 42.350952
                    longitude: -71.064804
                warnings: []
                matches:
                - property_id: '38766175'
                  name: Moxy Boston Downtown
                  city: Boston
                  address: 240 TREMONT STREET, Boston, MA
                  country: USA
                  url: https://www.hotels.com/ho38766175
                  rank: 0
                  score: 1.0
                  name_score: 1.0
                  identity_score: 1.0
                  match_score: 1.0
                  confidence: high
                  city_score: 1.0
                  winner_reason: EXACT_MATCH
                  coordinates:
                    latitude: 42.350952
                    longitude: -71.064804
                meta:
                  source: hotels
                  matches: 1
                  selection_method: name_city_confidence
                  match_threshold: 0.8
                  match_margin: 0.12
                  wire_bytes: 921
                  elapsed_s: 0.184
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/hotels:
    post:
      tags:
      - Hotels.com
      summary: Headline price for one stay window
      description: |-
        Hotels.com headline price for one stay window.

        One small request.
        `price_per_night` is the sticky bar's lead price, as it always was; on
        the US and DE points-of-sale that is the stay total including taxes and
        fees, so `price_per_night_is` says which it is and `total`/`nightly`
        carry the labelled figures. An unbookable stay is `available: false`
        with Hotels.com's own `unavailable_reason`, billed like any other
        answer; only a reply with nothing in it is free.

        Credits: 8 (failed requests are free)
      operationId: hotels_price
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HotelsRequest'
        required: true
      responses:
        '200':
          description: 'Headline price for one window, measured on www.hotels.com. `price_per_night` is the sticky bar''s lead price as before; here (`price_per_night_is: stay_total`) that is the stay total, and `nightly` is Hotels.com''s own nightly figure before taxes and fees. `currency` is what the point-of-sale actually priced in'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HotelsPriceResponse'
              example:
                search_parameters:
                  engine: hotels_property
                  property_id: '12570'
                  check_in_date: '2029-04-10'
                  check_out_date: '2029-04-11'
                  adults: 2
                  market: US
                  currency: USD
                property:
                  property_id: '12570'
                  price_per_night: 475.0
                  price_per_night_is: stay_total
                  total: 475.0
                  nightly: 374.0
                  lead_text: $475
                  total_text: $475
                  nightly_text: $374 nightly
                  currency: USD
                  currency_verified: true
                  available: true
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: hotels_com
                    source_kind: ota_offer
                    collector: scrapingme.ota.hotels
                    source_property_id: '12570'
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: stay_headline
                    derivation: parsed_display_price
                meta:
                  source: hotels
                  nights: 1
                  wire_bytes: 6066
                  egress_mode: direct
                  elapsed_s: 2.35
                  comparable_across_markets: false
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/ota/expedia/search:
    post:
      tags:
      - Expedia
      summary: Find an Expedia property id by hotel name
      description: |-
        Resolve a hotel name to Expedia's numeric property identifier.

        Uses Expedia's own typeahead (one small request). Add `city`
        to disambiguate brands, then store `recommended_match.property_id` for
        `POST /v1/ota/expedia`. It is null when only weak or ambiguous candidates
        were found. Expedia ids match Hotels.com's for newer properties only.

        Credits: 1 (failed requests are free)
      operationId: expedia_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExpediaSearchRequest'
        required: true
      responses:
        '200':
          description: Candidate Expedia numeric property ids, with city-aware ranking
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExpediaSearchResponse'
              example:
                search_parameters:
                  engine: expedia_search
                  name: Hilton Chicago
                  city: Chicago
                  market: US
                  limit: 5
                search_status: matched
                recommended_match:
                  property_id: '12570'
                  name: Hilton Chicago
                  city: Chicago
                  address: 720 S Michigan Ave, Chicago, IL
                  country: USA
                  url: https://www.expedia.com/h12570.Hotel-Information
                  rank: 0
                  score: 1.0
                  name_score: 1.0
                  identity_score: 1.0
                  match_score: 1.0
                  confidence: high
                  city_score: 1.0
                  winner_reason: ''
                  coordinates:
                    latitude: 41.872505
                    longitude: -87.62482
                warnings: []
                matches:
                - property_id: '12570'
                  name: Hilton Chicago
                  city: Chicago
                  address: 720 S Michigan Ave, Chicago, IL
                  country: USA
                  url: https://www.expedia.com/h12570.Hotel-Information
                  rank: 0
                  match_score: 1.0
                  confidence: high
                meta:
                  source: expedia
                  matches: 1
                  selection_method: name_city_confidence
                  match_threshold: 0.8
                  match_margin: 0.12
                  wire_bytes: 4008
                  elapsed_s: 0.31
                  egress_mode: direct
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/ota/expedia:
    post:
      tags:
      - Expedia
      summary: Rooms, rate plans and headline for one stay window
      description: |-
        Expedia's own rooms and rate plans.

        One request per stay. Each offer has the upstream
        stay `total` (Expedia labels it "Total with taxes and fees"), the upstream
        `nightly` price before taxes, `taxes_and_fees` derived from the two (see
        its provenance), cancellation terms read from the policy selector, and
        the payment model. `available` is false with Expedia's own
        `unavailable_reason` when the stay cannot be booked as asked - a minimum
        stay, for instance. That answer is billed like any other: only a reply
        with nothing in it is free.

        Credits: 8 (failed requests are free)
      operationId: expedia_rates
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExpediaRequest'
        required: true
      responses:
        '200':
          description: Headline plus rooms and rate plans. `total` is upstream (taxes and fees included); `taxes_and_fees` is derived and says so in its provenance
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExpediaRatesResponse'
              example:
                search_parameters:
                  engine: expedia_property
                  property_id: '12570'
                  check_in_date: '2029-04-10'
                  check_out_date: '2029-04-11'
                  adults: 2
                  market: US
                  currency: USD
                  rooms: true
                property:
                  property_id: '12570'
                  total: 475.0
                  price_per_night: 374.0
                  basis: sticky_bar
                  total_text: $475
                  nightly_text: $374 nightly
                  currency: USD
                  currency_verified: true
                  available: true
                  cheapest_total: 475.0
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: expedia_com
                    source_kind: ota_offer
                    collector: scrapingme.ota.expedia
                    source_property_id: '12570'
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: stay_headline
                    derivation: upstream
                rooms:
                - unit_id: '403873'
                  name: Room, 1 King Bed
                  cheapest_total: 635.0
                  offers:
                  - plan_id: '266071241'
                    room_type_id: '403873'
                    total: 635.0
                    nightly: 509.0
                    taxes_and_fees: 126.0
                    currency: USD
                    total_text: $635 total
                    nightly_text: $509 nightly
                    taxes_and_fees_included: true
                    payment_model: PAY_NOW
                    hotel_collect: false
                    member_only: false
                    refundable: false
                    cancellation_text: Non-Refundable
                    extras_text: No extras
                    strikeout_text: ''
                    inventory_type: MERCHANT
                    business_model: EXPEDIA_COLLECT
                    messages: []
                    provenance:
                      schema_version: 1
                      observation_id: rateobs_0123456789abcdef0123456789abcdef
                      collection_id: ratecol_0123456789abcdef0123456789abcdef
                      observed_at: '2026-08-07T01:23:45.678Z'
                      source: expedia_com
                      source_kind: ota_rate_plan
                      collector: scrapingme.ota.expedia
                      source_property_id: '12570'
                      requested_market: US
                      requested_currency: USD
                      returned_currency: USD
                      egress_mode: direct
                      price_basis: stay_total_including_taxes_and_fees
                      derivation: upstream
                      upstream_rate_id: '266071241'
                    taxes_and_fees_provenance:
                      schema_version: 1
                      observation_id: rateobs_0123456789abcdef0123456789abcdef
                      collection_id: ratecol_0123456789abcdef0123456789abcdef
                      observed_at: '2026-08-07T01:23:45.678Z'
                      source: expedia_com
                      source_kind: ota_rate_plan
                      collector: scrapingme.ota.expedia
                      source_property_id: '12570'
                      requested_market: US
                      requested_currency: USD
                      returned_currency: USD
                      egress_mode: direct
                      price_basis: taxes_and_fees_combined
                      derivation: total_minus_nightly_times_nights
                      upstream_rate_id: '266071241'
                  - plan_id: '266071239'
                    room_type_id: '403873'
                    total: 742.0
                    nightly: 599.0
                    taxes_and_fees: 143.0
                    currency: USD
                    total_text: $742 total
                    nightly_text: $599 nightly
                    taxes_and_fees_included: true
                    payment_model: PAY_LATER
                    hotel_collect: true
                    member_only: false
                    refundable: true
                    cancellation_text: Fully refundable before Nov 14
                    extras_text: No extras
                    strikeout_text: ''
                    inventory_type: DIRECT_AGENCY
                    business_model: HOTEL_COLLECT
                    messages: []
                    provenance:
                      schema_version: 1
                      observation_id: rateobs_0123456789abcdef0123456789abcdef
                      collection_id: ratecol_0123456789abcdef0123456789abcdef
                      observed_at: '2026-08-07T01:23:45.678Z'
                      source: expedia_com
                      source_kind: ota_rate_plan
                      collector: scrapingme.ota.expedia
                      source_property_id: '12570'
                      requested_market: US
                      requested_currency: USD
                      returned_currency: USD
                      egress_mode: direct
                      price_basis: stay_total_including_taxes_and_fees
                      derivation: upstream
                      upstream_rate_id: '266071239'
                meta:
                  source: expedia
                  nights: 1
                  wire_bytes: 181597
                  elapsed_s: 0.62
                  room_types: 37
                  offers: 149
                  egress_mode: direct
                  comparable_across_markets: false
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/ota/vrbo/search:
    post:
      tags:
      - Vrbo
      summary: Vacation-rental listings with stay prices
      description: |-
        Search Vrbo by destination and dates.

        Returns Vrbo's recommended listings with the numeric `property_id` that
        `POST /v1/ota/vrbo` quotes, the listing id and URL, and Vrbo's own nightly
        and stay prices. One request returns up to 50 listings.

        Credits: 1 (failed requests are free)
      operationId: vrbo_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VrboSearchRequest'
        required: true
      responses:
        '200':
          description: Vrbo listings with the property id that the quote endpoint takes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VrboSearchResponse'
              example:
                search_parameters:
                  engine: vrbo_search
                  destination: South Lake Tahoe, California
                  check_in_date: '2029-04-10'
                  check_out_date: '2029-04-13'
                  adults: 2
                  market: US
                  currency: USD
                  limit: 10
                summary:
                  matched_properties: 359
                  results_heading: Search results showing 359 properties in South Lake Tahoe, California
                listings:
                - property_id: '122942416'
                  listing_id: 20218736ha
                  name: Tahoe Keys Sunset Reflections
                  summary: House · 4 bedrooms · 4 Queen Beds
                  url: https://www.vrbo.com/20218736ha
                  nightly: 462.0
                  total: 1386.0
                  currency: USD
                  nightly_text: $462
                  total_text: $1,386 for 3 nights
                  fees_included: true
                  rank: 0
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: vrbo
                    source_kind: ota_search_listing
                    collector: scrapingme.ota.vrbo
                    source_property_id: '122942416'
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: stay_total_fees_included
                    derivation: upstream
                meta:
                  source: vrbo
                  listings: 1
                  wire_bytes: 107695
                  elapsed_s: 0.58
                  egress_mode: direct
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/ota/vrbo:
    post:
      tags:
      - Vrbo
      summary: Stay quote for one vacation rental
      description: |-
        A Vrbo stay quote: nightly and total price, fees and payment model.

        The total is Vrbo's own figure and `fees_included` repeats its "All fees
        included" label; cleaning and service fees and taxes are not itemised by
        Vrbo for this request, so they are not invented here. A stay Vrbo
        will not sell as asked (minimum stay, dates taken) returns
        `available: false` with Vrbo's reason, billed like any other answer.

        Credits: 8 (failed requests are free)
      operationId: vrbo_quote
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VrboRequest'
        required: true
      responses:
        '200':
          description: A Vrbo stay quote. `fees_included` repeats Vrbo's own label; fees and taxes are not itemised
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VrboQuoteResponse'
              example:
                search_parameters:
                  engine: vrbo_property
                  property_id: '122942416'
                  check_in_date: '2029-04-10'
                  check_out_date: '2029-04-13'
                  adults: 2
                  market: US
                  currency: USD
                property:
                  property_id: '122942416'
                  total: 1386.0
                  price_per_night: 462.0
                  basis: cheapest_offer
                  total_text: $1,386 for 3 nights
                  nightly_text: $462
                  fees_included: true
                  currency: USD
                  currency_verified: true
                  available: true
                  payment_model: PAY_LATER_WITH_DEPOSIT
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: vrbo
                    source_kind: ota_offer
                    collector: scrapingme.ota.vrbo
                    source_property_id: '122942416'
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: stay_headline
                    derivation: upstream
                offers:
                - plan_id: 0000f7528ddb0787463c9be9506a3b5eceb0
                  room_type_id: '122942416'
                  total: 1386.0
                  nightly: 462.0
                  currency: USD
                  total_text: $1,386 for 3 nights
                  nightly_text: $462
                  fees_included: true
                  payment_model: PAY_LATER_WITH_DEPOSIT
                  hotel_collect: true
                  member_only: false
                  inventory_type: VRBO
                  business_model: HOTEL_COLLECT
                  messages:
                  - Reserve now, pay deposit
                  - Your dates are available
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: vrbo
                    source_kind: ota_rate_plan
                    collector: scrapingme.ota.vrbo
                    source_property_id: '122942416'
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: stay_total_fees_included
                    derivation: upstream
                    upstream_rate_id: 0000f7528ddb0787463c9be9506a3b5eceb0
                meta:
                  source: vrbo
                  nights: 3
                  wire_bytes: 8065
                  listing_resolved: false
                  elapsed_s: 0.44
                  egress_mode: direct
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/ota/agoda/search:
    post:
      tags:
      - Agoda
      summary: Find an Agoda property id by hotel name
      description: |-
        Resolve a hotel name to Agoda's numeric property identifier.

        This uses Agoda's lightweight guest-facing suggestion endpoint. Add `city` to disambiguate common brands,
        then store `recommended_match.property_id` for room and rate-plan calls.
        It is null when only weak or ambiguous candidates were found.

        Credits: 1 (failed requests are free)
      operationId: agoda_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgodaSearchRequest'
        required: true
      responses:
        '200':
          description: Candidate Agoda numeric property ids, with city-aware ranking
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgodaSearchResponse'
              example:
                search_parameters:
                  engine: agoda_search
                  name: Moxy Boston Downtown
                  city: Boston
                  origin: US
                  limit: 5
                search_status: matched
                recommended_match:
                  property_id: '8795952'
                  name: Moxy Boston Downtown
                  city: Boston (MA)
                  country: US
                  location: Boston (MA), United States
                  rank: 0
                  score: 1.0
                  name_score: 1.0
                  identity_score: 1.0
                  match_score: 1.0
                  confidence: high
                  city_score: 1.0
                warnings: []
                matches:
                - property_id: '8795952'
                  name: Moxy Boston Downtown
                  city: Boston (MA)
                  country: US
                  location: Boston (MA), United States
                  rank: 0
                  score: 1.0
                  name_score: 1.0
                  identity_score: 1.0
                  match_score: 1.0
                  confidence: high
                  city_score: 1.0
                meta:
                  source: agoda
                  matches: 1
                  selection_method: name_city_confidence
                  match_threshold: 0.8
                  match_margin: 0.12
                  wire_bytes: 8144
                  elapsed_s: 0.221
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/agoda:
    post:
      tags:
      - Agoda
      summary: Rooms and rate plans for one night
      description: |-
        Agoda: every room type and rate plan for one stay window.

        Credits: 8 (failed requests are free)
      operationId: agoda_rooms
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AgodaRequest'
        required: true
      responses:
        '200':
          description: Agoda rooms and rate plans
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgodaRoomsResponse'
              example:
                search_parameters:
                  engine: agoda_property
                  property_id: '8795952'
                  check_in_date: '2029-02-05'
                  check_out_date: '2029-02-06'
                  adults: 2
                  rooms: 1
                  currency: USD
                property:
                  property_id: '8795952'
                  name: Moxy Boston Downtown
                  price_per_night: 527.0
                  currency: USD
                  tax_inclusive: true
                  sold_out: false
                  rooms:
                  - name: Center Stage, Guest room, 1 Queen, City view
                    offers:
                    - price: 527.0
                      currency: USD
                      currency_code: USD
                      price_text: USD 527
                      tax_inclusive: true
                      discount: -29%
                      free_cancellation: false
                      provenance:
                        schema_version: 1
                        observation_id: rateobs_0123456789abcdef0123456789abcdef
                        collection_id: ratecol_0123456789abcdef0123456789abcdef
                        observed_at: '2026-08-07T01:23:45.678Z'
                        source: agoda
                        source_kind: ota_rate_plan
                        collector: scrapingme.ota.agoda
                        source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                        requested_market: US
                        requested_currency: USD
                        returned_currency: USD
                        egress_mode: direct
                        price_basis: room_base_before_taxes_and_fees
                        derivation: normalized_upstream
                meta:
                  source: agoda
                  nights: 1
                  wire_bytes: 117723
                  elapsed_s: 0.361
                  room_types: 5
                  offers: 9
                  comparable_across_markets: true
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/tripadvisor/search:
    post:
      tags:
      - Tripadvisor
      summary: Find a Tripadvisor locationId by hotel name
      description: |-
        **Not available yet.** Tripadvisor name search is not implemented in the current release: this operation always returns `502` with `{"detail": "TripadvisorError"}` (not charged). Take the `locationId` from the hotel's Tripadvisor URL instead — the digits after `-d` in `/Hotel_Review-g{geoId}-d{locationId}-...` — and pass it to `POST /v1/ota/tripadvisor`. The 200 example below shows the planned response shape.

        Resolve a hotel name to Tripadvisor's locationId.

        Tripadvisor uses locationId for both search and availability queries.
        Store `recommended_match.location_id` for pricing calls. It is null when
        only weak or ambiguous candidates were found.

        Credits: 1 (failed requests are free)
      operationId: tripadvisor_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TripadvisorSearchRequest'
        required: true
      responses:
        '200':
          description: Tripadvisor location search results with locationId
          content:
            application/json:
              schema: {}
              example:
                query: Moxy Boston Downtown
                matches:
                - location_id: '97679'
                  title: Moxy Boston Downtown
                  secondary_text: Boston, MA
                  place_type: HOTEL
                  hierarchy: Massachusetts > Boston
                recommended_match:
                  location_id: '97679'
                  title: Moxy Boston Downtown
                  secondary_text: Boston, MA
                  place_type: HOTEL
                  hierarchy: Massachusetts > Boston
                wire_bytes: 3245
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/tripadvisor:
    post:
      tags:
      - Tripadvisor
      summary: Metasearch prices for one stay window
      description: |-
        Tripadvisor metasearch: aggregated offers from multiple providers.

        Returns prices from Booking, Hotels.com, Expedia, and other providers as
        aggregated by Tripadvisor.

        Credits: 8 (failed requests are free)
      operationId: tripadvisor_prices
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TripadvisorRequest'
        required: true
      responses:
        '200':
          description: Metasearch aggregation of provider offers for one stay window
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TripadvisorPricesResponse'
              example:
                search_parameters:
                  engine: tripadvisor_property
                  location_id: '97679'
                  check_in_date: '2029-02-22'
                  check_out_date: '2029-02-23'
                  nights: 1
                  adults: 2
                  rooms: 1
                  currency: USD
                property:
                  location_id: '97679'
                  hotel_id: '97679'
                  price_per_night: 150.0
                  currency: USD
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: tripadvisor
                    source_kind: metasearch
                    collector: scrapingme.ota.tripadvisor
                    source_property_id: '97679'
                    requested_market: null
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: unknown
                    derivation: normalized_upstream
                offers:
                - price: 150.0
                  currency: USD
                  provider_name: booking.com
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: tripadvisor
                    source_kind: metasearch
                    collector: scrapingme.ota.tripadvisor
                    source_property_id: '97679'
                    requested_market: null
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: unknown
                    derivation: normalized_upstream
                - price: 155.0
                  currency: USD
                  provider_name: hotels.com
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: tripadvisor
                    source_kind: metasearch
                    collector: scrapingme.ota.tripadvisor
                    source_property_id: '97679'
                    requested_market: null
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: unknown
                    derivation: normalized_upstream
                meta:
                  source: tripadvisor
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
                  nights: 1
                  wire_bytes: 8456
                  elapsed_s: 0.342
                  offers: 2
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/expedia/reviews:
    post:
      tags:
      - Expedia
      summary: Guest reviews for one property, newest first
      description: |-
        Expedia guest reviews for one property.

        One POST, no cookies, no browser. Ratings are 0-10 parsed from the
        upstream score label; the "Verified review" disclaimer and "Liked: …"
        themes ride in `labels`, exactly as Expedia publishes them. Page by
        `start_index += size`.

        Credits: 2 (failed requests are free)
      operationId: expedia_reviews
      x-credits: 2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExpediaReviewsRequest'
        required: true
      responses:
        '200':
          description: One page of Expedia guest reviews with the property's replies
          content:
            application/json:
              schema: {}
              example:
                source: expedia
                property_id: '12570'
                total: 3324
                offset: 0
                limit: 10
                rating_scale: 10.0
                count: 2
                reviews:
                - source: expedia
                  review_id: 6aa5f679b71e666498336ee6
                  rating: 10.0
                  text: Great hotel and location!
                  date: '2029-02-04'
                  author: Rebecca
                  management_reply: Dear Valued Guest, it's wonderful to receive your outstanding rating of Hilton Chicago!
                  language: en_CA
                  helpful_votes: 0
                  labels:
                  - 'Liked: Cleanliness, staff & service, amenities, property conditions & facilities'
                  - Verified review
                  stay_info: Stayed 4 nights in Sep 2026
                - source: expedia
                  review_id: f2b3a1d0c5e266498336ee7
                  rating: 10.0
                  text: Beautiful historic property, comfortable beds.
                  date: '2029-01-11'
                  author: Jazmin
                  language: en_US
                  labels:
                  - 'Liked: Cleanliness'
                  - Verified review
                  stay_info: Stayed 3 nights in Aug 2026
                provenance:
                  schema_version: 1
                  observation_id: rateobs_0123456789abcdef0123456789abcdef
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
                  source: google_hotels_calendar
                  source_kind: calendar
                  collector: scrapingme.google_calendar
                  source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  requested_market: US
                  requested_currency: USD
                  returned_currency: USD
                  egress_mode: direct
                  price_basis: room_base_before_taxes_and_fees
                  derivation: normalized_upstream
                wire_bytes: 19859
                elapsed_s: 0.471
                egress_mode: direct
                collection_id: ratecol_0123456789abcdef0123456789abcdef
                observed_at: '2026-08-07T01:23:45.678Z'
                warnings: []
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/ota/hotels/reviews:
    post:
      tags:
      - Hotels.com
      summary: Guest reviews for one property, newest first
      description: |-
        Hotels.com guest reviews via the site's own registered reviews query.

        The same registered query Expedia answers, POSTed to the Hotels.com
        host with the Hotels.com point-of-sale. One POST, no browser; page by
        `start_index += size`.

        Credits: 2 (failed requests are free)
      operationId: hotels_reviews
      x-credits: 2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HotelsReviewsRequest'
        required: true
      responses:
        '200':
          description: Google Hotels guest reviews, aggregated by provider with each row's own rating scale
          content:
            application/json:
              schema: {}
              example:
                source: google
                property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                offset: 0
                limit: 10
                next_page_token: CjEIARIpCgoAP7_LACnN____EhAgaDet6skqGaNbIqMAAAAAGgn92PwCYGHGd2UYACIA:10
                count: 3
                reviews:
                - source: google
                  review_id: Ci9DQUlRQUNvZENodHljRjlvT25SZmJHOVBVMHh0VTJkSlNsa3lMVmMxZVMxMWVtYxAB
                  rating: 3.0
                  text: We stayed here for one night during a trip to Chicago, and overall, the hotel served its purpose, but I don't think we'd book here again.
                  date: a month ago
                  author: Amber S
                  management_reply: Dear Amber, thank you for choosing us for your stay.
                  provider: Google
                - source: google
                  review_id: ChdDSUhNMG9nS0VQLXBpdUc4aE5peXZ3RRAB
                  rating: 4.0
                  text: It is a magnificent old building with spacious rooms.
                  date: 4 weeks ago
                  author: adflanagan13
                  url: https://www.tripadvisor.com/ShowUserReviews-g35805-d87590-r1075812531
                  provider: Tripadvisor
                - source: google
                  review_id: ChdDSUhNMG9nS0VJYVBqUG1LMGJmZzBnRRAB
                  rating: 9.0
                  text: The location, having access to the pool and fitness center, was just lovely.
                  date: 5 months ago
                  author: Ronald
                  provider: Priceline
                provenance:
                  schema_version: 1
                  observation_id: rateobs_0123456789abcdef0123456789abcdef
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
                  source: google_hotels_calendar
                  source_kind: calendar
                  collector: scrapingme.google_calendar
                  source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  requested_market: US
                  requested_currency: USD
                  returned_currency: USD
                  egress_mode: direct
                  price_basis: room_base_before_taxes_and_fees
                  derivation: normalized_upstream
                wire_bytes: 40175
                elapsed_s: 0.388
                egress_mode: direct
                collection_id: ratecol_0123456789abcdef0123456789abcdef
                observed_at: '2026-08-07T01:23:45.678Z'
                warnings: []
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/ota/tripadvisor/reviews:
    post:
      tags:
      - Tripadvisor
      summary: Guest reviews, newest first as the site orders them
      description: |-
        Tripadvisor guest reviews for one locationId.

        One persisted-query request through the same session warmup pricing
        uses. Ratings are 0-5; each review keeps the author, stay type, stay
        date, management reply and language the site publishes. Page by
        `offset += limit`.

        Credits: 2 (failed requests are free)
      operationId: tripadvisor_reviews
      x-credits: 2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TripadvisorReviewsRequest'
        required: true
      responses:
        '200':
          description: One page of Tripadvisor guest reviews, newest first
          content:
            application/json:
              schema: {}
              example:
                source: tripadvisor
                property_id: '208453'
                total: 9023
                offset: 0
                limit: 10
                rating_scale: 5.0
                count: 2
                reviews:
                - source: tripadvisor
                  review_id: '1079997723'
                  rating: 5.0
                  title: Hilton times square fab hotel
                  text: if you are coming to New York hilton times square is the best for location . large spacious rooms great service , friendly staff , highly recommend
                  date: '2029-02-21'
                  author: Sue B
                  trip_type: FAMILY
                  stay_date: '2029-02-21'
                  management_reply: Dear Gayatri, it's a privilege to learn about your memorable stay with us!
                  language: en
                  helpful_votes: 0
                  url: /ShowUserReviews-g60763-d208453-r1079997723-Hilton_New_York_Times_Square-New_York_City_New_York.html
                - source: tripadvisor
                  review_id: '1076579565'
                  rating: 4.0
                  title: Good location
                  text: Rooms were comfortable, staff friendly.
                  date: '2029-02-19'
                  author: Nina
                  trip_type: BUSINESS
                  stay_date: '2029-02-19'
                  language: en
                  helpful_votes: 2
                  url: /ShowUserReviews-g60763-d208453-r1076579565-Hilton_New_York_Times_Square-New_York_City_New_York.html
                provenance:
                  schema_version: 1
                  observation_id: rateobs_0123456789abcdef0123456789abcdef
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
                  source: google_hotels_calendar
                  source_kind: calendar
                  collector: scrapingme.google_calendar
                  source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  requested_market: US
                  requested_currency: USD
                  returned_currency: USD
                  egress_mode: direct
                  price_basis: room_base_before_taxes_and_fees
                  derivation: normalized_upstream
                wire_bytes: 15619
                elapsed_s: 0.412
                egress_mode: direct
                collection_id: ratecol_0123456789abcdef0123456789abcdef
                observed_at: '2026-08-07T01:23:45.678Z'
                warnings: []
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/booking/reviews:
    post:
      tags:
      - Booking.com
      summary: Guest reviews from the property page's own query document
      description: |-
        Booking.com guest reviews for one property slug.

        The bootstrap is the same WAF-cleared page fetch the calendar uses; it
        yields the CSRF token plus the numeric ids the reviews query needs.
        Ratings are 0-10; each review keeps the guest, their country, the room
        type, the stay dates, and the property's reply. `text` filters by
        keyword server-side. That answer is billed like any other: only a reply
        with nothing in it is free.

        Credits: 2 (failed requests are free)
      operationId: booking_reviews
      x-credits: 2
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookingReviewsRequest'
        required: true
      responses:
        '200':
          description: One page of Booking.com guest reviews with the property's replies
          content:
            application/json:
              schema: {}
              example:
                source: booking
                pagename: newbury-guest-house
                hotel_id: 236725
                ufi: 20061717
                country: us
                total: 523
                skip: 0
                limit: 10
                sort: MOST_RELEVANT
                rating_scale: 10.0
                count: 2
                reviews:
                - source: booking
                  review_id: 48b4dc6c098c149e
                  rating: 8.0
                  title: Good value, warm and inviting staff and very neat and clean rooms.
                  text: No breakfast but coffee/tea in lobby, location very good-on fanciest street in Boston and room was clean neat and comfortable.
                  date: '2026-10-15'
                  author: Anna
                  author_country: United States
                  stay_date: '2026-10-15'
                  room_type: Deluxe Room
                  management_reply: Hello Anna, we are pleased that you enjoyed your stay. We value your kind words and feedback.
                  language: xu
                  helpful_votes: 0
                  url: 48b4dc6c098c149e
                - source: booking
                  review_id: 23d02bc7e442bfa9
                  rating: 10.0
                  title: I will be returning to this hotel
                  text: This location was excellent. close to food and shops.
                  date: '2027-04-02'
                  author: Deborah
                  author_country: United States
                  stay_date: '2027-03-31'
                  room_type: Luxury Double
                  language: xu
                  helpful_votes: 0
                  url: 23d02bc7e442bfa9
                rating_scores:
                - name: Staff
                  value: 9.3
                  count: 258
                sorters:
                - value: MOST_RELEVANT
                  name: Most relevant
                - value: NEWEST_FIRST
                  name: Newest first
                - value: OLDEST_FIRST
                  name: Oldest first
                provenance:
                  schema_version: 1
                  observation_id: rateobs_0123456789abcdef0123456789abcdef
                  collection_id: ratecol_0123456789abcdef0123456789abcdef
                  observed_at: '2026-08-07T01:23:45.678Z'
                  source: google_hotels_calendar
                  source_kind: calendar
                  collector: scrapingme.google_calendar
                  source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  requested_market: US
                  requested_currency: USD
                  returned_currency: USD
                  egress_mode: direct
                  price_basis: room_base_before_taxes_and_fees
                  derivation: normalized_upstream
                wire_bytes: 14973
                elapsed_s: 0.521
                collection_id: ratecol_0123456789abcdef0123456789abcdef
                observed_at: '2026-08-07T01:23:45.678Z'
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/hostelworld:
    post:
      tags:
      - Hostelworld
      summary: Rooms and rate plans for one stay window
      description: |-
        Hostelworld: every dorm bed and private room with rate plans.

        Currency is NOT selectable — Hostelworld returns the property's native
        currency (typically GBP for UK hostels). Per-bed pricing for dorms,
        per-room pricing for privates.

        Credits: 8 (failed requests are free)
      operationId: hostelworld_rooms
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HostelworldRequest'
        required: true
      responses:
        '200':
          description: Hostelworld rooms and rate plans
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HostelworldResponse'
              example:
                search_parameters:
                  engine: hostelworld_property
                  property_id: '88047'
                  check_in_date: '2029-03-03'
                  check_out_date: '2029-03-04'
                  guests: 1
                property:
                  property_id: '88047'
                  price_per_night: 52.9
                  currency: GBP
                  sold_out: false
                  deposit_percentage: 15
                  free_cancellation_available: true
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: hostelworld
                    source_kind: ota_rate_plan
                    collector: scrapingme.ota.hostelworld
                    source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: room_base_before_taxes_and_fees
                    derivation: normalized_upstream
                  rooms:
                  - room_id: 383266
                    name: 8 Bed Mixed Dorm Ensuite
                    room_type: dorm
                    basic_type: Mixed Dorm
                    capacity: 8
                    ensuite: true
                    beds_available: 42
                    rate_plans:
                    - rate_plan_id: 151291
                      rate_plan_type: STANDARD
                      payment_procedure: depositPayable
                      payment_label: Deposit only
                      is_default: true
                      price: 52.9
                      original_price: 66.13
                      currency: GBP
                      min_nights: 1
                      restrictions: []
                      promotions:
                        discount: '20.00'
                      provenance:
                        schema_version: 1
                        observation_id: rateobs_0123456789abcdef0123456789abcdef
                        collection_id: ratecol_0123456789abcdef0123456789abcdef
                        observed_at: '2026-08-07T01:23:45.678Z'
                        source: hostelworld
                        source_kind: ota_rate_plan
                        collector: scrapingme.ota.hostelworld
                        source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                        requested_market: US
                        requested_currency: USD
                        returned_currency: USD
                        egress_mode: direct
                        price_basis: room_base_before_taxes_and_fees
                        derivation: normalized_upstream
                meta:
                  source: hostelworld
                  nights: 1
                  wire_bytes: 49946
                  elapsed_s: 0.284
                  dorms_count: 8
                  privates_count: 4
                  comparable_across_markets: false
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/booking/rooms:
    post:
      tags:
      - Booking.com
      summary: Room types and rate plans
      description: |-
        Booking.com room types and rate plans for one stay window.

        Fills the gap left by `/v1/rooms`: Google's entity page frequently carries
        no room detail for the Booking.com row, so this goes to Booking directly.

        Prices come from the property page's room grid, enriched with room
        size and occupancy when Booking.com provides them.

        Credits: 8 (failed requests are free)
      operationId: booking_rooms
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BookingRoomsRequest'
        required: true
      responses:
        '200':
          description: Room types with both rate plans — the cheap non-refundable one and the dearer free-cancellation one
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookingRoomsResponse'
              example:
                pagename: moxy-boston-downtown
                hotel_id: '5375786'
                property_name: Moxy Boston Downtown
                check_in: '2029-02-05'
                check_out: '2029-02-06'
                nights: 1
                currency: USD
                sold_out: false
                rendered: true
                catalogue_from_graphql: false
                cheapest_rate: 250.0
                wire_bytes: 2136057
                rooms:
                - name: Center Stage, Guest room, 1 Queen, City view
                  room_id: '537578602'
                  beds: 1 queen bed
                  room_size: 22.0
                  max_persons: 2
                  cheapest_rate: 250.0
                  rate_plans:
                  - block_id: '537578602_191393531_0_42_0'
                    price: 250.0
                    currency: USD
                    guests: 2
                    free_cancellation: false
                    no_prepayment: false
                    breakfast_included: false
                  - block_id: '537578602_246436396_0_42_0'
                    price: 269.0
                    currency: USD
                    guests: 2
                    free_cancellation: true
                    no_prepayment: true
                    breakfast_included: false
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/hotels/rooms:
    post:
      tags:
      - Hotels.com
      summary: Room types and rate plans
      description: |-
        Hotels.com room types and rate plans for one stay window.

        One request: the same document as
        `/v1/ota/hotels` with the room grid included. Each rate plan keeps its
        `price` (the card's lead price; on the US and DE points-of-sale the stay
        total including taxes and fees) and adds the labelled `total` and
        `nightly`, a derived `taxes_and_fees`, the payment model and the
        inventory source.

        ~100-200 KB against ~6 KB for the headline price, so use it on the dates
        that matter rather than sweeping a horizon.

        Credits: 8 (failed requests are free)
      operationId: hotels_rooms
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HotelsRoomsRequest'
        required: true
      responses:
        '200':
          description: Room types with rate plans, measured on www.hotels.com (Hilton Chicago, one night). `price` is the card's lead price - here the stay total including taxes and fees - and `total`/`nightly` are the labelled figures. A plan sold pay-now and pay-at-property is two rows
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HotelsRoomsResponse'
              example:
                property_id: '12570'
                market: US
                check_in: '2029-04-10'
                check_out: '2029-04-11'
                nights: 1
                currency: USD
                requested_currency: USD
                currency_verified: true
                available: true
                sold_out: false
                cheapest_rate: 475.0
                wire_bytes: 181614
                egress_mode: direct
                rooms:
                - name: Room, 2 Double Beds
                  unit_id: '16572'
                  cheapest_rate: 635.0
                  rate_plans:
                  - plan_id: '266071193'
                    price: 635.0
                    price_text: $635 total
                    currency: USD
                    refundable: false
                    refundable_until: ''
                    pay_now: true
                    provenance:
                      schema_version: 1
                      observation_id: rateobs_0123456789abcdef0123456789abcdef
                      collection_id: ratecol_0123456789abcdef0123456789abcdef
                      observed_at: '2026-08-07T01:23:45.678Z'
                      source: hotels_com
                      source_kind: ota_rate_plan
                      collector: scrapingme.ota.hotels_rooms
                      source_property_id: '12570'
                      requested_market: US
                      requested_currency: USD
                      returned_currency: USD
                      egress_mode: direct
                      price_basis: stay_rate_plan
                      derivation: upstream
                      upstream_rate_id: '266071193'
                    room_type_id: '16572'
                    payment_model: PAY_NOW
                    hotel_collect: false
                    total: 635.0
                    nightly: 509.0
                    taxes_and_fees: 126.0
                    taxes_and_fees_provenance:
                      schema_version: 1
                      observation_id: rateobs_0123456789abcdef0123456789abcdef
                      collection_id: ratecol_0123456789abcdef0123456789abcdef
                      observed_at: '2026-08-07T01:23:45.678Z'
                      source: hotels_com
                      source_kind: ota_rate_plan
                      collector: scrapingme.ota.hotels_rooms
                      source_property_id: '12570'
                      requested_market: US
                      requested_currency: USD
                      returned_currency: USD
                      egress_mode: direct
                      price_basis: taxes_and_fees_combined
                      derivation: total_minus_nightly_times_nights
                      upstream_rate_id: '266071193'
                    total_text: $635 total
                    nightly_text: $509 nightly
                    taxes_and_fees_included: true
                    cancellation_text: Non-Refundable
                    extras_text: No extras
                    member_only: false
                    inventory_type: MERCHANT
                    business_model: EXPEDIA_COLLECT
                  - plan_id: '266071191'
                    price: 742.0
                    price_text: $742 total
                    currency: USD
                    refundable: true
                    refundable_until: Nov 14
                    pay_now: false
                    room_type_id: '16572'
                    payment_model: PAY_LATER
                    hotel_collect: true
                    total: 742.0
                    nightly: 599.0
                    taxes_and_fees: 143.0
                    total_text: $742 total
                    nightly_text: $599 nightly
                    taxes_and_fees_included: true
                    cancellation_text: Fully refundable before Nov 14
                    extras_text: No extras
                    member_only: false
                    inventory_type: DIRECT_AGENCY
                    business_model: HOTEL_COLLECT
                - name: Suite, Multiple Beds, Non Smoking
                  unit_id: '325392434'
                  rate_plans: []
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/ota/compare:
    post:
      tags:
      - Cross-source
      summary: Rate parity across Booking, Hotels.com, Agoda and Expedia
      description: |-
        Fan out across every source given an identifier.

        Fail-soft per source: this returns 200 with per-source status even when one
        OTA is blocked, because losing three good answers to one bad one is worse
        than a partial result the caller can see. `comparison.comparable` is false
        for a single priced source or mixed currencies; mixed-currency minima and
        spreads are not calculated.

        Credits: 20 (failed requests are free)
      operationId: ota_compare
      x-credits: 20
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompareRequest'
        required: true
      responses:
        '200':
          description: 'One night per source. Fail-soft: a blocked OTA is a row with a status'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompareResponse'
              example:
                search_parameters:
                  engine: ota_compare
                  check_in_date: '2029-02-05'
                  check_out_date: '2029-02-06'
                  adults: 2
                  currency: USD
                  booking_pagename: moxy-boston-downtown
                  agoda_property_id: '8795952'
                comparison:
                  status: comparable
                  comparable: true
                  identifiers:
                    booking: moxy-boston-downtown
                    agoda: '8795952'
                  lowest_price: 285.0
                  lowest_source: booking
                  spread: 47.0
                  prices:
                    booking: 285.0
                    agoda: 332.0
                  currencies:
                    booking: USD
                    agoda: USD
                  price_provenance: {}
                  reason: Sources price on different bases (booking_display_average, total_including_taxes_and_fees); the headline minimum mixes them. Compare within `by_price_basis`.
                  price_basis_consistent: false
                  by_price_basis:
                    booking_display_average:
                      sources:
                      - booking
                      currencies:
                      - USD
                      lowest_source: booking
                      lowest_price_per_night: 285.0
                    total_including_taxes_and_fees:
                      sources:
                      - agoda
                      currencies:
                      - USD
                      lowest_source: agoda
                      lowest_price_per_night: 332.0
                sources:
                  booking:
                    status: ok
                    price_per_night: 285.0
                    currency: USD
                    price_basis: booking_display_average
                  agoda:
                    status: ok
                    price_per_night: 332.0
                    currency: USD
                    price_basis: total_including_taxes_and_fees
                meta:
                  requested: 2
                  ok: 2
                  elapsed_s: 15.89
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/official/engines:
    get:
      tags:
      - Official site
      summary: Supported booking engines and their cost
      description: |-
        Which booking engines can be scraped, and what each costs.

        Published because the spread is large — 0.2 s and no browser for
        SiteMinder against ~7 s and a browser per query for DerbySoft — and a
        caller batching a sweep should be able to plan around it.

        Credits: 0 (failed requests are free)
      operationId: official_engines
      x-credits: 0
      responses:
        '200':
          description: Booking engines the detector can route to, with browser cost. `identified_only` are active gaps; `retired` are historical products with no live flow
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialEnginesResponse'
              example:
                extractable:
                  accor:
                    browser: null
                    cost_s: 0.5
                  bookcore:
                    browser: null
                    cost_s: 1.0
                  channex:
                    browser: null
                    cost_s: 0.5
                  brand_choice:
                    browser: every query
                    cost_s: 9.0
                  derbysoft:
                    browser: every query
                    cost_s: 7.0
                  evt:
                    browser: every query
                    cost_s: 8.0
                  guestline:
                    browser: null
                    cost_s: 0.5
                  brand_hilton:
                    browser: every query
                    cost_s: 8.0
                  brand_ihg:
                    browser: null
                    cost_s: 1.0
                  ireshotels:
                    browser: null
                    cost_s: 1.0
                  cloudbeds:
                    browser: null
                    cost_s: 1.5
                  d_edge:
                    browser: every query
                    cost_s: 8.0
                  siteminder:
                    browser: null
                    cost_s: 0.2
                  seekda:
                    browser: null
                    cost_s: 1.0
                  minor:
                    browser: null
                    cost_s: 1.0
                  newbook:
                    browser: null
                    cost_s: 5.0
                  pointa:
                    browser: null
                    cost_s: 1.0
                  profitroom:
                    browser: null
                    cost_s: 2.5
                  mirai:
                    browser: null
                    cost_s: 1.0
                  simplebooking:
                    browser: null
                    cost_s: 1.0
                  resnexus:
                    browser: every query
                    cost_s: 7.0
                  ihotelier:
                    browser: once per token (hours)
                    cost_s: 0.3
                  innroad:
                    browser: once per session
                    cost_s: 1.5
                  langham:
                    browser: null
                    cost_s: 1.0
                  marriott:
                    browser: once per session
                    cost_s: 0.5
                  mews:
                    browser: null
                    cost_s: 1.5
                  rmscloud:
                    browser: null
                    cost_s: 1.0
                  thinkreservations:
                    browser: null
                    cost_s: 0.5
                  synxis:
                    browser: once per session
                    cost_s: 0.7
                  webrezpro:
                    browser: once per session
                    cost_s: 1.0
                  brand_wyndham:
                    browser: every query
                    cost_s: 7.0
                identified_only: []
                retired:
                - bookingcom_bs
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v1/official:
    post:
      tags:
      - Official site
      summary: Rates from the hotel's own booking engine
      description: |-
        Rates from the hotel's own booking engine.

        The hotel website is resolved to its booking page, then its booking engine is
        detected automatically. The caller never chooses a vendor.

        Credits: 4 (failed requests are free)
      operationId: official_rates
      x-credits: 4
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OfficialRequest'
        required: true
      responses:
        '200':
          description: Normalised public and member rates from the detected booking engine
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialResponse'
              example:
                search_parameters:
                  engine: official_marriott
                  source_url: https://www.marriott.com/en-us/hotels/yyzrz-the-ritz-carlton-toronto/overview/
                  booking_url: https://www.marriott.com/en-us/hotels/yyzrz-the-ritz-carlton-toronto/overview/
                  check_in_date: '2029-02-05'
                  check_out_date: '2029-02-06'
                  adults: 2
                  currency: CAD
                engine: marriott
                source_url: https://www.marriott.com/en-us/hotels/yyzrz-the-ritz-carlton-toronto/overview/
                booking_url: https://www.marriott.com/en-us/hotels/yyzrz-the-ritz-carlton-toronto/overview/
                detected_by: url
                discovery_pages: 0
                wrapper_resolutions: 0
                discovery_cache_hit: false
                discovery_elapsed_s: 0.001
                collection_id: ratecol_0123456789abcdef0123456789abcdef
                observed_at: '2026-08-07T01:23:45.678Z'
                property_ref: YYZRZ
                check_in: '2029-02-05'
                check_out: '2029-02-06'
                nights: 1
                currency: CAD
                sold_out: false
                cheapest_rate: 690.0
                cheapest_member_rate: 655.5
                member_rates_returned: 1
                rooms_returned: 1
                used_browser: false
                elapsed_s: 0.71
                rooms:
                - name: Deluxe King
                  code: GENR
                  max_occupancy: 2
                  quantity: 3
                  available: true
                  cheapest_rate: 690.0
                  rates:
                  - price: 690.0
                    price_total: 779.7
                    currency: CAD
                    rate_plan: Flexible
                    tax_inclusive: true
                    access_type: public
                    is_discounted: false
                    provenance:
                      schema_version: 1
                      observation_id: rateobs_0123456789abcdef0123456789abcdef
                      collection_id: ratecol_0123456789abcdef0123456789abcdef
                      observed_at: '2026-08-07T01:23:45.678Z'
                      source: official_marriott
                      source_kind: official
                      collector: scrapingme.official.marriott
                      source_property_id: YYZRZ
                      requested_market: US
                      requested_currency: USD
                      returned_currency: USD
                      egress_mode: direct
                      price_basis: room_base_before_taxes_and_fees
                      derivation: normalized_upstream
                  - price: 655.5
                    price_total: 740.72
                    original_price: 690.0
                    currency: CAD
                    rate_plan: Marriott Bonvoy Member
                    tax_inclusive: false
                    access_type: member
                    is_discounted: true
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/serp/airbnb:
    post:
      tags:
      - Airbnb
      summary: Airbnb search, SearchAPI-compatible
      description: |-
        Search Airbnb with SearchAPI's request names and response hierarchy.

        Each call runs one live Airbnb search. Use
        `next_page_token` from the response for the next page. The same engine is
        also available at SearchAPI's GET-style `/api/v1/search?engine=airbnb`.

        Credits: 8 (failed requests are free)
      operationId: serp_airbnb
      x-credits: 8
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AirbnbSearchRequest'
        required: true
      responses:
        '200':
          description: SearchAPI-compatible Airbnb destination results with live prices
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AirbnbSearchResponse'
              example:
                search_metadata:
                  id: search_2af4914e869a4a36958659ef
                  status: Success
                  created_at: '2026-08-06T18:46:11+00:00'
                  request_time_taken: 1.3
                  parsing_time_taken: 0.02
                  total_time_taken: 1.32
                  request_url: https://www.airbnb.ca/s/Toronto/homes?...
                  wire_bytes: 918246
                search_parameters:
                  engine: airbnb
                  airbnb_domain: airbnb.ca
                  currency: CAD
                  q: Toronto
                  check_in_date: '2029-02-01'
                  check_out_date: '2029-02-03'
                  adults: '2'
                  include_taxes: 'true'
                search_information:
                  query_displayed: Homes in Toronto, Canada
                  results: Over 1,000 homes in Toronto
                  check_in_date: '2029-02-01'
                  check_out_date: '2029-02-03'
                  adults: 2
                  guests: 2 guests
                properties:
                - position: 1
                  id: '734254017349424949'
                  title: Chic Studio w Balcony Fast WiFi by Yonge-Dundas
                  description: Condo in Toronto
                  link: https://www.airbnb.ca/rooms/734254017349424949
                  booking_link: https://www.airbnb.ca/rooms/734254017349424949?check_in=2026-09-10&check_out=2026-09-12&adults=2&children=0&infants=0&pets=0
                  booking_token: eyJjaGVja19pbiI6IjIwMjYtMDktMTAiLCJwcm9wZXJ0eV9pZCI6IjczNDI1NDAxNzM0OTQyNDk0OSJ9
                  rating: 4.96
                  reviews: 166
                  price:
                    total_price: $737 CAD
                    extracted_total_price: 737
                    total_with_taxes: $737 CAD
                    extracted_total_with_taxes: 737
                    qualifier: for 2 nights
                    extracted_qualifier: 2
                    price_per_qualifier: 2 nights x $310.00 CAD
                    extracted_price_per_qualifier: 310
                    breakdown:
                    - description: 2 nights x $310.00 CAD
                      price: $620.00 CAD
                      extracted_price: 620
                    - description: Taxes
                      price: $117.00 CAD
                      extracted_price: 117
                  check_in_date: '2029-02-01'
                  check_out_date: '2029-02-03'
                  time_period: Sep 10 – 12
                  accommodations:
                  - 1 bedroom
                  - 1 queen bed
                  - 1 bath
                  gps_coordinates:
                    latitude: 43.654
                    longitude: -79.38
                  has_free_cancellation: true
                  badges:
                  - Guest favourite
                  images:
                  - https://a0.muscache.com/im/pictures/example.jpeg
                pagination:
                  next_page_token: eyJzZWN0aW9uX29mZnNldCI6MH0=
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/search:
    get:
      tags:
      - Airbnb
      summary: SearchAPI GET alias for engine=airbnb
      description: |-
        Drop-in GET endpoint for existing SearchAPI Airbnb integrations.

        Keep ``engine=airbnb``, every existing query parameter and either the
        ``api_key`` query credential or Bearer token; only replace the origin.

        Credits: 8 (failed requests are free)
      operationId: searchapi_airbnb_get
      x-credits: 8
      parameters:
      - name: engine
        in: query
        required: false
        schema:
          type: string
          description: Must be `airbnb`.
          enum:
          - airbnb
          default: airbnb
          title: Engine
        description: Must be `airbnb`.
      - name: q
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Destination text. Required unless `bounding_box` is supplied.
          examples:
          - Toronto
          title: Q
        description: Destination text. Required unless `bounding_box` is supplied.
      - name: bounding_box
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Map bounds as `[[ne_lat,ne_lng],[sw_lat,sw_lng]]`; takes precedence over `q`.
          examples:
          - '[[43.72,-79.27],[43.62,-79.49]]'
          title: Bounding Box
        description: Map bounds as `[[ne_lat,ne_lng],[sw_lat,sw_lng]]`; takes precedence over `q`.
      - name: airbnb_domain
        in: query
        required: false
        schema:
          type: string
          description: Country/language Airbnb host.
          examples:
          - airbnb.ca
          enum:
          - airbnb.ae
          - airbnb.am
          - airbnb.at
          - airbnb.az
          - airbnb.ba
          - airbnb.be
          - airbnb.ca
          - airbnb.cat
          - airbnb.ch
          - airbnb.cl
          - airbnb.cn
          - airbnb.co.cr
          - airbnb.co.id
          - airbnb.co.in
          - airbnb.co.kr
          - airbnb.co.nz
          - airbnb.co.uk
          - airbnb.co.ve
          - airbnb.com
          - airbnb.com.ar
          - airbnb.com.au
          - airbnb.com.bo
          - airbnb.com.br
          - airbnb.com.bz
          - airbnb.com.co
          - airbnb.com.ec
          - airbnb.com.ee
          - airbnb.com.gt
          - airbnb.com.hk
          - airbnb.com.hn
          - airbnb.com.my
          - airbnb.com.ni
          - airbnb.com.pa
          - airbnb.com.pe
          - airbnb.com.ph
          - airbnb.com.py
          - airbnb.com.ro
          - airbnb.com.sg
          - airbnb.com.sv
          - airbnb.com.tr
          - airbnb.com.tw
          - airbnb.com.ua
          - airbnb.com.vn
          - airbnb.cz
          - airbnb.de
          - airbnb.dk
          - airbnb.es
          - airbnb.fi
          - airbnb.fr
          - airbnb.gr
          - airbnb.gy
          - airbnb.hu
          - airbnb.ie
          - airbnb.is
          - airbnb.it
          - airbnb.jp
          - airbnb.lt
          - airbnb.lu
          - airbnb.lv
          - airbnb.me
          - airbnb.mx
          - airbnb.nl
          - airbnb.no
          - airbnb.pl
          - airbnb.pt
          - airbnb.rs
          - airbnb.ru
          - airbnb.se
          - airbnb.si
          - ar.airbnb.com
          - bg.airbnb.com
          - de.airbnb.lu
          - es.airbnb.com
          - fr.airbnb.be
          - fr.airbnb.ca
          - fr.airbnb.ch
          - ga.airbnb.ie
          - he.airbnb.com
          - hi.airbnb.co.in
          - hr.airbnb.com
          - it.airbnb.ch
          - ka.airbnb.com
          - kn.airbnb.co.in
          - mk.airbnb.com
          - mr.airbnb.co.in
          - mt.airbnb.com.mt
          - sk.airbnb.com
          - sq.airbnb.com
          - sw.airbnb.com
          - th.airbnb.com
          - xh.airbnb.co.za
          - zh-t.airbnb.com
          - zh.airbnb.com
          - zu.airbnb.co.za
          default: airbnb.com
          title: Airbnb Domain
        description: Country/language Airbnb host.
      - name: currency
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Airbnb-supported ISO 4217 display currency.
          examples:
          - CAD
          enum:
          - AED
          - AUD
          - BAM
          - BGN
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CRC
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - GHS
          - GTQ
          - HKD
          - HNL
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KES
          - KRW
          - KZT
          - MAD
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - RUB
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - UAH
          - UGX
          - USD
          - UYU
          - VND
          - ZAR
          title: Currency
        description: Airbnb-supported ISO 4217 display currency.
      - name: include_taxes
        in: query
        required: false
        schema:
          type: boolean
          description: Include tax-inclusive totals when Airbnb exposes a tax line.
          default: false
          title: Include Taxes
        description: Include tax-inclusive totals when Airbnb exposes a tax line.
      - name: check_in_date
        in: query
        required: false
        schema:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          description: Exact check-in date in `YYYY-MM-DD` form.
          examples:
          - '2029-02-01'
          title: Check In Date
        description: Exact check-in date in `YYYY-MM-DD` form.
      - name: check_out_date
        in: query
        required: false
        schema:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          description: Exact check-out date; defaults to the next day.
          examples:
          - '2029-02-03'
          title: Check Out Date
        description: Exact check-out date; defaults to the next day.
      - name: time_period
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Flexible dates: `weekend_trip`, `one_week`, or `one_month`; cannot be mixed with exact dates.'
          examples:
          - weekend_trip
          enum:
          - one_month
          - one_week
          - weekend_trip
          title: Time Period
        description: 'Flexible dates: `weekend_trip`, `one_week`, or `one_month`; cannot be mixed with exact dates.'
      - name: adults
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Adults aged 13+, from 0 through 16.
          examples:
          - 2
          title: Adults
        description: Adults aged 13+, from 0 through 16.
      - name: children
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Children aged 2–12, from 0 through 15.
          examples:
          - 1
          title: Children
        description: Children aged 2–12, from 0 through 15.
      - name: infants
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Infants under 2, from 0 through 5.
          examples:
          - 1
          title: Infants
        description: Infants under 2, from 0 through 5.
      - name: pets
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Pets, from 0 through 5.
          examples:
          - 1
          title: Pets
        description: Pets, from 0 through 5.
      - name: price_min
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Minimum displayed trip price.
          examples:
          - 100
          title: Price Min
        description: Minimum displayed trip price.
      - name: price_max
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Maximum displayed trip price.
          examples:
          - 500
          title: Price Max
        description: Maximum displayed trip price.
      - name: type_of_place
        in: query
        required: false
        schema:
          type: string
          description: '`any`, `room`, or `entire_home`.'
          examples:
          - entire_home
          enum:
          - any
          - entire_home
          - room
          default: any
          title: Type Of Place
        description: '`any`, `room`, or `entire_home`.'
      - name: property_types
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Comma-separated `house`, `guesthouse`, `apartment`, and/or `hotel`.
          examples:
          - house,apartment
          x-options:
          - apartment
          - guesthouse
          - hotel
          - house
          x-multiple: true
          title: Property Types
        description: Comma-separated `house`, `guesthouse`, `apartment`, and/or `hotel`.
      - name: bedrooms
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Minimum bedrooms, from 0 through 8.
          examples:
          - 2
          title: Bedrooms
        description: Minimum bedrooms, from 0 through 8.
      - name: beds
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Minimum beds, from 0 through 8.
          examples:
          - 2
          title: Beds
        description: Minimum beds, from 0 through 8.
      - name: bathrooms
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
          - type: 'null'
          description: Minimum bathrooms, from 0 through 8.
          examples:
          - 1
          title: Bathrooms
        description: Minimum bathrooms, from 0 through 8.
      - name: amenities
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Comma-separated SearchAPI amenity names.
          examples:
          - wifi,kitchen
          x-options:
          - 24_hour_check_in
          - air_conditioning
          - bbq_grill
          - breakfast
          - buzzer_wireless_intercom
          - cable_tv
          - carbon_monoxide_alarm
          - cats
          - crib
          - dedicated_workspace
          - dogs
          - doorman
          - dryer
          - elevator
          - essentials
          - ev_charger
          - family_kid_friendly
          - fire_extinguisher
          - first_aid_kit
          - free_parking_on_premises
          - free_street_parking
          - garage_parking
          - guest_favorite
          - gym
          - hair_dryer
          - hangers
          - heating
          - hot_tub
          - indoor_fireplace
          - instant_book
          - internet
          - iron
          - jacuzzi_tub
          - kitchen
          - lock_on_bedroom_door
          - lockbox
          - luxe
          - other_pets
          - paid_parking_off_premises
          - permit_parking
          - pets_allowed
          - pets_live_on_this_property
          - pool
          - private_entrance
          - safety_card
          - self_check_in
          - shampoo
          - smoke_alarm
          - smoking_allowed
          - suitable_for_events
          - tv
          - washer
          - wheelchair_accessible
          - wifi
          x-multiple: true
          title: Amenities
        description: Comma-separated SearchAPI amenity names.
      - name: next_page_token
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Opaque cursor from `pagination.next_page_token` on the prior page.
          examples:
          - eyJzZWN0aW9uX29mZnNldCI6MH0=
          title: Next Page Token
        description: Opaque cursor from `pagination.next_page_token` on the prior page.
      - name: zero_retention
        in: query
        required: false
        schema:
          type: boolean
          description: Accepted for SearchAPI compatibility; raw search HTML and results are never persisted.
          default: false
          title: Zero Retention
        description: Accepted for SearchAPI compatibility; raw search HTML and results are never persisted.
      responses:
        '200':
          description: SearchAPI-compatible Airbnb destination results with live prices
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AirbnbSearchResponse'
              example:
                search_metadata:
                  id: search_2af4914e869a4a36958659ef
                  status: Success
                  created_at: '2026-08-06T18:46:11+00:00'
                  request_time_taken: 1.3
                  parsing_time_taken: 0.02
                  total_time_taken: 1.32
                  request_url: https://www.airbnb.ca/s/Toronto/homes?...
                  wire_bytes: 918246
                search_parameters:
                  engine: airbnb
                  airbnb_domain: airbnb.ca
                  currency: CAD
                  q: Toronto
                  check_in_date: '2029-02-01'
                  check_out_date: '2029-02-03'
                  adults: '2'
                  include_taxes: 'true'
                search_information:
                  query_displayed: Homes in Toronto, Canada
                  results: Over 1,000 homes in Toronto
                  check_in_date: '2029-02-01'
                  check_out_date: '2029-02-03'
                  adults: 2
                  guests: 2 guests
                properties:
                - position: 1
                  id: '734254017349424949'
                  title: Chic Studio w Balcony Fast WiFi by Yonge-Dundas
                  description: Condo in Toronto
                  link: https://www.airbnb.ca/rooms/734254017349424949
                  booking_link: https://www.airbnb.ca/rooms/734254017349424949?check_in=2026-09-10&check_out=2026-09-12&adults=2&children=0&infants=0&pets=0
                  booking_token: eyJjaGVja19pbiI6IjIwMjYtMDktMTAiLCJwcm9wZXJ0eV9pZCI6IjczNDI1NDAxNzM0OTQyNDk0OSJ9
                  rating: 4.96
                  reviews: 166
                  price:
                    total_price: $737 CAD
                    extracted_total_price: 737
                    total_with_taxes: $737 CAD
                    extracted_total_with_taxes: 737
                    qualifier: for 2 nights
                    extracted_qualifier: 2
                    price_per_qualifier: 2 nights x $310.00 CAD
                    extracted_price_per_qualifier: 310
                    breakdown:
                    - description: 2 nights x $310.00 CAD
                      price: $620.00 CAD
                      extracted_price: 620
                    - description: Taxes
                      price: $117.00 CAD
                      extracted_price: 117
                  check_in_date: '2029-02-01'
                  check_out_date: '2029-02-03'
                  time_period: Sep 10 – 12
                  accommodations:
                  - 1 bedroom
                  - 1 queen bed
                  - 1 bath
                  gps_coordinates:
                    latitude: 43.654
                    longitude: -79.38
                  has_free_cancellation: true
                  badges:
                  - Guest favourite
                  images:
                  - https://a0.muscache.com/im/pictures/example.jpeg
                pagination:
                  next_page_token: eyJzZWN0aW9uX29mZnNldCI6MH0=
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/serp/google_hotels_property:
    post:
      tags:
      - SearchAPI compatibility
      summary: google_hotels_property, drop-in
      description: |-
        Drop-in shape for SearchAPI's google_hotels_property.

        Repointing an existing integration is a base-URL change. `extracted_price`
        is populated where SearchAPI may omit it, and prices are exact floats
        rather than rounded integers.

        Credits: 3 (failed requests are free)
      operationId: serp_google_hotels_property
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SerpPropertyRequest'
        required: true
      responses:
        '200':
          description: SearchAPI's google_hotels_property shape. `extracted_price` is populated, which theirs omits
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SerpPropertyResponse'
              example:
                search_parameters:
                  engine: google_hotels_property
                  property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  check_in_date: '2029-02-05'
                  check_out_date: '2029-02-06'
                  adults: 2
                  currency: USD
                  gl: us
                  nights: 1
                property:
                  property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  name: Hilton Chicago
                  hotel_class: 4-star hotel
                  hotel_class_stars: 4
                  rating: 4.3
                  reviews: 10695
                  deal: 25% less than usual
                  deal_description: Great Deal
                  has_deal: true
                  price_insights:
                    lowest_price: $304
                    price_level: typical
                    price_level_code: 2
                    typical_price_range:
                      low_price: $304
                      high_price: $521
                  all_offers:
                  - source: Hilton Chicago
                    is_official: true
                    num_guests: 2
                    room_id: rate-plan-42
                    price_per_night:
                      price: $2,907
                      extracted_price: 2907.11
                      extracted_price_before_taxes: 2445.0
                      currency: USD
                    total_price:
                      price: $2,907
                      extracted_price: 2907.11
                      extracted_price_before_taxes: 2445.0
                      currency: USD
                    tax_basis: deeplink
                    is_outlier: false
                  featured_offers:
                  - source: Hilton Chicago
                    is_official: true
                    num_guests: 2
                    room_id: rate-plan-42
                    price_per_night:
                      price: $2,907
                      extracted_price: 2907.11
                      extracted_price_before_taxes: 2445.0
                      currency: USD
                    total_price:
                      price: $2,907
                      extracted_price: 2907.11
                      extracted_price_before_taxes: 2445.0
                      currency: USD
                    tax_basis: deeplink
                    is_outlier: false
                  price_per_night:
                    price: $2,208
                    extracted_price: 2207.96
                  currency_verified: true
                  tax_profile:
                    rate: 0.208
                    confidence: low
                meta:
                  wire_bytes: 2754373
                  elapsed_s: 1.548
                  offers: 15
                  priced: 15
                  property_fetch: miss
                  tax_profile_cache: hit
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/serp/google_hotels_calendar:
    post:
      tags:
      - SearchAPI compatibility
      summary: Horizon sweep in SearchAPI's parameter style
      description: |-
        No SearchAPI equivalent — a whole forward horizon in one call.

        SearchAPI bills one request per stay date; this returns ~330 nights in a
        single ~105 KB response. `extracted_price_before_taxes` uses SearchAPI's
        base-plus-mandatory-fees basis; `extracted_price_base` and `fees` preserve
        the itemised values.

        Credits: 5 (failed requests are free)
      operationId: serp_google_hotels_calendar
      x-credits: 5
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SerpCalendarRequest'
        required: true
      responses:
        '200':
          description: A whole horizon in one call, in SearchAPI's shape
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SerpCalendarResponse'
              example:
                search_parameters:
                  engine: google_hotels_calendar
                  property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                  days: 5
                  adults: 2
                  currency: USD
                  gl: us
                  los: 1
                calendar:
                - date: '2028-12-26'
                  price:
                    price: $327
                    extracted_price: 327.11
                  extracted_price_before_taxes: 352.11
                  extracted_price_base: 327.11
                  extracted_price_total: 418.65
                  tax: 66.54
                  fees: 25
                  currency: USD
                  rates_include_tax: false
                  provenance:
                    schema_version: 1
                    observation_id: rateobs_0123456789abcdef0123456789abcdef
                    collection_id: ratecol_0123456789abcdef0123456789abcdef
                    observed_at: '2026-08-07T01:23:45.678Z'
                    source: google_hotels_calendar
                    source_kind: calendar
                    collector: scrapingme.google_calendar
                    source_property_id: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
                    requested_market: US
                    requested_currency: USD
                    returned_currency: USD
                    egress_mode: direct
                    price_basis: room_base_before_taxes_and_fees
                    derivation: normalized_upstream
                - date: '2028-12-27'
                  price:
                    price: $324
                    extracted_price: 324.37
                  extracted_price_before_taxes: 349.37
                  extracted_price_base: 324.37
                  extracted_price_total: 415.4
                  tax: 66.03
                  fees: 25
                  currency: USD
                  rates_include_tax: false
                unavailable_dates: []
                tax_profile:
                  rate: 0.2051
                  confidence: high
                meta:
                  coverage: 1.0
                  wire_bytes: 1839
                  elapsed_s: 0.171
                  retries: 0
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/serp/google_flights:
    post:
      tags:
      - SearchAPI compatibility
      summary: Google Flights search for itineraries
      description: |-
        Every itinerary Google Flights offers, with per-segment detail.

        One request (~0.3 s for a typical one-way):
        Google's best and other flights, flight numbers, operating carrier,
        aircraft, legroom, amenities, layovers, emissions, bags included, price
        insights and a Google Flights link per itinerary. Round trips and
        multi-city return the first leg's options with a `departure_token` for
        `/v1/serp/google_flights_return`; complete itineraries carry a
        `booking_token` for `/v1/serp/google_flights_booking`.

        Credits: 3 (failed requests are free)
      operationId: serp_google_flights
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlightsSearchRequest'
        required: true
      responses:
        '200':
          description: Every itinerary for the first leg. Round-trip and multi-city options carry `departure_token`; complete ones (one-way, last leg) carry `booking_token` and `booking_url` instead
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlightsSearchResponse'
              example:
                departure_airport: YUL
                arrival_airport: CDG
                departure_date: '2029-03-28'
                currency: USD
                adults: 1
                itineraries:
                - legs:
                  - segments:
                    - departure_airport: YUL
                      arrival_airport: CDG
                      departure_time: '2026-11-04T18:10:00'
                      arrival_time: '2026-11-05T07:20:00'
                      airline: Air Canada
                      airline_code: AC
                      flight_number: AC 874
                      duration_minutes: 430
                      aircraft: Airbus A330
                      cabin_class: economy
                      departure_airport_name: Montréal-Pierre Elliott Trudeau International Airport
                      arrival_airport_name: Aéroport de Paris-Charles de Gaulle
                      ticket_also_sold_by:
                      - LH 6809
                      - SN 9636
                      legroom: 31 in
                      legroom_category: average
                      overnight: true
                      red_eye: false
                      often_delayed_by_over_30_min: false
                      carbon_emissions_kg: 325
                      extensions:
                      - Average legroom (31 in)
                      - Wi-Fi for a fee
                      - In-seat power & USB outlets
                      - On-demand video
                      - 'Carbon emissions estimate: 325 kg'
                      airline_logo: https://www.gstatic.com/flights/airline_logos/70px/AC.png
                    departure_airport: YUL
                    arrival_airport: CDG
                    duration_minutes: 430
                    stops: 0
                    layover_airports: []
                    is_direct: true
                    layovers: []
                    airlines:
                    - Air Canada
                    departure_time: '2026-11-04T18:10:00'
                    arrival_time: '2026-11-05T07:20:00'
                  price: 527.0
                  currency: USD
                  display_price: $527
                  carbon_emissions_kg: 325
                  carbon_emissions_comparison: 19% lower than typical
                  trip_type: round_trip
                  total_stops: 0
                  is_direct: true
                  departure_token: gf1.eNqFUMkKwjAU_Jd3TiGpVqU3TVuhBO1iIhpyEhe09NJWBfHfTRexxS2BlxneMvNygzPYBMEObJkWSYKqQOpHKo0kQbi8Cr3yn4IsD6w4A12rVMmBOtOGVSW4VQ4mNgcGwQax4Dmg7u5k6hF1x5hqPhr2Qf3w0quU29JdW9-NmCb8WbEReFMnCkFWfWMONtBj5C1db8bdq8dEFMRYzBm3AkHJhAnfC_klj0XkL04iDoW_1kttdBuPHY0OiYbbVKN9iYoM7g_hQ347
                  google_flights_url: https://www.google.com/travel/flights/search?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0agc...
                  group: best
                  price_exact: 526.19
                  carbon_emissions:
                    this_flight: 325000
                    typical_for_this_route: 399000
                    difference_percent: -19
                  total_duration_minutes: 430
                  carry_on_bags_included: 1
                  airline_logo: https://www.gstatic.com/flights/airline_logos/70px/AC.png
                - legs:
                  - segments:
                    - departure_airport: YUL
                      arrival_airport: YYZ
                      departure_time: '2026-11-04T10:10:00'
                      arrival_time: '2026-11-04T11:45:00'
                      airline: Air Canada
                      airline_code: AC
                      flight_number: AC 407
                      duration_minutes: 95
                      aircraft: Airbus A321
                      cabin_class: economy
                      departure_airport_name: Montréal-Pierre Elliott Trudeau International Airport
                      arrival_airport_name: Toronto Pearson International Airport
                      ticket_also_sold_by: []
                      legroom: 31 in
                      legroom_category: average
                      overnight: false
                      red_eye: false
                      often_delayed_by_over_30_min: false
                      carbon_emissions_kg: 71
                      extensions:
                      - Average legroom (31 in)
                      - Free Wi-Fi
                      - In-seat power & USB outlets
                      - On-demand video
                      - 'Carbon emissions estimate: 71 kg'
                      airline_logo: https://www.gstatic.com/flights/airline_logos/70px/AC.png
                    - departure_airport: YYZ
                      arrival_airport: CDG
                      departure_time: '2026-11-04T21:10:00'
                      arrival_time: '2026-11-05T10:20:00'
                      airline: Air Canada
                      airline_code: AC
                      flight_number: AC 872
                      duration_minutes: 430
                      aircraft: Boeing 777
                      cabin_class: economy
                      departure_airport_name: Toronto Pearson International Airport
                      arrival_airport_name: Aéroport de Paris-Charles de Gaulle
                      ticket_also_sold_by: []
                      legroom: 31 in
                      legroom_category: average
                      overnight: true
                      red_eye: true
                      often_delayed_by_over_30_min: true
                      carbon_emissions_kg: 394
                      extensions:
                      - Average legroom (31 in)
                      - Wi-Fi for a fee
                      - In-seat power & USB outlets
                      - On-demand video
                      - 'Carbon emissions estimate: 394 kg'
                      airline_logo: https://www.gstatic.com/flights/airline_logos/70px/AC.png
                    departure_airport: YUL
                    arrival_airport: CDG
                    duration_minutes: 1090
                    stops: 1
                    layover_airports:
                    - YYZ
                    is_direct: false
                    layovers:
                    - duration_minutes: 565
                      airport: YYZ
                      airport_name: Toronto Pearson International Airport
                      city: Toronto
                      departure_airport: YYZ
                      change_of_airport: false
                      overnight: false
                    airlines:
                    - Air Canada
                    departure_time: '2026-11-04T10:10:00'
                    arrival_time: '2026-11-05T10:20:00'
                  price: 535.0
                  currency: USD
                  display_price: $535
                  carbon_emissions_kg: 464
                  carbon_emissions_comparison: 16% higher than typical
                  trip_type: round_trip
                  total_stops: 1
                  is_direct: false
                  departure_token: gf1.eNqFUMkKwjAU_Jd3TiGpVqU3TVuhBO1iIhpyEhe09NJWBfHfTRexxS2BlxneMvNygzPYBMEObJkWSYKqQOpHKo0kQbi8Cr3yn4IsD6w4A12rVMmBOtOGVSW4VQ4mNgcGwQax4Dmg7u5k6hF1x5hqPhr2Qf3w0quU29JdW9-NmCb8WbEReFMnCkFWfWMONtBj5C1db8bdq8dEFMRYzBm3AkHJhAnfC_klj0XkL04iDoW_1kttdBuPHY0OiYbbVKN9iYoM7g_hQ347
                  google_flights_url: https://www.google.com/travel/flights/search?tfs=CBwQAhpgEgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDWVlaKgJBQzIDNDA3Ih8...
                  group: other
                  price_exact: 534.12
                  carbon_emissions:
                    this_flight: 464000
                    typical_for_this_route: 399000
                    difference_percent: 16
                  total_duration_minutes: 1090
                  carry_on_bags_included: 1
                  airline_logo: https://www.gstatic.com/flights/airline_logos/70px/AC.png
                wire_bytes: 330950
                elapsed_s: 0.942
                cheapest_price: 527.0
                trip_type: round_trip
                leg_index: 0
                legs_total: 2
                itinerary_count: 69
                best_count: 3
                price_insights:
                  lowest_price: 527
                  price_level: typical
                  typical_price_range:
                  - 475
                  - 530
                  price_history:
                  - - 1790568000
                    - 528
                  - - 1790654400
                    - 528
                  - - 1790740800
                    - 527
                airlines_available:
                - code: ONEWORLD
                  name: Oneworld
                  type: alliance
                - code: SKYTEAM
                  name: SkyTeam
                  type: alliance
                - code: STAR_ALLIANCE
                  name: Star Alliance
                  type: alliance
                - code: A3
                  name: Aegean
                  type: airline
                google_flights_url: https://www.google.com/travel/flights/search?tfs=CBwQAhoeEgoyMDI2LTExLTA0agcIARIDWVVMcgcIARIDQ0RHGh4SCjIwMjYtMTEtMTFqBwgBEgNDREdyBwgBEgNZVUxAAUgBcAGCAQsI____________AZgBAQ&hl=en&gl=us&curr=USD
                source: rpc
                return_date: '2029-04-04'
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/serp/google_flights_return:
    post:
      tags:
      - SearchAPI compatibility
      summary: Google Flights return or next-leg options
      description: |-
        The return flights for a chosen outbound (or the next multi-city leg).

        SerpApi/SearchApi's `departure_token` flow: pass the `departure_token`
        of an itinerary from `/v1/serp/google_flights`. Prices are for the whole
        trip, as Google shows them. Last-leg options carry a `booking_token`.

        Credits: 3 (failed requests are free)
      operationId: serp_google_flights_return
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlightsReturnRequest'
        required: true
      responses:
        '200':
          description: Return-leg options for the chosen outbound, priced for the whole trip, each with a `booking_token`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlightsReturnResponse'
              example:
                departure_airport: CDG
                arrival_airport: YUL
                departure_date: '2029-04-04'
                currency: USD
                adults: 1
                itineraries:
                - legs:
                  - segments:
                    - departure_airport: CDG
                      arrival_airport: ZRH
                      departure_time: '2026-11-11T07:15:00'
                      arrival_time: '2026-11-11T08:35:00'
                      airline: SWISS
                      airline_code: LX
                      flight_number: LX 647
                      duration_minutes: 80
                      aircraft: Airbus A320
                      cabin_class: economy
                      departure_airport_name: Aéroport de Paris-Charles de Gaulle
                      arrival_airport_name: Zurich Airport
                      ticket_also_sold_by: []
                      legroom: 29 in
                      legroom_category: below_average
                      overnight: false
                      red_eye: false
                      often_delayed_by_over_30_min: false
                      carbon_emissions_kg: 62
                      extensions:
                      - Below average legroom (29 in)
                      - 'Carbon emissions estimate: 62 kg'
                      airline_logo: https://www.gstatic.com/flights/airline_logos/70px/LX.png
                    - departure_airport: ZRH
                      arrival_airport: YUL
                      departure_time: '2026-11-11T12:40:00'
                      arrival_time: '2026-11-11T15:10:00'
                      airline: SWISS
                      airline_code: LX
                      flight_number: LX 86
                      duration_minutes: 510
                      aircraft: Airbus A330
                      cabin_class: economy
                      departure_airport_name: Zurich Airport
                      arrival_airport_name: Montréal-Pierre Elliott Trudeau International Airport
                      ticket_also_sold_by:
                      - AC 6821
                      legroom: 31 in
                      legroom_category: average
                      overnight: false
                      red_eye: false
                      often_delayed_by_over_30_min: true
                      carbon_emissions_kg: 351
                      extensions:
                      - Average legroom (31 in)
                      - Wi-Fi for a fee
                      - On-demand video
                      - 'Carbon emissions estimate: 351 kg'
                      airline_logo: https://www.gstatic.com/flights/airline_logos/70px/LX.png
                    departure_airport: CDG
                    arrival_airport: YUL
                    duration_minutes: 835
                    stops: 1
                    layover_airports:
                    - ZRH
                    is_direct: false
                    layovers:
                    - duration_minutes: 245
                      airport: ZRH
                      airport_name: Zurich Airport
                      city: Zürich
                      departure_airport: ZRH
                      change_of_airport: false
                      overnight: false
                    airlines:
                    - SWISS
                    departure_time: '2026-11-11T07:15:00'
                    arrival_time: '2026-11-11T15:10:00'
                  price: 527.0
                  currency: USD
                  display_price: $527
                  booking_token: gf1.eNp9T8sKwjAQ_Jc9p5BUqqU3tc0hBm0bE8WQk_hASy9tVRD_3aRVVBSzsJlhZjabK5wgIgi2EOmyKQrUNr-7tEEEaYKwK4Ne-q-m3QFGJ2C9xjgOfLh8sNaC3-zgY7_vEeyRAJ4DuvSH0o3oEjG3nAzCEMyfZXrfIjEIqvabNUQwPuR0kdCpTC6UqzwVWM24DFI1JiOuGM3kuRYqZ_OjEpliK_vo2sakiC3aFxZuSot2DjUV3O6AWl_r
                  booking_url: https://www.google.com/travel/flights/booking?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0ag...
                  carbon_emissions_kg: 413
                  carbon_emissions_comparison: 6% higher than typical
                  trip_type: round_trip
                  total_stops: 1
                  is_direct: false
                  google_flights_url: https://www.google.com/travel/flights/booking?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0ag...
                  group: other
                  price_exact: 526.18
                  carbon_emissions:
                    this_flight: 413000
                    typical_for_this_route: 390000
                    difference_percent: 6
                  total_duration_minutes: 835
                  carry_on_bags_included: 1
                  airline_logo: https://www.gstatic.com/flights/airline_logos/70px/LX.png
                wire_bytes: 104612
                elapsed_s: 0.543
                cheapest_price: 527.0
                trip_type: round_trip
                leg_index: 1
                legs_total: 2
                itinerary_count: 16
                best_count: 0
                airlines_available:
                - code: ONEWORLD
                  name: Oneworld
                  type: alliance
                - code: SKYTEAM
                  name: SkyTeam
                  type: alliance
                - code: STAR_ALLIANCE
                  name: Star Alliance
                  type: alliance
                google_flights_url: https://www.google.com/travel/flights/search?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0agcIARIDWVVMcgcIARIDQ0RHGh4SCjIwMjYtMTEtMTFqBwgBEgNDREdyBwgBEgNZVUxAAUgBcAGCAQsI____________AZgBAQ&hl=en&gl=us&curr=USD
                source: rpc
                return_date: '2029-04-04'
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/serp/google_flights_booking:
    post:
      tags:
      - SearchAPI compatibility
      summary: Google Flights booking options for an itinerary
      description: |-
        Who sells the itinerary and for how much (SerpApi `booking_options`).

        Airline direct and OTAs, each with price, fare name and rules, bag fees,
        the seller's local-currency price and Google's click-through as both a
        POST form (`booking_request`) and a GET link (`booking_url`). Google
        gathers seller prices while the request is open: expect 3-12 s.

        Credits: 3 (failed requests are free)
      operationId: serp_google_flights_booking
      x-credits: 3
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlightsBookingRequest'
        required: true
      responses:
        '200':
          description: Sellers of the chosen itinerary with prices, fare rules, bag fees and click-through links
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlightsBookingResponse'
              example:
                currency: USD
                trip_type: round_trip
                legs:
                - segments:
                  - departure_airport: YUL
                    arrival_airport: CDG
                    departure_time: '2026-11-04T18:10:00'
                    arrival_time: '2026-11-05T07:20:00'
                    airline: Air Canada
                    airline_code: AC
                    flight_number: AC 874
                    duration_minutes: 430
                    aircraft: Airbus A330
                    cabin_class: economy
                    departure_airport_name: Montréal-Pierre Elliott Trudeau International Airport
                    arrival_airport_name: Aéroport de Paris-Charles de Gaulle
                    ticket_also_sold_by:
                    - LH 6809
                    - SN 9636
                    legroom: 31 in
                    legroom_category: average
                    overnight: true
                    red_eye: false
                    often_delayed_by_over_30_min: false
                    carbon_emissions_kg: 325
                    extensions:
                    - Average legroom (31 in)
                    - Wi-Fi for a fee
                    - In-seat power & USB outlets
                    - On-demand video
                    - 'Carbon emissions estimate: 325 kg'
                    airline_logo: https://www.gstatic.com/flights/airline_logos/70px/AC.png
                  departure_airport: YUL
                  arrival_airport: CDG
                  duration_minutes: 430
                  stops: 0
                  layover_airports: []
                  is_direct: true
                  layovers: []
                  airlines:
                  - Air Canada
                  departure_time: '2026-11-04T18:10:00'
                  arrival_time: '2026-11-05T07:20:00'
                - segments:
                  - departure_airport: CDG
                    arrival_airport: ZRH
                    departure_time: '2026-11-11T07:15:00'
                    arrival_time: '2026-11-11T08:35:00'
                    airline: SWISS
                    airline_code: LX
                    flight_number: LX 647
                    duration_minutes: 80
                    aircraft: Airbus A320
                    cabin_class: economy
                    departure_airport_name: Aéroport de Paris-Charles de Gaulle
                    arrival_airport_name: Zurich Airport
                    ticket_also_sold_by: []
                    legroom: 29 in
                    legroom_category: below_average
                    overnight: false
                    red_eye: false
                    often_delayed_by_over_30_min: false
                    carbon_emissions_kg: 62
                    extensions:
                    - Below average legroom (29 in)
                    - 'Carbon emissions estimate: 62 kg'
                    airline_logo: https://www.gstatic.com/flights/airline_logos/70px/LX.png
                  - departure_airport: ZRH
                    arrival_airport: YUL
                    departure_time: '2026-11-11T12:40:00'
                    arrival_time: '2026-11-11T15:10:00'
                    airline: SWISS
                    airline_code: LX
                    flight_number: LX 86
                    duration_minutes: 510
                    aircraft: Airbus A330
                    cabin_class: economy
                    departure_airport_name: Zurich Airport
                    arrival_airport_name: Montréal-Pierre Elliott Trudeau International Airport
                    ticket_also_sold_by:
                    - AC 6821
                    legroom: 31 in
                    legroom_category: average
                    overnight: false
                    red_eye: false
                    often_delayed_by_over_30_min: true
                    carbon_emissions_kg: 351
                    extensions:
                    - Average legroom (31 in)
                    - Wi-Fi for a fee
                    - On-demand video
                    - 'Carbon emissions estimate: 351 kg'
                    airline_logo: https://www.gstatic.com/flights/airline_logos/70px/LX.png
                  departure_airport: CDG
                  arrival_airport: YUL
                  duration_minutes: 835
                  stops: 1
                  layover_airports:
                  - ZRH
                  is_direct: false
                  layovers:
                  - duration_minutes: 245
                    airport: ZRH
                    airport_name: Zurich Airport
                    city: Zürich
                    departure_airport: ZRH
                    change_of_airport: false
                    overnight: false
                  airlines:
                  - SWISS
                  departure_time: '2026-11-11T07:15:00'
                  arrival_time: '2026-11-11T15:10:00'
                booking_options:
                - book_with: SWISS
                  seller_code: LX
                  is_airline: true
                  price: 527.0
                  currency: USD
                  display_price: $527
                  local_prices:
                  - currency: CAD
                    price: 749
                  marketed_as:
                  - LH 6809
                  - LX 647
                  - LX 86
                  booking_request:
                    url: https://www.google.com/travel/clk/f
                    post_data: u=ADowPOL...&v=1
                  booking_url: https://www.google.com/travel/clk/f?u=ADowPOL...&v=1
                  seller_domain: www.swiss.com/...
                  separate_tickets: false
                  sellers:
                  - SWISS
                  extensions: []
                  baggage_prices:
                  - '1st checked bag: $127'
                  - '2nd checked bag: $183'
                  - 1 free carry-on
                - book_with: Lufthansa
                  seller_code: LH
                  is_airline: true
                  price: 527.0
                  currency: USD
                  display_price: $527
                  local_prices:
                  - currency: CAD
                    price: 749
                  marketed_as:
                  - LH 6809
                  - LX 647
                  - LX 86
                  booking_request:
                    url: https://www.google.com/travel/clk/f
                    post_data: u=ADowPOL...&v=1
                  booking_url: https://www.google.com/travel/clk/f?u=ADowPOL...&v=1
                  seller_domain: www.lufthansa.com/...
                  separate_tickets: false
                  sellers:
                  - Lufthansa
                  extensions: []
                  baggage_prices:
                  - '1st checked bag: $127'
                  - '2nd checked bag: $183'
                  - 1 free carry-on
                option_count: 9
                cheapest_price: 527.0
                price_insights:
                  lowest_price: 527
                  price_level: typical
                  typical_price_range:
                  - 495
                  - 880
                  price_history:
                  - - 1790568000
                    - 529
                  - - 1790654400
                    - 528
                  - - 1790740800
                    - 527
                google_flights_url: https://www.google.com/travel/flights/booking?tfs=CBwQAho_EgoyMDI2LTExLTA0Ih8KA1lVTBIKMjAyNi0xMS0wNBoDQ0RHKgJBQzIDODc0ag...
                wire_bytes: 79626
                elapsed_s: 6.247
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/serp/google_flights_location_search:
    post:
      tags:
      - SearchAPI compatibility
      summary: Resolve a city or airport to IATA codes
      description: |-
        Google Flights' own autocomplete: airports, cities (with their
        airports) and regions for a name. A city's `id` (`/m/...`) is accepted
        as `departure`/`arrival` by `/v1/serp/google_flights`. ~0.1 s; repeated
        queries are served from a 6-hour cache.

        Credits: 1 (failed requests are free)
      operationId: serp_google_flights_location_search
      x-credits: 1
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlightsLocationSearchRequest'
        required: true
      responses:
        '200':
          description: Airports, cities (with their airports) and regions matching the query
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlightsLocationSearchResponse'
              example:
                q: paris
                locations:
                - type: city
                  name: Paris, France
                  id: /m/05qtj
                  city: Paris
                  description: Capital of France
                  airports:
                  - iata: CDG
                    name: Aéroport de Paris-Charles de Gaulle
                    city: Paris
                    type: airport
                    distance: 14 mi
                  - iata: ORY
                    name: Paris Orly Airport
                    city: Paris
                    type: airport
                    distance: 9 mi
                  - iata: BVA
                    name: Paris Beauvais Airport
                    city: Paris
                    type: airport
                    distance: 42 mi
                  - iata: XHP
                    name: Gare de l'Est
                    city: Paris
                    type: train_station
                    distance: 1 mi
                  - iata: XPG
                    name: Gare du Nord
                    city: Paris
                    type: train_station
                    distance: 1 mi
                - type: airport
                  name: Paris Airport-Le Bourget
                  iata: LBG
                  id: /m/02vwgn
                  city: Paris
                  description: Airport in France
                  airports: []
                count: 5
                wire_bytes: 1593
                elapsed_s: 0.146
                cached: false
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/serp/google_flights_calendar:
    post:
      tags:
      - SearchAPI compatibility
      summary: Google Flights date-grid pricing
      description: |-
        Google Flights calendar/date-grid pricing.

        Similar to SearchAPI's google_flights_calendar. Returns cheapest prices
        across a date range for flexible-date comparison.

        Credits: 5 (failed requests are free)
      operationId: serp_google_flights_calendar
      x-credits: 5
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlightsCalendarRequest'
        required: true
      responses:
        '200':
          description: Date-grid pricing for flexible-date comparison
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlightsCalendarResponse'
              example:
                departure_airport: JFK
                arrival_airport: LAX
                currency: USD
                adults: 1
                trip_type: round_trip
                wire_bytes: 98234
                elapsed_s: 1.12
                cheapest_price: 198.0
                coverage: 14/15
                prices:
                - departure_date: '2029-03-01'
                  return_date: '2029-03-06'
                  price: 245.0
                  currency: USD
                  display_price: $245
                  is_priced: true
                - departure_date: '2029-03-02'
                  return_date: '2029-03-07'
                  price: 198.0
                  currency: USD
                  display_price: $198
                  is_priced: true
                - departure_date: '2029-03-03'
                  return_date: '2029-03-08'
                  price: 223.0
                  currency: USD
                  display_price: $223
                  is_priced: true
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
  /v1/airbnb/calendar:
    post:
      tags:
      - Airbnb
      summary: Priced Airbnb nightly calendar
      description: |-
        Day-by-day availability for 1-12 months with Airbnb's own quoted prices.

        One upstream call returns availability, min/max nights and check-in /
        check-out rules. With `price_nights` = `sample` or `all`, each priced
        date is the check-in of a real quoted stay (`stay_nights`, default the
        date's minimum stay) from the query the listing page's booking sidebar
        runs: the nightly figure, taxes, discounts and total the guest would see.

        Credits: 8, plus 1 per night actually priced (at most 92, so at most 100 a call); refused, failed and unsampled nights and failed requests are free
      operationId: airbnb_calendar
      x-credits: 8
      x-credits-variable: true
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AirbnbCalendarRequest'
        required: true
      responses:
        '200':
          description: Day-by-day availability with quoted nightly prices (trimmed to 3 days)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AirbnbCalendarResponse'
              example:
                listing_id: '34397368'
                link: https://www.airbnb.ca/rooms/34397368
                airbnb_domain: airbnb.ca
                currency: CAD
                requested_currency: CAD
                guests:
                  adults: 2
                  children: 0
                  infants: 0
                  pets: 0
                start_month: 10
                start_year: 2026
                months: 2
                price_nights: sample
                max_price_quotes: 8
                listing:
                  constant_min_nights: 2
                  max_guests: 2
                  pets_allowed: false
                  children_allowed: true
                summary:
                  days: 61
                  available: 35
                  available_for_checkin: 31
                  bookable: 34
                  priced: 8
                  min_price_per_night: 169.5
                  max_price_per_night: 178.0
                  median_price_per_night: 178.0
                  price_status:
                    check_in_not_allowed: 4
                    not_sampled: 23
                    priced: 8
                    unavailable: 26
                days:
                - date: '2029-03-03'
                  available: false
                  available_for_checkin: false
                  available_for_checkout: false
                  bookable: false
                  min_nights: 2
                  max_nights: 27
                  closed_to_arrival: false
                  closed_to_departure: false
                  price_status: unavailable
                - date: '2029-03-07'
                  available: true
                  available_for_checkin: true
                  available_for_checkout: true
                  bookable: true
                  min_nights: 2
                  max_nights: 27
                  closed_to_arrival: false
                  closed_to_departure: false
                  price_status: priced
                  price:
                    price_per_night: 178.0
                    currency: CAD
                    check_in: '2029-03-07'
                    check_out: '2029-03-09'
                    nights: 2
                    accommodation: 356.0
                    taxes: 67.64
                    total: 423.64
                    price_per_night_text: $178.00 CAD
                    total_text: $423.64 CAD
                    display_total: $424 CAD
                    price_basis: nightly_all_in_before_taxes
                    display_style: REGULATED_TOTAL
                    breakdown:
                    - description: 2 nights x $178.00 CAD
                      price: $356.00 CAD
                      extracted_price: 356.0
                      kind: nights
                    - description: Taxes
                      price: $67.64 CAD
                      extracted_price: 67.64
                      kind: tax
                    - description: Total
                      price: $423.64 CAD
                      extracted_price: 423.64
                      kind: total
                    provenance:
                      schema_version: 1
                      observation_id: rateobs_9e60ad832506e113550acd2fe556ad55
                      collection_id: ratecol_c328ca4cf9a747448dc64c2e80f86e25
                      observed_at: '2026-09-30T22:48:15.032Z'
                      source: airbnb
                      source_kind: vacation_rental_stay_quote
                      collector: scrapingme.ota.airbnb_calendar
                      source_property_id: '34397368'
                      requested_market: airbnb.ca
                      requested_currency: CAD
                      returned_currency: CAD
                      egress_mode: direct
                      price_basis: nightly_all_in_before_taxes
                      derivation: airbnb_stay_average_nightly
                - date: '2029-03-08'
                  available: true
                  available_for_checkin: true
                  available_for_checkout: true
                  bookable: true
                  min_nights: 2
                  max_nights: 27
                  closed_to_arrival: false
                  closed_to_departure: false
                  price_status: not_sampled
                metadata:
                  collection_id: ratecol_c328ca4cf9a747448dc64c2e80f86e25
                  observed_at: '2026-09-30T22:48:15.032Z'
                  calendar_operation: PdpAvailabilityCalendar
                  upstream_requests: 9
                  price_quotes: 8
                  wire_bytes: 8913
                  request_time_taken: 4.69
                  parsing_time_taken: 0.001
                  total_time_taken: 1.52
                  egress:
                  - direct
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/serp/airbnb_property_availability_calendar:
    post:
      tags:
      - Airbnb
      summary: Airbnb availability calendar, SearchAPI-compatible, with prices
      description: |-
        SearchAPI's `airbnb_property_availability_calendar`, field for field.

        `property_id`, `start_month`, `start_year`, `months` and `airbnb_domain`
        keep SearchAPI's names and defaults, and every day keeps `date`,
        `is_available`, `is_available_for_checkin`, `is_available_for_checkout`,
        `is_bookable`, `min_nights` and `max_nights`. SearchAPI has no prices;
        set `price_nights` to add a `price` object to priced days (SearchAPI's
        Airbnb search price vocabulary). The default `none` costs 8 credits.

        Credits: 8 with the default `price_nights: none`; with `sample` or `all`, plus 1 per night actually priced (at most 92). Failed requests are free
      operationId: serp_airbnb_property_availability_calendar
      x-credits: 8
      x-credits-variable: true
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AirbnbAvailabilityCalendarRequest'
        required: true
      responses:
        '200':
          description: SearchAPI airbnb_property_availability_calendar fields, plus prices
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AirbnbAvailabilityCalendarResponse'
              example:
                search_metadata:
                  id: search_5b0f8c1d2e3a4f5061728394
                  status: Success
                  created_at: '2026-09-30T22:48:15+00:00'
                  request_time_taken: 3.61
                  parsing_time_taken: 0.001
                  total_time_taken: 1.46
                  request_url: https://www.airbnb.ca/rooms/34397368
                  collection_id: ratecol_c328ca4cf9a747448dc64c2e80f86e25
                  observed_at: '2026-09-30T22:48:15.032Z'
                  wire_bytes: 7003
                  upstream_requests: 7
                search_parameters:
                  engine: airbnb_property_availability_calendar
                  airbnb_domain: airbnb.ca
                  property_id: '34397368'
                  start_month: 10
                  start_year: 2026
                  months: 2
                  currency: CAD
                  adults: 2
                  price_nights: sample
                  max_price_quotes: 6
                months:
                - year: 2026
                  month: 10
                  days:
                  - date: '2029-03-06'
                    is_available: true
                    is_available_for_checkin: true
                    is_available_for_checkout: true
                    is_bookable: true
                    min_nights: 2
                    max_nights: 27
                    price_status: not_sampled
                  - date: '2029-03-07'
                    is_available: true
                    is_available_for_checkin: true
                    is_available_for_checkout: true
                    is_bookable: true
                    min_nights: 2
                    max_nights: 27
                    price_status: priced
                    price:
                      check_in_date: '2029-03-07'
                      check_out_date: '2029-03-09'
                      currency: CAD
                      price_per_night: $178.00 CAD
                      extracted_price_per_night: 178.0
                      total_price: $424 CAD
                      extracted_total_price: 424
                      qualifier: for 2 nights
                      extracted_qualifier: 2
                      price_per_qualifier: 2 nights x $178.00 CAD
                      extracted_price_per_qualifier: 178.0
                      total_with_taxes: $423.64 CAD
                      extracted_total_with_taxes: 423.64
                      breakdown:
                      - description: 2 nights x $178.00 CAD
                        price: $356.00 CAD
                        extracted_price: 356.0
                      - description: Taxes
                        price: $67.64 CAD
                        extracted_price: 67.64
                      - description: Total
                        price: $423.64 CAD
                        extracted_price: 423.64
                      provenance:
                        schema_version: 1
                        observation_id: rateobs_9e60ad832506e113550acd2fe556ad55
                        collection_id: ratecol_c328ca4cf9a747448dc64c2e80f86e25
                        observed_at: '2026-09-30T22:48:15.032Z'
                        source: airbnb
                        source_kind: vacation_rental_stay_quote
                        collector: scrapingme.ota.airbnb_calendar
                        source_property_id: '34397368'
                        requested_market: airbnb.ca
                        requested_currency: CAD
                        returned_currency: CAD
                        egress_mode: direct
                        price_basis: nightly_all_in_before_taxes
                        derivation: airbnb_stay_average_nightly
                price_summary:
                  days: 61
                  available: 35
                  available_for_checkin: 31
                  bookable: 34
                  priced: 6
                  min_price_per_night: 169.5
                  max_price_per_night: 178.0
                  median_price_per_night: 178.0
                  price_status:
                    check_in_not_allowed: 4
                    not_sampled: 25
                    priced: 6
                    unavailable: 26
          headers:
            x-credits-charged:
              $ref: '#/components/headers/CreditsCharged'
            x-credits-remaining:
              $ref: '#/components/headers/CreditsRemaining'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/UpstreamError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/billing:
    get:
      tags:
      - Billing
      summary: Plan, credit balance and period
      description: 'Credits: 0 (failed requests are free)'
      operationId: billing_summary
      x-credits: 0
      responses:
        '200':
          description: Plan, balance and current period
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingSummary'
              example:
                mode: shadow
                plan:
                  code: starter
                  name: Starter
                  monthly_credits: 50000
                  price_usd: 49
                  concurrency: 10
                credits:
                  balance: 48210
                  reserved: 20
                  available: 48190
                  credits_used: 1790
                  credits_refunded: 0
                  billable_requests: 312
                period:
                  start: '2026-10-01T00:00:00+00:00'
                  end: '2026-11-01T00:00:00+00:00'
                subscription:
                  status: active
                  stripe_managed: true
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
  /v1/billing/ledger:
    get:
      tags:
      - Billing
      summary: Credit movements, newest first
      description: 'Credits: 0 (failed requests are free)'
      operationId: billing_ledger
      x-credits: 0
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 200
          minimum: 1
          default: 50
          title: Limit
      - name: before
        in: query
        required: false
        schema:
          anyOf:
          - type: integer
            minimum: 1
          - type: 'null'
          description: Return entries with an id below this.
          title: Before
        description: Return entries with an id below this.
      responses:
        '200':
          description: Credit movements, newest first
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingLedger'
              example:
                entries:
                - id: 912
                  kind: usage
                  amount: -5
                  balance_after: 48210
                  route: /v1/calendar
                  request_id: req_0123456789abcdef0123456789abcdef
                  detail: {}
                  created_at: '2026-10-14T09:12:44.120000+00:00'
                - id: 3
                  kind: grant
                  amount: 50000
                  balance_after: 50000
                  detail:
                    plan: starter
                    reason: plan change
                  created_at: '2026-10-01T00:00:03.000000+00:00'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationError'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /v1/billing/plans:
    get:
      tags:
      - Billing
      summary: Plans and per-endpoint credit costs
      description: 'Credits: 0 (failed requests are free)'
      operationId: billing_plans
      x-credits: 0
      responses:
        '200':
          description: Plans and per-endpoint credit costs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingPlans'
              example:
                plans:
                - code: free
                  name: Free
                  monthly_credits: 1000
                  price_usd: 0
                  concurrency: 2
                - code: starter
                  name: Starter
                  monthly_credits: 50000
                  price_usd: 49
                  concurrency: 10
                costs:
                - method: POST
                  path: /v1/calendar
                  credits: 5
                - method: POST
                  path: /v1/ota/compare
                  credits: 20
                free:
                - GET /v1/billing
                - GET /v1/usage
                notes:
                - Failed, blocked and empty results are not charged.
                mode: shadow
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key in the `x-api-key` header (recommended). Keys look like `sk_` followed by random characters.
    BearerAuth:
      type: http
      scheme: bearer
      description: 'The same API key sent as `Authorization: Bearer <key>`.'
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key
      description: The same API key as an `api_key` query parameter. Supported for SearchAPI-style GET integrations; prefer the header.
  headers:
    CreditsCharged:
      description: 'Credits charged for this request: the operation''s cost on success, 0 for failed or empty results. Sent when the key is linked to a customer account.'
      schema:
        type: integer
        minimum: 0
      example: 5
    CreditsRemaining:
      description: Credits available on the account after this request. Sent with `x-credits-charged` on charged requests.
      schema:
        type: integer
      example: 48190
  responses:
    BadRequest:
      description: 'Bad request: the parameters are well-formed but unusable (for example an unknown market or a malformed token).'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            detail: end must be on or after start
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            detail: missing or invalid API key
    NotFound:
      description: The property, stay, job or record was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            detail: job not found
    Conflict:
      description: The Idempotency-Key was already used for a different request body.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            detail: Idempotency-Key was already used for a different request
    ValidationError:
      description: Request validation failed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/HTTPValidationError'
          example:
            detail:
            - loc:
              - body
              - token
              msg: Field required
              type: missing
    UnprocessableRequest:
      description: Request validation failed. `detail` is a list of problems for schema errors, or a string for semantic checks performed by the endpoint.
      content:
        application/json:
          schema:
            anyOf:
            - $ref: '#/components/schemas/HTTPValidationError'
            - $ref: '#/components/schemas/ErrorResponse'
          example:
            detail:
            - loc:
              - body
              - name
              msg: Field required
              type: missing
    RateLimited:
      description: 'Too many requests: the key''s requests-per-minute limit was exceeded, or (once credit enforcement is on) the plan''s concurrent-request limit. No rate-limit or Retry-After headers are sent; back off and retry.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            detail: rate limit 60/min exceeded
    InsufficientCredits:
      description: Not enough credits for this request. Only returned once credit enforcement is switched on; during the beta metering runs in shadow mode and never blocks.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            detail: 'insufficient credits: this request costs 5, 0 available. Credits renew 2026-11-01.'
    UpstreamError:
      description: The upstream source failed, blocked the request or returned an unusable answer. Safe to retry later; failed requests are not charged.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            detail: RuntimeError
    ServiceUnavailable:
      description: 'Temporarily unavailable: a dependency of this endpoint is down, or the upstream source changed its contract. Retry later.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            detail: 'database unavailable: OperationalError'
  schemas:
    AgodaRequest:
      properties:
        property_id:
          type: string
          minLength: 1
          title: Property Id
          description: Numeric id returned by `POST /v1/ota/agoda/search`, or from the Agoda URL — the digits in `agoda.com/…/hotel/…-h8795952.html`, or the `hotelId` query parameter.
          examples:
          - '8795952'
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-02-06'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        rooms:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Rooms
          description: Rooms requested.
          default: 1
          examples:
          - 1
        currency:
          type: string
          enum:
          - AED
          - AUD
          - BRL
          - CAD
          - CHF
          - CZK
          - EUR
          - GBP
          - HKD
          - IDR
          - INR
          - JPY
          - KRW
          - MYR
          - NZD
          - PHP
          - PLN
          - SEK
          - SGD
          - THB
          - TWD
          - USD
          - ZAR
          title: Currency
          description: One of 23 supported. Unlike Hotels.com these ARE comparable — Agoda converts one underlying rate.
          default: USD
          examples:
          - USD
      additionalProperties: false
      type: object
      required:
      - property_id
      - check_in
      title: AgodaRequest
      description: |-
        Agoda's own room types and rate plans. Its currencies are genuine FX
        conversions of a single rate.
      examples:
      - adults: 2
        check_in: '2029-02-05'
        currency: USD
        nights: 1
        property_id: '8795952'
    AgodaSearchRequest:
      properties:
        name:
          type: string
          minLength: 1
          title: Name
          description: Hotel name as a guest would search for it.
          examples:
          - Moxy Boston Downtown
        city:
          type: string
          title: City
          description: Strongly recommended. Included in Agoda's query and used to rank same-brand results in the intended city.
          default: ''
          examples:
          - Boston
        origin:
          type: string
          enum:
          - AD
          - AE
          - AF
          - AG
          - AI
          - AL
          - AM
          - AO
          - AQ
          - AR
          - AS
          - AT
          - AU
          - AW
          - AX
          - AZ
          - BA
          - BB
          - BD
          - BE
          - BF
          - BG
          - BH
          - BI
          - BJ
          - BL
          - BM
          - BN
          - BO
          - BQ
          - BR
          - BS
          - BT
          - BV
          - BW
          - BY
          - BZ
          - CA
          - CC
          - CD
          - CF
          - CG
          - CH
          - CI
          - CK
          - CL
          - CM
          - CN
          - CO
          - CR
          - CU
          - CV
          - CW
          - CX
          - CY
          - CZ
          - DE
          - DJ
          - DK
          - DM
          - DO
          - DZ
          - EC
          - EE
          - EG
          - EH
          - ER
          - ES
          - ET
          - FI
          - FJ
          - FK
          - FM
          - FO
          - FR
          - GA
          - GB
          - GD
          - GE
          - GF
          - GG
          - GH
          - GI
          - GL
          - GM
          - GN
          - GP
          - GQ
          - GR
          - GS
          - GT
          - GU
          - GW
          - GY
          - HK
          - HM
          - HN
          - HR
          - HT
          - HU
          - ID
          - IE
          - IL
          - IM
          - IN
          - IO
          - IQ
          - IR
          - IS
          - IT
          - JE
          - JM
          - JO
          - JP
          - KE
          - KG
          - KH
          - KI
          - KM
          - KN
          - KP
          - KR
          - KW
          - KY
          - KZ
          - LA
          - LB
          - LC
          - LI
          - LK
          - LR
          - LS
          - LT
          - LU
          - LV
          - LY
          - MA
          - MC
          - MD
          - ME
          - MF
          - MG
          - MH
          - MK
          - ML
          - MM
          - MN
          - MO
          - MP
          - MQ
          - MR
          - MS
          - MT
          - MU
          - MV
          - MW
          - MX
          - MY
          - MZ
          - NA
          - NC
          - NE
          - NF
          - NG
          - NI
          - NL
          - 'NO'
          - NP
          - NR
          - NU
          - NZ
          - OM
          - PA
          - PE
          - PF
          - PG
          - PH
          - PK
          - PL
          - PM
          - PN
          - PR
          - PS
          - PT
          - PW
          - PY
          - QA
          - RE
          - RO
          - RS
          - RU
          - RW
          - SA
          - SB
          - SC
          - SD
          - SE
          - SG
          - SH
          - SI
          - SJ
          - SK
          - SL
          - SM
          - SN
          - SO
          - SR
          - SS
          - ST
          - SV
          - SX
          - SY
          - SZ
          - TC
          - TD
          - TF
          - TG
          - TH
          - TJ
          - TK
          - TL
          - TM
          - TN
          - TO
          - TR
          - TT
          - TV
          - TW
          - TZ
          - UA
          - UG
          - UK
          - UM
          - US
          - UY
          - UZ
          - VA
          - VC
          - VE
          - VG
          - VI
          - VN
          - VU
          - WF
          - WS
          - XK
          - YE
          - YT
          - ZA
          - ZM
          - ZW
          maxLength: 2
          minLength: 2
          title: Origin
          description: Two-letter user-country context sent to Agoda. This is not the hotel's country; `city` identifies the location.
          default: US
          examples:
          - US
        limit:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Limit
          description: Maximum hotel candidates to return, best match first.
          default: 5
          examples:
          - 5
      additionalProperties: false
      type: object
      required:
      - name
      title: AgodaSearchRequest
      description: |-
        Find Agoda's numeric property id from a hotel name.

        Read `recommended_match`, not `matches[0]`. It is null when the provider
        returned only weak or ambiguous candidates.
      examples:
      - city: Boston
        limit: 5
        name: Moxy Boston Downtown
        origin: US
    AirbnbAvailabilityCalendarRequest:
      properties:
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - AUD
          - BAM
          - BGN
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CRC
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - GHS
          - GTQ
          - HKD
          - HNL
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KES
          - KRW
          - KZT
          - MAD
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - RUB
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - UAH
          - UGX
          - USD
          - UYU
          - VND
          - ZAR
          title: Currency
          description: Airbnb-supported ISO 4217 currency for quoted prices. Omit for the domain's default; the currency Airbnb actually priced in is returned on every priced day.
          examples:
          - CAD
        adults:
          type: integer
          maximum: 16.0
          minimum: 1.0
          title: Adults
          description: Adults aged 13+; quotes are priced for this party.
          default: 1
          examples:
          - 2
        children:
          type: integer
          maximum: 15.0
          minimum: 0.0
          title: Children
          description: Children aged 2-12.
          default: 0
          examples:
          - 0
        infants:
          type: integer
          maximum: 5.0
          minimum: 0.0
          title: Infants
          description: Infants under 2.
          default: 0
          examples:
          - 0
        pets:
          type: integer
          maximum: 5.0
          minimum: 0.0
          title: Pets
          description: Pets.
          default: 0
          examples:
          - 0
        max_price_quotes:
          anyOf:
          - type: integer
            maximum: 92.0
            minimum: 1.0
          - type: 'null'
          title: Max Price Quotes
          description: Upper bound on price quotes, 1-92. The request holds 8 + this many credits and is charged 8 + the nights actually priced.
          examples:
          - 12
        stay_nights:
          anyOf:
          - type: integer
            maximum: 28.0
            minimum: 1.0
          - type: 'null'
          title: Stay Nights
          description: Length of the stay each priced date is quoted for. Omit to use each date's own minimum stay. Airbnb folds cleaning and service fees into its nightly rate, so the same night costs less per night on a longer stay. 1-28.
          examples:
          - 2
        engine:
          type: string
          const: airbnb_property_availability_calendar
          title: Engine
          description: Accepted for SearchAPI request compatibility; the path already selects the engine.
          default: airbnb_property_availability_calendar
        property_id:
          type: string
          pattern: ^\d{1,25}$
          title: Property Id
          description: 'Numeric Airbnb listing id: the number in `https://www.airbnb.com/rooms/<id>`, or `properties[].id` from `/v1/serp/airbnb`.'
          examples:
          - '34397368'
        start_month:
          anyOf:
          - type: integer
            maximum: 12.0
            minimum: 1.0
          - type: 'null'
          title: Start Month
          description: 'SearchAPI `start_month`: first month, 1-12. Defaults to the current month.'
          examples:
          - 10
        start_year:
          anyOf:
          - type: integer
            maximum: 2100.0
            minimum: 2020.0
          - type: 'null'
          title: Start Year
          description: SearchAPI `start_year`. Defaults to the current year.
          examples:
          - 2026
        months:
          type: integer
          maximum: 12.0
          minimum: 1.0
          title: Months
          description: 'SearchAPI `months`: 1-12, default 12.'
          default: 12
          examples:
          - 12
        airbnb_domain:
          type: string
          enum:
          - airbnb.ae
          - airbnb.am
          - airbnb.at
          - airbnb.az
          - airbnb.ba
          - airbnb.be
          - airbnb.ca
          - airbnb.cat
          - airbnb.ch
          - airbnb.cl
          - airbnb.cn
          - airbnb.co.cr
          - airbnb.co.id
          - airbnb.co.in
          - airbnb.co.kr
          - airbnb.co.nz
          - airbnb.co.uk
          - airbnb.co.ve
          - airbnb.com
          - airbnb.com.ar
          - airbnb.com.au
          - airbnb.com.bo
          - airbnb.com.br
          - airbnb.com.bz
          - airbnb.com.co
          - airbnb.com.ec
          - airbnb.com.ee
          - airbnb.com.gt
          - airbnb.com.hk
          - airbnb.com.hn
          - airbnb.com.my
          - airbnb.com.ni
          - airbnb.com.pa
          - airbnb.com.pe
          - airbnb.com.ph
          - airbnb.com.py
          - airbnb.com.ro
          - airbnb.com.sg
          - airbnb.com.sv
          - airbnb.com.tr
          - airbnb.com.tw
          - airbnb.com.ua
          - airbnb.com.vn
          - airbnb.cz
          - airbnb.de
          - airbnb.dk
          - airbnb.es
          - airbnb.fi
          - airbnb.fr
          - airbnb.gr
          - airbnb.gy
          - airbnb.hu
          - airbnb.ie
          - airbnb.is
          - airbnb.it
          - airbnb.jp
          - airbnb.lt
          - airbnb.lu
          - airbnb.lv
          - airbnb.me
          - airbnb.mx
          - airbnb.nl
          - airbnb.no
          - airbnb.pl
          - airbnb.pt
          - airbnb.rs
          - airbnb.ru
          - airbnb.se
          - airbnb.si
          - ar.airbnb.com
          - bg.airbnb.com
          - de.airbnb.lu
          - es.airbnb.com
          - fr.airbnb.be
          - fr.airbnb.ca
          - fr.airbnb.ch
          - ga.airbnb.ie
          - he.airbnb.com
          - hi.airbnb.co.in
          - hr.airbnb.com
          - it.airbnb.ch
          - ka.airbnb.com
          - kn.airbnb.co.in
          - mk.airbnb.com
          - mr.airbnb.co.in
          - mt.airbnb.com.mt
          - sk.airbnb.com
          - sq.airbnb.com
          - sw.airbnb.com
          - th.airbnb.com
          - xh.airbnb.co.za
          - zh-t.airbnb.com
          - zh.airbnb.com
          - zu.airbnb.co.za
          title: Airbnb Domain
          description: Country/language Airbnb host. The host does not change prices; it picks the market and the default currency.
          default: airbnb.com
          examples:
          - airbnb.ca
        price_nights:
          type: string
          enum:
          - none
          - sample
          - all
          title: Price Nights
          description: 'ScraperCompany addition. Default `none` returns exactly SearchAPI''s fields at the base cost. `none`: availability only (one upstream request). `sample`: quote `max_price_quotes` check-in dates spread evenly over the valid ones (default 12). `all`: quote every valid check-in date in order, up to `max_price_quotes` (default and maximum 92). Each quote is one ~0.9 KB upstream request and one credit.'
          default: none
          examples:
          - sample
        zero_retention:
          type: boolean
          title: Zero Retention
          description: Accepted for SearchAPI compatibility; calendars and quotes are never persisted.
          default: false
      additionalProperties: false
      type: object
      required:
      - property_id
      title: AirbnbAvailabilityCalendarRequest
      description: SearchAPI's ``airbnb_property_availability_calendar`` contract, plus prices.
      examples:
      - adults: 2
        airbnb_domain: airbnb.ca
        currency: CAD
        max_price_quotes: 6
        months: 2
        price_nights: sample
        property_id: '34397368'
    AirbnbCalendarRequest:
      properties:
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - AUD
          - BAM
          - BGN
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CRC
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - GHS
          - GTQ
          - HKD
          - HNL
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KES
          - KRW
          - KZT
          - MAD
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - RUB
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - UAH
          - UGX
          - USD
          - UYU
          - VND
          - ZAR
          title: Currency
          description: Airbnb-supported ISO 4217 currency for quoted prices. Omit for the domain's default; the currency Airbnb actually priced in is returned on every priced day.
          examples:
          - CAD
        adults:
          type: integer
          maximum: 16.0
          minimum: 1.0
          title: Adults
          description: Adults aged 13+; quotes are priced for this party.
          default: 1
          examples:
          - 2
        children:
          type: integer
          maximum: 15.0
          minimum: 0.0
          title: Children
          description: Children aged 2-12.
          default: 0
          examples:
          - 0
        infants:
          type: integer
          maximum: 5.0
          minimum: 0.0
          title: Infants
          description: Infants under 2.
          default: 0
          examples:
          - 0
        pets:
          type: integer
          maximum: 5.0
          minimum: 0.0
          title: Pets
          description: Pets.
          default: 0
          examples:
          - 0
        max_price_quotes:
          anyOf:
          - type: integer
            maximum: 92.0
            minimum: 1.0
          - type: 'null'
          title: Max Price Quotes
          description: Upper bound on price quotes, 1-92. The request holds 8 + this many credits and is charged 8 + the nights actually priced.
          examples:
          - 12
        stay_nights:
          anyOf:
          - type: integer
            maximum: 28.0
            minimum: 1.0
          - type: 'null'
          title: Stay Nights
          description: Length of the stay each priced date is quoted for. Omit to use each date's own minimum stay. Airbnb folds cleaning and service fees into its nightly rate, so the same night costs less per night on a longer stay. 1-28.
          examples:
          - 2
        listing_id:
          type: string
          pattern: ^\d{1,25}$
          title: Listing Id
          description: 'Numeric Airbnb listing id: the number in `https://www.airbnb.com/rooms/<id>`, or `properties[].id` from `/v1/serp/airbnb`.'
          examples:
          - '34397368'
        airbnb_domain:
          type: string
          enum:
          - airbnb.ae
          - airbnb.am
          - airbnb.at
          - airbnb.az
          - airbnb.ba
          - airbnb.be
          - airbnb.ca
          - airbnb.cat
          - airbnb.ch
          - airbnb.cl
          - airbnb.cn
          - airbnb.co.cr
          - airbnb.co.id
          - airbnb.co.in
          - airbnb.co.kr
          - airbnb.co.nz
          - airbnb.co.uk
          - airbnb.co.ve
          - airbnb.com
          - airbnb.com.ar
          - airbnb.com.au
          - airbnb.com.bo
          - airbnb.com.br
          - airbnb.com.bz
          - airbnb.com.co
          - airbnb.com.ec
          - airbnb.com.ee
          - airbnb.com.gt
          - airbnb.com.hk
          - airbnb.com.hn
          - airbnb.com.my
          - airbnb.com.ni
          - airbnb.com.pa
          - airbnb.com.pe
          - airbnb.com.ph
          - airbnb.com.py
          - airbnb.com.ro
          - airbnb.com.sg
          - airbnb.com.sv
          - airbnb.com.tr
          - airbnb.com.tw
          - airbnb.com.ua
          - airbnb.com.vn
          - airbnb.cz
          - airbnb.de
          - airbnb.dk
          - airbnb.es
          - airbnb.fi
          - airbnb.fr
          - airbnb.gr
          - airbnb.gy
          - airbnb.hu
          - airbnb.ie
          - airbnb.is
          - airbnb.it
          - airbnb.jp
          - airbnb.lt
          - airbnb.lu
          - airbnb.lv
          - airbnb.me
          - airbnb.mx
          - airbnb.nl
          - airbnb.no
          - airbnb.pl
          - airbnb.pt
          - airbnb.rs
          - airbnb.ru
          - airbnb.se
          - airbnb.si
          - ar.airbnb.com
          - bg.airbnb.com
          - de.airbnb.lu
          - es.airbnb.com
          - fr.airbnb.be
          - fr.airbnb.ca
          - fr.airbnb.ch
          - ga.airbnb.ie
          - he.airbnb.com
          - hi.airbnb.co.in
          - hr.airbnb.com
          - it.airbnb.ch
          - ka.airbnb.com
          - kn.airbnb.co.in
          - mk.airbnb.com
          - mr.airbnb.co.in
          - mt.airbnb.com.mt
          - sk.airbnb.com
          - sq.airbnb.com
          - sw.airbnb.com
          - th.airbnb.com
          - xh.airbnb.co.za
          - zh-t.airbnb.com
          - zh.airbnb.com
          - zu.airbnb.co.za
          title: Airbnb Domain
          description: Country/language Airbnb host. The host does not change prices; it picks the market and the default currency.
          default: airbnb.com
          examples:
          - airbnb.ca
        months:
          type: integer
          maximum: 12.0
          minimum: 1.0
          title: Months
          description: Calendar months to return, starting at `start_month` (default 3).
          default: 3
          examples:
          - 3
        start_month:
          anyOf:
          - type: integer
            maximum: 12.0
            minimum: 1.0
          - type: 'null'
          title: Start Month
          description: First month, 1-12. Defaults to the current month.
          examples:
          - 10
        start_year:
          anyOf:
          - type: integer
            maximum: 2100.0
            minimum: 2020.0
          - type: 'null'
          title: Start Year
          description: Year of `start_month`. Defaults to the current year.
          examples:
          - 2026
        price_nights:
          type: string
          enum:
          - none
          - sample
          - all
          title: Price Nights
          description: '`none`: availability only (one upstream request). `sample`: quote `max_price_quotes` check-in dates spread evenly over the valid ones (default 12). `all`: quote every valid check-in date in order, up to `max_price_quotes` (default and maximum 92). Each quote is one ~0.9 KB upstream request and one credit.'
          default: sample
          examples:
          - sample
        include_listing:
          type: boolean
          title: Include Listing
          description: Add title, property type, rating, capacity and coordinates from one extra ~10 KB upstream request. No extra credits.
          default: false
      additionalProperties: false
      type: object
      required:
      - listing_id
      title: AirbnbCalendarRequest
      description: Native priced Airbnb nightly calendar.
      examples:
      - adults: 2
        airbnb_domain: airbnb.ca
        currency: CAD
        listing_id: '34397368'
        max_price_quotes: 8
        months: 2
        price_nights: sample
    AirbnbSearchRequest:
      properties:
        q:
          anyOf:
          - type: string
          - type: 'null'
          title: Q
          description: Destination text. Required unless `bounding_box` is supplied; ignored for map bounds only when the two conflict.
          examples:
          - Toronto
        bounding_box:
          anyOf:
          - type: string
          - type: 'null'
          title: Bounding Box
          description: Map bounds as `[[ne_lat,ne_lng],[sw_lat,sw_lng]]`. Takes precedence over `q`.
          examples:
          - '[[43.72,-79.27],[43.62,-79.49]]'
        airbnb_domain:
          type: string
          enum:
          - airbnb.ae
          - airbnb.am
          - airbnb.at
          - airbnb.az
          - airbnb.ba
          - airbnb.be
          - airbnb.ca
          - airbnb.cat
          - airbnb.ch
          - airbnb.cl
          - airbnb.cn
          - airbnb.co.cr
          - airbnb.co.id
          - airbnb.co.in
          - airbnb.co.kr
          - airbnb.co.nz
          - airbnb.co.uk
          - airbnb.co.ve
          - airbnb.com
          - airbnb.com.ar
          - airbnb.com.au
          - airbnb.com.bo
          - airbnb.com.br
          - airbnb.com.bz
          - airbnb.com.co
          - airbnb.com.ec
          - airbnb.com.ee
          - airbnb.com.gt
          - airbnb.com.hk
          - airbnb.com.hn
          - airbnb.com.my
          - airbnb.com.ni
          - airbnb.com.pa
          - airbnb.com.pe
          - airbnb.com.ph
          - airbnb.com.py
          - airbnb.com.ro
          - airbnb.com.sg
          - airbnb.com.sv
          - airbnb.com.tr
          - airbnb.com.tw
          - airbnb.com.ua
          - airbnb.com.vn
          - airbnb.cz
          - airbnb.de
          - airbnb.dk
          - airbnb.es
          - airbnb.fi
          - airbnb.fr
          - airbnb.gr
          - airbnb.gy
          - airbnb.hu
          - airbnb.ie
          - airbnb.is
          - airbnb.it
          - airbnb.jp
          - airbnb.lt
          - airbnb.lu
          - airbnb.lv
          - airbnb.me
          - airbnb.mx
          - airbnb.nl
          - airbnb.no
          - airbnb.pl
          - airbnb.pt
          - airbnb.rs
          - airbnb.ru
          - airbnb.se
          - airbnb.si
          - ar.airbnb.com
          - bg.airbnb.com
          - de.airbnb.lu
          - es.airbnb.com
          - fr.airbnb.be
          - fr.airbnb.ca
          - fr.airbnb.ch
          - ga.airbnb.ie
          - he.airbnb.com
          - hi.airbnb.co.in
          - hr.airbnb.com
          - it.airbnb.ch
          - ka.airbnb.com
          - kn.airbnb.co.in
          - mk.airbnb.com
          - mr.airbnb.co.in
          - mt.airbnb.com.mt
          - sk.airbnb.com
          - sq.airbnb.com
          - sw.airbnb.com
          - th.airbnb.com
          - xh.airbnb.co.za
          - zh-t.airbnb.com
          - zh.airbnb.com
          - zu.airbnb.co.za
          title: Airbnb Domain
          description: Country/language Airbnb host, such as `airbnb.com`, `airbnb.ca` or `fr.airbnb.ca`.
          default: airbnb.com
          examples:
          - airbnb.ca
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - AUD
          - BAM
          - BGN
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CRC
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - GHS
          - GTQ
          - HKD
          - HNL
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KES
          - KRW
          - KZT
          - MAD
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - RUB
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - UAH
          - UGX
          - USD
          - UYU
          - VND
          - ZAR
          title: Currency
          description: Airbnb-supported ISO 4217 display currency. Omit to use the selected domain's default.
          examples:
          - CAD
        include_taxes:
          type: boolean
          title: Include Taxes
          description: Expose tax-inclusive totals when Airbnb includes a tax line in the search price breakdown.
          default: false
        check_in_date:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check In Date
          description: Exact check-in date, `YYYY-MM-DD`. Cannot be mixed with `time_period`.
          examples:
          - '2029-02-01'
        check_out_date:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out Date
          description: Exact departure date. Requires `check_in_date`; defaults to the next day when omitted.
          examples:
          - '2029-02-03'
        time_period:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - one_month
          - one_week
          - weekend_trip
          title: Time Period
          description: 'Flexible date search: `weekend_trip`, `one_week` or `one_month`. Defaults to `one_week` when no exact dates are supplied.'
          examples:
          - weekend_trip
        adults:
          anyOf:
          - type: integer
            maximum: 16.0
            minimum: 0.0
          - type: 'null'
          title: Adults
          description: Adults aged 13+, from 0 through 16. Defaults to one when another guest count is set.
          examples:
          - 2
        children:
          anyOf:
          - type: integer
            maximum: 15.0
            minimum: 0.0
          - type: 'null'
          title: Children
          description: Children aged 2–12. Maximum 15.
          examples:
          - 1
        infants:
          anyOf:
          - type: integer
            maximum: 5.0
            minimum: 0.0
          - type: 'null'
          title: Infants
          description: Infants under 2. Maximum 5.
          examples:
          - 1
        pets:
          anyOf:
          - type: integer
            maximum: 5.0
            minimum: 0.0
          - type: 'null'
          title: Pets
          description: Pets. Maximum 5.
          examples:
          - 1
        price_min:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Price Min
          description: Minimum displayed trip price.
          examples:
          - 100
        price_max:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Price Max
          description: Maximum displayed trip price.
          examples:
          - 500
        type_of_place:
          type: string
          enum:
          - any
          - entire_home
          - room
          title: Type Of Place
          description: '`any`, `room`, or `entire_home`.'
          default: any
          examples:
          - entire_home
        property_types:
          anyOf:
          - type: string
          - type: 'null'
          title: Property Types
          description: Comma-separated `house`, `guesthouse`, `apartment` and/or `hotel`.
          examples:
          - house,apartment
          x-multiple: true
          x-options:
          - apartment
          - guesthouse
          - hotel
          - house
        bedrooms:
          anyOf:
          - type: integer
            maximum: 8.0
            minimum: 0.0
          - type: 'null'
          title: Bedrooms
          description: Minimum bedrooms, 0–8.
          examples:
          - 2
        beds:
          anyOf:
          - type: integer
            maximum: 8.0
            minimum: 0.0
          - type: 'null'
          title: Beds
          description: Minimum beds, 0–8.
          examples:
          - 2
        bathrooms:
          anyOf:
          - type: integer
            maximum: 8.0
            minimum: 0.0
          - type: 'null'
          title: Bathrooms
          description: Minimum bathrooms, 0–8.
          examples:
          - 1
        amenities:
          anyOf:
          - type: string
          - type: 'null'
          title: Amenities
          description: Comma-separated SearchAPI amenity names, such as `guest_favorite,wifi,kitchen,instant_book`.
          examples:
          - wifi,kitchen
          x-multiple: true
          x-options:
          - 24_hour_check_in
          - air_conditioning
          - bbq_grill
          - breakfast
          - buzzer_wireless_intercom
          - cable_tv
          - carbon_monoxide_alarm
          - cats
          - crib
          - dedicated_workspace
          - dogs
          - doorman
          - dryer
          - elevator
          - essentials
          - ev_charger
          - family_kid_friendly
          - fire_extinguisher
          - first_aid_kit
          - free_parking_on_premises
          - free_street_parking
          - garage_parking
          - guest_favorite
          - gym
          - hair_dryer
          - hangers
          - heating
          - hot_tub
          - indoor_fireplace
          - instant_book
          - internet
          - iron
          - jacuzzi_tub
          - kitchen
          - lock_on_bedroom_door
          - lockbox
          - luxe
          - other_pets
          - paid_parking_off_premises
          - permit_parking
          - pets_allowed
          - pets_live_on_this_property
          - pool
          - private_entrance
          - safety_card
          - self_check_in
          - shampoo
          - smoke_alarm
          - smoking_allowed
          - suitable_for_events
          - tv
          - washer
          - wheelchair_accessible
          - wifi
        next_page_token:
          anyOf:
          - type: string
          - type: 'null'
          title: Next Page Token
          description: Opaque cursor returned in `pagination.next_page_token`.
          examples:
          - eyJzZWN0aW9uX29mZnNldCI6MH0=
        zero_retention:
          type: boolean
          title: Zero Retention
          description: Accepted for SearchAPI request compatibility. This endpoint never stores raw HTML or search results, regardless of the value.
          default: false
      additionalProperties: false
      type: object
      title: AirbnbSearchRequest
      description: SearchAPI's ``engine=airbnb`` request contract.
      examples:
      - adults: 2
        airbnb_domain: airbnb.ca
        amenities: wifi,kitchen
        check_in_date: '2029-02-01'
        check_out_date: '2029-02-03'
        currency: CAD
        include_taxes: true
        q: Toronto
    AmazonReviewsRequest:
      properties:
        asin:
          type: string
          maxLength: 10
          minLength: 10
          pattern: ^[A-Z0-9]+$
          title: Asin
          description: Product ASIN.
          examples:
          - B084PBWBJR
      additionalProperties: false
      type: object
      required:
      - asin
      title: AmazonReviewsRequest
      description: |-
        A product's ratings histogram and featured reviews.

        The `/product-reviews` list requires sign-in, so this answers with the
        product page's own reviews widget: the 5→1 histogram, the global
        ratings count, and the featured reviews. Rendered in a real browser.
      examples:
      - asin: B084PBWBJR
    AmazonSearchRequest:
      properties:
        q:
          type: string
          maxLength: 300
          minLength: 1
          title: Q
          description: Search query.
          examples:
          - bathrobe
        page:
          type: integer
          maximum: 20.0
          minimum: 1.0
          title: Page
          description: Result page.
          default: 1
          examples:
          - 1
        sort:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - date-desc-rank
          - price-asc-rank
          - price-desc-rank
          - relevanceblanks
          - review-rank
          title: Sort
          description: Amazon's own sort values.
          examples:
          - null
        min_rating:
          anyOf:
          - type: number
            maximum: 4.5
            minimum: 0.0
          - type: 'null'
          title: Min Rating
          description: Amazon's customer-rating filter (0..4.5).
          examples:
          - null
      additionalProperties: false
      type: object
      required:
      - q
      title: AmazonSearchRequest
      description: |-
        Amazon product search over plain HTTP.

        One page (~48) of result cards. Prices follow the local
        point-of-sale (a Canadian exit answers CAD): `price_text` is the
        display string verbatim with a best-effort `currency` guess — never
        silently USD'd. Sponsored rows are labelled, not dropped.
      examples:
      - q: bathrobe
    BingSearchRequest:
      properties:
        q:
          type: string
          maxLength: 400
          minLength: 1
          title: Q
          description: Search query.
          examples:
          - Hilton Chicago
        first:
          anyOf:
          - type: integer
            maximum: 1000.0
            minimum: 1.0
          - type: 'null'
          title: First
          description: 1-based result to start from; 11 pages past the first ten.
          examples:
          - null
        count:
          type: integer
          maximum: 35.0
          minimum: 1.0
          title: Count
          description: Results per page (Bing serves up to 35).
          default: 10
          examples:
          - 10
        market:
          anyOf:
          - type: string
            pattern: ^[a-z]{2,3}-[A-Za-z]{2,4}$
          - type: 'null'
          title: Market
          description: Bing `mkt` (`en-US`, `fr-CA`); Bing geo-resolves when omitted.
          examples:
          - en-US
      additionalProperties: false
      type: object
      required:
      - q
      title: BingSearchRequest
      description: |-
        Bing organic web search over plain HTTP.

        One page of up to 35 organic results with the click tracker decoded
        back to the destination URL. `first` is the 1-based result to start
        from (11 = second page of ten); `market` is Bing's own `mkt` value.
      examples:
      - count: 10
        q: Hilton Chicago
    BookingRequest:
      properties:
        pagename:
          type: string
          minLength: 2
          title: Pagename
          description: URL slug returned by `POST /v1/ota/booking/search`. For `booking.com/hotel/us/moxy-boston-downtown.html` the slug is `moxy-boston-downtown` and `country` is `us`.
          examples:
          - moxy-boston-downtown
        country:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          maxLength: 2
          minLength: 2
          title: Country
          description: The two-letter segment in the URL *before* the slug — part of the property's address on Booking, not your own location.
          default: us
          examples:
          - us
        start:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Start
          description: Defaults to today.
          examples:
          - '2029-02-05'
        days:
          type: integer
          maximum: 365.0
          minimum: 1.0
          title: Days
          description: Booking truncates any single response to 61 days, so larger windows are paged automatically — a year is 6 calls, not 1.
          default: 61
          examples:
          - 61
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        rooms:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Rooms
          description: Rooms requested.
          default: 1
          examples:
          - 1
      additionalProperties: false
      type: object
      required:
      - pagename
      title: BookingRequest
      description: Booking.com's own price calendar — 61 priced dates for ~5.5 KB.
      examples:
      - adults: 2
        country: us
        currency: USD
        days: 61
        pagename: moxy-boston-downtown
        start: '2029-02-05'
    BookingReviewsRequest:
      properties:
        pagename:
          type: string
          minLength: 2
          title: Pagename
          description: URL slug returned by `POST /v1/ota/booking/search`.
          examples:
          - newbury-guest-house
        country:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Country
          description: Two-letter segment before the slug in that URL.
          default: us
          examples:
          - us
        skip:
          type: integer
          minimum: 0.0
          title: Skip
          description: Reviews to skip before this page.
          default: 0
          examples:
          - 0
        limit:
          type: integer
          maximum: 25.0
          minimum: 1.0
          title: Limit
          description: Reviews per page (Booking caps at 25).
          default: 10
          examples:
          - 10
        sort:
          type: string
          enum:
          - MOST_RELEVANT
          - NEWEST_FIRST
          - OLDEST_FIRST
          title: Sort
          description: One of Booking's own sort enums.
          default: MOST_RELEVANT
          examples:
          - MOST_RELEVANT
        text:
          anyOf:
          - type: string
            maxLength: 100
          - type: 'null'
          title: Text
          description: Keyword filter Booking applies server-side.
          examples:
          - clean
      additionalProperties: false
      type: object
      required:
      - pagename
      title: BookingReviewsRequest
      description: |-
        Booking.com guest reviews from the property page's own query document.

        Ratings are 0-10. `sort` accepts the enums Booking's own UI lists.
        `text` filters reviews by keyword — Booking counts matches upstream, so
        a keyworded page can return fewer rows than `limit`.
      examples:
      - country: us
        limit: 10
        pagename: newbury-guest-house
        skip: 0
    BookingRoomsRequest:
      properties:
        pagename:
          type: string
          minLength: 2
          title: Pagename
          description: URL slug returned by `POST /v1/ota/booking/search`, e.g. `moxy-boston-downtown` from `booking.com/hotel/us/moxy-boston-downtown.html`.
          examples:
          - moxy-boston-downtown
        country:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Country
          description: Two-letter segment before the slug in that URL.
          default: us
          examples:
          - us
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        rooms:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Rooms
          description: Rooms requested.
          default: 1
          examples:
          - 1
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
      additionalProperties: false
      type: object
      required:
      - pagename
      - check_in
      title: BookingRoomsRequest
      description: |-
        Booking.com room types and rate plans for one night.

        Prices come from the property page's room grid, enriched with room
        size and occupancy when Booking.com provides them.
      examples:
      - adults: 2
        check_in: '2029-02-05'
        country: us
        currency: USD
        nights: 1
        pagename: moxy-boston-downtown
    BookingSearchRequest:
      properties:
        name:
          type: string
          minLength: 1
          title: Name
          description: Hotel name as a guest would search for it.
          examples:
          - Moxy Boston Downtown
        city:
          type: string
          title: City
          description: Strongly recommended for common hotel names. It is sent to Booking.com with the name so results come from the intended city.
          default: ''
          examples:
          - Boston
        limit:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Limit
          description: Maximum candidates to return, best match first.
          default: 5
          examples:
          - 5
      additionalProperties: false
      type: object
      required:
      - name
      title: BookingSearchRequest
      description: |-
        Find Booking.com's country and URL slug from a hotel name.

        Read `recommended_match`, not `matches[0]`. It is null when the provider
        returned only weak or ambiguous candidates.
      examples:
      - city: Boston
        limit: 5
        name: Moxy Boston Downtown
    CalendarJobItem:
      properties:
        token:
          type: string
          minLength: 8
          title: Token
          description: Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        market:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AG
          - AT
          - AU
          - BE
          - BZ
          - CA
          - CH
          - DE
          - ES
          - FR
          - GB
          - IE
          - IT
          - MX
          - NL
          - NZ
          - PT
          - US
          title: Market
          description: Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`.
          examples:
          - US
        country:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Country
          description: Two-letter `gl` override. Normally set by `market`.
          examples:
          - us
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO currency for the returned prices.
          examples:
          - USD
        days:
          type: integer
          maximum: 330.0
          minimum: 1.0
          title: Days
          description: Nights to price, starting at `start`. Max 330.
          default: 90
          examples:
          - 90
        start:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Start
          description: First stay date. Defaults to tomorrow.
          examples:
          - '2029-02-05'
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: 'Occupancy: number of adults, 1-8. Children are not supported by the Google calendar.'
          default: 2
          examples:
          - 2
        los:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Los
          description: Length of stay per quote. Nightly price genuinely moves with LOS.
          default: 1
          examples:
          - 1
        rates_include_tax:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Rates Include Tax
          description: Overrides the market default; pass the property's own setting
        is_hostel:
          type: boolean
          title: Is Hostel
          description: Hostels are priced per bed rather than per room, so occupancy changes the rate differently. Set this and the per-person maths is applied.
          default: false
        probe_min_stay:
          type: boolean
          title: Probe Min Stay
          description: Re-ask for any night that will not price as a single night. Google returns a two-night-minimum night identically to a sold-out one — empty, with no reason and no min-stay field — so without this, weekends silently vanish. On a beach market in August that was every Friday and Saturday on half the comp set. Filled rows carry `min_length_of_stay` and a per-night rate derived from the longer stay. Costs one extra call per probe level, not per date.
          default: true
        basis:
          type: string
          enum:
          - cheapest
          - mainstream
          pattern: ^(cheapest|mainstream)$
          title: Basis
          description: |-
            What the nightly figure should mean.

            **`cheapest` (default)** is the fast calendar path: one small request for the whole horizon. It returns Google's lowest bookable rate, including aggregators. The base/fees/taxes/total split and SearchAPI-compatible `rate_before_taxes_with_fees` remain populated.

            **`mainstream`** also returns `rate_mainstream_total` / `rate_mainstream_base` / `mainstream_source` / `aggregator_discount` — the cheapest rate on Booking, Expedia, Hotels.com, Priceline, Tripadvisor or Agoda, which is what a comp-set audit means by 'the OTA rate'. `rate_total` is left untouched, so both bases are available. This is intentionally expensive: it samples multi-megabyte offers pages and, when an aggregator sets the floor, re-prices each date. Measured on a 14-day request it took about 8s versus 0.4s for `cheapest`; use it selectively. `basis_applied` reports which path ran.
          default: cheapest
        verify_sources:
          type: integer
          maximum: 5.0
          minimum: 0.0
          title: Verify Sources
          description: 'Spot-check this many nights against the per-OTA offers page and return a `source_check` block. The Google calendar gives one price per night and never says which source it came from — usually a mainstream OTA, but where a discounter undercuts them it reports the discounter. Measured on four properties: three matched the cheapest mainstream OTA to the cent, the fourth''s figure was Super.com''s at 15% under. Costs one ~3 MB offers fetch per sampled night, so it is a sample, not every date.'
          default: 0
        label:
          anyOf:
          - type: string
            maxLength: 200
          - type: 'null'
          title: Label
          description: Optional customer label returned with this item.
          examples:
          - Boston Marriott Copley Place
      additionalProperties: false
      type: object
      required:
      - token
      title: CalendarJobItem
      description: One property in an asynchronous calendar batch.
      examples:
      - adults: 2
        basis: cheapest
        currency: USD
        days: 90
        los: 1
        market: US
        token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
    CalendarJobRequest:
      properties:
        items:
          items:
            $ref: '#/components/schemas/CalendarJobItem'
          type: array
          maxItems: 50
          minItems: 1
          title: Items
          description: One to 50 Google calendar requests. Each item keeps its own market, currency, horizon, occupancy and price basis.
        priority:
          type: integer
          maximum: 9.0
          minimum: 0.0
          title: Priority
          description: Queue priority from 0 (lowest) to 9 (highest). FIFO is preserved among jobs with the same priority.
          default: 5
          examples:
          - 5
        callback_url:
          anyOf:
          - type: string
            maxLength: 2048
          - type: 'null'
          title: Callback Url
          description: Optional public HTTPS endpoint. ScraperCompany POSTs a signed `job.completed` event to it after the batch finishes. If webhook delivery is not enabled for the service, a submission with `callback_url` is rejected with 503.
          examples:
          - https://example.com/webhooks/scrapercompany
      additionalProperties: false
      type: object
      required:
      - items
      title: CalendarJobRequest
      description: A durable, asynchronously executed batch of calendar requests.
      examples:
      - callback_url: https://example.com/webhooks/scrapercompany
        items:
        - basis: cheapest
          currency: USD
          days: 90
          label: Boston Marriott Copley Place
          market: US
          token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        priority: 5
    CalendarRequest:
      properties:
        token:
          type: string
          minLength: 8
          title: Token
          description: Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        market:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AG
          - AT
          - AU
          - BE
          - BZ
          - CA
          - CH
          - DE
          - ES
          - FR
          - GB
          - IE
          - IT
          - MX
          - NL
          - NZ
          - PT
          - US
          title: Market
          description: Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`.
          examples:
          - US
        country:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Country
          description: Two-letter `gl` override. Normally set by `market`.
          examples:
          - us
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO currency for the returned prices.
          examples:
          - USD
        days:
          type: integer
          maximum: 330.0
          minimum: 1.0
          title: Days
          description: Nights to price, starting at `start`. Max 330.
          default: 90
          examples:
          - 90
        start:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Start
          description: First stay date. Defaults to tomorrow.
          examples:
          - '2029-02-05'
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: 'Occupancy: number of adults, 1-8. Children are not supported by the Google calendar.'
          default: 2
          examples:
          - 2
        los:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Los
          description: Length of stay per quote. Nightly price genuinely moves with LOS.
          default: 1
          examples:
          - 1
        rates_include_tax:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Rates Include Tax
          description: Overrides the market default; pass the property's own setting
        is_hostel:
          type: boolean
          title: Is Hostel
          description: Hostels are priced per bed rather than per room, so occupancy changes the rate differently. Set this and the per-person maths is applied.
          default: false
        probe_min_stay:
          type: boolean
          title: Probe Min Stay
          description: Re-ask for any night that will not price as a single night. Google returns a two-night-minimum night identically to a sold-out one — empty, with no reason and no min-stay field — so without this, weekends silently vanish. On a beach market in August that was every Friday and Saturday on half the comp set. Filled rows carry `min_length_of_stay` and a per-night rate derived from the longer stay. Costs one extra call per probe level, not per date.
          default: true
        basis:
          type: string
          enum:
          - cheapest
          - mainstream
          pattern: ^(cheapest|mainstream)$
          title: Basis
          description: |-
            What the nightly figure should mean.

            **`cheapest` (default)** is the fast calendar path: one small request for the whole horizon. It returns Google's lowest bookable rate, including aggregators. The base/fees/taxes/total split and SearchAPI-compatible `rate_before_taxes_with_fees` remain populated.

            **`mainstream`** also returns `rate_mainstream_total` / `rate_mainstream_base` / `mainstream_source` / `aggregator_discount` — the cheapest rate on Booking, Expedia, Hotels.com, Priceline, Tripadvisor or Agoda, which is what a comp-set audit means by 'the OTA rate'. `rate_total` is left untouched, so both bases are available. This is intentionally expensive: it samples multi-megabyte offers pages and, when an aggregator sets the floor, re-prices each date. Measured on a 14-day request it took about 8s versus 0.4s for `cheapest`; use it selectively. `basis_applied` reports which path ran.
          default: cheapest
        verify_sources:
          type: integer
          maximum: 5.0
          minimum: 0.0
          title: Verify Sources
          description: 'Spot-check this many nights against the per-OTA offers page and return a `source_check` block. The Google calendar gives one price per night and never says which source it came from — usually a mainstream OTA, but where a discounter undercuts them it reports the discounter. Measured on four properties: three matched the cheapest mainstream OTA to the cent, the fourth''s figure was Super.com''s at 15% under. Costs one ~3 MB offers fetch per sampled night, so it is a sample, not every date.'
          default: 0
      additionalProperties: false
      type: object
      required:
      - token
      title: CalendarRequest
      description: |-
        A forward horizon of nightly rates for one property.

        The cheapest call here by a wide margin: one request returns the
        whole window in ~30 KB, so a 90-night sweep costs one request, not 90.
      examples:
      - adults: 2
        basis: cheapest
        currency: USD
        days: 90
        los: 1
        market: US
        token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
    CompareRequest:
      properties:
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-02-06'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
        booking_pagename:
          anyOf:
          - type: string
          - type: 'null'
          title: Booking Pagename
          description: Booking slug. Omit to skip Booking entirely.
          examples:
          - moxy-boston-downtown
        booking_country:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Booking Country
          description: Two-letter segment before the slug in the Booking URL.
          default: us
          examples:
          - us
        hotels_property_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Hotels Property Id
          description: Hotels.com numeric id. Omit to skip Hotels.com.
          examples:
          - '38766175'
        hotels_market:
          type: string
          enum:
          - AU
          - CA
          - DE
          - EU
          - FR
          - GB
          - IE
          - IT
          - NL
          - NZ
          - US
          title: Hotels Market
          description: Hotels.com point-of-sale; also picks its currency.
          default: US
          examples:
          - US
        agoda_property_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Agoda Property Id
          description: Agoda numeric id. Omit to skip Agoda.
          examples:
          - '8795952'
        expedia_property_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Expedia Property Id
          description: Expedia numeric id from `POST /v1/ota/expedia/search`. Omit to skip Expedia.
          examples:
          - '38766175'
        expedia_market:
          type: string
          enum:
          - CA
          - US
          title: Expedia Market
          description: Expedia point-of-sale; also picks its currency.
          default: US
          examples:
          - US
      additionalProperties: false
      type: object
      required:
      - check_in
      title: CompareRequest
      description: |-
        One night across every source an identifier is supplied for.

        Identifiers differ per site and there is no shared key, so each is named
        explicitly rather than pretending one id resolves everywhere.

        **The three ids are unrelated strings and nothing here can check they name
        the same hotel.** Pass a Booking slug for one property and an Agoda id for
        another and you get a confident, meaningless spread. `comparison.identifiers`
        echoes back what was used so the mistake is visible in the answer.

        Leave any identifier out to skip that source. Fail-soft per source: a
        blocked OTA comes back as a row with a status, not a lost result.
        `comparison.comparable` is false when fewer than two prices return or the
        sources return different currencies; mixed-currency minima are suppressed.
      examples:
      - agoda_property_id: '8795952'
        booking_country: us
        booking_pagename: moxy-boston-downtown
        check_in: '2029-02-05'
        currency: USD
        nights: 1
    ExpediaRequest:
      properties:
        property_id:
          type: string
          minLength: 1
          pattern: ^\d+$
          title: Property Id
          description: 'Numeric id returned by `POST /v1/ota/expedia/search`. For `expedia.com/Chicago-Hotels-Hilton-Chicago.h12570.Hotel-Information` it is `12570`. Not always the Hotels.com id: older properties differ between brands.'
          examples:
          - '12570'
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-04-10'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-04-11'
        nights:
          type: integer
          maximum: 28.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room.
          default: 2
          examples:
          - 2
        market:
          type: string
          enum:
          - CA
          - US
          title: Market
          description: Expedia point-of-sale, which is how currency is selected - there is no currency field. `US` prices in USD on www.expedia.com, `CA` in CAD on www.expedia.ca. The display basis differs by market (the US room card leads with the stay total, CA with the nightly price), so compare within one market.
          default: US
          examples:
          - US
        rooms:
          type: boolean
          title: Rooms
          description: Return every room type and rate plan (~50-250 KB upstream). False returns the headline price only (~6 KB). Same credit cost.
          default: true
          examples:
          - true
      additionalProperties: false
      type: object
      required:
      - property_id
      - check_in
      title: ExpediaRequest
      description: |-
        Expedia rooms, rate plans and headline price for one stay window.

        One request. Each offer carries the upstream stay total
        (taxes and fees included, as Expedia labels it), the nightly price before
        taxes, and the combined taxes and fees derived from the two.
      examples:
      - adults: 2
        check_in: '2029-04-10'
        market: US
        nights: 1
        property_id: '12570'
        rooms: true
    ExpediaReviewsRequest:
      properties:
        property_id:
          type: string
          minLength: 1
          pattern: ^\d+$
          title: Property Id
          description: Numeric id returned by `POST /v1/ota/expedia/search`.
          examples:
          - '12570'
        size:
          type: integer
          maximum: 25.0
          minimum: 1.0
          title: Size
          description: Reviews per page.
          default: 10
          examples:
          - 10
        start_index:
          type: integer
          minimum: 0.0
          title: Start Index
          description: Row to start from; page by `start_index += size`.
          default: 0
          examples:
          - 0
        market:
          type: string
          enum:
          - CA
          - US
          title: Market
          description: Point-of-sale; also selects the currency.
          default: US
          examples:
          - US
      additionalProperties: false
      type: object
      required:
      - property_id
      title: ExpediaReviewsRequest
      description: |-
        Expedia guest reviews for one property.

        One registered query, without a browser. Ratings are 0-10, parsed
        from the upstream score label; the "Verified review" disclaimer and
        "Liked: …" themes ride in `labels`, exactly as Expedia publishes them.
      examples:
      - property_id: '12570'
        size: 10
        start_index: 0
    ExpediaSearchRequest:
      properties:
        name:
          type: string
          minLength: 1
          title: Name
          description: Hotel name as a guest would search for it.
          examples:
          - Hilton Chicago
        city:
          type: string
          title: City
          description: Strongly recommended. Sent with the name to Expedia's typeahead and used to rank same-brand hotels in other cities lower.
          default: ''
          examples:
          - Chicago
        market:
          type: string
          enum:
          - CA
          - US
          title: Market
          description: Expedia point-of-sale, which is how currency is selected - there is no currency field. `US` prices in USD on www.expedia.com, `CA` in CAD on www.expedia.ca. The display basis differs by market (the US room card leads with the stay total, CA with the nightly price), so compare within one market.
          default: US
          examples:
          - US
        limit:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Limit
          description: Maximum hotel candidates to return, best match first.
          default: 5
          examples:
          - 5
      additionalProperties: false
      type: object
      required:
      - name
      title: ExpediaSearchRequest
      description: |-
        Find Expedia's numeric property id from a hotel name.

        Read `recommended_match`, not `matches[0]`. It is null when the provider
        returned only weak or ambiguous candidates.
      examples:
      - city: Chicago
        limit: 5
        market: US
        name: Hilton Chicago
    FlightsBookingRequest:
      properties:
        booking_token:
          type: string
          pattern: ^gf1\.[A-Za-z0-9_\-]{16,16384}$
          title: Booking Token
          description: '`booking_token` of a complete itinerary: a one-way result of `/v1/serp/google_flights`, or a return/last-leg result of `/v1/serp/google_flights_return`.'
          examples:
          - gf1.eNp9T8sKwjAQ_Jc9p5BUqqU3tc0hBm0bE8WQk_hASy9tVRD_3aRVVBSzsJlhZjabK5wgIgi2EOmyKQrUNr-7tEEEaYKwK4Ne-q-m3QFGJ2C9xjgOfLh8sNaC3-zgY7_vEeyRAJ4DuvSH0o3oEjG3nAzCEMyfZXrfIjEIqvabNUQwPuR0kdCpTC6UqzwVWM24DFI1JiOuGM3kuRYqZ_OjEpliK_vo2sakiC3aFxZuSot2DjUV3O6AWl_r
      additionalProperties: false
      type: object
      required:
      - booking_token
      title: FlightsBookingRequest
      description: |-
        Sellers of a complete itinerary: airline direct and OTAs, with prices,
        fare names and click-through links (SerpApi `booking_options`).
      examples:
      - booking_token: gf1.eNp9T8sKwjAQ_Jc9p5BUqqU3tc0hBm0bE8WQk_hASy9tVRD_3aRVVBSzsJlhZjabK5wgIgi2EOmyKQrUNr-7tEEEaYKwK4Ne-q-m3QFGJ2C9xjgOfLh8sNaC3-zgY7_vEeyRAJ4DuvSH0o3oEjG3nAzCEMyfZXrfIjEIqvabNUQwPuR0kdCpTC6UqzwVWM24DFI1JiOuGM3kuRYqZ_OjEpliK_vo2sakiC3aFxZuSot2DjUV3O6AWl_r
    FlightsCalendarRequest:
      properties:
        departure:
          type: string
          maxLength: 3
          minLength: 3
          title: Departure
          description: IATA departure airport code.
          examples:
          - JFK
        arrival:
          type: string
          maxLength: 3
          minLength: 3
          title: Arrival
          description: IATA arrival airport code.
          examples:
          - LAX
        departure_date:
          type: string
          format: date
          title: Departure Date
          description: Target outbound date (center of date range).
          examples:
          - '2029-03-08'
        return_date:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Return Date
          description: Target return date for round-trip. Omit for one-way.
          examples:
          - '2029-03-13'
        adults:
          type: integer
          maximum: 9.0
          minimum: 1.0
          title: Adults
          description: Number of passengers.
          default: 1
          examples:
          - 1
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
        hl:
          type: string
          title: Hl
          description: Language code.
          default: en
          examples:
          - en
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Market/country code.
          default: us
          examples:
          - us
        date_window_days:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Date Window Days
          description: Days before/after target date to include in grid.
          default: 7
          examples:
          - 7
      additionalProperties: false
      type: object
      required:
      - departure
      - arrival
      - departure_date
      title: FlightsCalendarRequest
      description: |-
        Google Flights calendar/date-grid pricing.

        Returns cheapest prices across a date range, similar to SearchAPI's
        google_flights_calendar. Useful for flexible-date price comparison.
      examples:
      - adults: 1
        arrival: LAX
        currency: USD
        date_window_days: 7
        departure: JFK
        departure_date: '2029-03-08'
        return_date: '2029-03-13'
    FlightsLegSpec:
      properties:
        departure:
          type: string
          maxLength: 80
          minLength: 3
          title: Departure
          description: 'IATA airport code (`JFK`), IATA city code (`NYC`, `LON`, `PAR`: every airport of the city), a Google city id from `/v1/serp/google_flights_location_search` (`/m/02_286`), or up to 7 of these comma-separated (`JFK,EWR`).'
          examples:
          - YUL
        arrival:
          type: string
          maxLength: 80
          minLength: 3
          title: Arrival
          description: 'IATA airport code (`JFK`), IATA city code (`NYC`, `LON`, `PAR`: every airport of the city), a Google city id from `/v1/serp/google_flights_location_search` (`/m/02_286`), or up to 7 of these comma-separated (`JFK,EWR`).'
          examples:
          - CDG
        date:
          type: string
          format: date
          title: Date
          description: Departure date of this leg, `YYYY-MM-DD`.
          examples:
          - '2029-03-28'
        times:
          anyOf:
          - type: string
            pattern: ^\d{1,2},\d{1,2}(,\d{1,2},\d{1,2})?$
          - type: 'null'
          title: Times
          description: Hour window `from,to` for departure, optionally followed by `from,to` for arrival (0-23; `8,12` = leaves 08:00-12:59). SerpApi's format.
          examples:
          - 6,20
      additionalProperties: false
      type: object
      required:
      - departure
      - arrival
      - date
      title: FlightsLegSpec
      description: One leg of a multi-city trip.
    FlightsLocationSearchRequest:
      properties:
        q:
          type: string
          maxLength: 100
          minLength: 1
          title: Q
          description: City, airport or region name, or a code (`paris`, `Heathrow`, `NYC`).
          examples:
          - paris
        hl:
          type: string
          pattern: ^[A-Za-z]{2,3}(-[A-Za-z]{2,4})?$
          title: Hl
          description: Language of the returned names.
          default: en
          examples:
          - en
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Market/country code (two letters).
          default: us
          examples:
          - us
      additionalProperties: false
      type: object
      required:
      - q
      title: FlightsLocationSearchRequest
      description: Resolve a city or airport name to IATA codes and Google city ids.
      examples:
      - gl: us
        hl: en
        q: paris
    FlightsReturnRequest:
      properties:
        departure_token:
          type: string
          pattern: ^gf1\.[A-Za-z0-9_\-]{16,16384}$
          title: Departure Token
          description: '`departure_token` of an itinerary from `/v1/serp/google_flights` (or of a previous `/v1/serp/google_flights_return` leg of a multi-city trip). It carries the search, so nothing else is needed.'
          examples:
          - gf1.eNqFUMkKwjAU_Jd3TiGpVqU3TVuhBO1iIhpyEhe09NJWBfHfTRexxS2BlxneMvNygzPYBMEObJkWSYKqQOpHKo0kQbi8Cr3yn4IsD6w4A12rVMmBOtOGVSW4VQ4mNgcGwQax4Dmg7u5k6hF1x5hqPhr2Qf3w0quU29JdW9-NmCb8WbEReFMnCkFWfWMONtBj5C1db8bdq8dEFMRYzBm3AkHJhAnfC_klj0XkL04iDoW_1kttdBuPHY0OiYbbVKN9iYoM7g_hQ347
      additionalProperties: false
      type: object
      required:
      - departure_token
      title: FlightsReturnRequest
      description: |-
        Options for the next leg after the one a `departure_token` chose.

        For a round trip these are the return flights (priced for the whole
        trip, each with a `booking_token`); for multi-city, the next leg.
      examples:
      - departure_token: gf1.eNqFUMkKwjAU_Jd3TiGpVqU3TVuhBO1iIhpyEhe09NJWBfHfTRexxS2BlxneMvNygzPYBMEObJkWSYKqQOpHKo0kQbi8Cr3yn4IsD6w4A12rVMmBOtOGVSW4VQ4mNgcGwQax4Dmg7u5k6hF1x5hqPhr2Qf3w0quU29JdW9-NmCb8WbEReFMnCkFWfWMONtBj5C1db8bdq8dEFMRYzBm3AkHJhAnfC_klj0XkL04iDoW_1kttdBuPHY0OiYbbVKN9iYoM7g_hQ347
    FlightsSearchRequest:
      properties:
        departure:
          type: string
          maxLength: 3
          minLength: 3
          title: Departure
          description: 'IATA airport code (`JFK`) or IATA city code (`NYC`, `LON`, `PAR`, `TYO`...: every airport of that city). For several airports or a Google city id use `departure_id`.'
          examples:
          - JFK
        arrival:
          type: string
          maxLength: 3
          minLength: 3
          title: Arrival
          description: 'IATA airport code (`JFK`) or IATA city code (`NYC`, `LON`, `PAR`, `TYO`...: every airport of that city). For several airports or a Google city id use `arrival_id`.'
          examples:
          - LAX
        departure_date:
          type: string
          format: date
          title: Departure Date
          description: Outbound flight date, `YYYY-MM-DD`.
          examples:
          - '2029-03-08'
        return_date:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Return Date
          description: Return flight date for round-trip. Omit for one-way.
          examples:
          - '2029-03-13'
        departure_id:
          anyOf:
          - type: string
            maxLength: 200
            minLength: 3
          - type: 'null'
          title: Departure Id
          description: 'SerpApi''s `departure_id`: overrides `departure` with comma-separated IATA airport/city codes and/or Google city ids (`/m/02_286`), up to 7. `departure` is then only the label echoed back.'
          examples:
          - JFK,EWR
        arrival_id:
          anyOf:
          - type: string
            maxLength: 200
            minLength: 3
          - type: 'null'
          title: Arrival Id
          description: 'SerpApi''s `arrival_id`: overrides `arrival` the same way, e.g. a city id from `/v1/serp/google_flights_location_search`.'
          examples:
          - /m/05qtj
        multi_city:
          anyOf:
          - items:
              $ref: '#/components/schemas/FlightsLegSpec'
            type: array
            maxItems: 4
            minItems: 1
          - type: 'null'
          title: Multi City
          description: 'Makes the trip multi-city: the legs after the first (`departure` -> `arrival` on `departure_date`), 1-4 of them, in date order. The response lists options for the first leg; follow `departure_token` for each next leg. Not combinable with `return_date`.'
        adults:
          type: integer
          maximum: 9.0
          minimum: 1.0
          title: Adults
          description: Number of adult passengers (12+ years old).
          default: 1
          examples:
          - 1
        children:
          type: integer
          maximum: 8.0
          minimum: 0.0
          title: Children
          description: Number of children (2-11 years old).
          default: 0
          examples:
          - 0
        infants_in_seat:
          type: integer
          maximum: 4.0
          minimum: 0.0
          title: Infants In Seat
          description: Number of infants with seat (under 2 years old).
          default: 0
          examples:
          - 0
        infants_on_lap:
          type: integer
          maximum: 4.0
          minimum: 0.0
          title: Infants On Lap
          description: Number of lap infants (under 2 years old); at most one per adult.
          default: 0
          examples:
          - 0
        cabin_class:
          type: string
          enum:
          - business
          - economy
          - first
          - premium_economy
          pattern: ^(economy|premium_economy|business|first)$
          title: Cabin Class
          description: 'Cabin class: economy, premium_economy, business, first.'
          default: economy
          examples:
          - economy
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
        hl:
          type: string
          title: Hl
          description: Language code for results.
          default: en
          examples:
          - en
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Market/country code (two letters).
          default: us
          examples:
          - us
        stops:
          anyOf:
          - type: integer
            maximum: 2.0
            minimum: 0.0
          - type: 'null'
          title: Stops
          description: 'Maximum stops filter: 0=nonstop only, 1=max 1 stop, 2=max 2 stops. Omit for any number of stops.'
          examples:
          - null
        include_airlines:
          anyOf:
          - type: string
            pattern: ^[A-Za-z0-9_]{2,13}(,[A-Za-z0-9_]{2,13}){0,19}$
          - type: 'null'
          title: Include Airlines
          description: Comma-separated IATA airline codes and/or alliances (`STAR_ALLIANCE`, `SKYTEAM`, `ONEWORLD`) to keep, e.g. `AC,UA`. Cannot be combined with `exclude_airlines`.
          examples:
          - AC,UA
        exclude_airlines:
          anyOf:
          - type: string
            pattern: ^[A-Za-z0-9_]{2,13}(,[A-Za-z0-9_]{2,13}){0,19}$
          - type: 'null'
          title: Exclude Airlines
          description: 'Comma-separated airline codes to drop. Google''s rule: an itinerary also sold under a codeshare partner that is not excluded is kept.'
          examples:
          - B6
        max_price:
          anyOf:
          - type: integer
            maximum: 1000000.0
            minimum: 1.0
          - type: 'null'
          title: Max Price
          description: Only itineraries at or below this price, in `currency`.
          examples:
          - 400
        max_duration:
          anyOf:
          - type: integer
            maximum: 5760.0
            minimum: 30.0
          - type: 'null'
          title: Max Duration
          description: Maximum door-to-door travel time per leg, minutes.
          examples:
          - 600
        outbound_times:
          anyOf:
          - type: string
            pattern: ^\d{1,2},\d{1,2}(,\d{1,2},\d{1,2})?$
          - type: 'null'
          title: Outbound Times
          description: Hour window `from,to` for departure, optionally followed by `from,to` for arrival (0-23; `8,12` = leaves 08:00-12:59). SerpApi's format. First leg.
          examples:
          - 6,12
        return_times:
          anyOf:
          - type: string
            pattern: ^\d{1,2},\d{1,2}(,\d{1,2},\d{1,2})?$
          - type: 'null'
          title: Return Times
          description: Hour window `from,to` for departure, optionally followed by `from,to` for arrival (0-23; `8,12` = leaves 08:00-12:59). SerpApi's format. Return leg; needs `return_date`.
          examples:
          - 14,23
        carry_on_bags:
          type: integer
          maximum: 1.0
          minimum: 0.0
          title: Carry On Bags
          description: Carry-on bags per passenger to include in the price (Google adds the airline's bag fees).
          default: 0
          examples:
          - 0
        checked_bags:
          type: integer
          maximum: 2.0
          minimum: 0.0
          title: Checked Bags
          description: Checked bags per passenger to include in the price.
          default: 0
          examples:
          - 0
        exclude_basic_economy:
          type: boolean
          title: Exclude Basic Economy
          description: Hide basic-economy fares (Google's "Economy (exclude Basic)"; offered on US routes).
          default: false
          examples:
          - false
        less_emissions:
          type: boolean
          title: Less Emissions
          description: Only flights with lower-than-typical emissions.
          default: false
          examples:
          - false
        layover_duration:
          anyOf:
          - type: string
            pattern: ^\d{1,4},\d{1,4}$
          - type: 'null'
          title: Layover Duration
          description: Layover length window `min,max` in minutes, e.g. `60,240`.
          examples:
          - 60,240
        connecting_airports:
          anyOf:
          - type: string
            pattern: ^[A-Za-z0-9]{3}(,[A-Za-z0-9]{3}){0,19}$
          - type: 'null'
          title: Connecting Airports
          description: Only connect through these airports (comma-separated IATA codes).
          examples:
          - ORD,DTW
        exclude_connecting_airports:
          anyOf:
          - type: string
            pattern: ^[A-Za-z0-9]{3}(,[A-Za-z0-9]{3}){0,19}$
          - type: 'null'
          title: Exclude Connecting Airports
          description: Never connect through these airports.
          examples:
          - YYZ
        sort_by:
          type: string
          enum:
          - arrival_time
          - departure_time
          - duration
          - emissions
          - price
          - top_flights
          pattern: ^(top_flights|price|departure_time|arrival_time|duration|emissions)$
          title: Sort By
          description: 'Result order (SerpApi `sort_by` 1-6 in the same order): top_flights, price, departure_time, arrival_time, duration, emissions. With anything but top_flights Google returns no separate best group.'
          default: top_flights
          examples:
          - top_flights
      additionalProperties: false
      type: object
      required:
      - departure
      - arrival
      - departure_date
      title: FlightsSearchRequest
      description: |-
        Google Flights search: every itinerary Google offers, with segments.

        One-way when `return_date` is omitted; round trip when it is given (the
        response lists outbound options priced for the whole trip, each with a
        `departure_token` for `/v1/serp/google_flights_return`); multi-city when
        `multi_city` lists the legs after the first. Complete itineraries carry a
        `booking_token` for `/v1/serp/google_flights_booking`.
      examples:
      - adults: 1
        arrival: LAX
        cabin_class: economy
        currency: USD
        departure: JFK
        departure_date: '2029-03-08'
        return_date: '2029-03-13'
      - arrival: NYC
        checked_bags: 1
        departure: YUL
        departure_date: '2029-03-08'
        exclude_airlines: B6
        outbound_times: 6,12
        sort_by: price
        stops: 0
      - arrival: PAR
        arrival_id: /m/05qtj
        departure: YUL
        departure_date: '2029-03-08'
        multi_city:
        - arrival: FCO
          date: '2029-03-13'
          departure: CDG,ORY
        - arrival: YUL
          date: '2029-03-19'
          departure: FCO
    GoogleHotelsPropertyRequest:
      properties:
        property_token:
          type: string
          maxLength: 200
          minLength: 10
          title: Property Token
          description: Token returned by `POST /v1/hotels/search`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country for the request.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language for the request.
          default: en
          examples:
          - en
      additionalProperties: false
      type: object
      required:
      - property_token
      title: GoogleHotelsPropertyRequest
      description: |-
        One Google Hotels property's details record, by token.

        This is the address-bearing render: the search card omits the mailing
        address, the pinned property answers with it. Use it to confirm a
        `POST /v1/hotels/search` result is the property you meant.
      examples:
      - currency: USD
        property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
    GoogleHotelsResolveRequest:
      properties:
        q:
          type: string
          maxLength: 200
          minLength: 2
          title: Q
          description: Hotel name plus city, region or country.
          examples:
          - Hilton Chicago
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country market for the search.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language for the search.
          default: en
          examples:
          - en
        limit:
          type: integer
          maximum: 3.0
          minimum: 1.0
          title: Limit
          description: How many candidates to resolve with addresses (1-3).
          default: 3
          examples:
          - 3
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
      additionalProperties: false
      type: object
      required:
      - q
      title: GoogleHotelsResolveRequest
      description: |-
        Find Google Hotels properties by name and place, with addresses.

        Runs the destination search for `q` (name plus city, region or country —
        `gl` biases the market), then fetches each candidate's details record to
        attach the mailing address. Returns the top `limit` properties with
        their `property_token`, ready for `/v1/calendar`, `/v1/offers` and
        `/v1/hotels/reviews`.
      examples:
      - gl: us
        limit: 3
        q: Hilton Chicago
    GoogleHotelsReviewsRequest:
      properties:
        property_token:
          type: string
          maxLength: 200
          minLength: 10
          title: Property Token
          description: Token returned by `POST /v1/hotels/search` or `POST /v1/hotels/property`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        pages:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Pages
          description: How many 10-review pages to follow.
          default: 1
          examples:
          - 1
        page_token:
          anyOf:
          - type: string
          - type: 'null'
          title: Page Token
          description: Continuation token from a previous answer's `next_page_token`.
          examples:
          - null
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country for the request.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language for the request.
          default: en
          examples:
          - en
      additionalProperties: false
      type: object
      required:
      - property_token
      title: GoogleHotelsReviewsRequest
      description: |-
        Google Hotels guest reviews for one property.

        `property_token` is the `Ch…` token `POST /v1/hotels/search` returns.
        Google mixes its own reviews with Tripadvisor's, Priceline's and others;
        each row names its `provider`, and ratings follow that provider's scale
        (5 for Google/Tripadvisor, 10 for Priceline). Dates are the relative
        strings Google shows ("a month ago") — Google publishes no absolute
        dates here. Ten reviews per page; `pages` follows the continuation
        token up to ten pages in one call.
      examples:
      - pages: 1
        property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
    GoogleHotelsSearchRequest:
      properties:
        q:
          type: string
          maxLength: 200
          minLength: 2
          title: Q
          description: Destination query exactly as a traveller would type it into Google Hotels, e.g. `hotels in Montreal`, `Paris`, `hotels near JFK`. Google resolves it to a place; the response reports which in `search_information.location`.
          examples:
          - hotels in Montreal
        adults:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Encoded as one guest entry each, the way Google's own control sends them.
          default: 2
          examples:
          - 2
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - CAD
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Two-letter Google country (market). Sets the market; the currency is requested separately.
          default: us
          examples:
          - ca
        hl:
          type: string
          pattern: ^[a-z]{2,3}(-[A-Za-z]{2,4})?$
          title: Hl
          description: Interface language. Display strings follow it; hotel amenity names are always English.
          default: en
          examples:
          - en
        sort_by:
          type: string
          enum:
          - highest_rating
          - lowest_price
          - most_reviewed
          - relevance
          title: Sort By
          description: Result order, as Google's Sort by control.
          default: relevance
        price_min:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Price Min
          description: Minimum nightly price in `currency`.
          examples:
          - 50
        price_max:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Price Max
          description: Maximum nightly price in `currency`.
          examples:
          - 300
        free_cancellation:
          type: boolean
          title: Free Cancellation
          description: Only properties Google lists with free cancellation.
          default: false
        special_offers:
          type: boolean
          title: Special Offers
          description: Only properties with a special offer.
          default: false
        eco_certified:
          type: boolean
          title: Eco Certified
          description: Only eco-certified properties.
          default: false
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-03-14'
        check_out:
          type: string
          format: date
          title: Check Out
          description: Departure date, after `check_in`; at most 30 nights.
          examples:
          - '2029-03-16'
        children_ages:
          items:
            type: integer
          type: array
          maxItems: 8
          title: Children Ages
          description: One age (0-17) per child. Google prices on each age; the response is rejected if Google priced a different party.
          default: []
          examples:
          - - 8
        page_token:
          anyOf:
          - type: string
            pattern: ^[A-Za-z0-9_\-+/=]{1,200}$
          - type: 'null'
          title: Page Token
          description: Opaque cursor from `pagination.next_page_token` of the previous page. Resend the same query, stay, occupancy and filters with it, exactly as with SearchAPI.
          examples:
          - CBI=
        min_rating:
          anyOf:
          - type: number
          - type: 'null'
          enum:
          - 3.5
          - 4.0
          - 4.5
          title: Min Rating
          description: 'Minimum guest rating: 3.5, 4.0 or 4.5.'
          examples:
          - 4.0
        hotel_class:
          items:
            type: integer
          type: array
          maxItems: 4
          title: Hotel Class
          description: Star classes to include, 2-5.
          default: []
          examples:
          - - 4
            - 5
          x-multiple: true
          x-options:
          - 2
          - 3
          - 4
          - 5
        amenities:
          items:
            type: integer
          type: array
          maxItems: 19
          title: Amenities
          description: 'Amenity filter ids: 1 Free parking, 3 Parking, 4 Indoor pool, 5 Outdoor pool, 6 Pool, 7 Fitness center, 8 Restaurant, 9 Free breakfast, 10 Spa, 11 Beach access, 12 Child-friendly, 15 Bar, 19 Pet-friendly, 22 Room service, 35 Free Wi-Fi, 40 Air-conditioned, 52 All-inclusive available, 53 Wheelchair accessible, 61 EV charger.'
          default: []
          examples:
          - - 6
            - 35
          x-multiple: true
          x-options:
          - 1
          - 3
          - 4
          - 5
          - 6
          - 7
          - 8
          - 9
          - 10
          - 11
          - 12
          - 15
          - 19
          - 22
          - 35
          - 40
          - 52
          - 53
          - 61
        property_types:
          items:
            type: integer
          type: array
          maxItems: 13
          title: Property Types
          description: 'Property-type filter ids: 12 Beach hotels, 13 Boutique hotels, 14 Hostels, 15 Inns, 16 Motels, 17 Resorts, 18 Spa hotels, 19 Bed and breakfasts, 20 Other, 21 Apartment hotels, 22 Minshuku, 23 Japanese-style business hotels, 24 Ryokan.'
          default: []
          examples:
          - - 19
          x-multiple: true
          x-options:
          - 12
          - 13
          - 14
          - 15
          - 16
          - 17
          - 18
          - 19
          - 20
          - 21
          - 22
          - 23
          - 24
      additionalProperties: false
      type: object
      required:
      - q
      - check_in
      - check_out
      title: GoogleHotelsSearchRequest
      description: |-
        Search a destination on Google Hotels (native field names).

        One request is one page of about 20 properties. Page on with
        `page_token`; every page costs the same.
      examples:
      - adults: 2
        check_in: '2029-03-14'
        check_out: '2029-03-16'
        currency: CAD
        gl: ca
        hl: en
        hotel_class:
        - 3
        - 4
        - 5
        min_rating: 4.0
        price_max: 300
        q: hotels in Montreal
        sort_by: relevance
    GoogleJobsRequest:
      properties:
        q:
          type: string
          maxLength: 300
          minLength: 1
          title: Q
          description: Jobs query.
          examples:
          - hotel jobs chicago
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country market.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language.
          default: en
          examples:
          - en
      additionalProperties: false
      type: object
      required:
      - q
      title: GoogleJobsRequest
      description: |-
        Google Jobs listings for a query.

        Google serves a JavaScript shell to plain HTTP, so this renders the
        jobs panel in a real browser (seconds per call). Each card carries the
        title, company, location, the upstream publisher (`via`), the relative
        posting age, the employment type, and the apply links (Google
        redirects, with their sources).
      examples:
      - q: hotel jobs chicago
    GoogleNewsRequest:
      properties:
        q:
          anyOf:
          - type: string
            maxLength: 200
          - type: 'null'
          title: Q
          description: Search query. Omit to read `topic` (or top stories).
          examples:
          - Hilton Chicago
        topic:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - business
          - entertainment
          - health
          - nation
          - science
          - sports
          - technology
          - top_stories
          - world
          title: Topic
          description: 'Section feed: one of Google''s reader sections.'
          examples:
          - business
        when:
          anyOf:
          - type: string
            pattern: ^\d+[hdmy]$
          - type: 'null'
          title: When
          description: Freshness window appended to `q` (`1h`, `1d`, `7d`, `1y`).
          examples:
          - 1y
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country market.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language.
          default: en
          examples:
          - en
        ceid:
          anyOf:
          - type: string
            pattern: ^[A-Z]{2}:[a-z]{2}$
          - type: 'null'
          title: Ceid
          description: Explicit edition override (`CA:fr`, `GB:en`); built from `gl`/`hl` when omitted.
          examples:
          - null
      additionalProperties: false
      type: object
      title: GoogleNewsRequest
      description: |-
        Google News search or section headlines, via Google's own RSS feed.

        Pass `q` to search, or `topic` for a section feed — not both. `when`
        appends Google's `when:` operator (`1h`, `1d`, `7d`, `1y`), the feed's
        only freshness control. One page returns up to 100 stories.
      examples:
      - q: Hilton Chicago
        when: 1y
    GoogleSearchRequest:
      properties:
        q:
          type: string
          maxLength: 400
          minLength: 1
          title: Q
          description: Search query.
          examples:
          - Hilton Chicago
        page:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Page
          description: Result page (10 results per page).
          default: 1
          examples:
          - 1
        num:
          type: integer
          maximum: 20.0
          minimum: 1.0
          title: Num
          description: Results per page.
          default: 10
          examples:
          - 10
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country market.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language.
          default: en
          examples:
          - en
        resolve:
          type: boolean
          title: Resolve
          description: Follow each result's `/goto` redirect to the destination URL (one HTTP request per result).
          default: false
          examples:
          - false
      additionalProperties: false
      type: object
      required:
      - q
      title: GoogleSearchRequest
      description: |-
        Google web search: organic results, People Also Ask, AI overview.

        Google serves a JavaScript shell to plain HTTP, so this renders the page
        in a real browser (seconds, not milliseconds). `link` values are
        Google's `/goto` redirects unless `resolve=true`, which follows each
        redirect (one request per result) and returns the destination.
      examples:
      - q: best time to visit japan
    GoogleShoppingRequest:
      properties:
        q:
          type: string
          maxLength: 300
          minLength: 1
          title: Q
          description: Shopping query.
          examples:
          - hilton bathrobe
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country market.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language.
          default: en
          examples:
          - en
      additionalProperties: false
      type: object
      required:
      - q
      title: GoogleShoppingRequest
      description: |-
        Google Shopping products for a query.

        Google serves a JavaScript shell to plain HTTP, so this renders the
        shopping SERP in a real browser (seconds per call). Each card carries
        the title, price, merchant and condition chips, plus Google's
        `data-pid` product id. Products dedupe by `data-pid`.
      examples:
      - q: hilton bathrobe
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    HostelworldRequest:
      properties:
        property_id:
          type: string
          minLength: 1
          title: Property Id
          description: Numeric property id from Hostelworld URL, e.g. `hostelworld.com/pwa/hosteldetails.php/88047/...`
          examples:
          - '88047'
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-03-03'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-03-04'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        guests:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Guests
          description: Number of guests. For dorms, this is the number of beds needed. For private rooms, this is the occupancy.
          default: 1
          examples:
          - 1
      additionalProperties: false
      type: object
      required:
      - property_id
      - check_in
      title: HostelworldRequest
      description: |-
        Hostelworld: every dorm bed and private room with rate plans.

        Currency is NOT selectable — Hostelworld returns the property's native
        currency (typically GBP for UK hostels). Per-bed pricing for dorms,
        per-room pricing for privates.
      examples:
      - check_in: '2029-03-03'
        guests: 1
        nights: 1
        property_id: '88047'
    HotelsRequest:
      properties:
        property_id:
          type: string
          minLength: 1
          title: Property Id
          description: Numeric id returned by `POST /v1/ota/hotels/search`. For `hotels.com/h38766175.Hotel-Information` it is `38766175` — digits only, no leading `h`. The `ho…` number in a page URL is a legacy id the rate endpoints do not price.
          examples:
          - '12570'
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-02-06'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        market:
          type: string
          enum:
          - AU
          - CA
          - DE
          - EU
          - FR
          - GB
          - IE
          - IT
          - NL
          - NZ
          - US
          title: Market
          description: 'Point-of-sale, which is how currency is selected — there is no currency field. **Prices are not comparable across markets**: the display basis differs, so the same night reads 527 USD on `US` and 585 CAD on `CA`, an implied 1.11 against a real rate near 1.37. Pick one market per comparison.'
          default: US
          examples:
          - US
      additionalProperties: false
      type: object
      required:
      - property_id
      - check_in
      title: HotelsRequest
      description: |-
        Hotels.com headline price for one stay window.

        No price calendar exists on this OTA, so it is one call per date — use it
        on the dates that matter rather than sweeping a horizon.
      examples:
      - adults: 2
        check_in: '2029-04-10'
        market: US
        nights: 1
        property_id: '12570'
    HotelsReviewsRequest:
      properties:
        property_id:
          type: string
          minLength: 1
          pattern: ^\d+$
          title: Property Id
          description: Numeric id returned by `POST /v1/ota/hotels/search`, or from `hotels.com/h38766175.Hotel-Information` (not the legacy `ho…` number).
          examples:
          - '12570'
        size:
          type: integer
          maximum: 25.0
          minimum: 1.0
          title: Size
          description: Reviews per page.
          default: 10
          examples:
          - 10
        start_index:
          type: integer
          minimum: 0.0
          title: Start Index
          description: Row to start from; page by `start_index += size`.
          default: 0
          examples:
          - 0
        market:
          type: string
          enum:
          - AU
          - CA
          - DE
          - EU
          - FR
          - GB
          - IE
          - IT
          - NL
          - NZ
          - US
          title: Market
          description: Point-of-sale; also selects the currency.
          default: US
          examples:
          - US
      additionalProperties: false
      type: object
      required:
      - property_id
      title: HotelsReviewsRequest
      description: |-
        Hotels.com guest reviews for one property.

        Same registered query as Expedia's, POSTed to the Hotels.com host with
        the Hotels.com point-of-sale. Ratings are 0-10; the "Verified review"
        disclaimer and "Liked: …" themes ride in `labels`.
      examples:
      - market: US
        property_id: '12570'
        size: 10
        start_index: 0
    HotelsRoomsRequest:
      properties:
        property_id:
          type: string
          minLength: 1
          title: Property Id
          description: Numeric id returned by `POST /v1/ota/hotels/search`, or from `hotels.com/h38766175.Hotel-Information` (not the legacy `ho…` number).
          examples:
          - '12570'
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        market:
          type: string
          enum:
          - AU
          - CA
          - DE
          - EU
          - FR
          - GB
          - IE
          - IT
          - NL
          - NZ
          - US
          title: Market
          description: Point-of-sale; also selects the currency.
          default: US
          examples:
          - US
      additionalProperties: false
      type: object
      required:
      - property_id
      - check_in
      title: HotelsRoomsRequest
      description: |-
        Hotels.com room types and rate plans for one stay window.

        One request, ~100-200 KB against ~6 KB for the headline price. Per-date lookup, not a sweep.
      examples:
      - adults: 2
        check_in: '2029-04-10'
        market: US
        nights: 1
        property_id: '12570'
    HotelsSearchRequest:
      properties:
        name:
          type: string
          minLength: 1
          title: Name
          description: Hotel name as a guest would search for it.
          examples:
          - Moxy Boston Downtown
        city:
          type: string
          title: City
          description: Strongly recommended. Used both in Hotels.com's query and in local candidate ranking so same-brand hotels in other cities rank lower.
          default: ''
          examples:
          - Boston
        market:
          type: string
          enum:
          - AU
          - CA
          - DE
          - EU
          - FR
          - GB
          - IE
          - IT
          - NL
          - NZ
          - US
          title: Market
          description: Hotels.com point-of-sale used for search results. This also matches the market accepted by the rate and room endpoints.
          default: US
          examples:
          - US
        limit:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Limit
          description: Maximum hotel candidates to return, best match first.
          default: 5
          examples:
          - 5
      additionalProperties: false
      type: object
      required:
      - name
      title: HotelsSearchRequest
      description: |-
        Find Hotels.com's numeric property id from a hotel name.

        Read `recommended_match`, not `matches[0]`. It is null when the provider
        returned only weak or ambiguous candidates.
      examples:
      - city: Boston
        limit: 5
        market: US
        name: Moxy Boston Downtown
    IndeedJobsRequest:
      properties:
        q:
          type: string
          maxLength: 300
          minLength: 1
          title: Q
          description: Job query.
          examples:
          - hotel jobs
        location:
          anyOf:
          - type: string
            maxLength: 120
          - type: 'null'
          title: Location
          description: 'Indeed''s `l` parameter: a city, state or `remote`.'
          examples:
          - Chicago, IL
        page:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Page
          description: Result page.
          default: 1
          examples:
          - 1
        radius_km:
          anyOf:
          - type: integer
            maximum: 2000.0
            minimum: 0.0
          - type: 'null'
          title: Radius Km
          description: Indeed's `radius`, in km.
          examples:
          - null
        fromage_days:
          anyOf:
          - type: integer
            maximum: 30.0
            minimum: 0.0
          - type: 'null'
          title: Fromage Days
          description: Posting age limit, in days (Indeed's `fromage`).
          examples:
          - null
      additionalProperties: false
      type: object
      required:
      - q
      title: IndeedJobsRequest
      description: |-
        Indeed job search over plain HTTP.

        One page (~45) of job records from Indeed's own embedded model.
        Sponsored rows come labelled in `sponsored`, not dropped. Indeed's
        job links are its own redirects (`/rc/clk?jk=…`).
      examples:
      - location: Chicago, IL
        q: hotel jobs
    MapsDetailRequest:
      properties:
        place_token:
          type: string
          minLength: 10
          title: Place Token
          description: Place token from `POST /v1/maps/search` (`0x…:0x…`).
          examples:
          - 0x880e2c99242c7a2f:0x4de3d4bb09dba1
        name:
          type: string
          maxLength: 200
          minLength: 1
          title: Name
          description: The place's name, from the same search row as the token.
          examples:
          - Hilton Chicago
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country market.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language.
          default: en
          examples:
          - en
      additionalProperties: false
      type: object
      required:
      - place_token
      - name
      title: MapsDetailRequest
      description: |-
        One Google Maps place's detail record, by token and name.

        The detail card adds the review count to the search fields. The token
        pin answers only when `name` matches the place — take both from the
        same `POST /v1/maps/search` row.
      examples:
      - name: Hilton Chicago
        place_token: 0x880e2c99242c7a2f:0x4de3d4bb09dba1
    MapsSearchRequest:
      properties:
        q:
          type: string
          maxLength: 200
          minLength: 1
          title: Q
          description: Maps search query.
          examples:
          - Hilton Chicago
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Country market.
          default: us
          examples:
          - us
        hl:
          type: string
          title: Hl
          description: Language.
          default: en
          examples:
          - en
      additionalProperties: false
      type: object
      required:
      - q
      title: MapsSearchRequest
      description: |-
        Google Maps places search.

        `q` is whatever the Google Maps search box takes: a business name, a
        category in a place ("ramen near Shibuya"), a landmark. One page of
        place cards: name, address, coordinates, rating, phone, website,
        category and the `place_token` for `POST /v1/maps/detail`.
      examples:
      - q: Hilton Chicago
    OffersRequest:
      properties:
        token:
          type: string
          minLength: 8
          title: Token
          description: Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Alternative to `nights`; wins if both are given.
          examples:
          - '2029-02-06'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Ignored when `check_out` is given.
          default: 1
          examples:
          - 1
        market:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AG
          - AT
          - AU
          - BE
          - BZ
          - CA
          - CH
          - DE
          - ES
          - FR
          - GB
          - IE
          - IT
          - MX
          - NL
          - NZ
          - PT
          - US
          title: Market
          description: Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`.
          examples:
          - US
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO currency for the returned prices.
          examples:
          - USD
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: 'Occupancy: number of adults, 1-8. Children are not supported by the Google calendar.'
          default: 2
          examples:
          - 2
        rates_include_tax:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Rates Include Tax
          description: Which basis the summary price uses. Defaults to the market convention.
        property_name:
          type: string
          title: Property Name
          description: Improves official-site detection
          default: ''
        include_metasearch:
          type: boolean
          title: Include Metasearch
          description: 'Include metasearch aggregators (Trivago, Vio, Kayak, Goseek) alongside real OTAs. Off by default: they resell other sources, so they inflate the offer count without adding inventory.'
          default: false
        free_cancellation_only:
          type: boolean
          title: Free Cancellation Only
          description: Only offers with a stated free-cancellation deadline
          default: false
        device:
          type: string
          enum:
          - android
          - desktop
          - iphone
          title: Device
          description: Render profile. Google returns a different offer list per device and desktop is the thinnest — iphone found 17 offers where desktop found 12 on the same property.
          default: iphone
        coverage:
          type: integer
          maximum: 3.0
          minimum: 1.0
          title: Coverage
          description: Fetch this many device profiles and merge. Costs one ~3 MB page each; 2 is the sensible maximum.
          default: 1
        require_sources:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          title: Require Sources
          description: Sources to insist on; retries a thin render. Defaults to official + Booking + Hotels.com + Expedia + Agoda. Pass [] to disable.
      additionalProperties: false
      type: object
      required:
      - token
      - check_in
      title: OffersRequest
      examples:
      - adults: 2
        check_in: '2029-02-05'
        coverage: 2
        currency: USD
        device: iphone
        include_metasearch: false
        nights: 1
        token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
    OfficialRequest:
      properties:
        url:
          type: string
          minLength: 8
          title: Url
          description: The hotel's public homepage or property page. The API finds its booking link and detects the booking engine automatically; a direct booking URL is also accepted.
          examples:
          - https://www.marriott.com/en-us/hotels/yyzrz-the-ritz-carlton-toronto/overview/
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-02-06'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        rooms:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Rooms
          description: Rooms requested.
          default: 1
          examples:
          - 1
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
      additionalProperties: false
      type: object
      required:
      - url
      - check_in
      title: OfficialRequest
      description: |-
        One official-site lookup, whichever booking engine the hotel runs.

        Paste the hotel's public website. Discovery finds its reservation link,
        identifies the PMS/booking engine, and routes to the right extractor. A
        direct booking URL also works, but callers never select an engine.
      examples:
      - adults: 2
        check_in: '2029-02-05'
        currency: CAD
        nights: 1
        url: https://www.marriott.com/en-us/hotels/yyzrz-the-ritz-carlton-toronto/overview/
    RoomMatrixRequest:
      properties:
        token:
          type: string
          minLength: 8
          title: Token
          description: Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        market:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AG
          - AT
          - AU
          - BE
          - BZ
          - CA
          - CH
          - DE
          - ES
          - FR
          - GB
          - IE
          - IT
          - MX
          - NL
          - NZ
          - PT
          - US
          title: Market
          description: Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`.
          examples:
          - US
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO currency for the returned prices.
          examples:
          - USD
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: 'Occupancy: number of adults, 1-8. Children are not supported by the Google calendar.'
          default: 2
          examples:
          - 2
        sources:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          title: Sources
          description: Defaults to ['Official site', 'Booking.com', 'Hotels.com', 'Expedia']
      additionalProperties: false
      type: object
      required:
      - token
      - check_in
      title: RoomMatrixRequest
      description: Room types by OTA, aligned onto one comparable signature per row.
      examples:
      - adults: 2
        check_in: '2029-02-05'
        currency: USD
        nights: 1
        token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
    SearchRequest:
      properties:
        name:
          type: string
          title: Name
          description: Property name as a guest would type it. Fuzzy — exact punctuation does not matter.
          examples:
          - Hilton Chicago
        city:
          type: string
          title: City
          description: Strongly recommended. Without it a common brand name matches the wrong city.
          default: ''
          examples:
          - Chicago
        market:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AD
          - AE
          - AF
          - AG
          - AI
          - AL
          - AM
          - AO
          - AQ
          - AR
          - AS
          - AT
          - AU
          - AW
          - AX
          - AZ
          - BA
          - BB
          - BD
          - BE
          - BF
          - BG
          - BH
          - BI
          - BJ
          - BL
          - BM
          - BN
          - BO
          - BQ
          - BR
          - BS
          - BT
          - BV
          - BW
          - BY
          - BZ
          - CA
          - CC
          - CD
          - CF
          - CG
          - CH
          - CI
          - CK
          - CL
          - CM
          - CN
          - CO
          - CR
          - CU
          - CV
          - CW
          - CX
          - CY
          - CZ
          - DE
          - DJ
          - DK
          - DM
          - DO
          - DZ
          - EC
          - EE
          - EG
          - EH
          - ER
          - ES
          - ET
          - FI
          - FJ
          - FK
          - FM
          - FO
          - FR
          - GA
          - GB
          - GD
          - GE
          - GF
          - GG
          - GH
          - GI
          - GL
          - GM
          - GN
          - GP
          - GQ
          - GR
          - GS
          - GT
          - GU
          - GW
          - GY
          - HK
          - HM
          - HN
          - HR
          - HT
          - HU
          - ID
          - IE
          - IL
          - IM
          - IN
          - IO
          - IQ
          - IR
          - IS
          - IT
          - JE
          - JM
          - JO
          - JP
          - KE
          - KG
          - KH
          - KI
          - KM
          - KN
          - KP
          - KR
          - KW
          - KY
          - KZ
          - LA
          - LB
          - LC
          - LI
          - LK
          - LR
          - LS
          - LT
          - LU
          - LV
          - LY
          - MA
          - MC
          - MD
          - ME
          - MF
          - MG
          - MH
          - MK
          - ML
          - MM
          - MN
          - MO
          - MP
          - MQ
          - MR
          - MS
          - MT
          - MU
          - MV
          - MW
          - MX
          - MY
          - MZ
          - NA
          - NC
          - NE
          - NF
          - NG
          - NI
          - NL
          - 'NO'
          - NP
          - NR
          - NU
          - NZ
          - OM
          - PA
          - PE
          - PF
          - PG
          - PH
          - PK
          - PL
          - PM
          - PN
          - PR
          - PS
          - PT
          - PW
          - PY
          - QA
          - RE
          - RO
          - RS
          - RU
          - RW
          - SA
          - SB
          - SC
          - SD
          - SE
          - SG
          - SH
          - SI
          - SJ
          - SK
          - SL
          - SM
          - SN
          - SO
          - SR
          - SS
          - ST
          - SV
          - SX
          - SY
          - SZ
          - TC
          - TD
          - TF
          - TG
          - TH
          - TJ
          - TK
          - TL
          - TM
          - TN
          - TO
          - TR
          - TT
          - TV
          - TW
          - TZ
          - UA
          - UG
          - UK
          - UM
          - US
          - UY
          - UZ
          - VA
          - VC
          - VE
          - VG
          - VI
          - VN
          - VU
          - WF
          - WS
          - XK
          - YE
          - YT
          - ZA
          - ZM
          - ZW
          title: Market
          description: ISO country/Google market to try first, e.g. `US`, `MX`, `GD`. Search accepts markets beyond the pricing markets listed by `GET /v1/markets` because property tokens are global; the response reports where it matched.
          examples:
          - GD
        fallback_markets:
          items:
            type: string
          type: array
          maxItems: 5
          title: Fallback Markets
          description: Markets tried in order only when the requested market returns zero candidates. Defaults to `US`, which often indexes Caribbean properties absent from their local Google market. Pass `[]` to disable fallback. The response always reports `attempted_markets`, `matched_market`, and `market_fallback_used`.
          default:
          - US
          examples:
          - - US
          x-multiple: true
          x-options:
          - AD
          - AE
          - AF
          - AG
          - AI
          - AL
          - AM
          - AO
          - AQ
          - AR
          - AS
          - AT
          - AU
          - AW
          - AX
          - AZ
          - BA
          - BB
          - BD
          - BE
          - BF
          - BG
          - BH
          - BI
          - BJ
          - BL
          - BM
          - BN
          - BO
          - BQ
          - BR
          - BS
          - BT
          - BV
          - BW
          - BY
          - BZ
          - CA
          - CC
          - CD
          - CF
          - CG
          - CH
          - CI
          - CK
          - CL
          - CM
          - CN
          - CO
          - CR
          - CU
          - CV
          - CW
          - CX
          - CY
          - CZ
          - DE
          - DJ
          - DK
          - DM
          - DO
          - DZ
          - EC
          - EE
          - EG
          - EH
          - ER
          - ES
          - ET
          - FI
          - FJ
          - FK
          - FM
          - FO
          - FR
          - GA
          - GB
          - GD
          - GE
          - GF
          - GG
          - GH
          - GI
          - GL
          - GM
          - GN
          - GP
          - GQ
          - GR
          - GS
          - GT
          - GU
          - GW
          - GY
          - HK
          - HM
          - HN
          - HR
          - HT
          - HU
          - ID
          - IE
          - IL
          - IM
          - IN
          - IO
          - IQ
          - IR
          - IS
          - IT
          - JE
          - JM
          - JO
          - JP
          - KE
          - KG
          - KH
          - KI
          - KM
          - KN
          - KP
          - KR
          - KW
          - KY
          - KZ
          - LA
          - LB
          - LC
          - LI
          - LK
          - LR
          - LS
          - LT
          - LU
          - LV
          - LY
          - MA
          - MC
          - MD
          - ME
          - MF
          - MG
          - MH
          - MK
          - ML
          - MM
          - MN
          - MO
          - MP
          - MQ
          - MR
          - MS
          - MT
          - MU
          - MV
          - MW
          - MX
          - MY
          - MZ
          - NA
          - NC
          - NE
          - NF
          - NG
          - NI
          - NL
          - 'NO'
          - NP
          - NR
          - NU
          - NZ
          - OM
          - PA
          - PE
          - PF
          - PG
          - PH
          - PK
          - PL
          - PM
          - PN
          - PR
          - PS
          - PT
          - PW
          - PY
          - QA
          - RE
          - RO
          - RS
          - RU
          - RW
          - SA
          - SB
          - SC
          - SD
          - SE
          - SG
          - SH
          - SI
          - SJ
          - SK
          - SL
          - SM
          - SN
          - SO
          - SR
          - SS
          - ST
          - SV
          - SX
          - SY
          - SZ
          - TC
          - TD
          - TF
          - TG
          - TH
          - TJ
          - TK
          - TL
          - TM
          - TN
          - TO
          - TR
          - TT
          - TV
          - TW
          - TZ
          - UA
          - UG
          - UK
          - UM
          - US
          - UY
          - UZ
          - VA
          - VC
          - VE
          - VG
          - VI
          - VN
          - VU
          - WF
          - WS
          - XK
          - YE
          - YT
          - ZA
          - ZM
          - ZW
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          examples:
          - USD
        limit:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Limit
          description: Candidates to return, best match first.
          default: 5
          examples:
          - 5
        verify:
          type: boolean
          title: Verify
          description: Fetch each candidate to confirm the token resolves and read back its real name. Slower, far fewer wrong matches.
          default: true
      additionalProperties: false
      type: object
      required:
      - name
      title: SearchRequest
      description: Find a property token by name. **Start here if you have no token.**
      examples:
      - city: St George's
        fallback_markets:
        - US
        limit: 5
        market: GD
        name: Blue Horizons Garden Resort
        verify: true
    SerpCalendarRequest:
      properties:
        property_token:
          type: string
          minLength: 8
          title: Property Token
          description: Google property token, as returned by `/v1/search`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        days:
          type: integer
          maximum: 330.0
          minimum: 1.0
          title: Days
          description: Nights to price in one call. Max 330.
          default: 90
          examples:
          - 90
        start:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Start
          description: First stay date. Defaults to tomorrow.
          examples:
          - '2029-02-05'
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Two-letter country for the request.
          default: us
          examples:
          - us
        los:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Los
          description: Length of stay each night is priced at. The per-night figure genuinely moves with LOS.
          default: 1
          examples:
          - 1
      additionalProperties: false
      type: object
      required:
      - property_token
      title: SerpCalendarRequest
      description: |-
        A horizon sweep in SearchAPI's parameter style.

        SearchAPI has no calendar engine — it bills one `google_hotels_property`
        call per stay date. This returns the whole window in a single request, so
        the same 90-night sweep is 1 call rather than 90.
      examples:
      - adults: 2
        currency: USD
        days: 90
        gl: us
        los: 1
        property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        start: '2029-02-05'
    SerpGoogleHotelsRequest:
      properties:
        q:
          type: string
          maxLength: 200
          minLength: 2
          title: Q
          description: Destination query exactly as a traveller would type it into Google Hotels, e.g. `hotels in Montreal`, `Paris`, `hotels near JFK`. Google resolves it to a place; the response reports which in `search_information.location`.
          examples:
          - hotels in Montreal
        adults:
          type: integer
          maximum: 10.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Encoded as one guest entry each, the way Google's own control sends them.
          default: 2
          examples:
          - 2
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - CAD
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Two-letter Google country (market). Sets the market; the currency is requested separately.
          default: us
          examples:
          - ca
        hl:
          type: string
          pattern: ^[a-z]{2,3}(-[A-Za-z]{2,4})?$
          title: Hl
          description: Interface language. Display strings follow it; hotel amenity names are always English.
          default: en
          examples:
          - en
        sort_by:
          type: string
          enum:
          - highest_rating
          - lowest_price
          - most_reviewed
          - relevance
          title: Sort By
          description: Result order, as Google's Sort by control.
          default: relevance
        price_min:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Price Min
          description: Minimum nightly price in `currency`.
          examples:
          - 50
        price_max:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Price Max
          description: Maximum nightly price in `currency`.
          examples:
          - 300
        free_cancellation:
          type: boolean
          title: Free Cancellation
          description: Only properties Google lists with free cancellation.
          default: false
        special_offers:
          type: boolean
          title: Special Offers
          description: Only properties with a special offer.
          default: false
        eco_certified:
          type: boolean
          title: Eco Certified
          description: Only eco-certified properties.
          default: false
        engine:
          type: string
          enum:
          - google_hotels
          const: google_hotels
          title: Engine
          description: Accepted for SearchAPI compatibility; must be `google_hotels`.
          default: google_hotels
        property_type:
          type: string
          enum:
          - hotel
          - vacation_rental
          title: Property Type
          description: '`hotel` (default) is Google''s own list, which Google may blend with vacation rentals; each result states its `type`. `vacation_rental` is refused with 422: Google does not honour the rentals-only category for this search, so it is refused rather than silently ignored.'
          default: hotel
        check_in_date:
          type: string
          format: date
          title: Check In Date
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-03-21'
        check_out_date:
          type: string
          format: date
          title: Check Out Date
          description: Departure date, after `check_in_date`; at most 30 nights.
          examples:
          - '2029-03-23'
        children_ages:
          anyOf:
          - type: string
          - items:
              type: integer
            type: array
          - type: 'null'
          title: Children Ages
          description: 'Comma-separated child ages, 0-17 (SearchAPI: `2,5`).'
          examples:
          - '8'
        rating:
          anyOf:
          - type: integer
          - type: 'null'
          enum:
          - 7
          - 8
          - 9
          title: Rating
          description: 'SearchAPI rating code: 7 (3.5+), 8 (4.0+), 9 (4.5+).'
          examples:
          - 8
        hotel_class:
          anyOf:
          - type: string
          - items:
              type: integer
            type: array
          - type: 'null'
          title: Hotel Class
          description: Comma-separated star classes, 2-5.
          examples:
          - 4,5
        amenities:
          anyOf:
          - type: string
          - items:
              type: integer
            type: array
          - type: 'null'
          title: Amenities
          description: Comma-separated amenity ids (same ids as SearchAPI/SerpApi, e.g. 6 Pool, 35 Free Wi-Fi).
          examples:
          - 6,35
        property_types:
          anyOf:
          - type: string
          - items:
              type: integer
            type: array
          - type: 'null'
          title: Property Types
          description: Comma-separated property-type ids, e.g. 19 Bed and breakfasts, 14 Hostels.
          examples:
          - '19'
        brands:
          anyOf:
          - type: string
          - items:
              type: integer
            type: array
          - type: 'null'
          title: Brands
          description: 'Not supported: Google ignores brand filters on this search, so a non-empty value is refused with 422.'
        for_displaced_individuals:
          type: boolean
          title: For Displaced Individuals
          description: Not supported; `true` is refused with 422.
          default: false
        bedrooms:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Bedrooms
          description: Vacation-rental filter. Not supported; a value above 0 is refused with 422.
        bathrooms:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Bathrooms
          description: Vacation-rental filter. Not supported; a value above 0 is refused with 422.
        bounding_box:
          anyOf:
          - type: string
          - type: 'null'
          title: Bounding Box
          description: Not supported; search by `q`.
        next_page_token:
          anyOf:
          - type: string
            pattern: ^[A-Za-z0-9_\-+/=]{1,200}$
          - type: 'null'
          title: Next Page Token
          description: Opaque cursor from `pagination.next_page_token` of the previous page. Resend the same query, stay, occupancy and filters with it, exactly as with SearchAPI.
          examples:
          - CBI=
        zero_retention:
          type: boolean
          title: Zero Retention
          description: Accepted for SearchAPI compatibility; search results are never persisted.
          default: false
      additionalProperties: false
      type: object
      required:
      - q
      - check_in_date
      - check_out_date
      title: SerpGoogleHotelsRequest
      description: |-
        SearchAPI's `engine=google_hotels` request, field for field.

        Comma-separated id lists (`hotel_class`, `amenities`, `property_types`,
        `children_ages`) are accepted as SearchAPI sends them, or as JSON arrays.
        Parameters this source cannot honour are refused with a 422 rather than
        ignored, because an ignored filter returns a plausible unfiltered list.
      examples:
      - adults: 2
        amenities: '6'
        check_in_date: '2029-03-21'
        check_out_date: '2029-03-23'
        currency: USD
        engine: google_hotels
        gl: us
        hl: en
        hotel_class: 4,5
        q: Hotels in Chicago
        rating: 8
        sort_by: lowest_price
    SerpPropertyRequest:
      properties:
        property_token:
          type: string
          minLength: 8
          title: Property Token
          description: Google property token — SearchAPI's name for the same value `/v1/search` returns as `token`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        check_in_date:
          type: string
          format: date
          title: Check In Date
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        check_out_date:
          type: string
          format: date
          title: Check Out Date
          description: Departure date. Must be after `check_in_date`.
          examples:
          - '2029-02-06'
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO 4217 code for the returned prices. Major currencies include AED, AUD, BRL, CAD, CHF, CNY, EUR, GBP, HKD, INR, JPY, KRW, MXN, NZD, SGD, USD; all 39 supported codes are listed in the enum.
          default: USD
          examples:
          - USD
        gl:
          type: string
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Gl
          description: Two-letter country for the Google request, SearchAPI's spelling of `market`.
          default: us
          examples:
          - us
        property_name:
          type: string
          title: Property Name
          description: Optional. Improves official-site detection when the hotel's own row is labelled with its brand name.
          default: ''
          examples:
          - Hilton Chicago
        sources:
          anyOf:
          - items:
              type: string
            type: array
            maxItems: 20
            minItems: 1
          - type: 'null'
          title: Sources
          description: Optional seller allowlist. Names are canonicalized, so `Expedia.com` and `Expedia` are equivalent. Omit for all Google sellers.
          examples:
          - - Booking.com
            - Hotels.com
            - Agoda
            - Official site
          x-multiple: true
          x-options:
          - Agoda
          - Booking.com
          - Expedia
          - Hotels.com
          - Official site
        source_coverage:
          type: string
          enum:
          - adaptive
          - full
          title: Source Coverage
          description: '`full` starts iPhone and desktop renders in parallel for maximum breadth. `adaptive` starts with iPhone and fetches desktop only when a requested seller is absent.'
          default: full
      additionalProperties: false
      type: object
      required:
      - property_token
      - check_in_date
      - check_out_date
      title: SerpPropertyRequest
      description: |-
        Mirrors SearchAPI's `google_hotels_property` parameters.

        Field names are theirs, not ours, so an existing integration only needs its
        base URL repointed. The optional `sources` and `source_coverage` fields are
        ScraperCompany additions; omitting them preserves the full SearchAPI-shaped
        offer list.
      examples:
      - adults: 2
        check_in_date: '2029-02-05'
        check_out_date: '2029-02-06'
        currency: USD
        gl: us
        property_token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
    StayRequest:
      properties:
        token:
          type: string
          minLength: 8
          title: Token
          description: Google property token. Get one from `POST /v1/search` — it is the `token` on each match. Looks like `ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ`.
          examples:
          - ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-05'
        check_out:
          type: string
          format: date
          title: Check Out
          description: Must be after `check_in`. The gap is the LOS, and the per-night price does change with it.
          examples:
          - '2029-02-08'
        market:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AG
          - AT
          - AU
          - BE
          - BZ
          - CA
          - CH
          - DE
          - ES
          - FR
          - GB
          - IE
          - IT
          - MX
          - NL
          - NZ
          - PT
          - US
          title: Market
          description: Market/country, e.g. `US`, `MX`, `AU`, `GB`. Sets `gl` and the default tax basis. Omit to derive it from `currency`.
          examples:
          - US
        country:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - ad
          - ae
          - af
          - ag
          - ai
          - al
          - am
          - ao
          - aq
          - ar
          - as
          - at
          - au
          - aw
          - ax
          - az
          - ba
          - bb
          - bd
          - be
          - bf
          - bg
          - bh
          - bi
          - bj
          - bl
          - bm
          - bn
          - bo
          - bq
          - br
          - bs
          - bt
          - bv
          - bw
          - by
          - bz
          - ca
          - cc
          - cd
          - cf
          - cg
          - ch
          - ci
          - ck
          - cl
          - cm
          - cn
          - co
          - cr
          - cu
          - cv
          - cw
          - cx
          - cy
          - cz
          - de
          - dj
          - dk
          - dm
          - do
          - dz
          - ec
          - ee
          - eg
          - eh
          - er
          - es
          - et
          - fi
          - fj
          - fk
          - fm
          - fo
          - fr
          - ga
          - gb
          - gd
          - ge
          - gf
          - gg
          - gh
          - gi
          - gl
          - gm
          - gn
          - gp
          - gq
          - gr
          - gs
          - gt
          - gu
          - gw
          - gy
          - hk
          - hm
          - hn
          - hr
          - ht
          - hu
          - id
          - ie
          - il
          - im
          - in
          - io
          - iq
          - ir
          - is
          - it
          - je
          - jm
          - jo
          - jp
          - ke
          - kg
          - kh
          - ki
          - km
          - kn
          - kp
          - kr
          - kw
          - ky
          - kz
          - la
          - lb
          - lc
          - li
          - lk
          - lr
          - ls
          - lt
          - lu
          - lv
          - ly
          - ma
          - mc
          - md
          - me
          - mf
          - mg
          - mh
          - mk
          - ml
          - mm
          - mn
          - mo
          - mp
          - mq
          - mr
          - ms
          - mt
          - mu
          - mv
          - mw
          - mx
          - my
          - mz
          - na
          - nc
          - ne
          - nf
          - ng
          - ni
          - nl
          - 'no'
          - np
          - nr
          - nu
          - nz
          - om
          - pa
          - pe
          - pf
          - pg
          - ph
          - pk
          - pl
          - pm
          - pn
          - pr
          - ps
          - pt
          - pw
          - py
          - qa
          - re
          - ro
          - rs
          - ru
          - rw
          - sa
          - sb
          - sc
          - sd
          - se
          - sg
          - sh
          - si
          - sj
          - sk
          - sl
          - sm
          - sn
          - so
          - sr
          - ss
          - st
          - sv
          - sx
          - sy
          - sz
          - tc
          - td
          - tf
          - tg
          - th
          - tj
          - tk
          - tl
          - tm
          - tn
          - to
          - tr
          - tt
          - tv
          - tw
          - tz
          - ua
          - ug
          - uk
          - um
          - us
          - uy
          - uz
          - va
          - vc
          - ve
          - vg
          - vi
          - vn
          - vu
          - wf
          - ws
          - xk
          - ye
          - yt
          - za
          - zm
          - zw
          title: Country
          description: '`gl` override.'
          examples:
          - us
        currency:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - COP
          - CZK
          - DKK
          - EGP
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - ILS
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PEN
          - PHP
          - PLN
          - QAR
          - RON
          - SAR
          - SEK
          - SGD
          - THB
          - TRY
          - TWD
          - USD
          - VND
          - ZAR
          title: Currency
          description: ISO currency for the returned prices.
          examples:
          - USD
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: 'Occupancy: number of adults, 1-8. Children are not supported by the Google calendar.'
          default: 2
          examples:
          - 2
        rates_include_tax:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Rates Include Tax
          description: Which basis the summary price uses. Omit to take the market convention; pass the property's own setting to override.
        is_hostel:
          type: boolean
          title: Is Hostel
          description: Hostels are priced per bed rather than per room, so occupancy changes the rate differently. Set this and the per-person maths is applied.
          default: false
      additionalProperties: false
      type: object
      required:
      - token
      - check_in
      - check_out
      title: StayRequest
      description: One explicit check-in/check-out window.
      examples:
      - adults: 2
        check_in: '2029-02-05'
        check_out: '2029-02-08'
        currency: USD
        token: ChUIoben2Mv6-CYaCi9tLzA3czVwbjQQAQ
    TrendsInterestRequest:
      properties:
        keyword:
          type: string
          maxLength: 200
          minLength: 1
          title: Keyword
          description: Search term to chart.
          examples:
          - Hilton
        geo:
          type: string
          enum:
          - AD
          - AE
          - AF
          - AG
          - AI
          - AL
          - AM
          - AO
          - AQ
          - AR
          - AS
          - AT
          - AU
          - AW
          - AX
          - AZ
          - BA
          - BB
          - BD
          - BE
          - BF
          - BG
          - BH
          - BI
          - BJ
          - BL
          - BM
          - BN
          - BO
          - BQ
          - BR
          - BS
          - BT
          - BV
          - BW
          - BY
          - BZ
          - CA
          - CC
          - CD
          - CF
          - CG
          - CH
          - CI
          - CK
          - CL
          - CM
          - CN
          - CO
          - CR
          - CU
          - CV
          - CW
          - CX
          - CY
          - CZ
          - DE
          - DJ
          - DK
          - DM
          - DO
          - DZ
          - EC
          - EE
          - EG
          - EH
          - ER
          - ES
          - ET
          - FI
          - FJ
          - FK
          - FM
          - FO
          - FR
          - GA
          - GB
          - GD
          - GE
          - GF
          - GG
          - GH
          - GI
          - GL
          - GM
          - GN
          - GP
          - GQ
          - GR
          - GS
          - GT
          - GU
          - GW
          - GY
          - HK
          - HM
          - HN
          - HR
          - HT
          - HU
          - ID
          - IE
          - IL
          - IM
          - IN
          - IO
          - IQ
          - IR
          - IS
          - IT
          - JE
          - JM
          - JO
          - JP
          - KE
          - KG
          - KH
          - KI
          - KM
          - KN
          - KP
          - KR
          - KW
          - KY
          - KZ
          - LA
          - LB
          - LC
          - LI
          - LK
          - LR
          - LS
          - LT
          - LU
          - LV
          - LY
          - MA
          - MC
          - MD
          - ME
          - MF
          - MG
          - MH
          - MK
          - ML
          - MM
          - MN
          - MO
          - MP
          - MQ
          - MR
          - MS
          - MT
          - MU
          - MV
          - MW
          - MX
          - MY
          - MZ
          - NA
          - NC
          - NE
          - NF
          - NG
          - NI
          - NL
          - 'NO'
          - NP
          - NR
          - NU
          - NZ
          - OM
          - PA
          - PE
          - PF
          - PG
          - PH
          - PK
          - PL
          - PM
          - PN
          - PR
          - PS
          - PT
          - PW
          - PY
          - QA
          - RE
          - RO
          - RS
          - RU
          - RW
          - SA
          - SB
          - SC
          - SD
          - SE
          - SG
          - SH
          - SI
          - SJ
          - SK
          - SL
          - SM
          - SN
          - SO
          - SR
          - SS
          - ST
          - SV
          - SX
          - SY
          - SZ
          - TC
          - TD
          - TF
          - TG
          - TH
          - TJ
          - TK
          - TL
          - TM
          - TN
          - TO
          - TR
          - TT
          - TV
          - TW
          - TZ
          - UA
          - UG
          - UK
          - UM
          - US
          - UY
          - UZ
          - VA
          - VC
          - VE
          - VG
          - VI
          - VN
          - VU
          - WF
          - WS
          - XK
          - YE
          - YT
          - ZA
          - ZM
          - ZW
          title: Geo
          description: Two-letter country.
          default: US
          examples:
          - US
        time_range:
          type: string
          title: Time Range
          description: 'Google''s window grammar: `today 1-m` (default), `now 7-d`, `today 12-m`, `all`, or `2026-01-01 2026-06-30`.'
          default: today 1-m
          examples:
          - today 1-m
        hl:
          type: string
          title: Hl
          description: Language.
          default: en-US
          examples:
          - en-US
      additionalProperties: false
      type: object
      required:
      - keyword
      title: TrendsInterestRequest
      description: |-
        Google Trends interest over time for one keyword.

        Values are 0-100 relative to the keyword's own peak in the window,
        exactly as Google's charts state. `time_range` uses Google's grammar.
      examples:
      - geo: US
        keyword: Hilton
        time_range: today 1-m
    TrendsRelatedRequest:
      properties:
        keyword:
          type: string
          maxLength: 200
          minLength: 1
          title: Keyword
          description: Search term.
          examples:
          - Hilton
        geo:
          type: string
          enum:
          - AD
          - AE
          - AF
          - AG
          - AI
          - AL
          - AM
          - AO
          - AQ
          - AR
          - AS
          - AT
          - AU
          - AW
          - AX
          - AZ
          - BA
          - BB
          - BD
          - BE
          - BF
          - BG
          - BH
          - BI
          - BJ
          - BL
          - BM
          - BN
          - BO
          - BQ
          - BR
          - BS
          - BT
          - BV
          - BW
          - BY
          - BZ
          - CA
          - CC
          - CD
          - CF
          - CG
          - CH
          - CI
          - CK
          - CL
          - CM
          - CN
          - CO
          - CR
          - CU
          - CV
          - CW
          - CX
          - CY
          - CZ
          - DE
          - DJ
          - DK
          - DM
          - DO
          - DZ
          - EC
          - EE
          - EG
          - EH
          - ER
          - ES
          - ET
          - FI
          - FJ
          - FK
          - FM
          - FO
          - FR
          - GA
          - GB
          - GD
          - GE
          - GF
          - GG
          - GH
          - GI
          - GL
          - GM
          - GN
          - GP
          - GQ
          - GR
          - GS
          - GT
          - GU
          - GW
          - GY
          - HK
          - HM
          - HN
          - HR
          - HT
          - HU
          - ID
          - IE
          - IL
          - IM
          - IN
          - IO
          - IQ
          - IR
          - IS
          - IT
          - JE
          - JM
          - JO
          - JP
          - KE
          - KG
          - KH
          - KI
          - KM
          - KN
          - KP
          - KR
          - KW
          - KY
          - KZ
          - LA
          - LB
          - LC
          - LI
          - LK
          - LR
          - LS
          - LT
          - LU
          - LV
          - LY
          - MA
          - MC
          - MD
          - ME
          - MF
          - MG
          - MH
          - MK
          - ML
          - MM
          - MN
          - MO
          - MP
          - MQ
          - MR
          - MS
          - MT
          - MU
          - MV
          - MW
          - MX
          - MY
          - MZ
          - NA
          - NC
          - NE
          - NF
          - NG
          - NI
          - NL
          - 'NO'
          - NP
          - NR
          - NU
          - NZ
          - OM
          - PA
          - PE
          - PF
          - PG
          - PH
          - PK
          - PL
          - PM
          - PN
          - PR
          - PS
          - PT
          - PW
          - PY
          - QA
          - RE
          - RO
          - RS
          - RU
          - RW
          - SA
          - SB
          - SC
          - SD
          - SE
          - SG
          - SH
          - SI
          - SJ
          - SK
          - SL
          - SM
          - SN
          - SO
          - SR
          - SS
          - ST
          - SV
          - SX
          - SY
          - SZ
          - TC
          - TD
          - TF
          - TG
          - TH
          - TJ
          - TK
          - TL
          - TM
          - TN
          - TO
          - TR
          - TT
          - TV
          - TW
          - TZ
          - UA
          - UG
          - UK
          - UM
          - US
          - UY
          - UZ
          - VA
          - VC
          - VE
          - VG
          - VI
          - VN
          - VU
          - WF
          - WS
          - XK
          - YE
          - YT
          - ZA
          - ZM
          - ZW
          title: Geo
          description: Two-letter country.
          default: US
          examples:
          - US
        time_range:
          type: string
          title: Time Range
          description: Google's window grammar (see interest over time).
          default: today 1-m
          examples:
          - today 1-m
        hl:
          type: string
          title: Hl
          description: Language.
          default: en-US
          examples:
          - en-US
      additionalProperties: false
      type: object
      required:
      - keyword
      title: TrendsRelatedRequest
      description: 'Google Trends related queries: top and rising.'
      examples:
      - geo: US
        keyword: Hilton
    TripadvisorRequest:
      properties:
        location_id:
          type: string
          minLength: 1
          title: Location Id
          description: 'Numeric Tripadvisor locationId: the digits after `-d` in the hotel''s Tripadvisor URL (`/Hotel_Review-g{geoId}-d{locationId}-...`).'
          examples:
          - '97679'
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-02-22'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-02-23'
        nights:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 1
        adults:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Adults
          description: Adults in the room. Two is the hotel default; pass one for a hostel, which is priced per bed. Any value from 1 to 8 is accepted.
          default: 2
          examples:
          - 2
        rooms:
          type: integer
          maximum: 8.0
          minimum: 1.0
          title: Rooms
          description: Rooms requested.
          default: 1
          examples:
          - 1
        currency:
          type: string
          enum:
          - AED
          - ARS
          - AUD
          - BRL
          - CAD
          - CHF
          - CLP
          - CNY
          - CZK
          - DKK
          - EUR
          - GBP
          - HKD
          - HUF
          - IDR
          - INR
          - JPY
          - KRW
          - MXN
          - MYR
          - NOK
          - NZD
          - PHP
          - PLN
          - SAR
          - SEK
          - SGD
          - THB
          - TWD
          - USD
          title: Currency
          description: One of 30 supported currencies.
          default: USD
          examples:
          - USD
      additionalProperties: false
      type: object
      required:
      - location_id
      - check_in
      title: TripadvisorRequest
      description: |-
        Tripadvisor hotel availability and pricing from multiple providers.

        Tripadvisor aggregates prices from Booking, Hotels.com, Expedia, and others
        as a metasearch. Returns offers from all available providers for the given
        dates.
      examples:
      - adults: 2
        check_in: '2029-02-22'
        currency: USD
        location_id: '97679'
        nights: 1
    TripadvisorReviewsRequest:
      properties:
        location_id:
          type: string
          minLength: 1
          pattern: ^\d+$
          title: Location Id
          description: Numeric id in the property URL, e.g. `208453` from `/Hotel_Review-g60763-d208453-...`.
          examples:
          - '208453'
        limit:
          type: integer
          maximum: 30.0
          minimum: 1.0
          title: Limit
          description: Reviews per page (the backend accepts up to 30).
          default: 10
          examples:
          - 10
        offset:
          type: integer
          minimum: 0.0
          title: Offset
          description: Row to start from; page by `offset += limit`.
          default: 0
          examples:
          - 0
      additionalProperties: false
      type: object
      required:
      - location_id
      title: TripadvisorReviewsRequest
      description: |-
        Tripadvisor guest reviews, newest first as the site orders them.

        `location_id` is the numeric id in the property URL
        (`/Hotel_Review-g{geoId}-d{locationId}-...`). Ratings are 0-5.
      examples:
      - limit: 10
        location_id: '208453'
        offset: 0
    TripadvisorSearchRequest:
      properties:
        query:
          type: string
          minLength: 1
          title: Query
          description: Hotel name or location to search for.
          examples:
          - Moxy Boston Downtown
        limit:
          type: integer
          maximum: 50.0
          minimum: 1.0
          title: Limit
          description: Maximum results to return.
          default: 10
          examples:
          - 10
      additionalProperties: false
      type: object
      required:
      - query
      title: TripadvisorSearchRequest
      description: |-
        Find Tripadvisor's locationId from a hotel name.

        Read `recommended_match`, not `matches[0]`. It is null when the provider
        returned only weak or ambiguous candidates.
      examples:
      - limit: 10
        query: Moxy Boston Downtown
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    VrboRequest:
      properties:
        property_id:
          anyOf:
          - type: string
            pattern: ^\d+$
          - type: 'null'
          title: Property Id
          description: Numeric id returned by `POST /v1/ota/vrbo/search` (`property_id` on each listing). Not the id in the Vrbo URL.
          examples:
          - '122942416'
        listing_id:
          anyOf:
          - type: string
            pattern: ^\d+(?:ha)?$
          - type: 'null'
          title: Listing Id
          description: The listing id in a Vrbo URL, e.g. `20218736ha` for `vrbo.com/20218736ha`. Resolved to `property_id` with one page load.
          examples:
          - 20218736ha
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-04-10'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-04-13'
        nights:
          type: integer
          maximum: 28.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 3
        adults:
          type: integer
          maximum: 16.0
          minimum: 1.0
          title: Adults
          description: Guests (adults).
          default: 2
          examples:
          - 2
        market:
          type: string
          enum:
          - US
          title: Market
          description: Vrbo point-of-sale. Only `US` (www.vrbo.com, USD) is verified.
          default: US
          examples:
          - US
      additionalProperties: false
      type: object
      required:
      - check_in
      title: VrboRequest
      description: |-
        A Vrbo stay quote: nightly and total price, fees, payment model.

        Supply `property_id` (from `POST /v1/ota/vrbo/search`) or `listing_id`
        (the path segment of a Vrbo URL). A listing id costs one extra page load
        to resolve, so store the `property_id` the answer returns.
      examples:
      - adults: 2
        check_in: '2029-04-10'
        nights: 3
        property_id: '122942416'
    VrboSearchRequest:
      properties:
        destination:
          type: string
          minLength: 2
          title: Destination
          description: Place as a guest would type it, e.g. `South Lake Tahoe, California`. Vrbo resolves it to a region.
          examples:
          - South Lake Tahoe, California
        check_in:
          type: string
          format: date
          title: Check In
          description: First night of the stay, `YYYY-MM-DD`.
          examples:
          - '2029-04-10'
        check_out:
          anyOf:
          - type: string
            format: date
          - type: 'null'
          title: Check Out
          description: Departure date. An alternative to `nights` — if both are given, this wins.
          examples:
          - '2029-04-13'
        nights:
          type: integer
          maximum: 28.0
          minimum: 1.0
          title: Nights
          description: Length of stay. Ignored when `check_out` is supplied.
          default: 1
          examples:
          - 3
        adults:
          type: integer
          maximum: 16.0
          minimum: 1.0
          title: Adults
          description: Guests (adults).
          default: 2
          examples:
          - 2
        limit:
          type: integer
          maximum: 50.0
          minimum: 1.0
          title: Limit
          description: Maximum listings to return, in Vrbo's recommended order.
          default: 20
          examples:
          - 10
        market:
          type: string
          enum:
          - US
          title: Market
          description: Vrbo point-of-sale. Only `US` (www.vrbo.com, USD) is verified.
          default: US
          examples:
          - US
      additionalProperties: false
      type: object
      required:
      - destination
      - check_in
      title: VrboSearchRequest
      description: |-
        Vrbo vacation-rental listings for a destination and stay window.

        Each listing carries the numeric `property_id` that `POST /v1/ota/vrbo`
        quotes, the listing id from Vrbo's URL, and Vrbo's own nightly and stay
        prices ("All fees included" is reported as `fees_included`).
      examples:
      - adults: 2
        check_in: '2029-04-10'
        destination: South Lake Tahoe, California
        limit: 10
        nights: 3
    WalmartReviewsRequest:
      properties:
        item_id:
          type: string
          minLength: 1
          pattern: ^\d+$
          title: Item Id
          description: Numeric item id returned by `POST /v1/walmart/search`.
          examples:
          - '5255687930'
        page:
          type: integer
          maximum: 100.0
          minimum: 1.0
          title: Page
          description: Review page.
          default: 1
          examples:
          - 1
        sort:
          type: string
          enum:
          - highest-rating
          - lowest-rating
          - most-helpful
          - most-recent
          - relevancy
          title: Sort
          description: Walmart's own review sort.
          default: relevancy
          examples:
          - relevancy
      additionalProperties: false
      type: object
      required:
      - item_id
      title: WalmartReviewsRequest
      description: |-
        One page (10) of Walmart reviews for an item, without a browser.

        Answers the review list plus the summary (average, total, per-star
        counts and percentages, recommended percentage) and Walmart's own
        `next_page` url.
      examples:
      - item_id: '5255687930'
    WalmartSearchRequest:
      properties:
        q:
          type: string
          maxLength: 200
          minLength: 1
          title: Q
          description: Search query.
          examples:
          - bathrobe
        page:
          type: integer
          maximum: 50.0
          minimum: 1.0
          title: Page
          description: Result page.
          default: 1
          examples:
          - 1
        sort:
          anyOf:
          - type: string
          - type: 'null'
          enum:
          - best_match
          - best_seller
          - new
          - price_high
          - price_low
          - rating
          title: Sort
          description: Walmart's own sort values.
          examples:
          - null
      additionalProperties: false
      type: object
      required:
      - q
      title: WalmartSearchRequest
      description: |-
        Walmart product search over plain HTTP.

        One page (~40) of items from Walmart's own store JSON. Sponsored items
        come labelled in `sponsored` rather than dropped.
      examples:
      - q: bathrobe
    BillingPlan:
      type: object
      required:
      - code
      - name
      - monthly_credits
      - price_usd
      - concurrency
      properties:
        code:
          type: string
          description: Plan code.
          enum:
          - free
          - starter
          - growth
          - scale
          - enterprise
        name:
          type: string
        monthly_credits:
          type: integer
          description: Credits granted at the start of each period.
        price_usd:
          type: integer
          description: Monthly price in USD; 0 = free, -1 = custom (sales).
        concurrency:
          type: integer
          description: Concurrent metered requests allowed once enforcement is on.
    BillingSummary:
      type: object
      required:
      - mode
      - plan
      - credits
      - period
      properties:
        mode:
          type: string
          description: 'Credit metering mode: `shadow` (metered and recorded, never blocks) during the beta; `enforce` once paid plans are on sale.'
          enum:
          - 'off'
          - shadow
          - enforce
        plan:
          $ref: '#/components/schemas/BillingPlan'
        credits:
          type: object
          required:
          - balance
          - reserved
          - available
          - credits_used
          - credits_refunded
          - billable_requests
          properties:
            balance:
              type: integer
              description: Credits on the account. In shadow mode this can go negative; the overdraft is forgiven at renewal.
            reserved:
              type: integer
              description: Credits held by requests that are still running.
            available:
              type: integer
              description: '`balance - reserved`.'
            credits_used:
              type: integer
              description: Credits charged this period.
            credits_refunded:
              type: integer
              description: Credits returned this period.
            billable_requests:
              type: integer
              description: Requests charged this period.
        period:
          type: object
          required:
          - start
          - end
          properties:
            start:
              type: string
              format: date-time
            end:
              type: string
              description: Renewal time; unspent credits expire then.
              format: date-time
        subscription:
          type: object
          properties:
            status:
              type: string
            stripe_managed:
              type: boolean
    BillingLedgerEntry:
      type: object
      required:
      - id
      - kind
      - amount
      - balance_after
      - created_at
      properties:
        id:
          type: integer
          description: Entry id; pass the last one as `before` to page.
        kind:
          type: string
          description: '`usage`, `grant`, `expiry`, `refund`, `adjustment`, ...'
        amount:
          type: integer
          description: Signed credit change (negative for usage).
        balance_after:
          type: integer
        route:
          type: string
          description: Route template for usage entries.
        request_id:
          type: string
          description: '`x-request-id` of the charged request.'
        detail:
          type: object
        created_at:
          type: string
          format: date-time
    BillingLedger:
      type: object
      required:
      - entries
      - next_before
      properties:
        entries:
          type: array
          items:
            $ref: '#/components/schemas/BillingLedgerEntry'
          description: Newest first.
        next_before:
          type:
          - integer
          - 'null'
          description: Pass as `before` for the next page; null on the last page.
    BillingPlans:
      type: object
      required:
      - plans
      - costs
      - free
      - notes
      - mode
      properties:
        plans:
          type: array
          items:
            $ref: '#/components/schemas/BillingPlan'
        costs:
          type: array
          items:
            type: object
            required:
            - method
            - path
            - credits
            properties:
              method:
                type: string
              path:
                type: string
              credits:
                type: integer
          description: Base credit cost of every metered operation.
        free:
          type: array
          items:
            type: string
          description: Operations that never cost credits.
        notes:
          type: array
          items:
            type: string
        mode:
          type: string
          enum:
          - 'off'
          - shadow
          - enforce
    ErrorResponse:
      type: object
      description: 'Error body for every non-validation error: `{"detail": "..."}`.'
      required:
      - detail
      properties:
        detail:
          type: string
          description: Human-readable error message.
      examples:
      - detail: missing or invalid API key
    RateProvenance:
      type: object
      description: Where, when and how one normalized price was observed.
      required:
      - schema_version
      - observation_id
      - collection_id
      - observed_at
      - source
      - source_kind
      - collector
      - source_property_id
      - requested_market
      - requested_currency
      - returned_currency
      - egress_mode
      - price_basis
      - derivation
      - upstream_rate_id
      properties:
        schema_version:
          type: integer
          description: Provenance schema version (currently 1).
        observation_id:
          type: string
          description: Deterministic id of this price observation (`rateobs_...`).
        collection_id:
          type: string
          description: Id shared by every price from one upstream fetch (`ratecol_...`).
        observed_at:
          type: string
          description: UTC observation time, ISO-8601.
        source:
          type: string
          description: Upstream source, e.g. `google_hotels_calendar`.
        source_kind:
          type: string
          description: Kind of source, e.g. `calendar`, `offer`, `ota_calendar`, `official`.
        collector:
          type: string
          description: Identifier of the collector that produced the price.
        source_property_id:
          type: string
          description: Property identifier at the source.
        requested_market:
          type:
          - string
          - 'null'
        requested_currency:
          type:
          - string
          - 'null'
        returned_currency:
          type:
          - string
          - 'null'
        egress_mode:
          type: string
          description: How the request reached the source, e.g. `direct`.
        price_basis:
          type: string
          description: What the price represents, e.g. `room_base_before_taxes_and_fees`.
        derivation:
          type: string
          description: How the figure was derived, e.g. `normalized_upstream`.
        upstream_rate_id:
          type:
          - string
          - 'null'
          description: Source-native rate/room id when available.
    CalendarRateProvenance:
      allOf:
      - $ref: '#/components/schemas/RateProvenance'
      - type: object
        required:
        - derived_fields
        properties:
          derived_fields:
            type: array
            items:
              type: string
            description: Fields computed by ScraperCompany rather than read from the source.
          mainstream:
            type: object
            description: 'Present only when mainstream figures were added (`basis: mainstream`).'
            required:
            - source
            - supplier
            - method
            properties:
              source:
                type: string
              supplier:
                type:
                - string
                - 'null'
              method:
                type: string
      description: Provenance of one calendar row.
    CalendarRate:
      type: object
      description: One priced night from the Google Hotels calendar.
      required:
      - token
      - stay_date
      - rate
      - rate_base
      - rate_before_taxes_with_fees
      - rate_total
      - tax
      - fees
      - currency
      - market
      - rates_include_tax
      - adults
      - los
      - min_length_of_stay
      - rate_mainstream_base
      - rate_mainstream_total
      - mainstream_source
      - aggregator_discount
      - implied_tax_rate
      - provenance
      properties:
        token:
          type: string
          description: Google property token.
        stay_date:
          type: string
          description: Stay (check-in) date.
          format: date
        rate:
          type: number
          description: 'The market-correct figure to store: all-in (`rate_total`) when `rates_include_tax` is true, otherwise the pre-tax base. For `POST /v1/stay` it is the whole-stay figure.'
        rate_base:
          type:
          - number
          - 'null'
          description: Room-only price before tax and mandatory fees.
        rate_before_taxes_with_fees:
          type:
          - number
          - 'null'
          description: '`rate_base` + `fees` (SearchAPI''s `extracted_price_before_taxes` basis).'
        rate_total:
          type:
          - number
          - 'null'
          description: All-in price including tax and fees.
        tax:
          type:
          - number
          - 'null'
        fees:
          type:
          - number
          - 'null'
        currency:
          type: string
        market:
          type: string
        rates_include_tax:
          type: boolean
          description: Which basis `rate` uses.
        adults:
          type: integer
        los:
          type: integer
          description: Length of stay the price was quoted for.
        min_length_of_stay:
          type:
          - integer
          - 'null'
          description: Set when the night only prices at a longer stay; `rate` is then a per-night figure derived from that stay.
        rate_mainstream_base:
          type:
          - number
          - 'null'
          description: 'Cheapest mainstream-OTA base price (only populated with `basis: mainstream`).'
        rate_mainstream_total:
          type:
          - number
          - 'null'
          description: 'Cheapest mainstream-OTA all-in price (only populated with `basis: mainstream`).'
        mainstream_source:
          type:
          - string
          - 'null'
          description: OTA that produced the mainstream figure.
        aggregator_discount:
          type:
          - number
          - 'null'
          description: '`rate_mainstream_total - rate_total` when both exist.'
        implied_tax_rate:
          type:
          - number
          - 'null'
          description: '`tax / rate_base`.'
        provenance:
          $ref: '#/components/schemas/CalendarRateProvenance'
    CalendarResponse:
      type: object
      description: Response of `POST /v1/calendar` (also each item `result` of a calendar job).
      required:
      - token
      - collection_id
      - observed_at
      - market
      - requested_days
      - coverage
      - wire_bytes
      - elapsed_s
      - calendar_elapsed_s
      - egress_mode
      - tax_profile
      - unpriced_dates
      - validation
      - rates
      properties:
        token:
          type: string
        collection_id:
          type: string
          description: Shared by every row of this collection (`ratecol_...`).
        observed_at:
          type: string
          description: UTC observation time, ISO-8601.
        market:
          type: string
        requested_days:
          type: integer
          description: Nights requested (capped at 330).
        coverage:
          type: number
          description: Share of requested nights that returned a priced row, 0-1 rounded to 4 decimals (e.g. `0.9333` = 84 of 90). A number, not an `N/M` string.
        wire_bytes:
          type: integer
        elapsed_s:
          type: number
          description: End-to-end seconds for this request.
        calendar_elapsed_s:
          type: number
          description: Seconds spent on the upstream calendar fetch.
        egress_mode:
          type: string
          enum:
          - direct
          - proxy_fallback
        tax_profile:
          anyOf:
          - type: object
            required:
            - rate
            - confidence
            - itemised
            - derived
            properties:
              rate:
                type: number
                description: Median tax / base ratio observed across nights.
              confidence:
                type: string
                enum:
                - high
                - low
                - none
              itemised:
                type: integer
                description: Nights where the tax split was itemised.
              derived:
                type: integer
                description: Nights where only a total was given and the split was derived.
          - type: 'null'
          description: The property's effective tax profile, derived from the returned nights.
        unpriced_dates:
          type: array
          items:
            type: string
            format: date
          description: Requested nights with no bookable offer.
        validation:
          type: object
          description: Plausibility checks on the returned rows.
          required:
          - ok
          - errors
          - warnings
          properties:
            ok:
              type: boolean
              description: False when any error-level finding exists.
            errors:
              type: array
              items:
                type: string
            warnings:
              type: array
              items:
                type: string
        booking_window:
          type: object
          description: How far out the property actually sells. Present on successful collections.
          required:
          - requested_days
          - priced_days
          - last_priced_day
          - dry_after_day
          - note
          properties:
            requested_days:
              type: integer
            priced_days:
              type: integer
            last_priced_day:
              type:
              - integer
              - 'null'
              description: 1-based day of the last priced night.
            contiguous_days:
              type: integer
              description: Priced nights from the start with no gap (absent when nothing priced).
            dry_after_day:
              type: integer
            note:
              type: string
        basis_applied:
          type: string
          description: 'Present only with `basis: mainstream`.'
          enum:
          - mainstream:annotated
          - mainstream:calendar-already-matched
        source_check:
          type: object
          description: 'Present only when `verify_sources` > 0 or `basis: mainstream` sampled nights against the offers page.'
          required:
          - sampled
          - mainstream_sources
          - calendar_matches_mainstream
          - note
          - checks
          properties:
            sampled:
              type: integer
            mainstream_sources:
              type: array
              items:
                type: string
            calendar_matches_mainstream:
              type: boolean
            note:
              type: string
            checks:
              type: array
              items:
                type: object
                required:
                - stay_date
                - calendar_total
                - cheapest_mainstream
                - cheapest_any_source
                - cheapest_source
                - calendar_is_mainstream
                properties:
                  stay_date:
                    type: string
                    format: date
                  calendar_total:
                    type:
                    - number
                    - 'null'
                  cheapest_mainstream:
                    type:
                    - number
                    - 'null'
                  cheapest_any_source:
                    type: number
                  cheapest_source:
                    type: string
                  calendar_is_mainstream:
                    type: boolean
            reprice:
              type: object
              description: Present when mainstream re-pricing ran.
              required:
              - replaced
              - dropped_no_mainstream_offer
              properties:
                replaced:
                  type: integer
                dropped_no_mainstream_offer:
                  type: integer
        rates:
          type: array
          items:
            $ref: '#/components/schemas/CalendarRate'
          description: One row per priced night.
    StayResponse:
      allOf:
      - type: object
        required:
        - nights
        properties:
          nights:
            type: integer
            description: Nights between check_in and check_out.
      - $ref: '#/components/schemas/CalendarRate'
      description: One priced stay window. `rate` is the WHOLE-STAY figure.
    SearchMatch:
      type: object
      required:
      - token
      - rank
      - verified
      - name
      - name_score
      properties:
        token:
          type: string
          description: Google property token; pass it as `token` / `property_token`.
        rank:
          type: integer
          description: Google's own ordering, 0 = first.
        verified:
          type:
          - boolean
          - 'null'
          description: Whether the token prices. `null` when `verify` was false.
        name:
          type:
          - string
          - 'null'
          description: Property name read back from Google. `null` when unchecked, empty string when checked but unreadable.
        name_score:
          type:
          - number
          - 'null'
          description: 0-1 word-overlap between the requested and real name. `null` when unchecked.
    SearchResponse:
      type: object
      required:
      - query
      - gl
      - requested_market
      - attempted_markets
      - matched_market
      - market_fallback_used
      - search_status
      - external_fallback_recommended
      - matches
      properties:
        query:
          type: string
          description: '`name` and `city` as searched.'
        gl:
          type: string
          description: Google country (`gl`) of the market that matched, or of the first market tried.
        requested_market:
          type: string
        attempted_markets:
          type: array
          items:
            type: string
          description: Markets tried, in order, up to and including the one that matched.
        matched_market:
          type:
          - string
          - 'null'
        market_fallback_used:
          type: boolean
        search_status:
          type: string
          enum:
          - matched
          - not_found
        external_fallback_recommended:
          type: boolean
          description: True when nothing matched.
        matches:
          type: array
          items:
            $ref: '#/components/schemas/SearchMatch'
          description: Best match first when `verify` is on (verified, then name score, then Google rank).
    Market:
      type: object
      required:
      - code
      - currency
      - label
      - rates_include_tax
      properties:
        code:
          type: string
        currency:
          type: string
        label:
          type: string
        rates_include_tax:
          type: boolean
          description: Default tax basis for the market.
    MarketsResponse:
      type: object
      required:
      - markets
      properties:
        markets:
          type: array
          items:
            $ref: '#/components/schemas/Market'
    GoogleOfferRoom:
      type: object
      required:
      - name
      - description
      - link
      - price_before_taxes
      - price_total
      - is_suite
      - beds
      - has_free_cancellation
      - free_cancellation_until
      - free_cancellation_time
      - thumbnail
      properties:
        name:
          type: string
        description:
          type: string
        link:
          type:
          - string
          - 'null'
        price_before_taxes:
          type:
          - number
          - 'null'
        price_total:
          type:
          - number
          - 'null'
        is_suite:
          type: boolean
        beds:
          type:
          - integer
          - 'null'
        has_free_cancellation:
          type: boolean
        free_cancellation_until:
          type:
          - string
          - 'null'
        free_cancellation_time:
          type:
          - string
          - 'null'
        thumbnail:
          type:
          - string
          - 'null'
    GoogleOffer:
      type: object
      required:
      - source
      - raw_source
      - is_official
      - currency
      - nights
      - room_id
      - price_per_night
      - price_per_night_before_taxes
      - total
      - tax
      - fees
      - has_free_cancellation
      - free_cancellation_until
      - free_cancellation_time
      - discount_remarks
      - has_member_rate
      - rooms
      - headline_price_total
      - headline_price_before_taxes
      - price_derived_from_room
      - provenance
      properties:
        source:
          type: string
          description: Normalized seller name, e.g. `Booking.com`, `Official site`.
        raw_source:
          type: string
          description: Seller name exactly as Google rendered it.
        is_official:
          type: boolean
        currency:
          type:
          - string
          - 'null'
        nights:
          type: integer
        room_id:
          type:
          - string
          - 'null'
          description: Seller-native room / rate-plan id.
        price_per_night:
          type:
          - number
          - 'null'
          description: All-in price per night.
        price_per_night_before_taxes:
          type:
          - number
          - 'null'
        total:
          type:
          - number
          - 'null'
          description: All-in price for the stay window.
        tax:
          type:
          - number
          - 'null'
        fees:
          type:
          - number
          - 'null'
        has_free_cancellation:
          type: boolean
        free_cancellation_until:
          type:
          - string
          - 'null'
        free_cancellation_time:
          type:
          - string
          - 'null'
        discount_remarks:
          type: array
          items:
            type: string
          description: Member/loyalty remarks shown beside the offer.
        has_member_rate:
          type: boolean
        rooms:
          type: array
          items:
            $ref: '#/components/schemas/GoogleOfferRoom'
        headline_price_total:
          type:
          - number
          - 'null'
        headline_price_before_taxes:
          type:
          - number
          - 'null'
        price_derived_from_room:
          type: boolean
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    PriceInsights:
      type: object
      required:
      - lowest_price
      - price_level
      - price_level_code
      - typical_price_range
      properties:
        lowest_price:
          type:
          - string
          - 'null'
          description: As Google displays it, e.g. `$304`.
        price_level:
          type:
          - string
          - 'null'
        price_level_code:
          type:
          - integer
          - 'null'
        typical_price_range:
          anyOf:
          - type: object
            required:
            - low_price
            - high_price
            properties:
              low_price:
                type:
                - string
                - 'null'
              high_price:
                type:
                - string
                - 'null'
          - type: 'null'
    OffersResponse:
      type: object
      required:
      - token
      - check_in
      - check_out
      - nights
      - adults
      - device
      - coverage
      - currency
      - currency_matches_request
      - requested_market
      - egress_market
      - egress_geo_locked_ok
      - price_insights_market_verified
      - rates_include_tax
      - lowest_price_per_night
      - rooms_total
      - name
      - hotel_class
      - hotel_class_stars
      - rating
      - reviews
      - deal
      - deal_description
      - has_deal
      - price_insights
      - sources
      - missing_sources
      - refundable_offers
      - wire_bytes
      - elapsed_s
      - warnings
      - offers
      properties:
        token:
          type: string
        check_in:
          type: string
          format: date
        check_out:
          type: string
          format: date
        nights:
          type: integer
        adults:
          type: integer
        device:
          type: string
        coverage:
          type: integer
          description: Device profiles fetched (echo of the request).
        currency:
          type:
          - string
          - 'null'
          description: Currency the page actually priced in.
        currency_matches_request:
          type: boolean
        requested_market:
          type: string
        egress_market:
          type:
          - string
          - 'null'
          description: Market the seller list is verified for, or null when unverified.
        egress_geo_locked_ok:
          type: boolean
        price_insights_market_verified:
          type: boolean
        rates_include_tax:
          type: boolean
          description: Basis used for `lowest_price_per_night`.
        lowest_price_per_night:
          type:
          - number
          - 'null'
        rooms_total:
          type: integer
        name:
          type: string
        hotel_class:
          type: string
        hotel_class_stars:
          type:
          - integer
          - 'null'
        rating:
          type:
          - number
          - 'null'
        reviews:
          type:
          - integer
          - 'null'
        deal:
          type:
          - string
          - 'null'
        deal_description:
          type:
          - string
          - 'null'
        has_deal:
          type: boolean
        price_insights:
          $ref: '#/components/schemas/PriceInsights'
        sources:
          type: array
          items:
            type: string
          description: Distinct sellers in `offers`.
        missing_sources:
          type: array
          items:
            type: string
          description: Required sources not offered after retry.
        refundable_offers:
          type: integer
        wire_bytes:
          type: integer
        elapsed_s:
          type: number
        warnings:
          type: array
          items:
            type: string
        offers:
          type: array
          items:
            $ref: '#/components/schemas/GoogleOffer'
    RoomMatrixResponse:
      type: object
      required:
      - search_parameters
      - property
      - render
      - sources
      - rows
      - totals
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - token
          - check_in_date
          - check_out_date
          - adults
          - currency
          - sources
          properties:
            engine:
              type: string
              enum:
              - google_hotels_rooms
            token:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            currency:
              type: string
            sources:
              type: array
              items:
                type: string
        property:
          type: object
          required:
          - name
          - currency
          - currency_matches_request
          - requested_market
          - egress_market
          - egress_geo_locked_ok
          properties:
            name:
              type: string
            currency:
              type: string
            currency_matches_request:
              type: boolean
            requested_market:
              type: string
            egress_market:
              type:
              - string
              - 'null'
            egress_geo_locked_ok:
              type: boolean
        render:
          type: object
          required:
          - wire_bytes
          - carried_room_detail
          properties:
            wire_bytes:
              type: integer
            carried_room_detail:
              type: boolean
        sources:
          type: array
          items:
            type: object
            required:
            - source
            - rooms
            - cheapest
            - dearest
            - currency
            - is_official
            - duplicate_of
            - provenance
            properties:
              source:
                type: string
              rooms:
                type: integer
                description: Distinct rooms this render carried for the source; 0 does NOT mean no inventory.
              cheapest:
                type:
                - number
                - 'null'
              dearest:
                type:
                - number
                - 'null'
              currency:
                type: string
              is_official:
                type: boolean
              duplicate_of:
                type:
                - string
                - 'null'
              provenance:
                anyOf:
                - $ref: '#/components/schemas/RateProvenance'
                - type: 'null'
        rows:
          type: array
          items:
            type: object
            required:
            - signature
            - cells
            properties:
              signature:
                type: string
                description: Normalized room signature, e.g. `1 king`.
              cells:
                type: object
                description: Keyed by source name.
                additionalProperties:
                  type: object
                  required:
                  - name
                  - price
                  - total
                  - provenance
                  properties:
                    name:
                      type: string
                      description: The source's own room name.
                    price:
                      type:
                      - number
                      - 'null'
                      description: Price before taxes.
                    total:
                      type:
                      - number
                      - 'null'
                    provenance:
                      anyOf:
                      - $ref: '#/components/schemas/RateProvenance'
                      - type: 'null'
        totals:
          type: object
          required:
          - sources_present
          - sources_with_rooms
          - distinct_signatures
          properties:
            sources_present:
              type: integer
            sources_with_rooms:
              type: integer
            distinct_signatures:
              type: integer
    CalendarJobItemStatus:
      type: object
      required:
      - id
      - item_index
      - token
      - label
      - status
      - request
      - result
      - error
      - attempts
      - started_at
      - finished_at
      - updated_at
      properties:
        id:
          type: string
          description: '`refreshitem_...`'
        item_index:
          type: integer
        token:
          type: string
        label:
          type:
          - string
          - 'null'
        status:
          type: string
          enum:
          - queued
          - running
          - succeeded
          - failed
        request:
          $ref: '#/components/schemas/CalendarJobItem'
        result:
          anyOf:
          - $ref: '#/components/schemas/CalendarResponse'
          - type: 'null'
          description: The item's calendar payload. Only populated with `include_results=true` once the item succeeded; otherwise null.
        error:
          type:
          - string
          - 'null'
        attempts:
          type: integer
        started_at:
          type:
          - string
          - 'null'
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        finished_at:
          type:
          - string
          - 'null'
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        updated_at:
          type: string
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
    CalendarJob:
      type: object
      description: A calendar batch and its per-item status (same shape for submit and poll).
      required:
      - id
      - job_id
      - poll_url
      - status
      - priority
      - callback_url
      - callback_status
      - callback_attempts
      - callback_last_error
      - artifact_uri
      - artifact_sha256
      - result_summary
      - error
      - items_total
      - items_succeeded
      - items_failed
      - created_at
      - started_at
      - finished_at
      - updated_at
      - items
      properties:
        id:
          type: string
          description: '`refreshjob_...`'
        job_id:
          type: string
          description: Same as `id`.
        poll_url:
          type: string
          description: '`/v1/jobs/{job_id}`'
        status:
          type: string
          enum:
          - queued
          - running
          - succeeded
          - partial
          - failed
        priority:
          type: integer
        callback_url:
          type:
          - string
          - 'null'
        callback_status:
          type: string
          enum:
          - not_configured
          - pending
          - delivered
          - failed
        callback_attempts:
          type: integer
        callback_last_error:
          type:
          - string
          - 'null'
        artifact_uri:
          type:
          - string
          - 'null'
        artifact_sha256:
          type:
          - string
          - 'null'
        result_summary:
          type: object
          description: Empty object until the job finishes.
          properties:
            rates:
              type: integer
            wire_bytes:
              type: integer
            database:
              type: object
              required:
              - run_id
              - rows_written
              - rows_changed
              - rows_removed
              properties:
                run_id:
                  type: string
                rows_written:
                  type: integer
                rows_changed:
                  type: integer
                rows_removed:
                  type: integer
        error:
          type:
          - string
          - 'null'
        items_total:
          type: integer
        items_succeeded:
          type: integer
        items_failed:
          type: integer
        created_at:
          type: string
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        started_at:
          type:
          - string
          - 'null'
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        finished_at:
          type:
          - string
          - 'null'
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        updated_at:
          type: string
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        items:
          type: array
          items:
            $ref: '#/components/schemas/CalendarJobItemStatus'
    UsageResponse:
      type: object
      required:
      - key
      - period
      - totals
      - by_status
      - by_endpoint
      - by_day
      properties:
        key:
          type: object
          required:
          - name
          - prefix
          - rate_limit_per_min
          - role
          properties:
            name:
              type: string
            prefix:
              type: string
              description: First characters of the key, for display.
            rate_limit_per_min:
              type: integer
              description: This key's requests-per-minute limit.
            role:
              type: string
        period:
          type: object
          required:
          - name
          - start
          - end
          properties:
            name:
              type: string
              enum:
              - 24h
              - 7d
              - 30d
              - 90d
            start:
              type: string
              format: date-time
            end:
              type: string
              format: date-time
        totals:
          type: object
          required:
          - requests
          - successful
          - errors
          - rate_limited
          - response_bytes
          - avg_duration_ms
          - p95_duration_ms
          properties:
            requests:
              type: integer
            successful:
              type: integer
            errors:
              type: integer
            rate_limited:
              type: integer
            response_bytes:
              type: integer
            avg_duration_ms:
              type: integer
            p95_duration_ms:
              type: integer
        by_status:
          type: array
          items:
            type: object
            required:
            - status
            - requests
            properties:
              status:
                type: integer
              requests:
                type: integer
        by_endpoint:
          type: array
          items:
            type: object
            required:
            - method
            - path
            - requests
            - errors
            - avg_duration_ms
            - p95_duration_ms
            properties:
              method:
                type: string
              path:
                type: string
              requests:
                type: integer
              errors:
                type: integer
              avg_duration_ms:
                type: integer
              p95_duration_ms:
                type: integer
          description: Top 50 endpoints by request count.
        by_day:
          type: array
          items:
            type: object
            required:
            - date
            - requests
            - errors
            - response_bytes
            properties:
              date:
                type: string
                format: date
              requests:
                type: integer
              errors:
                type: integer
              response_bytes:
                type: integer
    RequestRecord:
      type: object
      required:
      - id
      - method
      - path
      - status
      - duration_ms
      - response_bytes
      - request
      - created_at
      properties:
        id:
          type: string
          description: '`req_...`; equals the `x-request-id` response header.'
        method:
          type: string
        path:
          type: string
          description: Route path, e.g. `/v1/calendar`.
        status:
          type: integer
        duration_ms:
          type: integer
        response_bytes:
          type: integer
        request:
          type: object
          description: Sanitized request metadata; each key present only when the request had it.
          properties:
            path:
              type: object
              description: Path parameters.
            query:
              type: object
              description: Query parameters (credentials redacted).
            body:
              description: JSON body (credentials redacted), or `{truncated, bytes}` / `{invalid_json, bytes}`.
        created_at:
          type: string
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
    RequestHistoryResponse:
      type: object
      required:
      - requests
      - count
      - has_more
      properties:
        requests:
          type: array
          items:
            $ref: '#/components/schemas/RequestRecord'
          description: Newest first.
        count:
          type: integer
        has_more:
          type: boolean
        next_cursor:
          type: string
          description: Present only when `has_more` is true; pass it back as the `cursor` query parameter.
    StoredRate:
      type: object
      required:
      - property_name
      - stay_date
      - occupancy_key
      - los
      - rate
      - rate_base
      - rate_before_taxes_with_fees
      - rate_total
      - tax
      - fees
      - currency
      - market
      - rates_include_tax
      - min_length_of_stay
      - observed_at
      - last_changed_at
      - collection_id
      - observation_id
      - provenance
      properties:
        property_name:
          type: string
        stay_date:
          type: string
          format: date
        occupancy_key:
          type: string
          description: e.g. `adults=2`
        los:
          type: integer
        rate:
          type:
          - number
          - 'null'
        rate_base:
          type:
          - number
          - 'null'
        rate_before_taxes_with_fees:
          type:
          - number
          - 'null'
        rate_total:
          type:
          - number
          - 'null'
        tax:
          type:
          - number
          - 'null'
        fees:
          type:
          - number
          - 'null'
        currency:
          type: string
        market:
          type:
          - string
          - 'null'
        rates_include_tax:
          type: boolean
        min_length_of_stay:
          type:
          - integer
          - 'null'
        observed_at:
          type: string
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        last_changed_at:
          type: string
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        collection_id:
          type: string
        observation_id:
          type: string
        provenance:
          $ref: '#/components/schemas/CalendarRateProvenance'
    StoredRatesResponse:
      type: object
      required:
      - source
      - source_property_id
      - count
      - last_observed_at
      - last_success_at
      - age_seconds
      - freshness
      - rates
      properties:
        source:
          type: string
          enum:
          - google_hotels
        source_property_id:
          type: string
          description: The requested token.
        count:
          type: integer
        last_observed_at:
          type:
          - string
          - 'null'
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        last_success_at:
          type:
          - string
          - 'null'
          description: Timestamp string, e.g. `2026-08-10 14:05:00.123456+00`.
        age_seconds:
          type:
          - integer
          - 'null'
        freshness:
          type: string
          description: '`fresh` <= 24 h, `stale` <= 48 h, `expired` older, `missing` when never collected.'
          enum:
          - missing
          - fresh
          - stale
          - expired
        rates:
          type: array
          items:
            $ref: '#/components/schemas/StoredRate'
    OtaSearchMeta:
      type: object
      required:
      - source
      - matches
      - selection_method
      - match_threshold
      - match_margin
      - wire_bytes
      - elapsed_s
      properties:
        source:
          type: string
        matches:
          type: integer
        selection_method:
          type: string
        match_threshold:
          type: number
        match_margin:
          type: number
        wire_bytes:
          type: integer
        elapsed_s:
          type: number
    BookingSearchMatch:
      type: object
      required:
      - pagename
      - country
      - name
      - url
      - rank
      - name_score
      - identity_score
      - match_score
      - confidence
      properties:
        pagename:
          type: string
          description: URL slug; pass as `pagename`.
        country:
          type: string
          description: Two-letter URL segment; pass as `country`.
        name:
          type: string
        url:
          type: string
        rank:
          type: integer
        name_score:
          type: number
        identity_score:
          type: number
        match_score:
          type: number
        confidence:
          type: string
          enum:
          - high
          - medium
          - low
    BookingSearchResponse:
      type: object
      description: Response of `POST /v1/ota/booking/search`.
      required:
      - search_parameters
      - search_status
      - recommended_match
      - warnings
      - matches
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - name
          - city
          - limit
          properties:
            engine:
              type: string
              enum:
              - booking_search
            name:
              type: string
            city:
              type: string
            limit:
              type: integer
        search_status:
          type: string
          description: '`matched` only when the top candidate clears the identity threshold and margin.'
          enum:
          - matched
          - ambiguous
          - not_found
        recommended_match:
          anyOf:
          - $ref: '#/components/schemas/BookingSearchMatch'
          - type: 'null'
          description: Safe to store; null unless `search_status` is `matched`.
        warnings:
          type: array
          items:
            type: string
        matches:
          type: array
          items:
            $ref: '#/components/schemas/BookingSearchMatch'
          description: Candidates, best first, for manual review.
        meta:
          $ref: '#/components/schemas/OtaSearchMeta'
    HotelsSearchMatch:
      type: object
      required:
      - property_id
      - name
      - city
      - address
      - country
      - url
      - rank
      - score
      - name_score
      - identity_score
      - match_score
      - confidence
      - winner_reason
      properties:
        property_id:
          type: string
          description: Numeric Hotels.com id (digits); pass as `property_id`.
        name:
          type: string
        city:
          type: string
        address:
          type: string
        country:
          type: string
        url:
          type: string
        rank:
          type: integer
        score:
          type: number
        name_score:
          type: number
        identity_score:
          type: number
        match_score:
          type: number
        confidence:
          type: string
          enum:
          - high
          - medium
          - low
        winner_reason:
          type: string
        city_score:
          type: number
          description: Present only when `city` was supplied.
        coordinates:
          type: object
          description: Present only when the source returned coordinates.
          required:
          - latitude
          - longitude
          properties:
            latitude:
              type: number
            longitude:
              type: number
    HotelsSearchResponse:
      type: object
      description: Response of `POST /v1/ota/hotels/search`.
      required:
      - search_parameters
      - search_status
      - recommended_match
      - warnings
      - matches
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - name
          - city
          - market
          - limit
          properties:
            engine:
              type: string
              enum:
              - hotels_search
            name:
              type: string
            city:
              type: string
            market:
              type: string
            limit:
              type: integer
        search_status:
          type: string
          description: '`matched` only when the top candidate clears the identity threshold and margin.'
          enum:
          - matched
          - ambiguous
          - not_found
        recommended_match:
          anyOf:
          - $ref: '#/components/schemas/HotelsSearchMatch'
          - type: 'null'
          description: Safe to store; null unless `search_status` is `matched`.
        warnings:
          type: array
          items:
            type: string
        matches:
          type: array
          items:
            $ref: '#/components/schemas/HotelsSearchMatch'
          description: Candidates, best first, for manual review.
        meta:
          $ref: '#/components/schemas/OtaSearchMeta'
    AgodaSearchMatch:
      type: object
      required:
      - property_id
      - name
      - city
      - country
      - location
      - rank
      - score
      - name_score
      - identity_score
      - match_score
      - confidence
      properties:
        property_id:
          type: string
          description: Numeric Agoda id; pass as `property_id`.
        name:
          type: string
        city:
          type: string
        country:
          type: string
        location:
          type: string
        rank:
          type: integer
        score:
          type: number
        name_score:
          type: number
        identity_score:
          type: number
        match_score:
          type: number
        confidence:
          type: string
          enum:
          - high
          - medium
          - low
        city_score:
          type: number
          description: Present only when `city` was supplied.
    AgodaSearchResponse:
      type: object
      description: Response of `POST /v1/ota/agoda/search`.
      required:
      - search_parameters
      - search_status
      - recommended_match
      - warnings
      - matches
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - name
          - city
          - origin
          - limit
          properties:
            engine:
              type: string
              enum:
              - agoda_search
            name:
              type: string
            city:
              type: string
            origin:
              type: string
            limit:
              type: integer
        search_status:
          type: string
          description: '`matched` only when the top candidate clears the identity threshold and margin.'
          enum:
          - matched
          - ambiguous
          - not_found
        recommended_match:
          anyOf:
          - $ref: '#/components/schemas/AgodaSearchMatch'
          - type: 'null'
          description: Safe to store; null unless `search_status` is `matched`.
        warnings:
          type: array
          items:
            type: string
        matches:
          type: array
          items:
            $ref: '#/components/schemas/AgodaSearchMatch'
          description: Candidates, best first, for manual review.
        meta:
          $ref: '#/components/schemas/OtaSearchMeta'
    BookingCalendarNight:
      type: object
      required:
      - stay_date
      - available
      - price
      - currency
      - min_length_of_stay
      - provenance
      properties:
        stay_date:
          type: string
          format: date
        available:
          type: boolean
        price:
          type:
          - number
          - 'null'
          description: Null for unsellable dates.
        currency:
          type: string
        min_length_of_stay:
          type:
          - integer
          - 'null'
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    BookingCalendarResponse:
      type: object
      description: Response of `POST /v1/ota/booking`.
      required:
      - search_parameters
      - property
      - calendar
      - unavailable_dates
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - pagename
          - country
          - start_date
          - days
          - currency
          - adults
          - rooms
          properties:
            engine:
              type: string
              enum:
              - booking_calendar
            pagename:
              type: string
            country:
              type: string
            start_date:
              type: string
              format: date
            days:
              type: integer
            currency:
              type: string
            adults:
              type: integer
            rooms:
              type: integer
        property:
          type: object
          required:
          - pagename
          - hotel_id
          properties:
            pagename:
              type: string
            hotel_id:
              type:
              - integer
              - 'null'
              description: Booking.com's numeric hotel id as returned upstream.
        calendar:
          type: array
          items:
            $ref: '#/components/schemas/BookingCalendarNight'
        unavailable_dates:
          type: array
          items:
            type: string
            format: date
        meta:
          type: object
          required:
          - source
          - collection_id
          - observed_at
          - calls
          - wire_bytes
          - elapsed_s
          - dates
          - priced
          properties:
            source:
              type: string
              enum:
              - booking
            collection_id:
              type: string
            observed_at:
              type: string
            calls:
              type: integer
            wire_bytes:
              type: integer
            elapsed_s:
              type: number
            dates:
              type: integer
            priced:
              type: integer
    BookingRoomRatePlan:
      type: object
      required:
      - block_id
      - price
      - currency
      - guests
      - free_cancellation
      - no_prepayment
      - breakfast_included
      - provenance
      properties:
        block_id:
          type: string
        price:
          type:
          - number
          - 'null'
        currency:
          type: string
        guests:
          type:
          - integer
          - 'null'
        free_cancellation:
          type: boolean
        no_prepayment:
          type: boolean
        breakfast_included:
          type: boolean
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    BookingRoomsResponse:
      type: object
      description: Response of `POST /v1/ota/booking/rooms`.
      required:
      - pagename
      - hotel_id
      - property_name
      - check_in
      - check_out
      - nights
      - currency
      - sold_out
      - rendered
      - catalogue_from_graphql
      - cheapest_rate
      - wire_bytes
      - collection_id
      - observed_at
      - rooms
      properties:
        pagename:
          type: string
        hotel_id:
          type: string
          description: Empty string when the room catalogue was unavailable.
        property_name:
          type: string
        check_in:
          type: string
          format: date
        check_out:
          type: string
          format: date
        nights:
          type: integer
        currency:
          type: string
        sold_out:
          type:
          - boolean
          - 'null'
        rendered:
          type: boolean
        catalogue_from_graphql:
          type: boolean
          description: Whether room size / occupancy enrichment was available.
        cheapest_rate:
          type:
          - number
          - 'null'
        wire_bytes:
          type: integer
        collection_id:
          type: string
        observed_at:
          type: string
        rooms:
          type: array
          items:
            type: object
            required:
            - name
            - room_id
            - beds
            - room_size
            - max_persons
            - cheapest_rate
            - rate_plans
            properties:
              name:
                type: string
              room_id:
                type: string
              beds:
                type: string
              room_size:
                type:
                - number
                - 'null'
              max_persons:
                type:
                - integer
                - 'null'
              cheapest_rate:
                type:
                - number
                - 'null'
              rate_plans:
                type: array
                items:
                  $ref: '#/components/schemas/BookingRoomRatePlan'
    HotelsPriceResponse:
      type: object
      description: Response of `POST /v1/ota/hotels`.
      required:
      - search_parameters
      - property
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - property_id
          - check_in_date
          - check_out_date
          - adults
          - market
          - currency
          properties:
            engine:
              type: string
              enum:
              - hotels_property
            property_id:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            market:
              type: string
            currency:
              type: string
              description: The market's currency.
        property:
          type: object
          required:
          - property_id
          - price_per_night
          - currency
          - currency_verified
          - available
          - provenance
          properties:
            property_id:
              type: string
            price_per_night:
              type:
              - number
              - 'null'
            currency:
              type: string
              description: Currency the point-of-sale actually priced in.
            currency_verified:
              type: boolean
            available:
              type: boolean
            provenance:
              $ref: '#/components/schemas/RateProvenance'
        meta:
          type: object
          required:
          - source
          - collection_id
          - observed_at
          - nights
          - elapsed_s
          - comparable_across_markets
          properties:
            source:
              type: string
              enum:
              - hotels
            collection_id:
              type: string
            observed_at:
              type: string
            nights:
              type: integer
            elapsed_s:
              type: number
            comparable_across_markets:
              type: boolean
              description: Always false.
    HotelsRoomRatePlan:
      type: object
      required:
      - plan_id
      - price
      - price_text
      - currency
      - refundable
      - refundable_until
      - pay_now
      - provenance
      properties:
        plan_id:
          type: string
        price:
          type:
          - number
          - 'null'
        price_text:
          type: string
        currency:
          type: string
        refundable:
          type:
          - boolean
          - 'null'
          description: 'Tri-state: null means the source stated nothing, which is not the same as non-refundable.'
        refundable_until:
          type: string
        pay_now:
          type: boolean
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    HotelsRoomsResponse:
      type: object
      description: Response of `POST /v1/ota/hotels/rooms`.
      required:
      - property_id
      - market
      - check_in
      - check_out
      - nights
      - currency
      - sold_out
      - cheapest_rate
      - wire_bytes
      - collection_id
      - observed_at
      - rooms
      properties:
        property_id:
          type: string
        market:
          type: string
        check_in:
          type: string
          format: date
        check_out:
          type: string
          format: date
        nights:
          type: integer
        currency:
          type: string
        sold_out:
          type: boolean
        cheapest_rate:
          type:
          - number
          - 'null'
        wire_bytes:
          type: integer
        collection_id:
          type: string
        observed_at:
          type: string
        rooms:
          type: array
          items:
            type: object
            required:
            - name
            - unit_id
            - cheapest_rate
            - rate_plans
            properties:
              name:
                type: string
              unit_id:
                type: string
              cheapest_rate:
                type:
                - number
                - 'null'
              rate_plans:
                type: array
                items:
                  $ref: '#/components/schemas/HotelsRoomRatePlan'
    AgodaOffer:
      type: object
      required:
      - price
      - currency
      - currency_code
      - price_text
      - tax_inclusive
      - discount
      - free_cancellation
      - provenance
      properties:
        price:
          type:
          - number
          - 'null'
        currency:
          type: string
          description: Agoda's display token (may be a symbol such as `€`).
        currency_code:
          type: string
          description: ISO 4217 code.
        price_text:
          type: string
        tax_inclusive:
          type:
          - boolean
          - 'null'
        discount:
          type:
          - string
          - 'null'
          description: e.g. `-29%`
        free_cancellation:
          type: boolean
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    AgodaRoomsResponse:
      type: object
      description: Response of `POST /v1/ota/agoda`.
      required:
      - search_parameters
      - property
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - property_id
          - check_in_date
          - check_out_date
          - adults
          - rooms
          - currency
          properties:
            engine:
              type: string
              enum:
              - agoda_property
            property_id:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            rooms:
              type: integer
            currency:
              type: string
        property:
          type: object
          required:
          - property_id
          - name
          - price_per_night
          - currency
          - currency_display
          - tax_inclusive
          - sold_out
          - provenance
          - rooms
          properties:
            property_id:
              type: string
            name:
              type: string
            price_per_night:
              type:
              - number
              - 'null'
              description: Cheapest priced offer.
            currency:
              type: string
              description: ISO code of the cheapest offer (the requested currency when nothing priced).
            currency_display:
              type:
              - string
              - 'null'
            tax_inclusive:
              type:
              - boolean
              - 'null'
            sold_out:
              type: boolean
            provenance:
              anyOf:
              - $ref: '#/components/schemas/RateProvenance'
              - type: 'null'
              description: Provenance of the cheapest priced row; null when nothing priced.
            rooms:
              type: array
              items:
                type: object
                required:
                - name
                - offers
                properties:
                  name:
                    type: string
                  offers:
                    type: array
                    items:
                      $ref: '#/components/schemas/AgodaOffer'
        meta:
          type: object
          required:
          - source
          - collection_id
          - observed_at
          - nights
          - wire_bytes
          - elapsed_s
          - room_types
          - offers
          - comparable_across_markets
          properties:
            source:
              type: string
              enum:
              - agoda
            collection_id:
              type: string
            observed_at:
              type: string
            nights:
              type: integer
            wire_bytes:
              type: integer
            elapsed_s:
              type: number
            room_types:
              type: integer
            offers:
              type: integer
            comparable_across_markets:
              type: boolean
              description: Always true.
    TripadvisorOffer:
      type: object
      required:
      - provider
      - provider_name
      - location_id
      - check_in
      - check_out
      - price
      - price_value
      - currency
      - price_currency
      - room_plan
      - offer_type
      - provenance
      properties:
        provider:
          type: string
        provider_name:
          type: string
          description: Same value as `provider`.
        location_id:
          type: string
        check_in:
          type: string
          format: date
        check_out:
          type: string
          format: date
        price:
          type: number
        price_value:
          type: number
          description: Same value as `price`.
        currency:
          type: string
        price_currency:
          type: string
          description: Same value as `currency`.
        room_plan:
          type: string
          enum:
          - ''
          - CP
          - EP
          - MAP
          - AP
        offer_type:
          type: string
          enum:
          - chevron
          - hidden
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    TripadvisorPricesResponse:
      type: object
      description: Response of `POST /v1/ota/tripadvisor`.
      required:
      - search_parameters
      - property
      - offers
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - location_id
          - check_in_date
          - check_out_date
          - nights
          - adults
          - rooms
          - currency
          properties:
            engine:
              type: string
              enum:
              - tripadvisor_property
            location_id:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            nights:
              type: integer
            adults:
              type: integer
            rooms:
              type: integer
            currency:
              type: string
        property:
          type: object
          required:
          - location_id
          - hotel_id
          - price_per_night
          - currency
          - provenance
          properties:
            location_id:
              type: string
            hotel_id:
              type: string
            price_per_night:
              type:
              - number
              - 'null'
              description: Cheapest provider offer.
            currency:
              type: string
              description: The requested currency.
            provenance:
              anyOf:
              - $ref: '#/components/schemas/RateProvenance'
              - type: 'null'
              description: Provenance of the cheapest priced row; null when nothing priced.
        offers:
          type: array
          items:
            $ref: '#/components/schemas/TripadvisorOffer'
        meta:
          type: object
          required:
          - source
          - collection_id
          - observed_at
          - nights
          - wire_bytes
          - elapsed_s
          - offers
          properties:
            source:
              type: string
              enum:
              - tripadvisor
            collection_id:
              type: string
            observed_at:
              type: string
            nights:
              type: integer
            wire_bytes:
              type: integer
              description: Estimated.
            elapsed_s:
              type: number
            offers:
              type: integer
    HostelworldRatePlan:
      type: object
      required:
      - rate_plan_id
      - rate_plan_type
      - payment_procedure
      - payment_label
      - is_default
      - price
      - original_price
      - currency
      - min_nights
      - restrictions
      - promotions
      - provenance
      properties:
        rate_plan_id:
          type: integer
        rate_plan_type:
          type: string
        payment_procedure:
          type: string
        payment_label:
          type: string
        is_default:
          type: boolean
        price:
          type:
          - number
          - 'null'
        original_price:
          type:
          - number
          - 'null'
        currency:
          type: string
        min_nights:
          type:
          - integer
          - 'null'
        restrictions:
          type: array
          items:
            type: string
        promotions:
          anyOf:
          - type: object
            required:
            - discount
            - promotion_ids
            properties:
              discount:
                type: string
                description: e.g. `20.00`
              promotion_ids:
                type: array
                items: {}
          - type: 'null'
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    HostelworldRoom:
      type: object
      required:
      - room_id
      - name
      - room_type
      - basic_type
      - capacity
      - ensuite
      - description
      - label_description
      - beds_available
      - rooms_available
      - available
      - rate_plans
      properties:
        room_id:
          type: integer
        name:
          type: string
        room_type:
          type: string
          enum:
          - dorm
          - private
        basic_type:
          type: string
        capacity:
          type: integer
        ensuite:
          type: boolean
        description:
          type: string
        label_description:
          type: string
        beds_available:
          type:
          - integer
          - 'null'
        rooms_available:
          type:
          - integer
          - 'null'
        available:
          type: boolean
        rate_plans:
          type: array
          items:
            $ref: '#/components/schemas/HostelworldRatePlan'
    HostelworldResponse:
      type: object
      description: Response of `POST /v1/ota/hostelworld`.
      required:
      - search_parameters
      - property
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - property_id
          - check_in_date
          - check_out_date
          - guests
          properties:
            engine:
              type: string
              enum:
              - hostelworld_property
            property_id:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            guests:
              type: integer
        property:
          type: object
          required:
          - property_id
          - price_per_night
          - currency
          - sold_out
          - deposit_percentage
          - free_cancellation_available
          - vat
          - provenance
          - rooms
          properties:
            property_id:
              type: string
            price_per_night:
              type:
              - number
              - 'null'
            currency:
              type: string
              description: The property's native currency.
            sold_out:
              type: boolean
            deposit_percentage:
              type:
              - number
              - 'null'
            free_cancellation_available:
              type: boolean
            vat:
              type: number
            provenance:
              anyOf:
              - $ref: '#/components/schemas/RateProvenance'
              - type: 'null'
              description: Provenance of the cheapest priced row; null when nothing priced.
            rooms:
              type: array
              items:
                $ref: '#/components/schemas/HostelworldRoom'
        meta:
          type: object
          required:
          - source
          - collection_id
          - observed_at
          - nights
          - wire_bytes
          - elapsed_s
          - dorms_count
          - privates_count
          - total_rate_plans
          - comparable_across_markets
          - notes
          properties:
            source:
              type: string
              enum:
              - hostelworld
            collection_id:
              type: string
            observed_at:
              type: string
            nights:
              type: integer
            wire_bytes:
              type: integer
            elapsed_s:
              type: number
            dorms_count:
              type: integer
            privates_count:
              type: integer
            total_rate_plans:
              type: integer
            comparable_across_markets:
              type: boolean
              description: Always false.
            notes:
              type: string
    CompareResponse:
      type: object
      description: Response of `POST /v1/ota/compare`.
      required:
      - search_parameters
      - comparison
      - sources
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - check_in_date
          - check_out_date
          - adults
          - currency
          properties:
            engine:
              type: string
              enum:
              - ota_compare
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            currency:
              type: string
              description: Requested currency; used by Booking.com and Agoda. Hotels.com and Expedia price in their market's currency.
            booking_pagename:
              type: string
              description: Present only when supplied.
            hotels_property_id:
              type: string
              description: Present only when supplied.
            agoda_property_id:
              type: string
              description: Present only when supplied.
            expedia_property_id:
              type: string
              description: Present only when supplied.
        comparison:
          type: object
          required:
          - status
          - comparable
          - reason
          - identifiers
          - lowest_price
          - lowest_source
          - spread
          - prices
          - currencies
          - price_basis_consistent
          - by_price_basis
          - price_provenance
          properties:
            status:
              type: string
              enum:
              - no_prices
              - single_source
              - mixed_currency
              - comparable
            comparable:
              type: boolean
              description: True when at least two sources priced in one currency.
            reason:
              type:
              - string
              - 'null'
              description: Why the prices are not (fully) comparable. Null only when `status` is `comparable` and every price shares one basis; when bases differ it says the headline minimum mixes them.
            identifiers:
              type: object
              description: Echo of the identifiers used, keyed `booking` / `hotels` / `agoda` / `expedia` (supplied ones only).
              additionalProperties:
                type: string
            lowest_price:
              type:
              - number
              - 'null'
              description: Null when nothing priced or currencies are mixed. May span different price bases; see `price_basis_consistent`.
            lowest_source:
              type:
              - string
              - 'null'
            spread:
              type:
              - number
              - 'null'
              description: Highest minus lowest price per night; non-null only when `comparable` is true.
            prices:
              type: object
              description: Source -> price per night (priced sources only).
              additionalProperties:
                type: number
            currencies:
              type: object
              description: Source -> upper-case currency code (priced sources only).
              additionalProperties:
                type: string
            price_basis_consistent:
              type: boolean
              description: True when every priced source shares one price basis (also true when at most one priced).
            by_price_basis:
              type: object
              description: Priced sources grouped by price basis (keys as in `sources.<name>.price_basis`), so like is compared with like. Empty when nothing priced.
              additionalProperties:
                type: object
                required:
                - sources
                - currencies
                - lowest_source
                - lowest_price_per_night
                properties:
                  sources:
                    type: array
                    items:
                      type: string
                  currencies:
                    type: array
                    items:
                      type: string
                  lowest_source:
                    type:
                    - string
                    - 'null'
                    description: Null when the group mixes currencies.
                  lowest_price_per_night:
                    type:
                    - number
                    - 'null'
                    description: Null when the group mixes currencies.
            price_provenance:
              type: object
              description: Source -> provenance of the compared price (priced sources only).
              additionalProperties:
                $ref: '#/components/schemas/RateProvenance'
        sources:
          type: object
          description: 'One entry per requested source (`booking`, `hotels`, `agoda`, `expedia`). Fail-soft: a failed source is an entry with `status: error`, not a failed request.'
          additionalProperties:
            anyOf:
            - type: object
              required:
              - status
              - price_per_night
              - currency
              - price_basis
              - payload
              properties:
                status:
                  type: string
                  enum:
                  - ok
                price_per_night:
                  type: number
                  description: 'Expedia: its headline stay total divided by nights (its nightly figure is before taxes).'
                currency:
                  type: string
                price_basis:
                  type: string
                  description: 'Basis of `price_per_night`. Expedia: `total_including_taxes_and_fees`, `total_fees_included` or `stay_total_per_night`, from its own labels; other sources: `provenance.price_basis` of the compared price; `unknown` when not stated.'
                payload:
                  description: The full response of that source's endpoint (Expedia's is the headline-only form, with empty `rooms`).
                  anyOf:
                  - $ref: '#/components/schemas/BookingCalendarResponse'
                  - $ref: '#/components/schemas/HotelsPriceResponse'
                  - $ref: '#/components/schemas/AgodaRoomsResponse'
                  - $ref: '#/components/schemas/ExpediaRatesResponse'
            - type: object
              required:
              - status
              - price_per_night
              - currency
              - payload
              properties:
                status:
                  type: string
                  description: The source answered but returned no price (sold out or unpriced).
                  enum:
                  - no_price
                price_per_night:
                  type: 'null'
                currency:
                  type: string
                payload:
                  description: The full response of that source's endpoint.
                  anyOf:
                  - $ref: '#/components/schemas/BookingCalendarResponse'
                  - $ref: '#/components/schemas/HotelsPriceResponse'
                  - $ref: '#/components/schemas/AgodaRoomsResponse'
                  - $ref: '#/components/schemas/ExpediaRatesResponse'
            - type: object
              required:
              - status
              - error
              properties:
                status:
                  type: string
                  enum:
                  - error
                error:
                  type: string
                  description: '`ExceptionName: message`.'
        meta:
          type: object
          required:
          - requested
          - ok
          - elapsed_s
          properties:
            requested:
              type: integer
            ok:
              type: integer
              description: Sources that returned a price.
            elapsed_s:
              type: number
    OtaSourceCapability:
      type: object
      required:
      - engine
      - primary_operation
      - identifier
      - granularity
      - multi_date
      - max_dates_per_call
      - per_room
      - currency_selectable
      - needs_browser_token
      - operations
      - notes
      - available
      properties:
        engine:
          type: string
        primary_operation:
          type: string
        identifier:
          type: string
        granularity:
          type: string
        multi_date:
          type: boolean
        max_dates_per_call:
          type: integer
        per_room:
          type: boolean
        currency_selectable:
          type: boolean
        needs_browser_token:
          type: boolean
        operations:
          type: object
          required:
          - search
          - rates
          - rooms
          - calendar
          properties:
            search:
              type: object
              required:
              - supported
              - needs_browser_token
              - available
              properties:
                supported:
                  type: boolean
                needs_browser_token:
                  type: boolean
                available:
                  type: boolean
                unavailable_reason:
                  type: string
                  description: Present only when `available` is false.
            rates:
              type: object
              required:
              - supported
              - needs_browser_token
              - available
              properties:
                supported:
                  type: boolean
                needs_browser_token:
                  type: boolean
                available:
                  type: boolean
                unavailable_reason:
                  type: string
                  description: Present only when `available` is false.
            rooms:
              type: object
              required:
              - supported
              - needs_browser_token
              - available
              properties:
                supported:
                  type: boolean
                needs_browser_token:
                  type: boolean
                available:
                  type: boolean
                unavailable_reason:
                  type: string
                  description: Present only when `available` is false.
            calendar:
              type: object
              required:
              - supported
              - needs_browser_token
              - available
              properties:
                supported:
                  type: boolean
                needs_browser_token:
                  type: boolean
                available:
                  type: boolean
                unavailable_reason:
                  type: string
                  description: Present only when `available` is false.
        notes:
          type: string
        available:
          type: boolean
        unavailable_reason:
          type: string
          description: Present only when `available` is false.
        currency_mechanism:
          type: string
          description: '`point-of-sale`: currency follows the market. Hotels.com, Expedia and Vrbo only.'
        markets:
          type: array
          items:
            type: string
          description: Supported point-of-sale codes. Hotels.com, Expedia and Vrbo only.
        currencies:
          type: array
          items:
            type: string
          description: Selectable currencies. Agoda, Tripadvisor and Hostelworld only (empty for Hostelworld).
    OtaSourcesResponse:
      type: object
      required:
      - sources
      properties:
        sources:
          type: object
          required:
          - booking
          - hotels
          - agoda
          - tripadvisor
          - hostelworld
          - expedia
          - vrbo
          properties:
            booking:
              $ref: '#/components/schemas/OtaSourceCapability'
            hotels:
              $ref: '#/components/schemas/OtaSourceCapability'
            agoda:
              $ref: '#/components/schemas/OtaSourceCapability'
            tripadvisor:
              $ref: '#/components/schemas/OtaSourceCapability'
            hostelworld:
              $ref: '#/components/schemas/OtaSourceCapability'
            expedia:
              $ref: '#/components/schemas/OtaSourceCapability'
            vrbo:
              $ref: '#/components/schemas/OtaSourceCapability'
    OfficialEnginesResponse:
      type: object
      description: Response of `GET /v1/official/engines`.
      required:
      - extractable
      - identified_only
      - retired
      properties:
        extractable:
          type: object
          description: Booking engines rates can be extracted from, keyed by engine id (31 today).
          additionalProperties:
            type: object
            required:
            - cost_s
            - browser
            properties:
              cost_s:
                type: number
                description: Typical seconds per query.
              browser:
                type:
                - string
                - 'null'
                description: 'When a headless browser is needed: `every query`, `once per session`, `once per token (hours)`, or null when never.'
        identified_only:
          type: array
          items:
            type: string
          description: Engines that are detected but not yet extractable.
        retired:
          type: array
          items:
            type: string
          description: Historical engines with no live booking flow.
    OfficialRate:
      type: object
      required:
      - price
      - price_total
      - reference_price
      - tax
      - fees
      - original_price
      - currency
      - rate_plan
      - tax_inclusive
      - access_type
      - loyalty_points
      - loyalty_cash
      - is_discounted
      - provenance
      properties:
        price:
          type:
          - number
          - 'null'
          description: Headline price for the stay on the engine's own basis.
        price_total:
          type:
          - number
          - 'null'
        reference_price:
          type:
          - number
          - 'null'
        tax:
          type:
          - number
          - 'null'
        fees:
          type:
          - number
          - 'null'
        original_price:
          type:
          - number
          - 'null'
        currency:
          type: string
        rate_plan:
          type: string
        tax_inclusive:
          type:
          - boolean
          - 'null'
          description: Null means the engine did not state a basis, not that tax is excluded.
        access_type:
          type: string
          description: '`public`, `member`, `points_and_cash` or `points`.'
        loyalty_points:
          type:
          - integer
          - 'null'
        loyalty_cash:
          type:
          - number
          - 'null'
        is_discounted:
          type: boolean
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    OfficialRoom:
      type: object
      required:
      - name
      - code
      - max_occupancy
      - quantity
      - available
      - cheapest_rate
      - rates
      properties:
        name:
          type: string
        code:
          type: string
        max_occupancy:
          type:
          - integer
          - 'null'
        quantity:
          type:
          - integer
          - 'null'
        available:
          type: boolean
        cheapest_rate:
          type:
          - number
          - 'null'
          description: Cheapest PUBLIC rate in `rates`.
        rates:
          type: array
          items:
            $ref: '#/components/schemas/OfficialRate'
    OfficialResponse:
      type: object
      description: Response of `POST /v1/official`.
      required:
      - search_parameters
      - engine
      - source_url
      - booking_url
      - detected_by
      - discovery_pages
      - wrapper_resolutions
      - discovery_cache_hit
      - discovery_elapsed_s
      - collection_id
      - observed_at
      - property_ref
      - check_in
      - check_out
      - nights
      - currency
      - sold_out
      - cheapest_rate
      - cheapest_member_rate
      - member_rates_returned
      - rooms_returned
      - used_browser
      - elapsed_s
      - rooms
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - source_url
          - booking_url
          - check_in_date
          - check_out_date
          - adults
          - currency
          properties:
            engine:
              type: string
              description: '`official_` + engine id.'
            source_url:
              type: string
            booking_url:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            currency:
              type: string
        engine:
          type: string
          description: Detected engine id.
        source_url:
          type: string
        booking_url:
          type: string
        detected_by:
          type: string
          description: How the engine was detected, e.g. `url`, `redirect`, `booking_link`, `html_fingerprint`.
        discovery_pages:
          type: integer
        wrapper_resolutions:
          type: integer
        discovery_cache_hit:
          type: boolean
        discovery_elapsed_s:
          type: number
        collection_id:
          type: string
        observed_at:
          type: string
        property_ref:
          type: string
          description: Engine-native property id (may be empty).
        check_in:
          type: string
          format: date
        check_out:
          type: string
          format: date
        nights:
          type: integer
        currency:
          type: string
        sold_out:
          type: boolean
        cheapest_rate:
          type:
          - number
          - 'null'
          description: Cheapest public rate across available rooms.
        cheapest_member_rate:
          type:
          - number
          - 'null'
        member_rates_returned:
          type: integer
        rooms_returned:
          type: integer
        used_browser:
          type: boolean
        elapsed_s:
          type: number
        rooms:
          type: array
          items:
            $ref: '#/components/schemas/OfficialRoom'
    AirbnbPrice:
      type: object
      required:
      - total_price
      - extracted_total_price
      - provenance
      properties:
        total_price:
          type: string
          description: As displayed.
        extracted_total_price:
          type:
          - number
          - 'null'
        qualifier:
          type: string
          description: e.g. `for 2 nights`
        extracted_qualifier:
          type: integer
        price_per_qualifier:
          type: string
        extracted_price_per_qualifier:
          type:
          - number
          - 'null'
        original_price:
          type: string
        extracted_original_price:
          type: number
        discount:
          type: string
        extracted_discount:
          type: number
        breakdown:
          type: array
          items:
            type: object
            required:
            - description
            - price
            - extracted_price
            properties:
              description:
                type: string
              price:
                type: string
              extracted_price:
                type:
                - number
                - 'null'
        total_with_taxes:
          type: string
          description: Only with `include_taxes` and a tax line.
        extracted_total_with_taxes:
          type:
          - number
          - 'null'
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    AirbnbProperty:
      type: object
      description: One listing. Keys whose value would be null are omitted.
      required:
      - position
      - id
      - link
      - booking_link
      - booking_token
      properties:
        position:
          type: integer
        id:
          type: string
        title:
          type: string
        description:
          type: string
        link:
          type: string
        booking_link:
          type: string
        booking_token:
          type: string
        rating:
          type: number
        reviews:
          type: integer
        price:
          $ref: '#/components/schemas/AirbnbPrice'
        check_in_date:
          type: string
        check_out_date:
          type: string
        time_period:
          type: string
        accommodations:
          type: array
          items:
            type: string
        gps_coordinates:
          type: object
          required:
          - latitude
          - longitude
          properties:
            latitude:
              type: number
            longitude:
              type: number
        has_free_cancellation:
          type: boolean
          description: Only present (as true) when advertised.
        badges:
          type: array
          items:
            type: string
        images:
          type: array
          items:
            type: string
        distance:
          type: string
        extracted_distance:
          type: number
    AirbnbSearchResponse:
      type: object
      description: SearchAPI-compatible Airbnb search response.
      required:
      - search_metadata
      - search_parameters
      - search_information
      - properties
      properties:
        search_metadata:
          type: object
          required:
          - id
          - status
          - created_at
          - collection_id
          - observed_at
          - request_time_taken
          - parsing_time_taken
          - total_time_taken
          - request_url
          - wire_bytes
          properties:
            id:
              type: string
            status:
              type: string
            created_at:
              type: string
            collection_id:
              type: string
            observed_at:
              type: string
            request_time_taken:
              type: number
            parsing_time_taken:
              type: number
            total_time_taken:
              type: number
            request_url:
              type: string
            wire_bytes:
              type: integer
        search_parameters:
          type: object
          required:
          - engine
          - airbnb_domain
          description: Echo of the effective request. Every value is a string; parameters that were not set are omitted.
          properties:
            engine:
              type: string
              enum:
              - airbnb
            airbnb_domain:
              type: string
          additionalProperties:
            type: string
        search_information:
          type: object
          required:
          - query_displayed
          - results
          - guests
          properties:
            query_displayed:
              type: string
            results:
              type: string
            check_in_date:
              type: string
            check_out_date:
              type: string
            time_period:
              type: string
            adults:
              type: integer
            children:
              type: integer
            infants:
              type: integer
            pets:
              type: integer
            guests:
              type: string
              description: e.g. `2 guests` or `Add guests`.
        properties:
          type: array
          items:
            $ref: '#/components/schemas/AirbnbProperty'
        pagination:
          type: object
          description: Present only when another page exists.
          required:
          - next_page_token
          properties:
            next_page_token:
              type: string
    SerpMoney:
      type: object
      required:
      - extracted_price_before_taxes
      - currency
      properties:
        price:
          type: string
          description: Display string, e.g. `$2,907`. Omitted when unknown.
        extracted_price:
          type: number
          description: Omitted when unknown.
        extracted_price_before_taxes:
          type:
          - number
          - 'null'
        currency:
          type: string
    SerpOfferRoom:
      type: object
      required:
      - name
      - link
      - num_guests
      - price_per_night
      - total_price
      - is_suite
      - beds
      - free_cancellation_until
      - thumbnail
      - provenance
      properties:
        name:
          type: string
        link:
          type:
          - string
          - 'null'
        num_guests:
          type: integer
        price_per_night:
          $ref: '#/components/schemas/SerpMoney'
        total_price:
          $ref: '#/components/schemas/SerpMoney'
        is_suite:
          type: boolean
        beds:
          type:
          - integer
          - 'null'
        free_cancellation_until:
          type:
          - string
          - 'null'
        thumbnail:
          type:
          - string
          - 'null'
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    SerpOffer:
      type: object
      required:
      - source
      - raw_source
      - is_official
      - num_guests
      - room_id
      - price_per_night
      - total_price
      - tax_basis
      - is_outlier
      - rooms
      - is_featured
      - has_free_cancellation
      - free_cancellation_until
      - free_cancellation_time
      - price_derived_from_room
      - headline_price_total
      - headline_price_before_taxes
      - provenance
      properties:
        source:
          type: string
          description: Seller label (official offers use the hotel's rendered name).
        raw_source:
          type: string
        is_official:
          type: boolean
        num_guests:
          type: integer
        room_id:
          type:
          - string
          - 'null'
        price_per_night:
          $ref: '#/components/schemas/SerpMoney'
        total_price:
          $ref: '#/components/schemas/SerpMoney'
        tax_basis:
          type: string
          enum:
          - deeplink
          - derived
          - unknown
        is_outlier:
          type: boolean
        rooms:
          type: array
          items:
            $ref: '#/components/schemas/SerpOfferRoom'
        is_featured:
          type: boolean
        has_free_cancellation:
          type: boolean
        free_cancellation_until:
          type:
          - string
          - 'null'
        free_cancellation_time:
          type:
          - string
          - 'null'
        price_derived_from_room:
          type: boolean
        headline_price_total:
          type:
          - number
          - 'null'
        headline_price_before_taxes:
          type:
          - number
          - 'null'
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    SerpPropertyResponse:
      type: object
      description: SearchAPI-compatible `google_hotels_property` response.
      required:
      - search_parameters
      - property
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - property_token
          - check_in_date
          - check_out_date
          - adults
          - currency
          - gl
          - nights
          properties:
            engine:
              type: string
              enum:
              - google_hotels_property
            property_token:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            currency:
              type: string
            gl:
              type: string
            nights:
              type: integer
            sources:
              type: array
              items:
                type: string
              description: Present only when `sources` was requested.
            source_coverage:
              type: string
              description: Present only when `sources` was requested.
        property:
          type: object
          required:
          - property_token
          - name
          - hotel_class
          - hotel_class_stars
          - rating
          - reviews
          - deal
          - deal_description
          - has_deal
          - price_insights
          - all_offers
          - featured_offers
          - price_per_night
          - provenance
          - currency_verified
          - requested_market
          - egress_market
          - egress_geo_locked_ok
          - price_insights_market_verified
          - tax_profile
          properties:
            property_token:
              type: string
            name:
              type: string
            hotel_class:
              type: string
            hotel_class_stars:
              type:
              - integer
              - 'null'
            rating:
              type:
              - number
              - 'null'
            reviews:
              type:
              - integer
              - 'null'
            deal:
              type:
              - string
              - 'null'
            deal_description:
              type:
              - string
              - 'null'
            has_deal:
              type: boolean
            price_insights:
              $ref: '#/components/schemas/PriceInsights'
            all_offers:
              type: array
              items:
                $ref: '#/components/schemas/SerpOffer'
            featured_offers:
              type: array
              items:
                $ref: '#/components/schemas/SerpOffer'
              description: Offers Google rendered as featured cards.
            price_per_night:
              anyOf:
              - type: object
                required:
                - price
                - extracted_price
                properties:
                  price:
                    type: string
                  extracted_price:
                    type: number
              - type: 'null'
              description: Lowest all-in nightly price across offers.
            provenance:
              anyOf:
              - $ref: '#/components/schemas/RateProvenance'
              - type: 'null'
              description: Provenance of the lowest-priced offer.
            currency_verified:
              type: boolean
            requested_market:
              type: string
            egress_market:
              type:
              - string
              - 'null'
            egress_geo_locked_ok:
              type: boolean
            price_insights_market_verified:
              type: boolean
            tax_profile:
              anyOf:
              - type: object
                required:
                - rate
                - confidence
                properties:
                  rate:
                    type: number
                  confidence:
                    type: string
                    enum:
                    - high
                    - low
                    - none
              - type: 'null'
        meta:
          type: object
          required:
          - wire_bytes
          - elapsed_s
          - offers
          - priced
          - property_fetch
          - tax_profile_cache
          properties:
            wire_bytes:
              type: integer
            elapsed_s:
              type: number
            offers:
              type: integer
            priced:
              type: integer
            property_fetch:
              type: string
            tax_profile_cache:
              type: string
    SerpCalendarDay:
      type: object
      required:
      - date
      - price
      - extracted_price_before_taxes
      - extracted_price_base
      - extracted_price_total
      - tax
      - fees
      - currency
      - rates_include_tax
      - provenance
      properties:
        date:
          type: string
          format: date
        price:
          type: object
          description: The market-correct nightly figure (same as `rate` on `/v1/calendar`).
          required:
          - price
          - extracted_price
          properties:
            price:
              type: string
            extracted_price:
              type: number
        extracted_price_before_taxes:
          type:
          - number
          - 'null'
          description: Base + mandatory fees (SearchAPI basis).
        extracted_price_base:
          type:
          - number
          - 'null'
        extracted_price_total:
          type:
          - number
          - 'null'
        tax:
          type:
          - number
          - 'null'
        fees:
          type:
          - number
          - 'null'
        currency:
          type: string
        rates_include_tax:
          type: boolean
        provenance:
          $ref: '#/components/schemas/CalendarRateProvenance'
    SerpCalendarResponse:
      type: object
      description: Response of `POST /v1/serp/google_hotels_calendar`.
      required:
      - search_parameters
      - calendar
      - unavailable_dates
      - tax_profile
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - property_token
          - days
          - adults
          - currency
          - gl
          - los
          properties:
            engine:
              type: string
              enum:
              - google_hotels_calendar
            property_token:
              type: string
            days:
              type: integer
            adults:
              type: integer
            currency:
              type: string
            gl:
              type: string
            los:
              type: integer
        calendar:
          type: array
          items:
            $ref: '#/components/schemas/SerpCalendarDay'
          description: One row per priced night.
        unavailable_dates:
          type: array
          items:
            type: string
            format: date
        tax_profile:
          anyOf:
          - type: object
            required:
            - rate
            - confidence
            properties:
              rate:
                type: number
              confidence:
                type: string
                enum:
                - high
                - low
                - none
          - type: 'null'
        meta:
          type: object
          required:
          - coverage
          - collection_id
          - observed_at
          - wire_bytes
          - elapsed_s
          - retries
          properties:
            coverage:
              type: number
              description: Share of requested nights priced, 0-1.
            collection_id:
              type: string
            observed_at:
              type: string
            wire_bytes:
              type: integer
            elapsed_s:
              type: number
            retries:
              type: integer
    FlightSegment:
      type: object
      description: 'One flight: a single takeoff and landing.'
      required:
      - departure_airport
      - arrival_airport
      - departure_time
      - arrival_time
      - airline
      - airline_code
      - flight_number
      - duration_minutes
      - aircraft
      - cabin_class
      - departure_airport_name
      - arrival_airport_name
      - operated_by
      - ticket_also_sold_by
      - legroom
      - legroom_category
      - overnight
      - red_eye
      - often_delayed_by_over_30_min
      - carbon_emissions_kg
      - extensions
      - airline_logo
      properties:
        departure_airport:
          type: string
          description: IATA code.
        arrival_airport:
          type: string
          description: IATA code.
        departure_time:
          type:
          - string
          - 'null'
          description: Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. `2026-11-04T18:10:00`. Null when unknown.
        arrival_time:
          type:
          - string
          - 'null'
          description: Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. `2026-11-04T18:10:00`. Null when unknown.
        airline:
          type: string
          description: Marketing airline name (empty string when Google gives none).
        airline_code:
          type:
          - string
          - 'null'
          description: IATA code of the marketing airline.
        flight_number:
          type:
          - string
          - 'null'
          description: Marketing carrier and number, e.g. `AC 874`.
        duration_minutes:
          type:
          - integer
          - 'null'
          description: Flight time, minutes.
        aircraft:
          type:
          - string
          - 'null'
          description: e.g. `Airbus A330`.
        cabin_class:
          type:
          - string
          - 'null'
          enum:
          - economy
          - premium_economy
          - business
          - first
          - null
        departure_airport_name:
          type:
          - string
          - 'null'
        arrival_airport_name:
          type:
          - string
          - 'null'
        operated_by:
          type:
          - string
          - 'null'
          description: The airline actually flying it when Google names one other than the marketing carrier, e.g. `Endeavor Air DBA Delta Connection`.
        ticket_also_sold_by:
          type: array
          items:
            type: string
          description: Codeshare flight numbers the same flight is also sold under, e.g. `LH 6809`.
        legroom:
          type:
          - string
          - 'null'
          description: Seat pitch as Google shows it, e.g. `31 in`.
        legroom_category:
          type:
          - string
          - 'null'
          enum:
          - average
          - below_average
          - above_average
          - null
        overnight:
          type: boolean
          description: Lands on a later calendar day than it departs (local times).
        red_eye:
          type: boolean
          description: 'Heuristic: departs 20:00-02:59 and lands 04:00-10:59 after the night (local times). `overnight` is exact; this is not.'
        often_delayed_by_over_30_min:
          type: boolean
          description: Google's flag that this flight is often delayed by more than 30 minutes.
        carbon_emissions_kg:
          type:
          - integer
          - 'null'
          description: CO2e estimate for this flight, kilograms (rounded).
        extensions:
          type: array
          items:
            type: string
          description: 'Google''s amenity lines, e.g. `Average legroom (31 in)`, `Free Wi-Fi`, `Wi-Fi for a fee`, `In-seat power & USB outlets`, `Live TV`, `On-demand video`, `Stream media to your device`, `Carbon emissions estimate: 325 kg`.'
        airline_logo:
          type:
          - string
          - 'null'
          description: Logo URL of the marketing airline.
    FlightLeg:
      type: object
      description: One direction of travel, possibly with connections.
      required:
      - segments
      - departure_airport
      - arrival_airport
      - duration_minutes
      - stops
      - layover_airports
      - is_direct
      - layovers
      - airlines
      properties:
        segments:
          type: array
          items:
            $ref: '#/components/schemas/FlightSegment'
          description: Flights in order.
        departure_airport:
          type: string
          description: IATA code.
        arrival_airport:
          type: string
          description: IATA code.
        departure_time:
          type: string
          description: Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. `2026-11-04T18:10:00`. Present only when known.
        arrival_time:
          type: string
          description: Airport-local wall-clock time as Google shows it, ISO 8601 without a UTC offset, e.g. `2026-11-04T18:10:00`. Present only when known.
        duration_minutes:
          type:
          - integer
          - 'null'
          description: Door-to-door travel time including layovers, minutes.
        stops:
          type: integer
        layover_airports:
          type: array
          items:
            type: string
          description: IATA codes of the connection airports.
        is_direct:
          type: boolean
          description: '`stops` is 0.'
        layovers:
          type: array
          items:
            $ref: '#/components/schemas/FlightLayover'
        airlines:
          type: array
          items:
            type: string
          description: Airline names Google lists for this leg.
    FlightItinerary:
      type: object
      description: One option for the leg being chosen. A one-way option is the whole trip; on a round trip or multi-city trip each option is priced for the whole trip and carries `departure_token` (more legs to choose) or `booking_token` (last leg).
      required:
      - legs
      - price
      - currency
      - display_price
      - booking_token
      - booking_url
      - carbon_emissions_kg
      - carbon_emissions_comparison
      - trip_type
      - total_stops
      - is_direct
      - departure_token
      - google_flights_url
      - group
      - price_exact
      - price_token
      - priced_in
      - carbon_emissions
      - total_duration_minutes
      - carry_on_bags_included
      - checked_bags_included
      - airline_logo
      properties:
        legs:
          type: array
          items:
            $ref: '#/components/schemas/FlightLeg'
          description: The leg chosen in this call (one entry). Earlier legs are not repeated; `/v1/serp/google_flights_booking` returns every leg.
        price:
          type:
          - number
          - 'null'
          description: Google's displayed whole amount for the whole trip (every leg, all passengers), in `currency`. Google rounds up (527 where the exact fare is 526.19; see `price_exact`). When `priced_in` is set, the amount is in that currency instead.
        currency:
          type: string
          description: The requested currency.
        display_price:
          type:
          - string
          - 'null'
          description: '`price` with its currency symbol, e.g. `$527`. Null when `price` is null or `priced_in` is set.'
        booking_token:
          type:
          - string
          - 'null'
          description: 'Pass to `POST /v1/serp/google_flights_booking` for sellers, prices and booking links. Set only on complete itineraries (one-way options, and the options of a trip''s last leg); null when `departure_token` is set. Compatibility: until 2026-09-30 this field held Google''s raw price token on every itinerary; that value is now `price_token`.'
        booking_url:
          type:
          - string
          - 'null'
          description: Google Flights booking page for the complete itinerary. Set together with `booking_token`.
        carbon_emissions_kg:
          type:
          - integer
          - 'null'
          description: CO2e estimate for this itinerary, kilograms (rounded). `carbon_emissions` has the same figure in grams.
        carbon_emissions_comparison:
          type:
          - string
          - 'null'
          description: e.g. `19% lower than typical` or `typical for this route`.
        trip_type:
          type: string
          description: '`one_way`, `round_trip` or `multi_city`.'
          enum:
          - one_way
          - round_trip
          - multi_city
        total_stops:
          type: integer
          description: Stops across `legs`.
        is_direct:
          type: boolean
          description: '`total_stops` is 0.'
        departure_token:
          type:
          - string
          - 'null'
          description: 'Pass to `POST /v1/serp/google_flights_return` for the next leg''s options after choosing this one. Set while legs remain to choose (round-trip outbound, multi-city legs before the last); null when `booking_token` is set. Self-contained: nothing else is needed with it.'
        google_flights_url:
          type:
          - string
          - 'null'
          description: 'Google Flights page for this option: the search page with the earlier legs chosen, or the booking page once every leg is chosen.'
        group:
          type: string
          description: '`best` (Google''s top flights) or `other`. Every option is `other` when `sort_by` is not `top_flights`.'
          enum:
          - best
          - other
        price_exact:
          type:
          - number
          - 'null'
          description: Price with minor units, from Google's price token (526.19 where `price` is 527). Null when the token has no amount or is in another currency.
        price_token:
          type:
          - string
          - 'null'
          description: Google's own opaque price token for this option, on every itinerary (returned as `booking_token` until 2026-09-30). Usable as an itinerary key; no endpoint takes it.
        priced_in:
          type:
          - string
          - 'null'
          description: 'Set only when Google priced this option in another currency than requested: that ISO 4217 code. `price` is then in this currency and `warnings` says so.'
        carbon_emissions:
          anyOf:
          - $ref: '#/components/schemas/FlightCarbonEmissions'
          - type: 'null'
          description: Null when Google gives no estimate.
        total_duration_minutes:
          type:
          - integer
          - 'null'
          description: Sum of the legs' door-to-door durations, minutes; null when one is unknown.
        carry_on_bags_included:
          type:
          - integer
          - 'null'
          description: Carry-on bags included in the fare, as Google states it; null when not stated.
        checked_bags_included:
          type:
          - integer
          - 'null'
          description: Checked bags included in the fare, as Google states it; null when not stated.
        airline_logo:
          type:
          - string
          - 'null'
          description: Logo URL of the main airline; null when several airlines share the itinerary.
    FlightsSearchResponse:
      type: object
      description: Response of `POST /v1/serp/google_flights`.
      required:
      - departure_airport
      - arrival_airport
      - departure_date
      - currency
      - adults
      - itineraries
      - wire_bytes
      - elapsed_s
      - cheapest_price
      - trip_type
      - leg_index
      - legs_total
      - itinerary_count
      - best_count
      - airlines_available
      - google_flights_url
      - source
      - warnings
      properties:
        departure_airport:
          type: string
          description: Echo of the request's `departure`.
        arrival_airport:
          type: string
          description: Echo of the request's `arrival`.
        departure_date:
          type: string
          description: Date of the leg these options are for.
          format: date
        return_date:
          type: string
          description: Present only for round trips.
          format: date
        currency:
          type: string
          description: The requested currency.
        adults:
          type: integer
        itineraries:
          type: array
          items:
            $ref: '#/components/schemas/FlightItinerary'
          description: 'Options for the leg being chosen: Google''s best flights first, then the others.'
        wire_bytes:
          type: integer
          description: Size of Google's response, bytes.
        elapsed_s:
          type: number
          description: Time Google took to answer, seconds.
        cheapest_price:
          type:
          - number
          - 'null'
          description: Lowest `price` in `itineraries`; null when none is priced.
        trip_type:
          type: string
          description: '`one_way`, `round_trip` or `multi_city`.'
          enum:
          - one_way
          - round_trip
          - multi_city
        leg_index:
          type: integer
          description: 'Which leg these options are for: 0 = first (outbound), 1 = return or second multi-city leg, and so on.'
        legs_total:
          type: integer
          description: 'Legs in the trip: 1 one-way, 2 round trip, 2-5 multi-city.'
        itinerary_count:
          type: integer
          description: Number of entries in `itineraries`.
        best_count:
          type: integer
          description: 'How many `itineraries` have `group: best`.'
        price_insights:
          anyOf:
          - $ref: '#/components/schemas/FlightPriceInsights'
          - type: 'null'
          description: Null when Google gives none (some filtered searches). Omitted when `itineraries` is empty; that answer is not billed.
        airlines_available:
          type: array
          items:
            type: object
            required:
            - code
            - name
            - type
            properties:
              code:
                type: string
                description: IATA airline code, or `STAR_ALLIANCE` / `SKYTEAM` / `ONEWORLD`.
              name:
                type:
                - string
                - 'null'
              type:
                type: string
                enum:
                - alliance
                - airline
          description: Airlines and alliances Google offers as filters for this search; the codes work in `include_airlines`.
        google_flights_url:
          type: string
          description: Google Flights search page for this trip.
        source:
          type: string
          description: '`rpc` normally; `html` when the results came from Google''s server-rendered page fallback, which holds only Google''s first screen of results (about 8-10 itineraries).'
          enum:
          - rpc
          - html
        warnings:
          type: array
          items:
            type: string
          description: Notices about this answer, e.g. that Google priced some options in another currency (see each itinerary's `priced_in`). Empty when none.
    FlightsCalendarPrice:
      type: object
      required:
      - departure_date
      - price
      - currency
      - display_price
      - is_priced
      properties:
        departure_date:
          type: string
          format: date
        return_date:
          type: string
          description: Present only for round trips.
          format: date
        price:
          type:
          - number
          - 'null'
          description: Cheapest fare Google shows for this date combination (whole trip), in `currency`; null when unpriced.
        currency:
          type: string
        display_price:
          type:
          - string
          - 'null'
          description: '`price` with its currency symbol, e.g. `$245`.'
        is_priced:
          type: boolean
          description: '`price` is not null.'
    FlightsCalendarResponse:
      type: object
      description: Response of `POST /v1/serp/google_flights_calendar`.
      required:
      - departure_airport
      - arrival_airport
      - currency
      - adults
      - trip_type
      - prices
      - wire_bytes
      - elapsed_s
      - cheapest_price
      - coverage
      properties:
        departure_airport:
          type: string
          description: Echo of the request's `departure`.
        arrival_airport:
          type: string
          description: Echo of the request's `arrival`.
        currency:
          type: string
        adults:
          type: integer
        trip_type:
          type: string
          enum:
          - one_way
          - round_trip
        prices:
          type: array
          items:
            $ref: '#/components/schemas/FlightsCalendarPrice'
          description: One row per date combination in the window.
        wire_bytes:
          type:
          - integer
          - 'null'
          description: Size of Google's response, bytes; null when the grid was assembled from several searches.
        elapsed_s:
          type: number
          description: Seconds.
        cheapest_price:
          type:
          - number
          - 'null'
          description: Lowest `price` in `prices`.
        coverage:
          type: string
          description: '`priced/total`, e.g. `14/15` (a string here).'
    AirbnbCalendarPriceStatus:
      type: string
      description: 'Why a date is or isn''t priced. `priced`: quoted; see `price`. `not_sampled`: a valid check-in that `sample` mode didn''t pick. `quote_cap_reached`: a valid check-in past `max_price_quotes` in `all` mode. `not_requested`: a valid check-in while pricing is off (seen only in summary counts with `price_nights: none`). `unavailable`: the night is booked or blocked. `past`: before today (UTC). `check_in_not_allowed`: Airbnb doesn''t allow arrival on this date. `check_out_not_allowed`: the stay''s departure day doesn''t allow check-out. `stay_blocked`: a later night of the stay is unavailable. `stay_exceeds_max_nights`: the stay is longer than the date''s `max_nights`. `quote_refused`: the calendar allowed the stay but Airbnb''s quote refused it. `no_price`: the quote came back without a nightly price line. `quote_failed`: the quote request failed; the rest of the calendar is still returned. `quote_skipped`: the quote was never sent (time budget ran out, or three quotes in a row failed) and isn''t charged.'
      enum:
      - priced
      - not_sampled
      - quote_cap_reached
      - not_requested
      - unavailable
      - past
      - check_in_not_allowed
      - check_out_not_allowed
      - stay_blocked
      - stay_exceeds_max_nights
      - quote_refused
      - no_price
      - quote_failed
      - quote_skipped
    AirbnbCalendarSummary:
      type: object
      description: Counts over the returned days, and the spread of quoted nightly prices.
      required:
      - days
      - available
      - available_for_checkin
      - bookable
      - priced
      - price_status
      properties:
        days:
          type: integer
          description: Days returned.
        available:
          type: integer
          description: Days whose night is open.
        available_for_checkin:
          type: integer
          description: Days Airbnb allows arriving on.
        bookable:
          type: integer
          description: Days Airbnb marks bookable.
        priced:
          type: integer
          description: Days with a quoted price (each is charged 1 credit).
        min_price_per_night:
          type: number
          description: Lowest `price_per_night` among priced days. Present only when at least one day was priced.
        max_price_per_night:
          type: number
          description: Highest `price_per_night` among priced days. Present only when at least one day was priced.
        median_price_per_night:
          type: number
          description: Median `price_per_night` among priced days, 2 decimals. Present only when at least one day was priced.
        price_status:
          type: object
          description: Number of days per `price_status` value, keys sorted; only statuses that occur are present.
          properties:
            priced:
              type: integer
            not_sampled:
              type: integer
            quote_cap_reached:
              type: integer
            not_requested:
              type: integer
            unavailable:
              type: integer
            past:
              type: integer
            check_in_not_allowed:
              type: integer
            check_out_not_allowed:
              type: integer
            stay_blocked:
              type: integer
            stay_exceeds_max_nights:
              type: integer
            quote_refused:
              type: integer
            no_price:
              type: integer
            quote_failed:
              type: integer
            quote_skipped:
              type: integer
    AirbnbCalendarPriceLine:
      type: object
      description: One line of Airbnb's price breakdown.
      required:
      - description
      - price
      - kind
      properties:
        description:
          type: string
          description: Line label as Airbnb shows it, e.g. `2 nights x $178.00 CAD`, `Long stay discount`, `Taxes`, `Total`.
        price:
          type: string
          description: Amount as displayed, e.g. `$356.00 CAD`.
        extracted_price:
          type: number
          description: Signed amount (discounts are negative). Omitted when the amount can't be read.
        kind:
          type: string
          description: Line type.
          enum:
          - nights
          - discount
          - fee
          - tax
          - total
          - other
    AirbnbCalendarPrice:
      type: object
      description: Airbnb's quote for one stay checking in on this date, as the listing page's booking sidebar shows it.
      required:
      - price_per_night
      - check_in
      - check_out
      - nights
      - price_per_night_text
      - price_basis
      - breakdown
      - provenance
      properties:
        price_per_night:
          type: number
          description: 'Airbnb''s own nightly figure for the quoted stay (the `N nights x $X` line): all-in, with cleaning and service fees folded in, before taxes. It depends on the stay length, so read it with `check_in`, `check_out` and `nights`.'
        currency:
          type: string
          description: Currency Airbnb priced the quote in (ISO 4217). Omitted when it can't be read from the price text.
        check_in:
          type: string
          description: Check-in of the quoted stay (this date).
          format: date
        check_out:
          type: string
          description: Check-out of the quoted stay.
          format: date
        nights:
          type: integer
          description: 'Nights in the quoted stay: `stay_nights`, or the date''s minimum stay when that is longer or `stay_nights` was omitted.'
        accommodation:
          type: number
          description: Exact subtotal of the nightly line (`nights` x nightly rate). Omitted when the amount can't be read.
        discount:
          type: number
          description: Total discount as a positive amount (e.g. a long-stay discount). Present only when the quote has a discount line.
        fees:
          type: number
          description: Sum of separately listed fee lines. Present only when Airbnb itemizes fees; `price_basis` is then `nightly_before_listed_fees_and_taxes`.
        taxes:
          type: number
          description: Sum of tax lines. Present only when Airbnb itemizes taxes.
        total:
          type: number
          description: Stay total including taxes, from the quote's Total line. Present only when the quote has one.
        price_per_night_text:
          type: string
          description: Nightly figure as displayed, e.g. `$178.00 CAD`.
        total_text:
          type: string
          description: Total line as displayed. Present only when the quote has one.
        display_total:
          type: string
          description: Headline price Airbnb shows for the stay, rounded as displayed (e.g. `$424 CAD`). Present only when shown.
        price_basis:
          type: string
          description: 'What `price_per_night` includes. `nightly_all_in_before_taxes`: fees folded in, taxes separate. `nightly_before_listed_fees_and_taxes`: the quote itemized a fee line, so those fees are in `fees`, not in the nightly figure.'
          enum:
          - nightly_all_in_before_taxes
          - nightly_before_listed_fees_and_taxes
        display_style:
          type: string
          description: Airbnb's price display style for the quote, e.g. `REGULATED_TOTAL`. Present only when Airbnb returns one.
        breakdown:
          type: array
          items:
            $ref: '#/components/schemas/AirbnbCalendarPriceLine'
          description: Airbnb's price lines in display order.
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    AirbnbCalendarDay:
      type: object
      description: One calendar date with Airbnb's rules and, when priced, the quoted stay.
      required:
      - date
      - available
      - available_for_checkin
      - available_for_checkout
      - bookable
      properties:
        date:
          type: string
          description: Calendar date; the night starts on this date.
          format: date
        available:
          type: boolean
          description: The night is open (not booked or blocked).
        available_for_checkin:
          type: boolean
          description: Airbnb allows arriving on this date.
        available_for_checkout:
          type: boolean
          description: Airbnb allows departing on this date.
        bookable:
          type: boolean
          description: Airbnb's bookable flag for this date.
        min_nights:
          type: integer
          description: Minimum stay for a check-in on this date. Present only when Airbnb reports it.
        max_nights:
          type: integer
          description: Maximum stay for a check-in on this date. Present only when Airbnb reports it.
        closed_to_arrival:
          type: boolean
          description: Arrival restriction for this date. Present only when Airbnb returns arrival/departure rules for it.
        closed_to_departure:
          type: boolean
          description: Departure restriction for this date. Present only when Airbnb returns arrival/departure rules for it.
        price_status:
          allOf:
          - $ref: '#/components/schemas/AirbnbCalendarPriceStatus'
          description: Present unless `price_nights` is `none`.
        price_error:
          type: string
          description: Reason behind `quote_refused` (Airbnb's message), `no_price`, `quote_failed` or `quote_skipped` (`deadline_exceeded` or `stopped_after_failures`). Present only when there is one.
        price:
          allOf:
          - $ref: '#/components/schemas/AirbnbCalendarPrice'
          description: Present only when `price_status` is `priced`.
    AirbnbCalendarListing:
      type: object
      description: 'Listing facts gathered along the way: `constant_min_nights` from the calendar, capacity and guest policy from the price quotes, and the rest from one extra request with `include_listing: true`. Unknown keys are omitted.'
      properties:
        constant_min_nights:
          type: integer
          description: Minimum stay that applies to every date, when Airbnb reports one.
        max_guests:
          type: integer
          description: Guest capacity.
        pets_allowed:
          type: boolean
        children_allowed:
          type: boolean
        infants_allowed:
          type: boolean
        guest_policy:
          type: string
          description: Airbnb's guest-policy sentence, e.g. `This place has a maximum of 2 guests, not including infants.`
        title:
          type: string
          description: Listing title. Only with `include_listing`.
        property_type:
          type: string
          description: Airbnb property type, e.g. `PRIVATE_SUITE`. Only with `include_listing`.
        room_type:
          type: string
          description: Airbnb space type, e.g. `ENTIRE_HOME`. Only with `include_listing`.
        location:
          type: string
          description: Displayed location, e.g. `Toronto`. Only with `include_listing`.
        overview:
          type: array
          items:
            type: string
          description: Summary items, e.g. `Entire guest suite`, `1 bed`, `1 bath`. Only with `include_listing`.
        rating:
          type: number
          description: Average rating. Only with `include_listing`.
        reviews:
          type: integer
          description: Review count. Only with `include_listing`.
        is_guest_favorite:
          type: boolean
          description: Only with `include_listing`.
        is_luxe:
          type: boolean
          description: Only with `include_listing`.
        gps_coordinates:
          type: object
          description: Only with `include_listing`.
          required:
          - latitude
          - longitude
          properties:
            latitude:
              type: number
            longitude:
              type: number
    AirbnbCalendarMetadata:
      type: object
      required:
      - collection_id
      - observed_at
      - calendar_operation
      - upstream_requests
      - price_quotes
      - wire_bytes
      - request_time_taken
      - parsing_time_taken
      - total_time_taken
      - egress
      properties:
        collection_id:
          type: string
          description: Shared by every price in this response (`ratecol_...`).
        observed_at:
          type: string
          description: UTC observation time, ISO-8601.
        calendar_operation:
          type: string
          description: Upstream operation used.
        upstream_requests:
          type: integer
          description: Upstream requests made, including retried attempts.
        price_quotes:
          type: integer
          description: Stays planned for quoting (skipped quotes included).
        wire_bytes:
          type: integer
          description: Bytes received from upstream, compressed.
        request_time_taken:
          type: number
          description: Seconds spent in upstream requests, summed. Quotes run in parallel, so this can exceed `total_time_taken`.
        parsing_time_taken:
          type: number
          description: Seconds spent parsing the calendar.
        total_time_taken:
          type: number
          description: End-to-end seconds for this request.
        egress:
          type: array
          items:
            type: string
            enum:
            - direct
            - proxy
          description: 'How upstream requests were routed: `direct`, `proxy`, or both.'
    AirbnbCalendarResponse:
      type: object
      description: Response of `POST /v1/airbnb/calendar`.
      required:
      - listing_id
      - link
      - airbnb_domain
      - guests
      - start_month
      - start_year
      - months
      - price_nights
      - max_price_quotes
      - summary
      - days
      - metadata
      properties:
        listing_id:
          type: string
          description: Airbnb listing id.
        link:
          type: string
          description: Listing URL on `airbnb_domain`.
        airbnb_domain:
          type: string
        currency:
          type: string
          description: 'Currency of the quoted prices: the one Airbnb priced in, else the requested `currency`. Omitted when neither is known (no `currency` sent and no day priced).'
        requested_currency:
          type: string
          description: Present only when `currency` was sent.
        guests:
          type: object
          description: Party the quotes were priced for.
          required:
          - adults
          - children
          - infants
          - pets
          properties:
            adults:
              type: integer
            children:
              type: integer
            infants:
              type: integer
            pets:
              type: integer
        start_month:
          type: integer
          description: Effective first month (defaults to the current UTC month).
        start_year:
          type: integer
          description: Effective year of `start_month`.
        months:
          type: integer
        price_nights:
          type: string
          enum:
          - none
          - sample
          - all
        stay_nights:
          type: integer
          description: Present only when `stay_nights` was sent.
        max_price_quotes:
          type: integer
          description: 'Quote budget that applied: the requested `max_price_quotes` or the mode default (12 for `sample`, 92 for `all`), capped at 92 and at 31 x `months`; 0 with `price_nights: none`.'
        listing:
          allOf:
          - $ref: '#/components/schemas/AirbnbCalendarListing'
          description: Present only when at least one listing fact is known.
        summary:
          $ref: '#/components/schemas/AirbnbCalendarSummary'
        days:
          type: array
          items:
            $ref: '#/components/schemas/AirbnbCalendarDay'
          description: One row per date of the requested months, in date order.
        metadata:
          $ref: '#/components/schemas/AirbnbCalendarMetadata'
        warnings:
          type: array
          items:
            type: string
          description: 'Things worth checking: refused, failed or skipped quotes, a currency other than the one asked for, stays quoted longer than `stay_nights`, missing listing details. Present only when there is at least one.'
    AirbnbAvailabilityPrice:
      type: object
      description: Airbnb's quote for one stay checking in on this date, in SearchAPI's Airbnb search price vocabulary.
      required:
      - check_in_date
      - check_out_date
      - price_per_night
      - extracted_price_per_night
      - qualifier
      - extracted_qualifier
      - price_per_qualifier
      - extracted_price_per_qualifier
      - breakdown
      - provenance
      properties:
        check_in_date:
          type: string
          description: Check-in of the quoted stay (this date).
          format: date
        check_out_date:
          type: string
          description: Check-out of the quoted stay.
          format: date
        currency:
          type: string
          description: Currency Airbnb priced the quote in. Omitted when it can't be read from the price text.
        price_per_night:
          type: string
          description: 'Airbnb''s nightly figure for the quoted stay as displayed, e.g. `$178.00 CAD`: all-in, with cleaning and service fees folded in, before taxes.'
        extracted_price_per_night:
          type: number
          description: '`price_per_night` as a number.'
        total_price:
          type: string
          description: Headline price Airbnb shows for the stay, e.g. `$424 CAD`; falls back to the Total line. Omitted when neither exists.
        extracted_total_price:
          type: number
          description: '`total_price` as a number (rounded as displayed); falls back to `extracted_total_with_taxes`. Omitted when neither exists.'
        qualifier:
          type: string
          description: e.g. `for 2 nights`.
        extracted_qualifier:
          type: integer
          description: Nights in the quoted stay.
        price_per_qualifier:
          type: string
          description: Airbnb's nightly line, e.g. `2 nights x $178.00 CAD`.
        extracted_price_per_qualifier:
          type: number
          description: Nightly figure; same as `extracted_price_per_night`.
        total_with_taxes:
          type: string
          description: Total line as displayed, taxes included. Present only when the quote has one.
        extracted_total_with_taxes:
          type: number
          description: '`total_with_taxes` as a number. Present only when the quote has one.'
        breakdown:
          type: array
          items:
            type: object
            required:
            - description
            - price
            - extracted_price
            properties:
              description:
                type: string
              price:
                type: string
                description: As displayed.
              extracted_price:
                type:
                - number
                - 'null'
                description: Signed amount (discounts are negative); null when it can't be read.
          description: Airbnb's price lines in display order.
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    AirbnbAvailabilityDay:
      type: object
      description: One calendar date. SearchAPI's fields, plus `price_status` and `price` when prices were requested.
      required:
      - date
      - is_available
      - is_available_for_checkin
      - is_available_for_checkout
      - is_bookable
      properties:
        date:
          type: string
          description: Calendar date; the night starts on this date.
          format: date
        is_available:
          type: boolean
          description: The night is open (not booked or blocked).
        is_available_for_checkin:
          type: boolean
          description: Airbnb allows arriving on this date.
        is_available_for_checkout:
          type: boolean
          description: Airbnb allows departing on this date.
        is_bookable:
          type: boolean
        min_nights:
          type: integer
          description: Minimum stay for a check-in on this date. Present only when Airbnb reports it.
        max_nights:
          type: integer
          description: Maximum stay for a check-in on this date. Present only when Airbnb reports it.
        price_status:
          allOf:
          - $ref: '#/components/schemas/AirbnbCalendarPriceStatus'
          description: Present only when `price_nights` isn't `none`.
        price:
          allOf:
          - $ref: '#/components/schemas/AirbnbAvailabilityPrice'
          description: Present only when `price_status` is `priced`.
    AirbnbAvailabilityMonth:
      type: object
      required:
      - year
      - month
      - days
      properties:
        year:
          type: integer
        month:
          type: integer
          description: 1-12.
        days:
          type: array
          items:
            $ref: '#/components/schemas/AirbnbAvailabilityDay'
          description: In date order.
    AirbnbAvailabilityCalendarResponse:
      type: object
      description: Response of `POST /v1/serp/airbnb_property_availability_calendar`.
      required:
      - search_metadata
      - search_parameters
      - months
      properties:
        search_metadata:
          type: object
          required:
          - id
          - status
          - created_at
          - request_time_taken
          - parsing_time_taken
          - total_time_taken
          - request_url
          - collection_id
          - observed_at
          - wire_bytes
          - upstream_requests
          properties:
            id:
              type: string
            status:
              type: string
              enum:
              - Success
            created_at:
              type: string
              description: UTC, ISO-8601.
            request_time_taken:
              type: number
              description: Seconds spent in upstream requests, summed; can exceed `total_time_taken` because quotes run in parallel.
            parsing_time_taken:
              type: number
            total_time_taken:
              type: number
            request_url:
              type: string
              description: Listing URL.
            collection_id:
              type: string
              description: Shared by every price in this response (`ratecol_...`).
            observed_at:
              type: string
              description: UTC observation time, ISO-8601.
            wire_bytes:
              type: integer
              description: Bytes received from upstream, compressed.
            upstream_requests:
              type: integer
              description: 'Upstream requests made: 1 for the calendar plus one per quote attempt.'
        search_parameters:
          type: object
          description: Echo of the effective request.
          required:
          - engine
          - airbnb_domain
          - property_id
          - start_month
          - start_year
          - months
          properties:
            engine:
              type: string
              enum:
              - airbnb_property_availability_calendar
            airbnb_domain:
              type: string
            property_id:
              type: string
            start_month:
              type: integer
              description: Effective first month (defaults resolved).
            start_year:
              type: integer
            months:
              type: integer
            currency:
              type: string
              description: Present only when sent.
            adults:
              type: integer
              description: Present only when `price_nights` isn't `none`.
            children:
              type: integer
              description: Present only when non-zero and `price_nights` isn't `none`.
            infants:
              type: integer
              description: Present only when non-zero and `price_nights` isn't `none`.
            pets:
              type: integer
              description: Present only when non-zero and `price_nights` isn't `none`.
            price_nights:
              type: string
              description: Present only when not `none`.
              enum:
              - sample
              - all
            max_price_quotes:
              type: integer
              description: As sent. Present only when sent and `price_nights` isn't `none`.
            stay_nights:
              type: integer
              description: Present only when sent and `price_nights` isn't `none`.
        months:
          type: array
          items:
            $ref: '#/components/schemas/AirbnbAvailabilityMonth'
          description: One entry per requested month, in order.
        price_summary:
          allOf:
          - $ref: '#/components/schemas/AirbnbCalendarSummary'
          description: Present only when `price_nights` isn't `none`.
        warnings:
          type: array
          items:
            type: string
          description: 'Things worth checking: refused, failed or skipped quotes, a currency other than the one asked for, stays quoted longer than `stay_nights`. Present only when there is at least one.'
    ExpediaSearchMatch:
      type: object
      required:
      - property_id
      - name
      - city
      - address
      - country
      - url
      - rank
      - score
      - name_score
      - identity_score
      - match_score
      - confidence
      - winner_reason
      properties:
        property_id:
          type: string
          description: Numeric Expedia id (digits); pass as `property_id` to `POST /v1/ota/expedia` or as `expedia_property_id` to `POST /v1/ota/compare`. Matches the Hotels.com id only for newer properties.
        name:
          type: string
        city:
          type: string
        address:
          type: string
        country:
          type: string
        url:
          type: string
          description: Expedia property page, `https://<host>/h<property_id>.Hotel-Information`.
        rank:
          type: integer
        score:
          type: number
        name_score:
          type: number
        identity_score:
          type: number
        match_score:
          type: number
        confidence:
          type: string
          enum:
          - high
          - medium
          - low
        winner_reason:
          type: string
        city_score:
          type: number
          description: Present only when `city` was supplied.
        coordinates:
          type: object
          description: Present only when the source returned coordinates.
          required:
          - latitude
          - longitude
          properties:
            latitude:
              type: number
            longitude:
              type: number
    ExpediaSearchResponse:
      type: object
      description: Response of `POST /v1/ota/expedia/search`.
      required:
      - search_parameters
      - search_status
      - recommended_match
      - warnings
      - matches
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - name
          - city
          - market
          - limit
          properties:
            engine:
              type: string
              enum:
              - expedia_search
            name:
              type: string
            city:
              type: string
            market:
              type: string
              description: 'Point-of-sale searched: `US` (www.expedia.com) or `CA` (www.expedia.ca).'
            limit:
              type: integer
        search_status:
          type: string
          description: '`matched` only when the top candidate clears the identity threshold and margin.'
          enum:
          - matched
          - ambiguous
          - not_found
        recommended_match:
          anyOf:
          - $ref: '#/components/schemas/ExpediaSearchMatch'
          - type: 'null'
          description: Safe to store; null unless `search_status` is `matched`.
        warnings:
          type: array
          items:
            type: string
        matches:
          type: array
          items:
            $ref: '#/components/schemas/ExpediaSearchMatch'
          description: Candidates, best first, for manual review.
        meta:
          type: object
          required:
          - source
          - matches
          - selection_method
          - match_threshold
          - match_margin
          - wire_bytes
          - elapsed_s
          - egress_mode
          properties:
            source:
              type: string
              enum:
              - expedia
            matches:
              type: integer
            selection_method:
              type: string
            match_threshold:
              type: number
            match_margin:
              type: number
            wire_bytes:
              type: integer
            elapsed_s:
              type: number
            egress_mode:
              type: string
              description: 'How the request was routed: `direct` or `proxy`.'
              enum:
              - direct
              - proxy
    ExpediaOffer:
      type: object
      description: 'One bookable price: a rate plan under one payment model. `provenance.price_basis` is `stay_total_including_taxes_and_fees`, `stay_total_fees_included` or `stay_total`.'
      required:
      - plan_id
      - room_type_id
      - total
      - nightly
      - taxes_and_fees
      - currency
      - total_text
      - nightly_text
      - taxes_and_fees_included
      - fees_included
      - payment_model
      - hotel_collect
      - member_only
      - refundable
      - cancellation_text
      - extras
      - extras_text
      - strikeout_text
      - inventory_type
      - business_model
      - messages
      - provenance
      - taxes_and_fees_provenance
      properties:
        plan_id:
          type: string
          description: Expedia rate-plan id.
        room_type_id:
          type: string
        total:
          type:
          - number
          - 'null'
          description: Stay total for all nights, as the source states it; `taxes_and_fees_included` / `fees_included` repeat its label. Null when the plan carried no price.
        nightly:
          type:
          - number
          - 'null'
          description: Average nightly price before taxes and fees; Expedia rounds it to whole units.
        taxes_and_fees:
          type:
          - number
          - 'null'
          description: 'Derived, not read from the source: `total - nightly × nights`, set only when `taxes_and_fees_included` is true. Accurate to within `nights` currency units because `nightly` is rounded; taxes and fees are not itemised. See `taxes_and_fees_provenance`.'
        currency:
          type: string
          description: ISO 4217 code read back from the reply.
        total_text:
          type: string
          description: Total as displayed, e.g. `$635 total`.
        nightly_text:
          type: string
          description: Nightly price as displayed, e.g. `$509 nightly`.
        taxes_and_fees_included:
          type:
          - boolean
          - 'null'
          description: True when the source labels the total "Total with taxes and fees". Null means no such label was shown, not that taxes are excluded.
        fees_included:
          type:
          - boolean
          - 'null'
          description: True when the source labels the total "All fees included". Null means no such label was shown.
        payment_model:
          type: string
          description: '`PAY_NOW`, `PAY_LATER` or `PAY_LATER_WITH_DEPOSIT`; empty when not stated. A plan sold both ways is two offers.'
          enum:
          - PAY_NOW
          - PAY_LATER
          - PAY_LATER_WITH_DEPOSIT
          - ''
        hotel_collect:
          type:
          - boolean
          - 'null'
          description: True when the property collects payment; null when not stated.
        member_only:
          type: boolean
          description: True when booking the plan requires signing in as a member.
        refundable:
          type:
          - boolean
          - 'null'
          description: 'Tri-state, from the room card''s cancellation option: true = refundable / free cancellation, false = non-refundable, null = not stated (not the same as non-refundable).'
        cancellation_text:
          type: string
          description: Cancellation option as displayed, e.g. `Fully refundable before Nov 14`; for display only, use `refundable`. Empty when not stated.
        extras:
          type:
          - string
          - 'null'
          description: Add-on code, e.g. `breakfast`, `breakfast-for-two`; null for no extras or when not stated.
        extras_text:
          type: string
          description: Add-on as displayed, e.g. `No extras`; empty when not stated.
        strikeout_text:
          type: string
          description: Struck-through comparison price as displayed; empty when none.
        inventory_type:
          type: string
          description: Source inventory type, e.g. `MERCHANT`, `TRIPCOM`, `DIRECT_AGENCY`, `VRBO`; empty when not stated.
        business_model:
          type: string
          description: '`EXPEDIA_COLLECT` or `HOTEL_COLLECT`; empty when not stated.'
        messages:
          type: array
          items:
            type: string
          description: Highlighted plan messages, e.g. `Reserve now, pay deposit`; usually empty for hotel rooms.
        provenance:
          $ref: '#/components/schemas/RateProvenance'
        taxes_and_fees_provenance:
          anyOf:
          - $ref: '#/components/schemas/RateProvenance'
          - type: 'null'
          description: 'Provenance of `taxes_and_fees` (`price_basis: taxes_and_fees_combined`, `derivation: total_minus_nightly_times_nights`); null when `taxes_and_fees` is null.'
    ExpediaRoom:
      type: object
      required:
      - unit_id
      - name
      - cheapest_total
      - offers
      properties:
        unit_id:
          type: string
          description: Room type id. A vacation rental listed on Expedia is one room with `unit_id` = `property_id` and name `entire unit`.
        name:
          type: string
          description: Room name as displayed, e.g. `Room, 1 King Bed`.
        cheapest_total:
          type:
          - number
          - 'null'
          description: Lowest `total` among this room's offers; null when none priced.
        offers:
          type: array
          items:
            $ref: '#/components/schemas/ExpediaOffer'
    ExpediaRatesResponse:
      type: object
      description: Response of `POST /v1/ota/expedia`.
      required:
      - search_parameters
      - property
      - rooms
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - property_id
          - check_in_date
          - check_out_date
          - adults
          - market
          - currency
          - rooms
          properties:
            engine:
              type: string
              enum:
              - expedia_property
            property_id:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            market:
              type: string
              description: '`US` or `CA`.'
            currency:
              type: string
              description: The market's currency (`USD` for `US`, `CAD` for `CA`).
            rooms:
              type: boolean
              description: Whether room types and rate plans were requested.
        property:
          type: object
          required:
          - property_id
          - total
          - price_per_night
          - basis
          - total_text
          - nightly_text
          - taxes_and_fees_included
          - fees_included
          - currency
          - currency_verified
          - available
          - unavailable_reason
          - cheapest_total
          - provenance
          properties:
            property_id:
              type: string
            total:
              type:
              - number
              - 'null'
              description: Headline stay total for all nights; see `basis` and `taxes_and_fees_included`. Null when nothing priced.
            price_per_night:
              type:
              - number
              - 'null'
              description: Headline nightly price, before taxes and fees (Expedia rounds it to whole units).
            basis:
              type:
              - string
              - 'null'
              description: 'Where the headline comes from: `sticky_bar` (the page''s own headline price, read by its labels) or `cheapest_offer` (the cheapest priced offer). Null when nothing priced.'
              enum:
              - sticky_bar
              - cheapest_offer
              - null
            total_text:
              type: string
              description: Headline total as displayed; empty when not shown.
            nightly_text:
              type: string
              description: Headline nightly price as displayed; empty when not shown.
            taxes_and_fees_included:
              type:
              - boolean
              - 'null'
              description: True when the headline total is labelled "with taxes and fees"; null when no such label was shown.
            fees_included:
              type:
              - boolean
              - 'null'
              description: True when the headline total is labelled "All fees included"; null when no such label was shown.
            currency:
              type: string
              description: Currency the point-of-sale actually priced in.
            currency_verified:
              type: boolean
              description: Whether `currency` equals the market's currency.
            available:
              type: boolean
              description: False when nothing is bookable for this stay as asked.
            unavailable_reason:
              type:
              - string
              - 'null'
              description: Expedia's own message when it says why the stay cannot be booked, e.g. `This property requires you to stay at least 4 nights`. Null otherwise; `available` can be false with a null reason when nothing priced.
            cheapest_total:
              type:
              - number
              - 'null'
              description: Lowest offer `total` across `rooms`; null when `rooms` was false or no offer priced.
            provenance:
              $ref: '#/components/schemas/RateProvenance'
        rooms:
          type: array
          items:
            $ref: '#/components/schemas/ExpediaRoom'
          description: 'Every room type with its offers. Empty when the request set `rooms: false`.'
        meta:
          type: object
          required:
          - source
          - collection_id
          - observed_at
          - nights
          - wire_bytes
          - elapsed_s
          - egress_mode
          - room_types
          - offers
          - comparable_across_markets
          properties:
            source:
              type: string
              enum:
              - expedia
            collection_id:
              type: string
            observed_at:
              type: string
            nights:
              type: integer
            wire_bytes:
              type: integer
              description: Bytes received from the source.
            elapsed_s:
              type: number
            egress_mode:
              type: string
              description: 'How the request was routed: `direct` or `proxy`.'
              enum:
              - direct
              - proxy
            room_types:
              type: integer
              description: 0 when `rooms` was false.
            offers:
              type: integer
              description: Offers across all rooms; 0 when `rooms` was false.
            comparable_across_markets:
              type: boolean
              description: 'Always false: the display basis differs by market.'
    VrboListing:
      type: object
      required:
      - property_id
      - listing_id
      - name
      - summary
      - url
      - nightly
      - total
      - currency
      - nightly_text
      - total_text
      - fees_included
      - taxes_and_fees_included
      - rank
      - provenance
      properties:
        property_id:
          type: string
          description: Numeric Vrbo property id; pass as `property_id` to `POST /v1/ota/vrbo`.
        listing_id:
          type: string
          description: Id in the listing's Vrbo URL, e.g. `20218736ha`; empty when the card carried no listing link.
        name:
          type: string
        summary:
          type: string
          description: Card details joined with ` · `, e.g. `House · 4 bedrooms · 4 Queen Beds`.
        url:
          type: string
          description: '`https://www.vrbo.com/<listing_id>`; empty when `listing_id` is empty.'
        nightly:
          type:
          - number
          - 'null'
          description: Vrbo's nightly price, to the cent. Null when the card's price carried no recognised label.
        total:
          type:
          - number
          - 'null'
          description: Stay total for all nights; null when the card did not state one.
        currency:
          type: string
        nightly_text:
          type: string
          description: As displayed, e.g. `$462`.
        total_text:
          type: string
          description: As displayed, e.g. `$1,386 for 3 nights`.
        fees_included:
          type:
          - boolean
          - 'null'
          description: True when Vrbo labels the price "All fees included"; null when no such label was shown.
        taxes_and_fees_included:
          type:
          - boolean
          - 'null'
          description: True when labelled as including taxes and fees; null when no such label was shown.
        rank:
          type: integer
          description: 0-based position in Vrbo's recommended order.
        provenance:
          $ref: '#/components/schemas/RateProvenance'
    VrboSearchResponse:
      type: object
      description: Response of `POST /v1/ota/vrbo/search`.
      required:
      - search_parameters
      - summary
      - listings
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - destination
          - check_in_date
          - check_out_date
          - adults
          - market
          - currency
          - limit
          properties:
            engine:
              type: string
              enum:
              - vrbo_search
            destination:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            market:
              type: string
              description: '`US`.'
            currency:
              type: string
              description: The market's currency (`USD`).
            limit:
              type: integer
        summary:
          type: object
          required:
          - matched_properties
          - results_heading
          properties:
            matched_properties:
              type:
              - integer
              - 'null'
              description: Total listings Vrbo matched for the destination and dates.
            results_heading:
              type:
              - string
              - 'null'
              description: Vrbo's heading, e.g. `Search results showing 359 properties in ...`.
        listings:
          type: array
          items:
            $ref: '#/components/schemas/VrboListing'
          description: At most `limit` listings, in Vrbo's recommended order; sponsored placements are skipped.
        meta:
          type: object
          required:
          - source
          - listings
          - collection_id
          - observed_at
          - wire_bytes
          - elapsed_s
          - egress_mode
          properties:
            source:
              type: string
              enum:
              - vrbo
            listings:
              type: integer
            collection_id:
              type: string
            observed_at:
              type: string
            wire_bytes:
              type: integer
              description: Bytes received from the source.
            elapsed_s:
              type: number
            egress_mode:
              type: string
              description: 'How the request was routed: `direct` or `proxy`.'
              enum:
              - direct
              - proxy
    VrboOffer:
      type: object
      description: 'One bookable price for the rental: a rate plan under one payment model.'
      required:
      - plan_id
      - room_type_id
      - total
      - nightly
      - taxes_and_fees
      - currency
      - total_text
      - nightly_text
      - taxes_and_fees_included
      - fees_included
      - payment_model
      - hotel_collect
      - member_only
      - refundable
      - cancellation_text
      - extras
      - extras_text
      - strikeout_text
      - inventory_type
      - business_model
      - messages
      - provenance
      - taxes_and_fees_provenance
      properties:
        plan_id:
          type: string
          description: Vrbo rate-plan id.
        room_type_id:
          type: string
        total:
          type:
          - number
          - 'null'
          description: Stay total for all nights, Vrbo's own figure; `fees_included` repeats its "All fees included" label. Cleaning and service fees and taxes are not itemised.
        nightly:
          type:
          - number
          - 'null'
          description: Vrbo's nightly price.
        taxes_and_fees:
          type:
          - number
          - 'null'
          description: 'Derived, not read from the source: `total - nightly × nights`, set only when `taxes_and_fees_included` is true. Accurate to within `nights` currency units because `nightly` is rounded; taxes and fees are not itemised. See `taxes_and_fees_provenance`.'
        currency:
          type: string
          description: ISO 4217 code read back from the reply.
        total_text:
          type: string
          description: Total as displayed, e.g. `$635 total`.
        nightly_text:
          type: string
          description: Nightly price as displayed, e.g. `$509 nightly`.
        taxes_and_fees_included:
          type:
          - boolean
          - 'null'
          description: True when the source labels the total "Total with taxes and fees". Null means no such label was shown, not that taxes are excluded.
        fees_included:
          type:
          - boolean
          - 'null'
          description: True when the source labels the total "All fees included". Null means no such label was shown.
        payment_model:
          type: string
          description: '`PAY_NOW`, `PAY_LATER` or `PAY_LATER_WITH_DEPOSIT`; empty when not stated. A plan sold both ways is two offers.'
          enum:
          - PAY_NOW
          - PAY_LATER
          - PAY_LATER_WITH_DEPOSIT
          - ''
        hotel_collect:
          type:
          - boolean
          - 'null'
          description: True when the property collects payment; null when not stated.
        member_only:
          type: boolean
          description: True when booking the plan requires signing in as a member.
        refundable:
          type:
          - boolean
          - 'null'
          description: 'Always null on Vrbo: refundability is not read, rather than guessed.'
        cancellation_text:
          type: string
          description: Always empty on Vrbo.
        extras:
          type:
          - string
          - 'null'
          description: Always null on Vrbo.
        extras_text:
          type: string
          description: Always empty on Vrbo.
        strikeout_text:
          type: string
          description: Struck-through comparison price as displayed; empty when none.
        inventory_type:
          type: string
          description: Source inventory type, e.g. `MERCHANT`, `TRIPCOM`, `DIRECT_AGENCY`, `VRBO`; empty when not stated.
        business_model:
          type: string
          description: '`EXPEDIA_COLLECT` or `HOTEL_COLLECT`; empty when not stated.'
        messages:
          type: array
          items:
            type: string
          description: Vrbo's highlighted messages for the plan, e.g. `Reserve now, pay deposit`, `Your dates are available`.
        provenance:
          $ref: '#/components/schemas/RateProvenance'
        taxes_and_fees_provenance:
          anyOf:
          - $ref: '#/components/schemas/RateProvenance'
          - type: 'null'
          description: 'Provenance of `taxes_and_fees` (`price_basis: taxes_and_fees_combined`, `derivation: total_minus_nightly_times_nights`); null when `taxes_and_fees` is null.'
    VrboQuoteResponse:
      type: object
      description: Response of `POST /v1/ota/vrbo`.
      required:
      - search_parameters
      - property
      - offers
      - meta
      properties:
        search_parameters:
          type: object
          required:
          - engine
          - property_id
          - check_in_date
          - check_out_date
          - adults
          - market
          - currency
          properties:
            engine:
              type: string
              enum:
              - vrbo_property
            property_id:
              type: string
              description: The property id quoted (resolved from `listing_id` when only that was sent).
            listing_id:
              type: string
              description: Present only when `listing_id` was supplied.
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            market:
              type: string
              description: '`US`.'
            currency:
              type: string
              description: The market's currency (`USD`).
        property:
          type: object
          required:
          - property_id
          - listing_id
          - total
          - price_per_night
          - basis
          - total_text
          - nightly_text
          - taxes_and_fees_included
          - fees_included
          - currency
          - currency_verified
          - available
          - unavailable_reason
          - payment_model
          - provenance
          properties:
            property_id:
              type: string
              description: Numeric Vrbo property id; store it to skip listing resolution next time.
            listing_id:
              type:
              - string
              - 'null'
              description: The `listing_id` you sent, echoed; null when you sent only `property_id`. When both are sent, `property_id` is used and the two are not cross-checked.
            total:
              type:
              - number
              - 'null'
              description: Headline stay total for all nights (Vrbo's own figure); see `basis`. Null when nothing priced.
            price_per_night:
              type:
              - number
              - 'null'
              description: Headline nightly price.
            basis:
              type:
              - string
              - 'null'
              description: 'Where the headline comes from: `sticky_bar` (the page''s own headline price, read by its labels) or `cheapest_offer` (the cheapest priced offer). Null when nothing priced.'
              enum:
              - sticky_bar
              - cheapest_offer
              - null
            total_text:
              type: string
              description: Headline total as displayed; empty when not shown.
            nightly_text:
              type: string
              description: Headline nightly price as displayed; empty when not shown.
            taxes_and_fees_included:
              type:
              - boolean
              - 'null'
              description: True when the headline total is labelled "with taxes and fees"; null when no such label was shown.
            fees_included:
              type:
              - boolean
              - 'null'
              description: True when the headline total is labelled "All fees included"; null when no such label was shown.
            currency:
              type: string
              description: Currency the point-of-sale actually priced in.
            currency_verified:
              type: boolean
              description: Whether `currency` equals the market's currency.
            available:
              type: boolean
              description: False when Vrbo will not sell the stay as asked.
            unavailable_reason:
              type:
              - string
              - 'null'
              description: Vrbo's own message when the stay cannot be booked (minimum stay, dates taken). Null otherwise; `available` can be false with a null reason when nothing priced.
            payment_model:
              type:
              - string
              - 'null'
              description: '`payment_model` of the cheapest offer; null when nothing priced.'
              enum:
              - PAY_NOW
              - PAY_LATER
              - PAY_LATER_WITH_DEPOSIT
              - ''
              - null
            provenance:
              $ref: '#/components/schemas/RateProvenance'
        offers:
          type: array
          items:
            $ref: '#/components/schemas/VrboOffer'
          description: Every rate plan for the rental.
        meta:
          type: object
          required:
          - source
          - collection_id
          - observed_at
          - nights
          - wire_bytes
          - elapsed_s
          - egress_mode
          - listing_resolved
          properties:
            source:
              type: string
              enum:
              - vrbo
            collection_id:
              type: string
            observed_at:
              type: string
            nights:
              type: integer
            wire_bytes:
              type: integer
              description: Bytes received from the source, including the listing page when `listing_id` was resolved.
            elapsed_s:
              type: number
            egress_mode:
              type: string
              description: 'How the request was routed: `direct` or `proxy`.'
              enum:
              - direct
              - proxy
            listing_resolved:
              type: boolean
              description: True when `listing_id` was resolved to `property_id` in this call.
    FlightLayover:
      type: object
      description: A connection between two segments of a leg.
      required:
      - duration_minutes
      - airport
      - airport_name
      - city
      - departure_airport
      - change_of_airport
      - overnight
      properties:
        duration_minutes:
          type:
          - integer
          - 'null'
          description: Connection time, minutes.
        airport:
          type: string
          description: IATA code of the airport the traveller lands at.
        airport_name:
          type:
          - string
          - 'null'
        city:
          type:
          - string
          - 'null'
        departure_airport:
          type: string
          description: Airport the next flight leaves from; equals `airport` unless the connection changes airports.
        change_of_airport:
          type: boolean
          description: The next flight leaves from a different airport.
        overnight:
          type: boolean
          description: The next flight leaves on a later calendar day than the previous one lands.
    FlightCarbonEmissions:
      type: object
      description: Emissions in grams of CO2e (SerpApi's `carbon_emissions` shape).
      required:
      - this_flight
      - typical_for_this_route
      - difference_percent
      properties:
        this_flight:
          type: integer
          description: Estimate for this itinerary, grams of CO2e.
        typical_for_this_route:
          type:
          - integer
          - 'null'
          description: Typical estimate for this route, grams of CO2e.
        difference_percent:
          type:
          - integer
          - 'null'
          description: This itinerary vs typical, percent (negative = lower).
    FlightPriceInsights:
      type: object
      description: Google Flights price insights.
      required:
      - lowest_price
      - price_level
      - typical_price_range
      - price_history
      properties:
        lowest_price:
          type:
          - number
          - 'null'
          description: Lowest price Google shows for this search, in `currency`.
        price_level:
          type:
          - string
          - 'null'
          description: 'Google''s verdict on today''s price: `low` (below its typical range), `typical` (inside it) or `high` (above it).'
          enum:
          - low
          - typical
          - high
          - null
        typical_price_range:
          anyOf:
          - type: array
            items:
              type: number
            minItems: 2
            maxItems: 2
          - type: 'null'
          description: '`[low, high]`: Google''s typical price range for this trip.'
        price_history:
          type: array
          items:
            type: array
            items:
              type: number
            minItems: 2
            maxItems: 2
          description: '`[[unix_seconds, price], ...]`: Google''s price history for this trip, about 60 days. Empty when Google gives none.'
    FlightsReturnResponse:
      type: object
      description: Response of `POST /v1/serp/google_flights_return`. Same shape as the `/v1/serp/google_flights` response, for the leg after the one the `departure_token` chose. Options of the trip's last leg carry `booking_token`; earlier ones carry `departure_token`.
      required:
      - departure_airport
      - arrival_airport
      - departure_date
      - currency
      - adults
      - itineraries
      - wire_bytes
      - elapsed_s
      - cheapest_price
      - trip_type
      - leg_index
      - legs_total
      - itinerary_count
      - best_count
      - airlines_available
      - google_flights_url
      - source
      - warnings
      properties:
        departure_airport:
          type: string
          description: 'Origin of the leg these options are for: airport codes or Google city ids, comma-separated.'
        arrival_airport:
          type: string
          description: 'Destination of the leg these options are for: airport codes or Google city ids, comma-separated.'
        departure_date:
          type: string
          description: Date of the leg these options are for (the return date of a round trip).
          format: date
        return_date:
          type: string
          description: Present only for round trips (the same date as `departure_date`).
          format: date
        currency:
          type: string
          description: The requested currency.
        adults:
          type: integer
        itineraries:
          type: array
          items:
            $ref: '#/components/schemas/FlightItinerary'
          description: 'Options for the leg being chosen: Google''s best flights first, then the others.'
        wire_bytes:
          type: integer
          description: Size of Google's response, bytes.
        elapsed_s:
          type: number
          description: Time Google took to answer, seconds.
        cheapest_price:
          type:
          - number
          - 'null'
          description: Lowest `price` in `itineraries`; null when none is priced.
        trip_type:
          type: string
          description: '`one_way`, `round_trip` or `multi_city`.'
          enum:
          - one_way
          - round_trip
          - multi_city
        leg_index:
          type: integer
          description: 'Which leg these options are for: 1 = return or second multi-city leg, and so on.'
        legs_total:
          type: integer
          description: 'Legs in the trip: 1 one-way, 2 round trip, 2-5 multi-city.'
        itinerary_count:
          type: integer
          description: Number of entries in `itineraries`.
        best_count:
          type: integer
          description: 'How many `itineraries` have `group: best`.'
        price_insights:
          anyOf:
          - $ref: '#/components/schemas/FlightPriceInsights'
          - type: 'null'
          description: 'Usually null: Google rarely gives insights for a return or later leg. Omitted when `itineraries` is empty; that answer is not billed.'
        airlines_available:
          type: array
          items:
            type: object
            required:
            - code
            - name
            - type
            properties:
              code:
                type: string
                description: IATA airline code, or `STAR_ALLIANCE` / `SKYTEAM` / `ONEWORLD`.
              name:
                type:
                - string
                - 'null'
              type:
                type: string
                enum:
                - alliance
                - airline
          description: Airlines and alliances Google offers as filters for this search; the codes work in `include_airlines`.
        google_flights_url:
          type: string
          description: Google Flights search page for this trip.
        source:
          type: string
          description: Always `rpc` for this call.
          enum:
          - rpc
          - html
        warnings:
          type: array
          items:
            type: string
          description: Notices about this answer, e.g. that Google priced some options in another currency (see each itinerary's `priced_in`). Empty when none.
    FlightBookingOption:
      type: object
      description: One way to buy the itinerary (SerpApi's `booking_options`).
      required:
      - book_with
      - seller_code
      - is_airline
      - price
      - currency
      - display_price
      - local_prices
      - marketed_as
      - booking_request
      - booking_url
      - seller_domain
      - booking_phone
      - separate_tickets
      - sellers
      - option_title
      - extensions
      - baggage_prices
      properties:
        book_with:
          type: string
          description: Seller name; several sellers are joined with ` and ` when the option is separate tickets.
        seller_code:
          type:
          - string
          - 'null'
          description: 'Google''s code for the (first) seller: the IATA code for an airline, e.g. `LX`.'
        is_airline:
          type: boolean
          description: Every seller is an airline (airline direct).
        price:
          type:
          - number
          - 'null'
          description: This seller's price for the whole trip, in `currency`, as Google shows it.
        currency:
          type: string
          description: Currency of the original search.
        display_price:
          type:
          - string
          - 'null'
          description: '`price` with its currency symbol, e.g. `$527`.'
        local_prices:
          type: array
          items:
            type: object
            required:
            - currency
            - price
            properties:
              currency:
                type: string
              price:
                type: number
          description: The seller's own price when it charges in another currency, e.g. CAD 749.
        marketed_as:
          type: array
          items:
            type: string
          description: Flight numbers this seller sells the itinerary under, e.g. `LX 647`.
        booking_request:
          anyOf:
          - type: object
            required:
            - url
            - post_data
            properties:
              url:
                type: string
                description: Google's click-through URL.
              post_data:
                type: string
                description: URL-encoded form body.
          - type: 'null'
          description: 'Google''s click-through as a form (SerpApi''s shape): POST `post_data` as `application/x-www-form-urlencoded` to `url`. Null when the seller has no link (e.g. call to book).'
        booking_url:
          type:
          - string
          - 'null'
          description: The same click-through as a GET link; Google answers it with a redirect to the seller's page. Null when `booking_request` is.
        seller_domain:
          type:
          - string
          - 'null'
          description: The seller's site as Google shows it, e.g. `www.swiss.com/...`.
        booking_phone:
          type:
          - string
          - 'null'
          description: Phone number of a call-to-book seller (which has no link).
        separate_tickets:
          type: boolean
          description: The option is several tickets bought from different sellers (see `sellers`).
        sellers:
          type: array
          items:
            type: string
          description: Every seller of this option.
        option_title:
          type:
          - string
          - 'null'
          description: Fare family when Google names one, e.g. `Delta Main Basic`.
        extensions:
          type: array
          items:
            type: string
          description: Fare rules Google lists, e.g. `No refunds`, `Free seat selection`, `Ticket changes for a fee`. Mostly shown for airline-direct sellers.
        baggage_prices:
          type: array
          items:
            type: string
          description: 'Bag fees as Google words them, e.g. `1st checked bag: $45`, `1 free carry-on`.'
    FlightsBookingResponse:
      type: object
      description: Response of `POST /v1/serp/google_flights_booking`.
      required:
      - currency
      - trip_type
      - legs
      - booking_options
      - option_count
      - cheapest_price
      - google_flights_url
      - wire_bytes
      - elapsed_s
      properties:
        currency:
          type: string
          description: Currency of the original search.
        trip_type:
          type: string
          description: '`one_way`, `round_trip` or `multi_city`.'
          enum:
          - one_way
          - round_trip
          - multi_city
        legs:
          type: array
          items:
            $ref: '#/components/schemas/FlightLeg'
          description: Every leg of the chosen itinerary, in order.
        booking_options:
          type: array
          items:
            $ref: '#/components/schemas/FlightBookingOption'
          description: Airline-direct and online travel agency sellers.
        option_count:
          type: integer
          description: Number of entries in `booking_options`.
        cheapest_price:
          type:
          - number
          - 'null'
          description: Lowest `price` in `booking_options`; null when none is priced.
        price_insights:
          anyOf:
          - $ref: '#/components/schemas/FlightPriceInsights'
          - type: 'null'
          description: Null when Google gives none. Omitted when `booking_options` is empty; that answer is not billed.
        google_flights_url:
          type: string
          description: Google Flights booking page for this itinerary.
        wire_bytes:
          type: integer
          description: Size of Google's response, bytes.
        elapsed_s:
          type: number
          description: 'Time Google took to answer, seconds (typically 3-12 s: Google checks seller prices while the request is open).'
    FlightLocation:
      type: object
      description: One autocomplete result.
      required:
      - type
      - name
      - iata
      - id
      - city
      - description
      - airports
      properties:
        type:
          type: string
          enum:
          - airport
          - city
          - region
          - train_station
        name:
          type: string
          description: e.g. `Paris, France`.
        iata:
          type:
          - string
          - 'null'
          description: IATA code of an airport or train station; null for cities and regions.
        id:
          type:
          - string
          - 'null'
          description: Google entity id, e.g. `/m/05qtj`. A city's id can be passed as `departure_id`/`arrival_id` (or a `multi_city` leg's `departure`/`arrival`) of `/v1/serp/google_flights` to search all of its airports.
        city:
          type:
          - string
          - 'null'
        description:
          type:
          - string
          - 'null'
          description: e.g. `Capital of France`, `Airport in France`.
        airports:
          type: array
          items:
            type: object
            required:
            - iata
            - name
            - city
            - type
            - distance
            properties:
              iata:
                type: string
              name:
                type:
                - string
                - 'null'
              city:
                type:
                - string
                - 'null'
              type:
                type: string
                enum:
                - airport
                - city
                - region
                - train_station
              distance:
                type:
                - string
                - 'null'
                description: Distance from the city as Google shows it, e.g. `14 mi`.
          description: 'For a city: its airports and train stations. Empty otherwise.'
    FlightsLocationSearchResponse:
      type: object
      description: Response of `POST /v1/serp/google_flights_location_search`.
      required:
      - q
      - locations
      - count
      - wire_bytes
      - elapsed_s
      - cached
      properties:
        q:
          type: string
          description: Echo of the request's `q`.
        locations:
          type: array
          items:
            $ref: '#/components/schemas/FlightLocation'
          description: Google's autocomplete results, in its order. An empty list is not billed.
        count:
          type: integer
          description: Number of entries in `locations`.
        wire_bytes:
          type: integer
          description: Size of Google's response, bytes; 0 when served from cache.
        elapsed_s:
          type: number
          description: Time Google took to answer, seconds; 0 when served from cache.
        cached:
          type: boolean
          description: Served from the 6-hour cache of repeated queries.
    GoogleHotelsSearchImage:
      type: object
      required:
      - thumbnail
      - original
      properties:
        thumbnail:
          type: string
          description: Image URL as Google sent it (card size).
        original:
          type: string
          description: Largest rendition of the same image; equals `thumbnail` when no larger size is available.
    GoogleHotelsSearchReviewCategory:
      type: object
      required:
      - name
      - description
      - total
      - positive
      - neutral
      - negative
      properties:
        name:
          type: string
          description: Review topic, e.g. `Fitness`.
        description:
          type: string
        total:
          type: integer
          description: Reviews that mention the topic.
        positive:
          type: integer
        neutral:
          type: integer
          description: '`total - positive - negative`, never below 0.'
        negative:
          type: integer
    GoogleHotelsSearchNearbyPlace:
      type: object
      required:
      - name
      - category_code
      - transportations
      properties:
        name:
          type: string
        category_code:
          type:
          - integer
          - 'null'
          description: Google's place category code, as sent.
        transportations:
          type: array
          items:
            type: object
            required:
            - type
            - type_code
            - duration
            properties:
              type:
                type:
                - string
                - 'null'
                description: '`Taxi`, `Walking` or `Public transport`; null for an unmapped `type_code`.'
              type_code:
                type:
                - integer
                - 'null'
                description: 'Google''s code: 0 taxi, 2 walking, 3 public transport.'
              duration:
                type: string
                description: As displayed, e.g. `35 min`.
    GoogleHotelsSearchSellerPrice:
      type: object
      description: One seller row Google attached to a result card; mostly on vacation rentals. All prices are in the property's currency.
      required:
      - source
      - raw_source
      - displayed_prices
      - partner_id
      - logo
      - price_per_night
      - price_per_night_before_taxes
      - extracted_price_per_night
      - extracted_price_per_night_before_taxes
      - has_free_cancellation
      - free_cancellation_until
      - free_cancellation_time
      - is_featured
      properties:
        source:
          type: string
          description: Seller name, with country-domain variants merged (e.g. `Booking.com`).
        raw_source:
          type: string
          description: Seller name as displayed.
        displayed_prices:
          type: array
          items:
            type: string
          description: Every price string on the row, as displayed, including a lone one whose basis Google does not label.
        partner_id:
          type:
          - string
          - 'null'
          description: Google's partner id for the seller.
        logo:
          type:
          - string
          - 'null'
          description: Logo URL; may be protocol-relative (`//...`).
        price_per_night:
          type:
          - string
          - 'null'
          description: Nightly display string including taxes and fees. Null unless the row shows a before-taxes / all-in pair.
        price_per_night_before_taxes:
          type:
          - string
          - 'null'
          description: Nightly display string before taxes. Null unless the row shows a pair.
        extracted_price_per_night:
          type:
          - number
          - 'null'
          description: Nightly price including taxes and fees.
        extracted_price_per_night_before_taxes:
          type:
          - number
          - 'null'
          description: Nightly price before taxes.
        has_free_cancellation:
          type: boolean
        free_cancellation_until:
          type:
          - string
          - 'null'
          description: Last free-cancellation date as displayed, e.g. `Oct 16`.
        free_cancellation_time:
          type:
          - string
          - 'null'
          description: e.g. `4:00 PM`.
        is_featured:
          type: boolean
          description: True for rows from Google's featured list.
    GoogleHotelsSearchBrand:
      type: object
      description: 'A brand family Google offers as a filter for this destination. Informational only: brand filtering is not supported.'
      required:
      - id
      - title
      - children
      properties:
        id:
          type: integer
          description: Google brand id.
        title:
          type: string
          description: Brand name; empty string when Google did not name it.
        children:
          type: array
          items:
            type: object
            required:
            - id
            - title
            properties:
              id:
                type: integer
              title:
                type: string
          description: Sub-brands.
    GoogleHotelsSearchPagination:
      type: object
      description: Pages overlap by a few results (page 2 starts before page 1 ends); de-duplicate by `property_token`.
      required:
      - records_from
      - records_to
      - next_page_token
      properties:
        records_from:
          type:
          - integer
          - 'null'
          description: 1-based position of the first result on this page.
        records_to:
          type:
          - integer
          - 'null'
          description: 1-based position of the last result on this page.
        next_page_token:
          type:
          - string
          - 'null'
          description: Send it back (as `page_token` on `/v1/hotels/search`, `next_page_token` on `/v1/serp/google_hotels`) with the same query, stay, party and filters for the next page. Null on the last page.
    GoogleHotelsSearchRate:
      type: object
      description: Lowest price Google shows for the stay, itemised. Every figure is in `currency`.
      required:
      - currency
      - check_in
      - check_out
      - nights
      - price_per_night
      - price_per_night_before_taxes
      - extracted_price_per_night
      - extracted_price_per_night_before_taxes
      - total_price
      - total_price_before_taxes
      - base
      - taxes
      - fees
      - total
      - before_taxes
      - from_display_text
      properties:
        currency:
          type:
          - string
          - 'null'
          description: ISO 4217 code every figure in `rate` is in.
        check_in:
          type:
          - string
          - 'null'
          description: Stay Google priced (equals the requested stay whenever `total` is set).
          format: date
        check_out:
          type:
          - string
          - 'null'
          format: date
        nights:
          type:
          - integer
          - 'null'
        price_per_night:
          type:
          - string
          - 'null'
          description: Nightly display string including taxes and fees, e.g. `$121`.
        price_per_night_before_taxes:
          type:
          - string
          - 'null'
          description: Nightly display string before taxes (base + mandatory fees); the price Google's card shows.
        extracted_price_per_night:
          type:
          - number
          - 'null'
          description: '`total / nights`, rounded to 2 decimals: nightly price including taxes and fees.'
        extracted_price_per_night_before_taxes:
          type:
          - number
          - 'null'
          description: 'Google''s exact nightly figure before taxes: `(base + fees) / nights`.'
        total_price:
          type:
          - string
          - 'null'
          description: Whole-stay display string including taxes and fees.
        total_price_before_taxes:
          type:
          - string
          - 'null'
          description: Whole-stay display string before taxes.
        base:
          type:
          - number
          - 'null'
          description: Whole-stay room price before taxes and fees.
        taxes:
          type:
          - number
          - 'null'
          description: Whole-stay taxes.
        fees:
          type:
          - number
          - 'null'
          description: Whole-stay mandatory fees (e.g. a rental's cleaning fee), kept separate from taxes.
        total:
          type:
          - number
          - 'null'
          description: 'Whole-stay price: `base + taxes + fees`. Null when Google showed only a nightly display price.'
        before_taxes:
          type:
          - number
          - 'null'
          description: Whole-stay `base + fees`, rounded to 2 decimals (SearchAPI's before-taxes basis).
        from_display_text:
          type: boolean
          description: True when Google sent no itemised amounts and `total`/`base` were parsed from the display strings; `taxes` and `fees` are then null and `base` is the displayed before-taxes total.
    GoogleHotelsSearchProperty:
      type: object
      description: One result card. Every key is always present; unknown values are null.
      required:
      - type
      - property_token
      - name
      - data_id
      - description
      - link
      - gps_coordinates
      - country
      - check_in_time
      - check_out_time
      - hotel_class
      - extracted_hotel_class
      - rating
      - reviews
      - reviews_histogram
      - location_rating
      - proximity_to_things_to_do_rating
      - proximity_to_restaurants_rating
      - proximity_to_transit_rating
      - airport_access_rating
      - reviews_breakdown
      - amenities
      - amenity_codes
      - excluded_amenities
      - essential_info
      - thumbnail
      - images
      - nearby_places
      - deal
      - deal_description
      - deal_kind
      - rate
      - sources
      - provenance
      properties:
        type:
          type: string
          description: Google blends vacation rentals into the default list; this says which each result is.
          enum:
          - hotel
          - vacation_rental
        property_token:
          type: string
          description: Google property token; pass it to `/v1/calendar` or `/v1/offers`.
        name:
          type: string
        data_id:
          type:
          - string
          - 'null'
          description: Google Maps data id (`0x...:0x...`).
        description:
          type:
          - string
          - 'null'
        link:
          type:
          - string
          - 'null'
          description: The property's own website, when Google lists one.
        gps_coordinates:
          anyOf:
          - type: object
            required:
            - latitude
            - longitude
            properties:
              latitude:
                type: number
              longitude:
                type: number
          - type: 'null'
        country:
          type:
          - string
          - 'null'
          description: ISO 3166-1 alpha-2 country code.
        check_in_time:
          type:
          - string
          - 'null'
          description: As displayed, e.g. `3:00 PM`.
        check_out_time:
          type:
          - string
          - 'null'
          description: As displayed, e.g. `11:00 AM`.
        hotel_class:
          type:
          - string
          - 'null'
          description: As displayed, e.g. `4-star hotel`.
        extracted_hotel_class:
          type:
          - integer
          - 'null'
          description: Star class, 1-5.
        rating:
          type:
          - number
          - 'null'
          description: Guest rating out of 5.
        reviews:
          type:
          - integer
          - 'null'
          description: Number of reviews.
        reviews_histogram:
          anyOf:
          - type: object
            properties:
              '1':
                type: integer
              '2':
                type: integer
              '3':
                type: integer
              '4':
                type: integer
              '5':
                type: integer
          - type: 'null'
          description: Review count per star rating, keyed `1`-`5` (only the stars Google reported). Null when Google gave none.
        location_rating:
          type:
          - number
          - 'null'
          description: Overall location score, out of 5. Null when Google has no score.
        proximity_to_things_to_do_rating:
          type:
          - number
          - 'null'
          description: Score for proximity to things to do, out of 5. Null when Google has no score.
        proximity_to_restaurants_rating:
          type:
          - number
          - 'null'
          description: Score for proximity to restaurants, out of 5. Null when Google has no score.
        proximity_to_transit_rating:
          type:
          - number
          - 'null'
          description: Score for proximity to public transit, out of 5. Null when Google has no score.
        airport_access_rating:
          type:
          - number
          - 'null'
          description: Score for airport access, out of 5. Null when Google has no score.
        reviews_breakdown:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchReviewCategory'
          description: Review topics with mention counts; empty when Google gave none.
        amenities:
          type: array
          items:
            type: string
          description: Amenity names. Hotel amenity names are always English; rentals use Google's own labels.
        amenity_codes:
          type: array
          items:
            type: array
            items:
              type: integer
            minItems: 2
            maxItems: 2
          description: Raw `[flag, code]` pairs from the card. Codes are not the `amenities` filter ids; codes without a known name appear only here. The flag does not mark an amenity as absent.
        excluded_amenities:
          type: array
          items:
            type: string
          description: Amenities a rental states it lacks, e.g. `No balcony`; usually empty for hotels.
        essential_info:
          type: array
          items:
            type: string
          description: Rental basics such as `Entire apartment` or `Sleeps 2`; usually empty for hotels.
        thumbnail:
          type:
          - string
          - 'null'
        images:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchImage'
        nearby_places:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchNearbyPlace'
        deal:
          type:
          - string
          - 'null'
          description: Deal text, e.g. `27% less than usual` or `Great price for a 4-star hotel`. Null when there is no deal.
        deal_description:
          type:
          - string
          - 'null'
          description: 'Badge Google renders: `Deal`, `Great Deal`, `Great Price`, or another label.'
        deal_kind:
          type:
          - string
          - 'null'
          description: '`below_usual_price`, `great_price`, or `code_<n>` for a deal type not yet mapped. Null when there is no deal.'
        rate:
          anyOf:
          - $ref: '#/components/schemas/GoogleHotelsSearchRate'
          - type: 'null'
          description: Lowest price for the stay. Null when the card carried no price, or Google priced other dates and the price was removed (see `warnings`).
        sources:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchSellerPrice'
          description: Seller rows Google attached to the card; mostly vacation rentals, usually empty for hotels.
        provenance:
          anyOf:
          - $ref: '#/components/schemas/RateProvenance'
          - type: 'null'
          description: Provenance of `rate`; null unless `rate.total` is known.
    GoogleHotelsSearchResponse:
      type: object
      description: Response of `POST /v1/hotels/search`.
      required:
      - search_parameters
      - search_information
      - properties
      - brands
      - pagination
      - warnings
      - meta
      properties:
        search_parameters:
          type: object
          description: Echo of the effective request. Optional filters appear only when set.
          required:
          - engine
          - q
          - check_in_date
          - check_out_date
          - adults
          - children_ages
          - currency
          - gl
          - hl
          - sort_by
          properties:
            engine:
              type: string
              enum:
              - google_hotels_search
            q:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            children_ages:
              type: array
              items:
                type: integer
              description: One age per child; empty when none.
            currency:
              type: string
              description: Requested currency, upper-case.
            gl:
              type: string
              description: Market country code, lower-case.
            hl:
              type: string
            sort_by:
              type: string
              enum:
              - relevance
              - lowest_price
              - highest_rating
              - most_reviewed
            price_min:
              type: integer
              description: Present only when set in the request.
            price_max:
              type: integer
              description: Present only when set in the request.
            min_rating:
              type: number
              description: 3.5, 4.0 or 4.5. Present only when set in the request.
            hotel_class:
              type: array
              items:
                type: integer
              description: Present only when set in the request.
            amenities:
              type: array
              items:
                type: integer
              description: Present only when set in the request.
            property_types:
              type: array
              items:
                type: integer
              description: Present only when set in the request.
            free_cancellation:
              type: boolean
              description: Present only when true.
            special_offers:
              type: boolean
              description: Present only when true.
            eco_certified:
              type: boolean
              description: Present only when true.
            next_page_token:
              type: string
              description: Page token this page was fetched with. Present only when one was sent.
        search_information:
          type: object
          required:
          - total_results
          - location
          - location_data_id
          - nights
          - returned
          - priced
          - requested_currency
          - returned_currency
          - currency_matches_request
          - requested_market
          - available_property_types
          properties:
            total_results:
              type:
              - integer
              - 'null'
              description: Total properties Google reports for the search.
            location:
              type:
              - string
              - 'null'
              description: Place Google resolved `q` to.
            location_data_id:
              type:
              - string
              - 'null'
              description: Google's place id for `location`.
            nights:
              type: integer
            returned:
              type: integer
              description: Properties on this page.
            priced:
              type: integer
              description: Properties on this page with a known stay total.
            requested_currency:
              type: string
            returned_currency:
              type:
              - string
              - 'null'
              description: Currency the prices came back in; `MIXED` when properties differ; null when no property carried a currency.
            currency_matches_request:
              type: boolean
              description: False when Google returned another currency (also reported in `warnings`).
            requested_market:
              type: string
              description: '`gl`, upper-cased.'
            available_property_types:
              type: array
              items:
                type: object
                required:
                - id
                - name
                properties:
                  id:
                    type: integer
                    description: Pass in `property_types` to filter.
                  name:
                    type:
                    - string
                    - 'null'
                    description: Null for an id without a known name.
              description: Property-type filters Google offers for this destination.
        properties:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchProperty'
          description: About 20 per page.
        brands:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchBrand'
        pagination:
          $ref: '#/components/schemas/GoogleHotelsSearchPagination'
        warnings:
          type: array
          items:
            type: string
          description: 'Notices about this page: prices removed because Google priced other dates, a currency other than the one requested, results outside a requested `hotel_class`, `min_rating` or `price_max`, or prices not verified for the requested market.'
        meta:
          type: object
          required:
          - wire_bytes
          - elapsed_s
          - egress
          - skipped_records
          properties:
            wire_bytes:
              type: integer
              description: Bytes received from Google.
            elapsed_s:
              type: number
              description: Seconds spent fetching from Google.
            egress:
              type: object
              description: How the request reached Google.
              required:
              - mode
              - class
              - pool
              - attempts
              - path
              properties:
                mode:
                  type: string
                  enum:
                  - direct
                  - proxy
                class:
                  type: string
                  description: 'Route class: `direct`, `dc`, `isp`, `resi`, `mobile` or `unblocker`.'
                  enum:
                  - direct
                  - dc
                  - isp
                  - resi
                  - mobile
                  - unblocker
                pool:
                  type: string
                  description: Route pool that served the request.
                attempts:
                  type: integer
                  description: Routes tried, including the successful one.
                path:
                  type: array
                  items:
                    type: string
                  description: Each attempt as `<class>/<pool>:<outcome>`, in order.
            skipped_records:
              type: integer
              description: Result cards that could not be read and were left out.
    GoogleHotelsSearchSerpProperty:
      type: object
      description: One result card, SearchAPI field names. Keys whose value would be null are omitted, so every key outside `required` is present only when Google supplied it.
      required:
      - type
      - property_token
      - name
      - nearby_places
      - reviews_breakdown
      - amenities
      - images
      properties:
        type:
          type: string
          description: Google blends vacation rentals into the default list; this says which each result is.
          enum:
          - hotel
          - vacation_rental
        property_token:
          type: string
          description: Google property token; pass it to `/v1/serp/google_hotels_property` or `/v1/calendar`.
        data_id:
          type: string
          description: Google Maps data id (`0x...:0x...`).
        name:
          type: string
        link:
          type: string
          description: The property's own website.
        description:
          type: string
        gps_coordinates:
          type: object
          required:
          - latitude
          - longitude
          properties:
            latitude:
              type: number
            longitude:
              type: number
        city:
          type: string
          description: The place Google resolved `q` to (same as `search_information.location`), not a per-property city.
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code.
        check_in_time:
          type: string
          description: As displayed, e.g. `3:00 PM`.
        check_out_time:
          type: string
        price_per_night:
          type: object
          description: Present only when the stay total is known.
          required:
          - price
          - extracted_price
          - price_before_taxes
          - extracted_price_before_taxes
          properties:
            price:
              type:
              - string
              - 'null'
              description: Display string including taxes and fees.
            extracted_price:
              type:
              - number
              - 'null'
              description: 'Stay total / nights: nightly price including taxes and fees.'
            price_before_taxes:
              type:
              - string
              - 'null'
              description: Display string before taxes; the price Google's card shows.
            extracted_price_before_taxes:
              type:
              - number
              - 'null'
              description: Google's exact nightly figure before taxes (base + mandatory fees).
        total_price:
          type: object
          description: Present only when the stay total is known.
          required:
          - price
          - extracted_price
          - price_before_taxes
          - extracted_price_before_taxes
          properties:
            price:
              type:
              - string
              - 'null'
              description: Whole-stay display string including taxes and fees.
            extracted_price:
              type: number
              description: Whole-stay price including taxes and fees.
            price_before_taxes:
              type:
              - string
              - 'null'
              description: Whole-stay display string before taxes.
            extracted_price_before_taxes:
              type:
              - number
              - 'null'
              description: Whole-stay base + mandatory fees.
        deal:
          type: string
          description: Deal text, e.g. `27% less than usual`.
        deal_description:
          type: string
          description: 'Badge Google renders: `Deal`, `Great Deal`, `Great Price`, or another label.'
        nearby_places:
          type: array
          items:
            type: object
            required:
            - name
            - transportations
            properties:
              name:
                type: string
              transportations:
                type: array
                items:
                  type: object
                  required:
                  - type
                  - duration
                  properties:
                    type:
                      type:
                      - string
                      - 'null'
                      description: '`Taxi`, `Walking` or `Public transport`; null for an unmapped mode.'
                    duration:
                      type: string
                      description: As displayed, e.g. `35 min`.
        hotel_class:
          type: string
          description: As displayed, e.g. `4-star hotel`.
        extracted_hotel_class:
          type: integer
          description: Star class, 1-5.
        rating:
          type: number
          description: Guest rating out of 5.
        reviews:
          type: integer
        reviews_histogram:
          type: object
          properties:
            '1':
              type: integer
            '2':
              type: integer
            '3':
              type: integer
            '4':
              type: integer
            '5':
              type: integer
          description: Review count per star rating, keyed `1`-`5`.
        location_rating:
          type: number
          description: Overall location score, out of 5.
        proximity_to_things_to_do_rating:
          type: number
          description: Score for proximity to things to do, out of 5.
        proximity_to_restaurants_rating:
          type: number
          description: Score for proximity to restaurants, out of 5.
        proximity_to_transit_rating:
          type: number
          description: Score for proximity to public transit, out of 5.
        airport_access_rating:
          type: number
          description: Score for airport access, out of 5.
        reviews_breakdown:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchReviewCategory'
          description: Empty when Google gave none.
        amenities:
          type: array
          items:
            type: string
          description: Hotel amenity names are always English; rentals use Google's own labels.
        excluded_amenities:
          type: array
          items:
            type: string
          description: Amenities a rental states it lacks, e.g. `No balcony`.
        essential_info:
          type: array
          items:
            type: string
          description: Rental basics such as `Entire apartment` or `Sleeps 2`.
        images:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchImage'
        thumbnail:
          type: string
        prices:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchSellerPrice'
          description: Seller rows Google attached to the card (an addition to SearchAPI's shape); mostly vacation rentals.
        currency:
          type: string
          description: ISO 4217 code of every price on the property.
    SerpGoogleHotelsResponse:
      type: object
      description: Response of `POST /v1/serp/google_hotels`.
      required:
      - search_metadata
      - search_parameters
      - search_information
      - properties
      - brands
      - pagination
      properties:
        search_metadata:
          type: object
          required:
          - status
          - created_at
          - request_time_taken
          - total_time_taken
          properties:
            status:
              type: string
              enum:
              - Success
            created_at:
              type: string
              description: UTC, ISO-8601 with `Z`.
              format: date-time
            request_time_taken:
              type: number
              description: Seconds.
            total_time_taken:
              type: number
              description: Seconds.
        search_parameters:
          type: object
          description: Echo of the effective request. Optional filters appear only when set.
          required:
          - engine
          - q
          - check_in_date
          - check_out_date
          - adults
          - children_ages
          - currency
          - gl
          - hl
          - sort_by
          - property_type
          properties:
            engine:
              type: string
              enum:
              - google_hotels
            q:
              type: string
            check_in_date:
              type: string
              format: date
            check_out_date:
              type: string
              format: date
            adults:
              type: integer
            children_ages:
              type: array
              items:
                type: integer
              description: One age per child; empty when none.
            currency:
              type: string
              description: Requested currency, upper-case.
            gl:
              type: string
              description: Market country code, lower-case.
            hl:
              type: string
            sort_by:
              type: string
              enum:
              - relevance
              - lowest_price
              - highest_rating
              - most_reviewed
            price_min:
              type: integer
              description: Present only when set in the request.
            price_max:
              type: integer
              description: Present only when set in the request.
            min_rating:
              type: number
              description: 3.5, 4.0 or 4.5. Present only when set in the request. Converted from the `rating` code (7, 8, 9).
            hotel_class:
              type: array
              items:
                type: integer
              description: Present only when set in the request.
            amenities:
              type: array
              items:
                type: integer
              description: Present only when set in the request.
            property_types:
              type: array
              items:
                type: integer
              description: Present only when set in the request.
            free_cancellation:
              type: boolean
              description: Present only when true.
            special_offers:
              type: boolean
              description: Present only when true.
            eco_certified:
              type: boolean
              description: Present only when true.
            next_page_token:
              type: string
              description: Page token this page was fetched with. Present only when one was sent.
            property_type:
              type: string
              description: Always `hotel`.
              enum:
              - hotel
        search_information:
          type: object
          required:
          - total_results
          - location
          - currency_matches_request
          properties:
            total_results:
              type:
              - integer
              - 'null'
              description: Total properties Google reports for the search.
            location:
              type:
              - string
              - 'null'
              description: Place Google resolved `q` to.
            currency_matches_request:
              type: boolean
              description: False when Google returned a currency other than the one requested.
        properties:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchSerpProperty'
          description: About 20 per page.
        brands:
          type: array
          items:
            $ref: '#/components/schemas/GoogleHotelsSearchBrand'
        pagination:
          $ref: '#/components/schemas/GoogleHotelsSearchPagination'
