{
  "openapi": "3.0.3",
  "info": {
    "title": "Airbnb API & Short-Term Rental Data API | AirROI",
    "version": "2.3.0",
    "description": "*✨️ Feed this spec to your AI coding agent — Claude, Codex, OpenCode, etc.*\n\nUnlock the full potential of the short-term rental market with the AirROI API, the industry's leading data and analytics solution for Airbnb and vacation rentals.\nOur powerful API provides unparalleled access to comprehensive property-level data, advanced revenue forecasting, and in-depth competitive intelligence, giving you a decisive edge in the STR ecosystem.\n\nWhether you are a property manager, investor, or data analyst, the AirROI API delivers the actionable insights you need to identify high-yield investments, optimize rental performance, and master market dynamics. \nExperience the next level of STR data analytics and unlock superior returns with AirROI.\n\n**Onboarding:** [www.airroi.com/api/developer](https://www.airroi.com/api/developer)\n\n**Pricing:** [www.airroi.com/api/pricing](https://www.airroi.com/api/pricing)\n\n**Support:** [www.airroi.com/contact](https://www.airroi.com/contact)\n\n**Terms of Service:** [www.airroi.com/tos](https://www.airroi.com/tos)\n\n**Last Updated:** September 23rd, 2026\n",
    "contact": {
      "name": "API Tech Support",
      "url": "www.airroi.com/contact",
      "email": "admin@airroi.com"
    },
    "termsOfService": "www.airroi.com/tos"
  },
  "servers": [
    {
      "url": "https://api.airroi.com",
      "description": "Production server"
    }
  ],
  "tags": [
    {
      "name": "Authentication",
      "description": "This API is secured using an API key. To get your key, please visit www.airroi.com/api/developer/activate.\n\nInclude your assigned API key in the request headers as follows:\n\n- **Header Name:** `X-API-KEY`\n- **Value:** `your-airroi-api-key`\n\n**Example:**\n```\ncurl -X GET \\\n  -H \"X-API-KEY: your-airroi-api-key\" \\\n  https://api.airroi.com/listings?listing_id=1234567890\n```\n"
    },
    {
      "name": "Listings",
      "description": "Access comprehensive Airbnb listings and vacation rental search capabilities through our property data API. \nSearch and analyze short-term rental listing data across multiple markets to find investment opportunities \nand track competitor properties.\n"
    },
    {
      "name": "Markets",
      "description": "Analyze STR market analysis data including rental market data, occupancy rates, and ADR trends. \nGet insights into short-term rental market trends, historical performance metrics, and future market outlook \nto make informed investment decisions.\n"
    },
    {
      "name": "Calculator",
      "description": "Calculate accurate Airbnb revenue projections using our rental property valuation and investment analysis tools. \nGenerate property revenue estimates and performance projections based on real market data and competitive insights.\n"
    },
    {
      "name": "Price Recommendation",
      "description": "Estimate a property's **base price**, then calculate **calendar prices** with\noptional rules and limits. You can also supply your own base price.\nBoth endpoints return itemized explanations; neither stores settings nor\npublishes rates.\n\n### How it fits your stack\n\nAirROI recommends prices. Your property management system (PMS) or channel\nmanager is what actually sets them on Airbnb, Booking.com, Vrbo and the other\nOTAs. A typical integration runs in three steps, once a day or whenever a\nbooking changes the calendar.\n\n1. **Calendar state.** Your PMS or channel manager calls `POST /price-recommendation/calendar-prices` with the property, its base price, the current calendar (reserved, available and blocked nights) and the pricing rules you want applied.\n2. **Price recommendations.** AirROI returns a recommended price for every night in the horizon, each with an itemized explanation of how it was calculated.\n3. **Push rates.** Your PMS or channel manager writes those prices to the OTAs through its existing channel connections. AirROI never connects to an OTA on your behalf.\n\nStart with `POST /price-recommendation/base-price` if you do not have a base price yet; it estimates one from comparable listings in the market.\n"
    },
    {
      "name": "Filtering",
      "description": "Our API provides powerful filtering capabilities to help you refine your search results and retrieve the exact data you need.\n\nYou can filter your results by providing a `filter` object in the request body. The `filter` object is a simple object where each field maps to its condition(s). Multiple filters are ANDed together.\n\nFor most fields, each field condition must contain exactly one operator.\n\nThe `amenities` field is the exception. It may combine `all`, `any`, and `none`\nin the same object:\n- `all`: the listing must include every amenity in the list\n- `any`: the listing must include at least one amenity in the list\n- `none`: the listing must include none of the amenities in the list\n\nIf you provide more than one of these operators, the listing must satisfy all of\nthem. For example, `\"amenities\": {\"all\": [\"wifi\", \"kitchen\"], \"any\": [\"pool\",\n\"hot_tub\"], \"none\": [\"smoking_allowed\"]}` means:\n- the listing has `wifi` and `kitchen`\n- the listing has `pool` or `hot_tub`\n- the listing does not have `smoking_allowed`\n\n### Filter Operators\n\n| Operator | Description | Example |\n|---|---|---|\n| `eq` | Equal to | `\"bedrooms\": {\"eq\": 2}` |\n| `lt` | Less than | `\"price\": {\"lt\": 100}` |\n| `lte` | Less than or equal to | `\"price\": {\"lte\": 100}` |\n| `gt` | Greater than | `\"rating\": {\"gt\": 4.5}` |\n| `gte` | Greater than or equal to | `\"rating\": {\"gte\": 4.5}` |\n| `range` | Between two values (inclusive) | `\"bedrooms\": {\"range\": [2, 4]}` |\n| `any` | Contains any of the values in the list | `\"amenities\": {\"any\": [\"pool\", \"wifi\"]}` |\n| `all` | Contains all of the values in the list | `\"amenities\": {\"all\": [\"pool\", \"wifi\"]}` |\n| `none` | Contains none of the values in the list | `\"amenities\": {\"none\": [\"pets_allowed\"]}` |\n\n### Powerful Filter Sort Example\nHere's a comprehensive example showcasing multiple filters and sorts:\n```json\n{\n  \"filter\": {\n    \"room_type\": {\"eq\": \"entire_home\"},\n    \"bedrooms\": {\"range\": [2, 5]},\n    \"baths\": {\"gte\": 2},\n    \"guests\": {\"range\": [4, 10]},\n    \"amenities\": {\"all\": [\"wifi\", \"kitchen\", \"air_conditioning\"], \"any\": [\"pool\", \"hot_tub\", \"beach_access\", \"waterfront\"], \"none\": [\"pets_allowed\", \"smoking_allowed\"]},\n    \"superhost\": {\"eq\": true},\n    \"instant_book\": {\"eq\": true},\n    \"min_nights\": {\"lte\": 3},\n    \"rating_overall\": {\"gte\": 4.8},\n    \"num_reviews\": {\"gte\": 50},\n    \"ttm_revenue\": {\"range\": [75000, 250000]},\n    \"ttm_occupancy\": {\"gte\": 0.7},\n    \"ttm_avg_rate\": {\"range\": [200, 800]},\n    \"l90d_occupancy\": {\"gt\": 0.65},\n    \"cleaning_fee\": {\"lte\": 200}\n  },\n  \"sort\": {\n    \"ttm_revenue\": \"desc\",\n    \"rating_overall\": \"desc\",\n    \"ttm_occupancy\": \"desc\",\n    \"ttm_avg_rate\": \"asc\",\n    \"num_reviews\": \"desc\"\n  },\n  \"pagination\": {\n    \"page_size\": 10,\n    \"offset\": 0\n  },\n  \"currency\": \"native\"\n}\n```\nThis query finds high-performing entire homes that are family-friendly, have luxury amenities, excellent ratings, and strong financial performance, sorted by multiple criteria.\n\n### Location Filtering\nOur location filtering is powerful and flexible, allowing you to search at various geographic levels. If you are unsure about the exact spelling of a location, you can use the `/markets/search` or `/markets/lookup` endpoints to find the correct location names.\n\n**Understanding Market Administrative Levels**\n- **Country:** The country where the property is located. (e.g., \"US\", \"France\")\n- **Region:** The primary administrative division, such as a state or province. (e.g., \"California\", \"Ile-de-France\")\n- **Locality:** The city, town, or other municipality. (e.g., \"Los Angeles\", \"Paris\")\n- **District:** A neighborhood, borough, or other sub-city area. (e.g., \"18th Arrondissement\", \"10001\")\n\n#### By Market\nWhen searching for listings, you can specify a `market` object to narrow your search to a specific geographic area. The `country`, `region`, `locality`, and `district` fields are all optional, allowing for searches at different levels of granularity.\n\n**Global Search**\nTo search for listings globally, set the `market` object to `null`.\n```json\n{\n  \"market\": null,\n  \"sort\": {\n    \"ttm_revenue\": \"desc\"\n  }\n}\n```\n\n**Country-Level Search**\nTo find high-performing entire home listings with excellent ratings in the United States:\n```json\n{\n  \"market\": {\n    \"country\": \"United States\"\n  },\n  \"filter\": {\n    \"room_type\": {\"eq\": \"entire_home\"},\n    \"ttm_revenue\": {\"gte\": 75000},\n    \"ttm_occupancy\": {\"gt\": 0.65},\n    \"rating_overall\": {\"gte\": 4.8},\n    \"num_reviews\": {\"gte\": 25}\n  },\n  \"sort\": {\n    \"ttm_revenue\": \"desc\",\n    \"rating_overall\": \"desc\",\n    \"ttm_occupancy\": \"desc\"\n  },\n  \"pagination\": {\n    \"page_size\": 10,\n    \"offset\": 0\n  }\n}\n```\n\n**Region-Level Search**\nTo find premium vacation rentals in California with specific amenities and performance metrics:\n```json\n{\n  \"market\": {\n    \"country\": \"United States\",\n    \"region\": \"California\"\n  },\n  \"filter\": {\n    \"bedrooms\": {\"range\": [3, 6]},\n    \"baths\": {\"gte\": 2.5},\n    \"guests\": {\"gte\": 6},\n    \"amenities\": {\"all\": [\"pool\", \"hot_tub\", \"wifi\", \"kitchen\"]},\n    \"ttm_avg_rate\": {\"range\": [350, 1000]},\n    \"ttm_revenue\": {\"gt\": 100000},\n    \"superhost\": {\"eq\": true},\n    \"instant_book\": {\"eq\": true}\n  },\n  \"sort\": {\n    \"ttm_revenue\": \"desc\",\n    \"ttm_avg_rate\": \"desc\",\n    \"num_reviews\": \"desc\"\n  },\n  \"currency\": \"usd\"\n}\n```\n\n**Locality-Level Search**\nTo find high-performing short-term rentals in Miami Beach with beach proximity and luxury features:\n```json\n{\n  \"market\": {\n    \"country\": \"United States\",\n    \"region\": \"Florida\",\n    \"locality\": \"Miami Beach\"\n  },\n  \"filter\": {\n    \"bedrooms\": {\"gte\": 2},\n    \"baths\": {\"gte\": 2},\n    \"amenities\": {\"all\": [\"beach_access\", \"patio_or_balcony\", \"pool\", \"free_parking_on_premises\"]},\n    \"ttm_occupancy\": {\"gte\": 0.70},\n    \"ttm_revenue\": {\"gte\": 80000},\n    \"rating_overall\": {\"gte\": 4.7},\n    \"instant_book\": {\"eq\": true}\n  },\n  \"sort\": {\n    \"ttm_revenue\": \"desc\",\n    \"ttm_occupancy\": \"desc\"\n  },\n  \"currency\": \"usd\"\n}\n```\n\n**District-Level Search**\nTo find exceptional short-term rentals in the 18th Arrondissement of Paris with specific criteria:\n```json\n{\n  \"market\": {\n    \"country\": \"France\",\n    \"region\": \"Ile-de-France\",\n    \"locality\": \"Paris\",\n    \"district\": \"18th Arrondissement\"\n  },\n  \"filter\": {\n    \"superhost\": {\"eq\": true},\n    \"rating_overall\": {\"gte\": 4.9},\n    \"rating_cleanliness\": {\"gte\": 4.95},\n    \"num_reviews\": {\"range\": [50, 500]},\n    \"bedrooms\": {\"range\": [1, 3]},\n    \"min_nights\": {\"lte\": 3},\n    \"l90d_occupancy\": {\"gte\": 0.75},\n    \"amenities\": {\"any\": [\"elevator\", \"air_conditioning\"], \"none\": [\"pets_allowed\", \"smoking_allowed\"]}\n  },\n  \"sort\": {\n    \"rating_overall\": \"desc\",\n    \"num_reviews\": \"desc\",\n    \"l90d_revenue\": \"desc\",\n    \"ttm_avg_rate\": \"asc\"\n  },\n  \"pagination\": {\n    \"page_size\": 10\n  }\n}\n```\n\n#### For Market Data\nWhen querying for market data, the `country`, `region`, and `locality` fields are required. The `district` field is optional.\nMarket analytics request bodies support `filter`, `currency`, and `num_months`. They do not support `sort` or `pagination`.\n\n**Locality-Level Market Search**\nTo analyze performance metrics for premium family-friendly listings in Paris:\n```json\n{\n  \"market\": {\n    \"country\": \"France\",\n    \"region\": \"Ile-de-France\",\n    \"locality\": \"Paris\"\n  },\n  \"filter\": {\n    \"bedrooms\": {\"range\": [2, 4]},\n    \"baths\": {\"gte\": 1.5},\n    \"guests\": {\"range\": [4, 8]},\n    \"amenities\": {\"all\": [\"kitchen\", \"washer\", \"wifi\"], \"any\": [\"crib\", \"high_chair\", \"childrens_books_and_toys\"]},\n    \"ttm_revenue\": {\"gte\": 50000},\n    \"rating_overall\": {\"gte\": 4.7}\n  },\n  \"num_months\": 60,\n  \"currency\": \"usd\"\n}\n```\n\n**District-Level Market Search**\nTo analyze luxury apartment performance in Manhattan's 10001 zip code:\n```json\n{\n  \"market\": {\n    \"country\": \"United States\",\n    \"region\": \"New York\",\n    \"locality\": \"New York\",\n    \"district\": \"10001\"\n  },\n  \"filter\": {\n    \"room_type\": {\"eq\": \"entire_home\"},\n    \"bedrooms\": {\"gte\": 2},\n    \"amenities\": {\"all\": [\"air_conditioning\", \"elevator\", \"wifi\"], \"any\": [\"pool\", \"gym\", \"sauna\", \"hot_tub\"]},\n    \"ttm_avg_rate\": {\"gte\": 400},\n    \"l90d_occupancy\": {\"range\": [0.6, 0.95]},\n    \"cleaning_fee\": {\"lte\": 300},\n    \"min_nights\": {\"range\": [2, 7]}\n  },\n  \"num_months\": 24\n}\n```\n\n### Filterable Fields\n\n#### Location\n| Field | Type | Operators |\n|---|---|---|\n| `latitude` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `longitude` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `country` | String | `eq` (Accepts 2-letter country code or full name) |\n| `region` | String | `eq` |\n| `locality` | String | `eq` |\n| `district` | String | `eq` |\n| `exact_location` | Boolean | `eq` |\n\n#### Property Details\n| Field | Type | Operators |\n|---|---|---|\n| `amenities` | List | `any`, `all`, `none` (can be combined on the same field) |\n| `baths` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `bedrooms` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `beds` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `guests` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `listing_id` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `listing_type` | String | `eq` |\n| `min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `photos_count` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `room_type` | String | `eq` |\n| `guest_favorite` | Boolean | `eq` |\n\n#### Host\n| Field | Type | Operators |\n|---|---|---|\n| `cohost_ids` | List | `any`, `all`, `none` |\n| `cohost_names` | List | `any`, `all`, `none` |\n| `host_id` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `host_name` | String | `eq` |\n| `professional_management` | Boolean | `eq` |\n| `superhost` | Boolean | `eq` |\n\n#### Booking & Pricing\n| Field | Type | Operators |\n|---|---|---|\n| `cleaning_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `extra_guest_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `instant_book` | Boolean | `eq` |\n| `short_stay_cleaning_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `single_fee_structure` | Boolean | `eq` |\n\n#### Ratings\n| Field | Type | Operators |\n|---|---|---|\n| `num_reviews` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_accuracy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_checkin` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_cleanliness` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_communication` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_location` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_overall` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_value` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n\n#### Performance Metrics (Last 90 Days)\n| Field | Type | Operators |\n|---|---|---|\n| `l90d_adjusted_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_adjusted_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_rate` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_length_of_stay` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_available_days` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_days_booked` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_revenue` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n\n#### Performance Metrics (Trailing Twelve Months)\n| Field | Type | Operators |\n|---|---|---|\n| `ttm_adjusted_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_adjusted_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_rate` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_length_of_stay` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_available_days` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_days_booked` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_revenue` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n\n### Allowed Values\n\n#### `room_type`\n- `entire_home`\n- `private_room`\n- `shared_room`\n\n#### `amenities`\n- `air_conditioning`\n- `arcade_games`\n- `baby_bath`\n- `baby_monitor`\n- `baby_safety_gates`\n- `babysitter_recommendations`\n- `backyard`\n- `baking_sheet`\n- `bar`\n- `barbecue_utensils`\n- `bathtub`\n- `batting_cage`\n- `bbq_grill`\n- `beach_access`\n- `beach_essentials`\n- `bed_linens`\n- `bidet`\n- `bikes`\n- `blender`\n- `board_games`\n- `boat_slip`\n- `body_soap`\n- `books_and_reading_material`\n- `bowling_alley`\n- `bread_maker`\n- `breakfast`\n- `building_staff`\n- `cable_tv`\n- `carbon_monoxide_alarm`\n- `ceiling_fan`\n- `changing_table`\n- `childrens_bikes`\n- `childrens_books_and_toys`\n- `childrens_dinnerware`\n- `childrens_playroom`\n- `cleaning_before_checkout`\n- `cleaning_products`\n- `climbing_wall`\n- `clothing_storage`\n- `coffee`\n- `coffee_maker`\n- `conditioner`\n- `cooking_basics`\n- `crib`\n- `dedicated_workspace`\n- `dining_table`\n- `dishes_and_silverware`\n- `dishwasher`\n- `doorman`\n- `dryer`\n- `drying_rack_for_clothing`\n- `elevator`\n- `essentials`\n- `ethernet_connection`\n- `ev_charger`\n- `exercise_equipment`\n- `exterior_security_cameras_on_property`\n- `extra_pillows_and_blankets`\n- `fire_extinguisher`\n- `fire_pit`\n- `fireplace_guards`\n- `first_aid_kit`\n- `free_parking_on_premises`\n- `free_street_parking`\n- `freezer`\n- `game_console`\n- `garden_view`\n- `gated_property`\n- `gym`\n- `hair_dryer`\n- `hammock`\n- `hangers`\n- `heating`\n- `high_chair`\n- `hockey_rink`\n- `host_greets_you`\n- `hot_tub`\n- `hot_water`\n- `hot_water_kettle`\n- `indoor_fireplace`\n- `iron`\n- `kayak`\n- `keypad`\n- `kitchen`\n- `lake_access`\n- `laser_tag`\n- `laundromat_nearby`\n- `life_size_games`\n- `lock_on_bedroom_door`\n- `lockbox`\n- `long_term_stays_allowed`\n- `luggage_dropoff_allowed`\n- `microwave`\n- `mini_fridge`\n- `mini_golf`\n- `mosquito_net`\n- `movie_theater`\n- `noise_decibel_monitors_on_property`\n- `ocean_view`\n- `outdoor_dining_area`\n- `outdoor_furniture`\n- `outdoor_kitchen`\n- `outdoor_playground`\n- `outdoor_shower`\n- `outlet_covers`\n- `oven`\n- `pack_n_play_travel_crib`\n- `paid_parking_off_premises`\n- `paid_parking_on_premises`\n- `patio_or_balcony`\n- `pets_allowed`\n- `piano`\n- `ping_pong_table`\n- `pocket_wifi`\n- `pool`\n- `pool_table`\n- `pool_view`\n- `portable_fans`\n- `private_entrance`\n- `private_living_room`\n- `record_player`\n- `refrigerator`\n- `resort_access`\n- `rice_maker`\n- `river_view`\n- `room_darkening_shades`\n- `safe`\n- `sauna`\n- `security_system`\n- `self_check_in`\n- `shampoo`\n- `shower_gel`\n- `single_level_home`\n- `skate_ramp`\n- `ski_in_ski_out`\n- `smart_lock`\n- `smoke_alarm`\n- `smoking_allowed`\n- `sound_system`\n- `stove`\n- `sun_loungers`\n- `table_corner_guards`\n- `theme_room`\n- `toaster`\n- `trash_compactor`\n- `tv`\n- `washer`\n- `waterfront`\n- `wifi`\n- `window_guards`\n- `wine_glasses`\n"
    },
    {
      "name": "Sorting",
      "description": "Sorting is supported on the `/listings/search/*` endpoints. Provide a `sort` object in the request body to order listing results. The `sort` object is a map of field names to sort directions (`asc` or `desc`). Order is preserved, with the first field having highest priority.\n\n**Example:**\n```json\n{\n  \"sort\": {\n    \"ttm_revenue\": \"desc\",\n    \"rating_overall\": \"desc\",\n    \"num_reviews\": \"desc\"\n  }\n}\n```\n\n### Sortable Fields\n\n#### Location\n| Field | Type |\n|---|---|\n| `latitude` | Numeric |\n| `longitude` | Numeric |\n\n#### Property Details\n| Field | Type |\n|---|---|\n| `baths` | Numeric |\n| `bedrooms` | Numeric |\n| `beds` | Numeric |\n| `guests` | Numeric |\n| `listing_id` | Numeric |\n| `listing_type` | String |\n| `min_nights` | Numeric |\n| `photos_count` | Numeric |\n| `room_type` | String |\n| `guest_favorite` | Boolean |\n\n#### Host\n| Field | Type |\n|---|---|\n| `host_id` | Numeric |\n| `host_name` | String |\n| `professional_management` | Boolean |\n| `superhost` | Boolean |\n\n#### Booking & Pricing\n| Field | Type |\n|---|---|\n| `cleaning_fee` | Numeric |\n| `extra_guest_fee` | Numeric |\n| `instant_book` | Boolean |\n| `short_stay_cleaning_fee` | Numeric |\n\n#### Ratings\n| Field | Type |\n|---|---|\n| `num_reviews` | Numeric |\n| `rating_accuracy` | Numeric |\n| `rating_checkin` | Numeric |\n| `rating_cleanliness` | Numeric |\n| `rating_communication` | Numeric |\n| `rating_location` | Numeric |\n| `rating_overall` | Numeric |\n| `rating_value` | Numeric |\n\n#### Performance Metrics (Last 90 Days)\n| Field | Type |\n|---|---|\n| `l90d_adjusted_occupancy` | Numeric |\n| `l90d_adjusted_revpar` | Numeric |\n| `l90d_avg_rate` | Numeric |\n| `l90d_avg_min_nights` | Numeric |\n| `l90d_avg_length_of_stay` | Numeric |\n| `l90d_available_days` | Numeric |\n| `l90d_days_booked` | Numeric |\n| `l90d_occupancy` | Numeric |\n| `l90d_revenue` | Numeric |\n| `l90d_revpar` | Numeric |\n\n#### Performance Metrics (Trailing Twelve Months)\n| Field | Type |\n|---|---|\n| `ttm_adjusted_occupancy` | Numeric |\n| `ttm_adjusted_revpar` | Numeric |\n| `ttm_avg_rate` | Numeric |\n| `ttm_avg_min_nights` | Numeric |\n| `ttm_avg_length_of_stay` | Numeric |\n| `ttm_available_days` | Numeric |\n| `ttm_days_booked` | Numeric |\n| `ttm_occupancy` | Numeric |\n| `ttm_revenue` | Numeric |\n| `ttm_revpar` | Numeric |\n"
    },
    {
      "name": "Pagination",
      "description": "Pagination is controlled by the `pagination` object in the request body.\n\n- `/listings/search/*` defaults to `page_size: 10` and `offset: 0`\n- `/markets/summary` and `/markets/metrics/*` do not use pagination; use `num_months` to control the time window for aggregated market analytics\n\n**Example:**\n```json\n{\n  \"pagination\": {\n    \"page_size\": 10,\n    \"offset\": 20\n  }\n}\n```\n"
    }
  ],
  "paths": {
    "/listings": {
      "get": {
        "tags": [
          "Listings"
        ],
        "summary": "Retrieve Single Listing",
        "description": "Access our Airbnb property details API to retrieve comprehensive vacation rental listing data and STR property analytics for individual listing performance analysis. Get complete short-term rental property information using the listing's unique identifier.\n\nReturns extensive property information including:\n- Property characteristics (bedrooms, bathrooms, amenities)\n- Host details and superhost status\n- Location data with coordinates\n- Pricing structure and fees\n- Guest reviews and ratings\n- Performance metrics (TTM and L90D) for vacation rental listing data\n- Availability and booking patterns for STR property analytics\n",
        "operationId": "getListingDetails",
        "parameters": [
          {
            "name": "listing_id",
            "in": "query",
            "required": true,
            "description": "Airbnb listing ID to fetch detailed information about a specific property.\n",
            "schema": {
              "type": "integer",
              "format": "int64"
            },
            "example": 43036533
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for financial data conversion. Default: native currency.\nAllowed currency values are 'usd' (US Dollars) or 'native' (local currency).\nFor example, 'native' automatically uses EUR in France, JPY in Japan, or BRL in Brazil etc.\n",
            "schema": {
              "type": "string",
              "enum": [
                "usd",
                "native"
              ],
              "default": "native"
            },
            "example": "usd"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Get Listing Details",
            "source": "curl -X GET \"https://api.airroi.com/listings?listing_id=43036533&currency=native\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully retrieved listing details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListingDetailsResponse"
                },
                "examples": {
                  "entireHome": {
                    "summary": "Entire home listing details",
                    "value": {
                      "listing_info": {
                        "listing_id": 43036533,
                        "listing_name": "Beachfront Villa with Private Pool",
                        "description": "Oceanfront villa with a heated pool, outdoor shower, and direct beach access.",
                        "listing_type": "Entire villa",
                        "room_type": "entire_home",
                        "cover_photo_url": "https://a0.muscache.com/im/pictures/miso/Hosting-43036533/original/cover.jpeg",
                        "photos_count": 45,
                        "photo_urls": [
                          "https://a0.muscache.com/im/pictures/miso/Hosting-43036533/original/photo-1.jpeg",
                          "https://a0.muscache.com/im/pictures/miso/Hosting-43036533/original/photo-2.jpeg"
                        ],
                        "checkin_time": "4:00 PM - 10:00 PM",
                        "checkout_time": "11:00 AM",
                        "guest_favorite": true
                      },
                      "host_info": {
                        "host_id": 156789234,
                        "host_name": "Alexandra",
                        "cohost_ids": [],
                        "cohost_names": [],
                        "superhost": true,
                        "professional_management": false
                      },
                      "location_info": {
                        "country_code": "US",
                        "country": "United States",
                        "region": "California",
                        "locality": "Malibu",
                        "district": "Malibu Beach",
                        "latitude": 34.0259,
                        "longitude": -118.7798,
                        "exact_location": false
                      },
                      "property_details": {
                        "guests": 8,
                        "bedrooms": 4,
                        "beds": 5,
                        "baths": 3.5,
                        "registration": true,
                        "amenities": [
                          "wifi",
                          "kitchen",
                          "free_parking_on_premises",
                          "pool",
                          "hot_tub",
                          "beach_access",
                          "bbq_grill",
                          "outdoor_shower",
                          "fire_pit",
                          "dedicated_workspace"
                        ]
                      },
                      "booking_settings": {
                        "instant_book": false,
                        "min_nights": 3,
                        "cancellation_policy": "strict"
                      },
                      "pricing_info": {
                        "currency": "USD",
                        "cleaning_fee": 350,
                        "short_stay_cleaning_fee": 350,
                        "extra_guest_fee": 75,
                        "single_fee_structure": false
                      },
                      "ratings": {
                        "num_reviews": 89,
                        "rating_overall": 4.96,
                        "rating_accuracy": 4.98,
                        "rating_checkin": 4.97,
                        "rating_cleanliness": 4.95,
                        "rating_communication": 4.98,
                        "rating_location": 5,
                        "rating_value": 4.92
                      },
                      "performance_metrics": {
                        "ttm_revenue": 285000,
                        "ttm_avg_rate": 1250,
                        "ttm_occupancy": 0.625,
                        "ttm_adjusted_occupancy": 0.61,
                        "ttm_revpar": 781.25,
                        "ttm_adjusted_revpar": 762.5,
                        "ttm_total_days": 365,
                        "ttm_available_days": 350,
                        "ttm_blocked_days": 15,
                        "ttm_days_reserved": 219,
                        "ttm_avg_min_nights": 3.4,
                        "ttm_avg_length_of_stay": 5.1,
                        "l90d_revenue": 95000,
                        "l90d_avg_rate": 1500,
                        "l90d_occupancy": 0.7,
                        "l90d_adjusted_occupancy": 0.68,
                        "l90d_revpar": 1050,
                        "l90d_adjusted_revpar": 1020,
                        "l90d_total_days": 90,
                        "l90d_available_days": 88,
                        "l90d_blocked_days": 2,
                        "l90d_days_reserved": 62,
                        "l90d_avg_min_nights": 2.8,
                        "l90d_avg_length_of_stay": 4.6
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/listings/batch": {
      "post": {
        "tags": [
          "Listings"
        ],
        "summary": "Batch Retrieve Multiple Listings",
        "description": "Access our bulk Airbnb data API to fetch multiple vacation rental listings in a single request. This batch endpoint accepts up to 25 listing IDs and returns comprehensive property data for STR portfolio analysis, competitive intelligence, and market research. Perfect for property managers, real estate investors, and market analysts who need detailed listing information for multiple properties simultaneously.\n\nReturns comprehensive listing details including property characteristics, host information, amenities, pricing data, guest reviews, and performance metrics (TTM and L90D). The API optimizes bulk data retrieval by processing up to 25 listings per request, ensuring efficient data access for vacation rental analytics.\nThe response includes both successfully retrieved listings and error information for any listings that could not be found.\n",
        "operationId": "batchListings",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchListingsRequest"
              },
              "examples": {
                "smallBatch": {
                  "summary": "Small batch request",
                  "value": {
                    "listing_ids": [
                      43036533,
                      20609252,
                      52847291,
                      99999999
                    ],
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved listing details with error information for missing ones.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchListingsResponse"
                },
                "examples": {
                  "mixedResponse": {
                    "summary": "Response with both successful and failed listings",
                    "value": {
                      "results": [
                        {
                          "listing_info": {
                            "listing_id": 43036533,
                            "listing_name": "Beachfront Villa with Private Pool",
                            "description": "Oceanfront villa with a heated pool, outdoor shower, and direct beach access.",
                            "listing_type": "Entire villa",
                            "room_type": "entire_home",
                            "cover_photo_url": "https://a0.muscache.com/im/pictures/miso/Hosting-43036533/original/cover.jpeg",
                            "photos_count": 45,
                            "photo_urls": [
                              "https://a0.muscache.com/im/pictures/miso/Hosting-43036533/original/photo-1.jpeg",
                              "https://a0.muscache.com/im/pictures/miso/Hosting-43036533/original/photo-2.jpeg"
                            ],
                            "checkin_time": "4:00 PM - 10:00 PM",
                            "checkout_time": "11:00 AM",
                            "guest_favorite": true
                          },
                          "host_info": {
                            "host_id": 156789234,
                            "host_name": "Alexandra",
                            "cohost_ids": [],
                            "cohost_names": [],
                            "superhost": true,
                            "professional_management": false
                          },
                          "location_info": {
                            "country_code": "US",
                            "country": "United States",
                            "region": "California",
                            "locality": "Malibu",
                            "district": "Malibu Beach",
                            "latitude": 34.0259,
                            "longitude": -118.7798,
                            "exact_location": false
                          },
                          "property_details": {
                            "guests": 8,
                            "bedrooms": 4,
                            "beds": 5,
                            "baths": 3.5,
                            "registration": true,
                            "amenities": [
                              "wifi",
                              "kitchen",
                              "free_parking_on_premises",
                              "pool",
                              "hot_tub",
                              "beach_access",
                              "bbq_grill",
                              "outdoor_shower",
                              "fire_pit",
                              "dedicated_workspace"
                            ]
                          },
                          "booking_settings": {
                            "instant_book": false,
                            "min_nights": 3,
                            "cancellation_policy": "strict"
                          },
                          "pricing_info": {
                            "currency": "USD",
                            "cleaning_fee": 350,
                            "short_stay_cleaning_fee": 350,
                            "extra_guest_fee": 75,
                            "single_fee_structure": false
                          },
                          "ratings": {
                            "num_reviews": 89,
                            "rating_overall": 4.96,
                            "rating_accuracy": 4.98,
                            "rating_checkin": 4.97,
                            "rating_cleanliness": 4.95,
                            "rating_communication": 4.98,
                            "rating_location": 5,
                            "rating_value": 4.92
                          },
                          "performance_metrics": {
                            "ttm_revenue": 285000,
                            "ttm_avg_rate": 1250,
                            "ttm_occupancy": 0.625,
                            "ttm_adjusted_occupancy": 0.61,
                            "ttm_revpar": 781.25,
                            "ttm_adjusted_revpar": 762.5,
                            "ttm_total_days": 365,
                            "ttm_available_days": 350,
                            "ttm_blocked_days": 15,
                            "ttm_days_reserved": 219,
                            "ttm_avg_min_nights": 3.4,
                            "ttm_avg_length_of_stay": 5.1,
                            "l90d_revenue": 95000,
                            "l90d_avg_rate": 1500,
                            "l90d_occupancy": 0.7,
                            "l90d_adjusted_occupancy": 0.68,
                            "l90d_revpar": 1050,
                            "l90d_adjusted_revpar": 1020,
                            "l90d_total_days": 90,
                            "l90d_available_days": 88,
                            "l90d_blocked_days": 2,
                            "l90d_days_reserved": 62,
                            "l90d_avg_min_nights": 2.8,
                            "l90d_avg_length_of_stay": 4.6
                          }
                        },
                        {
                          "listing_info": {
                            "listing_id": 20609252,
                            "listing_name": "Cozy Downtown Loft",
                            "description": "Light-filled loft near transit, restaurants, and downtown offices.",
                            "listing_type": "Entire loft",
                            "room_type": "entire_home",
                            "cover_photo_url": "https://a0.muscache.com/im/pictures/miso/Hosting-20609252/original/cover.jpeg",
                            "photos_count": 25,
                            "photo_urls": [
                              "https://a0.muscache.com/im/pictures/miso/Hosting-20609252/original/photo-1.jpeg",
                              "https://a0.muscache.com/im/pictures/miso/Hosting-20609252/original/photo-2.jpeg"
                            ],
                            "checkin_time": "3:00 PM - 9:00 PM",
                            "checkout_time": "10:00 AM",
                            "guest_favorite": false
                          },
                          "host_info": {
                            "host_id": 987654321,
                            "host_name": "Michael",
                            "cohost_ids": [],
                            "cohost_names": [],
                            "superhost": false,
                            "professional_management": false
                          },
                          "location_info": {
                            "country_code": "US",
                            "country": "United States",
                            "region": "New York",
                            "locality": "New York",
                            "district": "Manhattan",
                            "latitude": 40.7128,
                            "longitude": -74.006,
                            "exact_location": true
                          },
                          "property_details": {
                            "guests": 4,
                            "bedrooms": 2,
                            "beds": 2,
                            "baths": 1,
                            "registration": false,
                            "amenities": [
                              "wifi",
                              "kitchen",
                              "air_conditioning",
                              "elevator"
                            ]
                          },
                          "booking_settings": {
                            "instant_book": true,
                            "min_nights": 1,
                            "cancellation_policy": "flexible"
                          },
                          "pricing_info": {
                            "currency": "USD",
                            "cleaning_fee": 100,
                            "short_stay_cleaning_fee": 100,
                            "extra_guest_fee": 25,
                            "single_fee_structure": true
                          },
                          "ratings": {
                            "num_reviews": 150,
                            "rating_overall": 4.8,
                            "rating_accuracy": 4.9,
                            "rating_checkin": 4.9,
                            "rating_cleanliness": 4.8,
                            "rating_communication": 4.9,
                            "rating_location": 4.9,
                            "rating_value": 4.7
                          },
                          "performance_metrics": {
                            "ttm_revenue": 150000,
                            "ttm_avg_rate": 410,
                            "ttm_occupancy": 0.85,
                            "ttm_adjusted_occupancy": 0.83,
                            "ttm_revpar": 348.5,
                            "ttm_adjusted_revpar": 340.3,
                            "ttm_total_days": 365,
                            "ttm_available_days": 360,
                            "ttm_blocked_days": 5,
                            "ttm_days_reserved": 306,
                            "ttm_avg_min_nights": 1.8,
                            "ttm_avg_length_of_stay": 3.2,
                            "l90d_revenue": 40000,
                            "l90d_avg_rate": 450,
                            "l90d_occupancy": 0.9,
                            "l90d_adjusted_occupancy": 0.88,
                            "l90d_revpar": 405,
                            "l90d_adjusted_revpar": 396,
                            "l90d_total_days": 90,
                            "l90d_available_days": 90,
                            "l90d_blocked_days": 0,
                            "l90d_days_reserved": 81,
                            "l90d_avg_min_nights": 1.4,
                            "l90d_avg_length_of_stay": 2.7
                          }
                        }
                      ],
                      "errors": [
                        {
                          "listing_id": 99999999,
                          "message": "Listing not found. This may be due to an invalid ID, or the listing has not been added to our system."
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/listings/comparables": {
      "get": {
        "tags": [
          "Listings"
        ],
        "summary": "Get Comparable Listings",
        "description": "Find Airbnb comparable properties using our STR competitive analysis and vacation rental comps API. Our property benchmarking tool identifies similar short-term rental properties for accurate short-term rental market comparison based on location and property characteristics.\n\nSpecify location using either `latitude`/`longitude` coordinates or a physical `address` string (but not both).\n",
        "operationId": "getComparableListings",
        "parameters": [
          {
            "name": "latitude",
            "in": "query",
            "required": false,
            "description": "Property latitude for comparison. Required if `address` is not provided.",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": -90,
              "maximum": 90
            },
            "example": 34.052235
          },
          {
            "name": "longitude",
            "in": "query",
            "required": false,
            "description": "Property longitude for comparison. Required if `address` is not provided.",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": -180,
              "maximum": 180
            },
            "example": -118.243683
          },
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "Physical address for comparison (e.g. \"123 Main St, Miami, FL\").\nUse as an alternative to `latitude`/`longitude`. Cannot be combined with coordinates.\n",
            "schema": {
              "type": "string"
            },
            "example": "123 Main St, Miami, FL"
          },
          {
            "name": "radius",
            "in": "query",
            "required": false,
            "description": "Search radius in miles for comparable listings. Default: 3 miles.\nIncrease the radius in low-density areas (e.g. rural locations or\nlarge homes with few similar properties nearby) to find more\ncomparables.\n",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": 1,
              "maximum": 10,
              "default": 3
            },
            "example": 5
          },
          {
            "name": "room_type",
            "in": "query",
            "required": false,
            "description": "Restrict comparable listings to a single room type. By default all\nroom types are searched. For whole-property comparisons,\n`entire_home` is recommended — it excludes private/shared rooms that\ncan otherwise appear as weak comparables in low-density areas.\n",
            "schema": {
              "type": "string",
              "enum": [
                "entire_home",
                "private_room",
                "shared_room"
              ]
            },
            "example": "entire_home"
          },
          {
            "name": "bedrooms",
            "in": "query",
            "required": true,
            "description": "Number of bedrooms in subject property",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 20
            },
            "example": 2
          },
          {
            "name": "baths",
            "in": "query",
            "required": true,
            "description": "Number of bathrooms in subject property (supports half baths as decimals)",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": 0,
              "maximum": 20
            },
            "example": 2
          },
          {
            "name": "guests",
            "in": "query",
            "required": true,
            "description": "Guest capacity of subject property",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 30
            },
            "example": 4
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for financial data in comparable listings. Default: each listing's native currency.\nAllowed currency values are 'usd' (US Dollars) or 'native' (local currency).\nFor example, 'native' automatically uses EUR in France, JPY in Japan, or BRL in Brazil etc.\n",
            "schema": {
              "type": "string",
              "enum": [
                "usd",
                "native"
              ],
              "default": "native"
            },
            "example": "native"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Coordinates Query",
            "source": "curl -X GET \"https://api.airroi.com/listings/comparables?latitude=34.052235&longitude=-118.243683&bedrooms=2&baths=2.0&guests=4&currency=native\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          },
          {
            "lang": "Shell",
            "label": "Address Query",
            "source": "curl -X GET \"https://api.airroi.com/listings/comparables?address=123+Main+St,+Miami,+FL&bedrooms=2&baths=2.0&guests=4&currency=native\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully retrieved comparable listings sorted by relevance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComparableListingsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/listings/search/market": {
      "post": {
        "tags": [
          "Listings"
        ],
        "summary": "Search Listings by Market",
        "description": "Search Airbnb listings and vacation rental properties within any market worldwide using our comprehensive STR market search API. This endpoint enables location-based property discovery for short-term rental market analysis, competitive research, and investment opportunities. Filter listings by property type, amenities, pricing, and performance metrics to identify the best vacation rental opportunities in your target market.\n\nPerfect for property managers, real estate investors, and market researchers analyzing Airbnb competition, market saturation, and revenue potential. Returns detailed listing data with performance metrics, enabling data-driven investment decisions in the short-term rental industry.\n",
        "operationId": "searchListingsByMarket",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListingSearchMarketRequest"
              },
              "examples": {
                "luxuryBeachfrontMiami": {
                  "summary": "Find luxury beachfront properties in Miami Beach",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Florida",
                      "locality": "Miami Beach"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "gte": 4
                      },
                      "ttm_revenue": {
                        "gt": 150000
                      },
                      "amenities": {
                        "all": [
                          "pool",
                          "beach_access",
                          "air_conditioning"
                        ]
                      }
                    },
                    "sort": {
                      "ttm_revenue": "desc"
                    },
                    "pagination": {
                      "page_size": 10,
                      "offset": 0
                    },
                    "currency": "native"
                  }
                },
                "budgetFamilyOrlando": {
                  "summary": "Family-friendly budget properties near Disney World",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Florida",
                      "locality": "Orlando"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "range": [
                          2,
                          3
                        ]
                      },
                      "guests": {
                        "gte": 6
                      },
                      "ttm_avg_rate": {
                        "lt": 200
                      },
                      "amenities": {
                        "any": [
                          "pool",
                          "kitchen",
                          "free_parking_on_premises"
                        ]
                      }
                    },
                    "sort": {
                      "ttm_occupancy": "desc",
                      "rating_overall": "desc"
                    },
                    "pagination": {
                      "page_size": 10,
                      "offset": 0
                    },
                    "currency": "native"
                  }
                },
                "highPerformingSuperhosts": {
                  "summary": "Top-performing superhost properties in Austin downtown",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Texas",
                      "locality": "Austin"
                    },
                    "filter": {
                      "superhost": {
                        "eq": true
                      },
                      "ttm_occupancy": {
                        "gt": 0.75
                      },
                      "rating_overall": {
                        "gte": 4.9
                      },
                      "num_reviews": {
                        "gte": 50
                      },
                      "instant_book": {
                        "eq": true
                      }
                    },
                    "sort": {
                      "ttm_revenue": "desc",
                      "rating_overall": "desc",
                      "num_reviews": "desc"
                    },
                    "pagination": {
                      "page_size": 10,
                      "offset": 0
                    },
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved listings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListingSearchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/listings/search/radius": {
      "post": {
        "tags": [
          "Listings"
        ],
        "summary": "Search Listings by Radius",
        "description": "Discover Airbnb listings and vacation rentals within a specific radius using our geospatial STR property search API. This proximity-based search endpoint finds all short-term rental properties within your defined distance from any location, perfect for competitive analysis, market research, and identifying investment opportunities near points of interest.\n\nIdeal for analyzing vacation rental density around attractions, business districts, or specific addresses. Returns comprehensive listing data including property details, performance metrics, and location coordinates, enabling location-based market analysis and strategic property investment decisions.\n",
        "operationId": "searchListingsByRadius",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListingSearchRadiusRequest"
              },
              "examples": {
                "nearTimesSquare": {
                  "summary": "Properties within 2 miles of Times Square NYC",
                  "value": {
                    "latitude": 40.758,
                    "longitude": -73.9855,
                    "radius_miles": 2,
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "min_nights": {
                        "lte": 7
                      },
                      "instant_book": {
                        "eq": true
                      },
                      "rating_cleanliness": {
                        "gte": 4.8
                      }
                    },
                    "sort": {
                      "ttm_revenue": "desc"
                    },
                    "pagination": {
                      "page_size": 10,
                      "offset": 0
                    },
                    "currency": "native"
                  }
                },
                "skiPropertiesVail": {
                  "summary": "Ski-in/ski-out properties near Vail Mountain base",
                  "value": {
                    "latitude": 39.6403,
                    "longitude": -106.3742,
                    "radius_miles": 3,
                    "filter": {
                      "bedrooms": {
                        "gte": 3
                      },
                      "guests": {
                        "gte": 8
                      },
                      "amenities": {
                        "all": [
                          "hot_tub",
                          "indoor_fireplace",
                          "ski_in_ski_out"
                        ]
                      },
                      "ttm_revenue": {
                        "gt": 100000
                      }
                    },
                    "sort": {
                      "ttm_avg_rate": "desc",
                      "rating_overall": "desc"
                    },
                    "pagination": {
                      "page_size": 10,
                      "offset": 0
                    },
                    "currency": "native"
                  }
                },
                "beachWalkingDistance": {
                  "summary": "Family rentals walking distance to Santa Monica Pier",
                  "value": {
                    "latitude": 34.0095,
                    "longitude": -118.4973,
                    "radius_miles": 1,
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "range": [
                          2,
                          4
                        ]
                      },
                      "amenities": {
                        "any": [
                          "beach_access",
                          "beach_view",
                          "ocean_view"
                        ]
                      },
                      "min_nights": {
                        "lte": 3
                      }
                    },
                    "sort": {
                      "ttm_occupancy": "desc"
                    },
                    "pagination": {
                      "page_size": 10,
                      "offset": 0
                    },
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved listings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListingSearchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/listings/search/polygon": {
      "post": {
        "tags": [
          "Listings"
        ],
        "summary": "Search Listings by Polygon",
        "description": "Search Airbnb listings within custom geographic boundaries using our polygon-based vacation rental search API. This advanced geospatial endpoint enables precise market analysis by finding all short-term rental properties within your defined area - perfect for neighborhood analysis, district comparisons, or custom market boundaries that don't align with standard administrative regions.\n\nEssential for sophisticated market research, zoning analysis, and targeted investment strategies. Define complex search areas using multiple coordinate points to analyze vacation rental distribution, market saturation, and revenue potential in specific neighborhoods or custom-defined regions. Returns detailed listing data with performance metrics for all properties within your polygon.\n",
        "operationId": "searchListingsByPolygon",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ListingSearchPolygonRequest"
              },
              "examples": {
                "frenchQuarterNewOrleans": {
                  "summary": "Historic French Quarter properties in New Orleans",
                  "value": {
                    "polygon": [
                      {
                        "latitude": 29.9511,
                        "longitude": -90.0715
                      },
                      {
                        "latitude": 29.9584,
                        "longitude": -90.0715
                      },
                      {
                        "latitude": 29.9584,
                        "longitude": -90.0589
                      },
                      {
                        "latitude": 29.9511,
                        "longitude": -90.0589
                      },
                      {
                        "latitude": 29.9511,
                        "longitude": -90.0715
                      }
                    ],
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "amenities": {
                        "any": [
                          "balcony",
                          "patio",
                          "courtyard"
                        ]
                      },
                      "ttm_revenue": {
                        "gte": 80000
                      },
                      "rating_location": {
                        "gte": 4.9
                      }
                    },
                    "sort": {
                      "ttm_revenue": "desc",
                      "rating_overall": "desc"
                    },
                    "pagination": {
                      "page_size": 10,
                      "offset": 0
                    },
                    "currency": "native"
                  }
                },
                "manhattanUpperEastSide": {
                  "summary": "Luxury rentals in Manhattan's Upper East Side",
                  "value": {
                    "polygon": [
                      {
                        "latitude": 40.7736,
                        "longitude": -73.9566
                      },
                      {
                        "latitude": 40.7851,
                        "longitude": -73.949
                      },
                      {
                        "latitude": 40.7648,
                        "longitude": -73.949
                      },
                      {
                        "latitude": 40.7648,
                        "longitude": -73.973
                      },
                      {
                        "latitude": 40.7736,
                        "longitude": -73.9566
                      }
                    ],
                    "filter": {
                      "bedrooms": {
                        "gte": 2
                      },
                      "baths": {
                        "gte": 2
                      },
                      "amenities": {
                        "all": [
                          "doorman",
                          "elevator",
                          "gym"
                        ]
                      },
                      "ttm_avg_rate": {
                        "gt": 500
                      },
                      "superhost": {
                        "eq": true
                      }
                    },
                    "sort": {
                      "ttm_revenue": "desc",
                      "ttm_avg_rate": "desc"
                    },
                    "pagination": {
                      "page_size": 10,
                      "offset": 0
                    },
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved listings",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListingSearchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/listings/metrics/all": {
      "get": {
        "tags": [
          "Listings"
        ],
        "summary": "Get Listing Metrics",
        "description": "Access comprehensive historical performance data and time-series analytics for any Airbnb listing with our vacation rental metrics API. This endpoint delivers up to 60 months of detailed performance history including occupancy rates, average daily rates (ADR), revenue, and booking patterns. Essential for understanding seasonal trends, year-over-year growth, and long-term property performance in the short-term rental market.\n\nTrack key performance indicators over time to identify booking trends, optimize pricing strategies, and forecast future performance. Perfect for property managers monitoring portfolio performance, investors evaluating acquisition targets, and analysts studying vacation rental market dynamics. Returns monthly aggregated data with revenue metrics, occupancy trends, and pricing evolution.\n",
        "operationId": "getListingMetrics",
        "parameters": [
          {
            "name": "listing_id",
            "in": "query",
            "required": true,
            "description": "The ID of the listing to retrieve metrics for.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for financial data conversion.\nAllowed currency values are 'usd' (US Dollars) or 'native' (local currency).\nFor example, 'native' automatically uses EUR in France, JPY in Japan, or BRL in Brazil etc.\n",
            "schema": {
              "type": "string",
              "enum": [
                "usd",
                "native"
              ],
              "default": "native"
            }
          },
          {
            "name": "num_months",
            "in": "query",
            "required": false,
            "description": "The number of months of data to return.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 60,
              "default": 12
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Get Time Series Metrics",
            "source": "curl -X GET \"https://api.airroi.com/listings/metrics/all?listing_id=43036533&currency=native&num_months=12\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully retrieved listing metrics.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListingTimeSeriesResponse"
                },
                "examples": {
                  "listingMetrics": {
                    "summary": "Miami beachfront property performance over 18 months",
                    "value": {
                      "results": [
                        {
                          "date": "2024-01",
                          "occupancy": 0.68,
                          "average_daily_rate": 285,
                          "rev_par": 193.8,
                          "revenue": 6007.8,
                          "min_nights": 2
                        },
                        {
                          "date": "2024-02",
                          "occupancy": 0.75,
                          "average_daily_rate": 315,
                          "rev_par": 236.25,
                          "revenue": 6615,
                          "min_nights": 2
                        },
                        {
                          "date": "2024-03",
                          "occupancy": 0.89,
                          "average_daily_rate": 425,
                          "rev_par": 378.25,
                          "revenue": 11725.75,
                          "min_nights": 3
                        },
                        {
                          "date": "2024-04",
                          "occupancy": 0.82,
                          "average_daily_rate": 385,
                          "rev_par": 315.7,
                          "revenue": 9471,
                          "min_nights": 3
                        },
                        {
                          "date": "2024-05",
                          "occupancy": 0.74,
                          "average_daily_rate": 325,
                          "rev_par": 240.5,
                          "revenue": 7455.5,
                          "min_nights": 2
                        },
                        {
                          "date": "2024-06",
                          "occupancy": 0.85,
                          "average_daily_rate": 295,
                          "rev_par": 250.75,
                          "revenue": 7522.5,
                          "min_nights": 2
                        },
                        {
                          "date": "2024-07",
                          "occupancy": 0.92,
                          "average_daily_rate": 345,
                          "rev_par": 317.4,
                          "revenue": 9839.4,
                          "min_nights": 3
                        },
                        {
                          "date": "2024-08",
                          "occupancy": 0.88,
                          "average_daily_rate": 335,
                          "rev_par": 294.8,
                          "revenue": 9138.8,
                          "min_nights": 3
                        },
                        {
                          "date": "2024-09",
                          "occupancy": 0.65,
                          "average_daily_rate": 265,
                          "rev_par": 172.25,
                          "revenue": 5167.5,
                          "min_nights": 2
                        },
                        {
                          "date": "2024-10",
                          "occupancy": 0.58,
                          "average_daily_rate": 245,
                          "rev_par": 142.1,
                          "revenue": 4405.1,
                          "min_nights": 2
                        },
                        {
                          "date": "2024-11",
                          "occupancy": 0.72,
                          "average_daily_rate": 285,
                          "rev_par": 205.2,
                          "revenue": 6156,
                          "min_nights": 2
                        },
                        {
                          "date": "2024-12",
                          "occupancy": 0.88,
                          "average_daily_rate": 395,
                          "rev_par": 347.6,
                          "revenue": 10775.6,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-01",
                          "occupancy": 0.71,
                          "average_daily_rate": 295,
                          "rev_par": 209.45,
                          "revenue": 6493.05,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02",
                          "occupancy": 0.78,
                          "average_daily_rate": 325,
                          "rev_par": 253.5,
                          "revenue": 7098,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-03",
                          "occupancy": 0.91,
                          "average_daily_rate": 445,
                          "rev_par": 404.95,
                          "revenue": 12553.45,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-04",
                          "occupancy": 0.85,
                          "average_daily_rate": 405,
                          "rev_par": 344.25,
                          "revenue": 10327.5,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-05",
                          "occupancy": 0.76,
                          "average_daily_rate": 345,
                          "rev_par": 262.2,
                          "revenue": 8128.2,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-06",
                          "occupancy": 0.87,
                          "average_daily_rate": 315,
                          "rev_par": 274.05,
                          "revenue": 8221.5,
                          "min_nights": 2
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/listings/future/rates": {
      "get": {
        "tags": [
          "Listings"
        ],
        "summary": "Get Listing Future Rates",
        "deprecated": true,
        "description": "**Deprecated.** Use [Get Live Calendar](#tag/Listings/operation/getLiveListingCalendar)\ninstead. It returns the same nightly data (in a `results` array instead of `rates`)\nplus the listing's cleaning fees, which this endpoint doesn't return: `cleaning_fee`,\nand `short_stay_cleaning_fee` for stays of 1–2 nights.\n\nReturns a listing's nightly rates, availability and minimum stays for the next 12 months.\n\n- `rate` is the nightly rate, excluding the cleaning fee.\n- `available: false` covers both booked and host-blocked nights.\n",
        "operationId": "getFutureRates",
        "parameters": [
          {
            "name": "listing_id",
            "in": "query",
            "required": true,
            "description": "The ID of the listing to retrieve future rates for.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for financial data conversion.\nAllowed currency values are 'usd' (US Dollars) or 'native' (local currency).\nFor example, 'native' automatically uses EUR in France, JPY in Japan, or BRL in Brazil etc.\n",
            "schema": {
              "type": "string",
              "enum": [
                "usd",
                "native"
              ],
              "default": "native"
            }
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Get Future Rates",
            "source": "curl -X GET \"https://api.airroi.com/listings/future/rates?listing_id=43036533&currency=native\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully retrieved future rates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FutureRatesResponse"
                },
                "examples": {
                  "futureRates": {
                    "summary": "Future rates for beachfront property in Miami",
                    "value": {
                      "currency": "USD",
                      "rates": [
                        {
                          "date": "2025-02-01",
                          "available": true,
                          "rate": 325,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-02",
                          "available": true,
                          "rate": 325,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-03",
                          "available": false,
                          "rate": 325,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-04",
                          "available": false,
                          "rate": 325,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-05",
                          "available": true,
                          "rate": 295,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-06",
                          "available": true,
                          "rate": 295,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-07",
                          "available": true,
                          "rate": 385,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-08",
                          "available": true,
                          "rate": 385,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-09",
                          "available": true,
                          "rate": 385,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-10",
                          "available": true,
                          "rate": 325,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-11",
                          "available": true,
                          "rate": 295,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-12",
                          "available": true,
                          "rate": 295,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-13",
                          "available": true,
                          "rate": 295,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-14",
                          "available": true,
                          "rate": 425,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-15",
                          "available": true,
                          "rate": 425,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-16",
                          "available": true,
                          "rate": 425,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-17",
                          "available": false,
                          "rate": 425,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-18",
                          "available": false,
                          "rate": 425,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-19",
                          "available": false,
                          "rate": 425,
                          "min_nights": 3
                        },
                        {
                          "date": "2025-02-20",
                          "available": true,
                          "rate": 345,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-21",
                          "available": true,
                          "rate": 395,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-22",
                          "available": true,
                          "rate": 395,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-23",
                          "available": true,
                          "rate": 350,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-24",
                          "available": true,
                          "rate": 315,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-25",
                          "available": true,
                          "rate": 315,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-26",
                          "available": true,
                          "rate": 315,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-27",
                          "available": true,
                          "rate": 335,
                          "min_nights": 2
                        },
                        {
                          "date": "2025-02-28",
                          "available": true,
                          "rate": 385,
                          "min_nights": 2
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          },
          "404": {
            "$ref": "#/components/responses/ListingNotFound"
          }
        }
      }
    },
    "/listings/live/calendar": {
      "get": {
        "tags": [
          "Listings"
        ],
        "summary": "Get Live Calendar",
        "operationId": "getLiveListingCalendar",
        "description": "Returns a listing's nightly rates, availability and minimum stays for the next 12 months.\n\n- `rate` is the nightly rate, excluding the cleaning fee.\n- `cleaning_fee` is the cleaning fee set by the host.\n- `short_stay_cleaning_fee` is the cleaning fee the host set for stays of 1–2 nights. It equals `cleaning_fee` when the host has one fee.\n- `available: false` covers both booked and host-blocked nights.\n- `currency=native` returns the listing's local currency; `usd` returns US dollars.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/listingIdParameter"
          },
          {
            "$ref": "#/components/parameters/currencyParameter"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Get a live calendar",
            "source": "curl -X GET \"https://api.airroi.com/listings/live/calendar?listing_id=43036533&currency=native\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "One entry per night with the estimated rate, availability and minimum stay.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LiveError"
                },
                "example": {
                  "code": "invalid_request",
                  "message": "listing_id must be positive."
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ListingNotFound"
          }
        }
      }
    },
    "/listings/live/rates": {
      "get": {
        "tags": [
          "Listings"
        ],
        "summary": "Get Live Rates",
        "operationId": "getLiveListingRates",
        "description": "Returns a listing's nightly rates for the next 12 months.\n\n- `rate` is the nightly rate, excluding the cleaning fee.\n- `currency=native` returns the listing's local currency; `usd` returns US dollars.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/listingIdParameter"
          },
          {
            "$ref": "#/components/parameters/currencyParameter"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Get live rates",
            "source": "curl -X GET \"https://api.airroi.com/listings/live/rates?listing_id=43036533&currency=usd\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "One entry per night with the estimated rate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RatesResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LiveError"
                },
                "example": {
                  "code": "invalid_request",
                  "message": "listing_id must be positive."
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ListingNotFound"
          }
        }
      }
    },
    "/listings/live/availability": {
      "get": {
        "tags": [
          "Listings"
        ],
        "summary": "Get Live Availability",
        "operationId": "getLiveListingAvailability",
        "description": "Returns a listing's nightly availability and stay rules for the next\n12 months.\n\n- `available: false` covers both booked and host-blocked nights.\n- `min_nights` and `max_nights` limit the length of a stay starting on that date.\n- `available_for_checkin` and `available_for_checkout` say whether guests can\n  arrive or leave on that date.\n- Stay rules are null when unknown.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/listingIdParameter"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Get live availability",
            "source": "curl -X GET \"https://api.airroi.com/listings/live/availability?listing_id=43036533\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "One entry per night with availability and stay rules.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LiveError"
                },
                "example": {
                  "code": "invalid_request",
                  "message": "listing_id must be positive."
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/ListingNotFound"
          }
        }
      }
    },
    "/listings/live/ranking": {
      "post": {
        "tags": [
          "Listings"
        ],
        "summary": "Get Live Search Ranking",
        "operationId": "getLiveListingRanking",
        "description": "Returns listing search rankings for an area, up to 270 listing IDs ordered by rank.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RankingRequest"
              },
              "examples": {
                "london": {
                  "summary": "Central London",
                  "value": {
                    "bounds": {
                      "south": 51.28676,
                      "west": -0.51036,
                      "north": 51.69188,
                      "east": 0.33404
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Rank listings in London",
            "source": "curl -X POST \"https://api.airroi.com/listings/live/ranking\" \\\n  -H \"x-api-key: your-airroi-api-key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"bounds\":{\"south\":51.28676,\"west\":-0.51036,\"north\":51.69188,\"east\":0.33404}}'\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Listings in search order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RankingResponse"
                },
                "example": {
                  "count": 3,
                  "results": [
                    {
                      "listing_id": "24978287",
                      "rank": 1
                    },
                    {
                      "listing_id": "1215478933284517640",
                      "rank": 2
                    },
                    {
                      "listing_id": "43036533",
                      "rank": 3
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LiveError"
                },
                "example": {
                  "code": "invalid_request",
                  "message": "Boundary exceeds the configured area or side-length limit."
                }
              }
            }
          }
        }
      }
    },
    "/listings/live/scan": {
      "post": {
        "tags": [
          "Listings"
        ],
        "summary": "Scan Live Listings",
        "operationId": "scanLiveListings",
        "description": "Returns the Airbnb listing IDs inside a polygon, up to 100 per page,\nin no particular order.\n\n### Pagination\n\nSend the first request without a cursor, then repeat it with `pagination.cursor`\nset to the previous `next_cursor` until `next_cursor` is null. A page can be short\nor empty before the scan ends.\n\n- Keep the same `polygon` and API key on every page.\n- To retry a failed page, resend the same cursor.\n- Cursors expire 24 hours after the first request.\n\n### Notes\n\n- IDs are unique within a scan, not across separate scans.\n- Listings are matched by their approximate location on Airbnb's map.\n- A scan returns at most 100,000 IDs. If the area is too large or dense, you get\n  a 422; split it into smaller areas.\n",
        "parameters": [
          {
            "name": "x-api-key",
            "in": "header",
            "required": true,
            "description": "Your API key. Every page of a scan must use the same key as the first request.\n",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScanRequest"
              },
              "examples": {
                "polygon": {
                  "summary": "Start a scan",
                  "value": {
                    "polygon": [
                      {
                        "latitude": 51.3,
                        "longitude": -0.5
                      },
                      {
                        "latitude": 51.7,
                        "longitude": -0.5
                      },
                      {
                        "latitude": 51.7,
                        "longitude": 0.3
                      },
                      {
                        "latitude": 51.3,
                        "longitude": 0.3
                      }
                    ],
                    "pagination": {
                      "page_size": 100
                    }
                  }
                },
                "nextPage": {
                  "summary": "Get the next page",
                  "description": "Same polygon as the first request, plus the `next_cursor` from the previous response.",
                  "value": {
                    "polygon": [
                      {
                        "latitude": 51.3,
                        "longitude": -0.5
                      },
                      {
                        "latitude": 51.7,
                        "longitude": -0.5
                      },
                      {
                        "latitude": 51.7,
                        "longitude": 0.3
                      },
                      {
                        "latitude": 51.3,
                        "longitude": 0.3
                      }
                    ],
                    "pagination": {
                      "page_size": 100,
                      "cursor": "<next_cursor from the previous response>"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Start a scan",
            "source": "curl -X POST \"https://api.airroi.com/listings/live/scan\" \\\n  -H \"x-api-key: your-airroi-api-key\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"polygon\":[{\"latitude\":51.3,\"longitude\":-0.5},{\"latitude\":51.7,\"longitude\":-0.5},{\"latitude\":51.7,\"longitude\":0.3},{\"latitude\":51.3,\"longitude\":0.3}],\"pagination\":{\"page_size\":100}}'\n"
          },
          {
            "lang": "Python",
            "label": "Scan every page",
            "source": "import requests\n\nURL = \"https://api.airroi.com/listings/live/scan\"\nHEADERS = {\"x-api-key\": \"your-airroi-api-key\"}\npolygon = [\n    {\"latitude\": 51.3, \"longitude\": -0.5},\n    {\"latitude\": 51.7, \"longitude\": -0.5},\n    {\"latitude\": 51.7, \"longitude\": 0.3},\n    {\"latitude\": 51.3, \"longitude\": 0.3},\n]\n\nlisting_ids = set()\ncursor = None\nwhile True:\n    body = {\"polygon\": polygon, \"pagination\": {\"page_size\": 100, \"cursor\": cursor}}\n    resp = requests.post(URL, json=body, headers=HEADERS, timeout=60)\n    resp.raise_for_status()\n    page = resp.json()\n    listing_ids.update(r[\"listing_id\"] for r in page[\"results\"])\n    cursor = page[\"pagination\"][\"next_cursor\"]\n    if cursor is None:  # short or empty pages don't mean the scan is done\n        break\n"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of listing IDs. Keep paging while `next_cursor` isn't null, even if the page is empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScanResponse"
                },
                "examples": {
                  "morePages": {
                    "summary": "More pages to fetch",
                    "value": {
                      "results": [
                        {
                          "listing_id": "24978287"
                        },
                        {
                          "listing_id": "1215478933284517640"
                        }
                      ],
                      "pagination": {
                        "page_size": 2,
                        "next_cursor": "<opaque cursor>"
                      }
                    }
                  },
                  "finished": {
                    "summary": "Last page",
                    "value": {
                      "results": [
                        {
                          "listing_id": "43036533"
                        }
                      ],
                      "pagination": {
                        "page_size": 1,
                        "next_cursor": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LiveError"
                },
                "example": {
                  "code": "invalid_request",
                  "message": "Invalid scan cursor or changed query/API key."
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired. Start a new scan.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LiveError"
                },
                "example": {
                  "code": "cursor_expired",
                  "message": "The scan cursor has expired; start a new scan."
                }
              }
            }
          },
          "422": {
            "description": "Area too large or dense to scan. Split it into smaller areas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LiveError"
                },
                "example": {
                  "code": "scan_limit_exceeded",
                  "message": "Scan reached its distinct-ID limit; use a smaller boundary."
                }
              }
            }
          }
        }
      }
    },
    "/markets/search": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "Find Market by Name",
        "description": "Search for Airbnb market data and vacation rental market information using our comprehensive STR market identifier lookup. Find short-term rental location data by searching with city names, neighborhoods, states, or countries to discover holiday rental market opportunities. The endpoint supports partial matching, making it ideal for building autocomplete and typeahead functionality in location search interfaces.\n\nReturns matching markets with their unique base64-encoded market IDs, active listing counts, and local currency information. Use the returned market ID for accessing historical performance data and future projections through our vacation rental market lookup system.\n",
        "operationId": "searchMarkets",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": true,
            "description": "Location search query for typeahead functionality. Start typing any location - from districts to entire countries. \nExamples: \n- Countries: \"Mex\" → Mexico, \"Jap\" → Japan, \"Port\" → Portugal\n- Regions: \"Calif\" → California, \"Tusc\" → Tuscany, \"Bav\" → Bavaria\n- Localities: \"Tok\" → Tokyo, \"Aus\" → Austin, \"Bar\" → Barcelona\n- Districts: \"Willi\" → Williamsburg, \"Soho\", \"Mission District\"\n- Tourist areas: \"French Riv\" → French Riviera, \"Costa\" → Costa Rica/Costa del Sol\n",
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "Paris"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Search Markets by Name",
            "source": "curl -X GET \"https://api.airroi.com/markets/search?query=Paris\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully retrieved matching markets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchMarketResponse"
                },
                "examples": {
                  "citySearch": {
                    "summary": "Search for Paris markets",
                    "value": {
                      "entries": [
                        {
                          "full_name": "Paris, Ile-de-France, France",
                          "country": "France",
                          "region": "Ile-de-France",
                          "locality": "Paris",
                          "district": null,
                          "native_currency": "EUR",
                          "active_listings_count": 35000
                        },
                        {
                          "full_name": "18th Arrondissement, Paris, Ile-de-France, France",
                          "country": "France",
                          "region": "Ile-de-France",
                          "locality": "Paris",
                          "district": "18th Arrondissement",
                          "native_currency": "EUR",
                          "active_listings_count": 2500
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/lookup": {
      "get": {
        "tags": [
          "Markets"
        ],
        "summary": "Find Market by Coordinates",
        "description": "Convert coordinates to market ID using our latitude longitude market lookup system. This STR geographic resolver finds the nearest short-term rental listing to the provided coordinates and returns the associated market ID for vacation rental location analysis.\n\nOur Airbnb market geocoding tool is perfect for converting property locations into market identifiers for further analysis. Returns a base64-encoded market ID that can be used with other market endpoints as a vacation rental location finder.\n",
        "operationId": "lookupMarket",
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": true,
            "description": "Latitude coordinate (-90 to 90)",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": -90,
              "maximum": 90
            },
            "example": 48.8566
          },
          {
            "name": "lng",
            "in": "query",
            "required": true,
            "description": "Longitude coordinate (-180 to 180)",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": -180,
              "maximum": 180
            },
            "example": 2.3522
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Lookup Market by Coordinates",
            "source": "curl -X GET \"https://api.airroi.com/markets/lookup?lat=48.8566&lng=2.3522\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully resolved market ID from coordinates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketLookupResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/markets/summary": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Summary",
        "description": "Get a comprehensive vacation rental market overview with key performance indicators for any Airbnb market worldwide. This endpoint provides essential market summary statistics including occupancy rates, average daily rates (ADR), revenue metrics, and minimum stay requirements for short-term rental market analysis. Perfect for quick market assessments, investment decisions, and competitive benchmarking in the vacation rental industry.\n\nReturns aggregated market performance data to help property managers, real estate investors, and market analysts understand market dynamics at a glance.\n",
        "operationId": "getMarketSummary",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "nashvilleMusicCity": {
                  "summary": "Nashville music district vacation rental market analysis",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Tennessee",
                      "locality": "Nashville"
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "miamiBeachLuxury": {
                  "summary": "Luxury beachfront condos in Miami Beach",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Florida",
                      "locality": "Miami Beach"
                    },
                    "filter": {
                      "bedrooms": {
                        "gte": 3
                      },
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "amenities": {
                        "all": [
                          "ocean_view",
                          "pool",
                          "gym"
                        ]
                      },
                      "ttm_revenue": {
                        "gte": 100000
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                },
                "coloradoSkiMarkets": {
                  "summary": "Ski resort markets comparison in Colorado",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Colorado",
                      "locality": "Aspen"
                    },
                    "filter": {
                      "bedrooms": {
                        "range": [
                          2,
                          4
                        ]
                      },
                      "amenities": {
                        "any": [
                          "hot_tub",
                          "indoor_fireplace",
                          "ski_in_ski_out"
                        ]
                      },
                      "min_nights": {
                        "lte": 7
                      }
                    },
                    "num_months": 36,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved market summary.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarketSummaryResponse"
                },
                "examples": {
                  "marketSummaryExample": {
                    "summary": "Key metrics for a city-level market",
                    "value": {
                      "market": {
                        "country": "United States",
                        "region": "California",
                        "locality": "Los Angeles"
                      },
                      "occupancy": 0.72,
                      "average_daily_rate": 285.5,
                      "rev_par": 205.56,
                      "revenue": 125000,
                      "booking_lead_time": 42.5,
                      "length_of_stay": 3.8,
                      "min_nights": 3.2,
                      "active_listings_count": 2458
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/all": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market All Metrics",
        "description": "Access comprehensive vacation rental market analytics with all available performance metrics for any Airbnb market worldwide. This endpoint delivers a complete market overview including occupancy rates, average daily rates (ADR), RevPAR, revenue trends, booking patterns, minimum stay requirements, and active listing counts. Essential for market research, investment analysis, and competitive benchmarking in the short-term rental industry.\n\nReturns historical market performance data with daily, monthly, and trailing twelve months (TTM) aggregations, enabling deep market analysis and trend identification for vacation rental markets.\n",
        "operationId": "getMarketMetrics",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "hawaiiIslandComparison": {
                  "summary": "Compare metrics across Hawaiian islands",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Hawaii",
                      "locality": "Maui"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "range": [
                          1,
                          3
                        ]
                      },
                      "amenities": {
                        "any": [
                          "ocean_view",
                          "beach_access",
                          "pool"
                        ]
                      }
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "europeCapitalCities": {
                  "summary": "Studio apartments in European capitals",
                  "value": {
                    "market": {
                      "country": "France",
                      "region": "Ile-de-France",
                      "locality": "Paris"
                    },
                    "filter": {
                      "bedrooms": {
                        "eq": 0
                      },
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "instant_book": {
                        "eq": true
                      },
                      "superhost": {
                        "eq": true
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved all market metrics.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CombinedMetricsResponse"
                },
                "examples": {
                  "combinedMetricsExample": {
                    "summary": "Monthly market metrics including minimum nights",
                    "value": {
                      "market": {
                        "country": "United States",
                        "region": "California",
                        "locality": "Los Angeles"
                      },
                      "results": [
                        {
                          "date": "2024-01-01",
                          "occupancy": {
                            "avg": 0.68,
                            "p25": 0.55,
                            "p50": 0.69,
                            "p75": 0.82,
                            "p90": 0.91
                          },
                          "average_daily_rate": {
                            "avg": 275,
                            "p25": 150,
                            "p50": 225,
                            "p75": 350,
                            "p90": 500
                          },
                          "revpar": {
                            "avg": 187,
                            "p25": 82.5,
                            "p50": 155.25,
                            "p75": 287,
                            "p90": 455
                          },
                          "revenue": {
                            "avg": 5797,
                            "p25": 2557.5,
                            "p50": 4812.75,
                            "p75": 8897,
                            "p90": 14105
                          },
                          "booking_lead_time": {
                            "avg": 38.5,
                            "p25": 14,
                            "p50": 28,
                            "p75": 56,
                            "p90": 90
                          },
                          "length_of_stay": {
                            "avg": 4.2,
                            "p25": 2,
                            "p50": 3,
                            "p75": 5,
                            "p90": 8
                          },
                          "min_nights": {
                            "avg": 3.1,
                            "p25": 2,
                            "p50": 3,
                            "p75": 4,
                            "p90": 5
                          },
                          "active_listings_count": 3245
                        },
                        {
                          "date": "2024-02-01",
                          "occupancy": {
                            "avg": 0.72,
                            "p25": 0.58,
                            "p50": 0.73,
                            "p75": 0.85,
                            "p90": 0.93
                          },
                          "average_daily_rate": {
                            "avg": 285,
                            "p25": 155,
                            "p50": 235,
                            "p75": 365,
                            "p90": 525
                          },
                          "revpar": {
                            "avg": 205.2,
                            "p25": 89.9,
                            "p50": 171.55,
                            "p75": 310.25,
                            "p90": 488.25
                          },
                          "revenue": {
                            "avg": 5745.6,
                            "p25": 2517.2,
                            "p50": 4803.4,
                            "p75": 8687,
                            "p90": 13671
                          },
                          "booking_lead_time": {
                            "avg": 42,
                            "p25": 15,
                            "p50": 30,
                            "p75": 60,
                            "p90": 95
                          },
                          "length_of_stay": {
                            "avg": 4.5,
                            "p25": 2,
                            "p50": 3,
                            "p75": 6,
                            "p90": 10
                          },
                          "min_nights": {
                            "avg": 3.4,
                            "p25": 2,
                            "p50": 3,
                            "p75": 4,
                            "p90": 6
                          },
                          "active_listings_count": 3289
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/occupancy": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Occupancy",
        "description": "Track vacation rental occupancy rates and booking patterns for any Airbnb market with detailed time-series data. This endpoint delivers historical occupancy percentages showing how often short-term rentals are booked in your target market. Essential for understanding market demand, seasonal trends, and booking dynamics in the vacation rental industry.\n\nReturns daily, monthly, and aggregated occupancy data to help optimize pricing strategies, identify peak seasons, and forecast market performance for short-term rental investments.\n",
        "operationId": "getMarketOccupancy",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "seattleUrbanCore": {
                  "summary": "Downtown Seattle apartment occupancy trends",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Washington",
                      "locality": "Seattle"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "lte": 2
                      },
                      "min_nights": {
                        "lte": 30
                      }
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "arizonaDesertResorts": {
                  "summary": "Scottsdale luxury golf resort area occupancy",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Arizona",
                      "locality": "Scottsdale"
                    },
                    "filter": {
                      "bedrooms": {
                        "gte": 3
                      },
                      "amenities": {
                        "all": [
                          "pool",
                          "hot_tub",
                          "golf_access"
                        ]
                      },
                      "ttm_revenue": {
                        "gte": 80000
                      },
                      "superhost": {
                        "eq": true
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                },
                "japanCherryBlossom": {
                  "summary": "Tokyo occupancy during cherry blossom season",
                  "value": {
                    "market": {
                      "country": "Japan",
                      "region": "Tokyo Prefecture",
                      "locality": "Tokyo"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "guests": {
                        "gte": 4
                      },
                      "amenities": {
                        "any": [
                          "kitchen",
                          "washer"
                        ]
                      }
                    },
                    "num_months": 36,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved occupancy data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetricTimeSeriesResponse"
                },
                "examples": {
                  "occupancyExample": {
                    "summary": "Monthly occupancy rates for Miami market",
                    "value": {
                      "market": {
                        "country": "United States",
                        "region": "Florida",
                        "locality": "Miami"
                      },
                      "results": [
                        {
                          "date": "2024-01-01",
                          "avg": 0.75,
                          "p25": 0.62,
                          "p50": 0.76,
                          "p75": 0.88,
                          "p90": 0.94
                        },
                        {
                          "date": "2024-02-01",
                          "avg": 0.78,
                          "p25": 0.65,
                          "p50": 0.79,
                          "p75": 0.9,
                          "p90": 0.95
                        },
                        {
                          "date": "2024-03-01",
                          "avg": 0.82,
                          "p25": 0.7,
                          "p50": 0.83,
                          "p75": 0.92,
                          "p90": 0.97
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/average-daily-rate": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Average Daily Rate",
        "description": "Access Airbnb pricing trends and average daily rate (ADR) analytics for vacation rental markets worldwide. This endpoint provides comprehensive pricing data showing what guests pay per night in your target market. Critical for revenue management, competitive pricing analysis, and understanding market rate dynamics in the short-term rental industry.\n\nReturns historical ADR time-series data with daily, monthly, and seasonal trends to help property managers optimize pricing strategies and maximize rental income.\n",
        "operationId": "getMarketAverageDailyRate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "nantucketSummerRates": {
                  "summary": "Nantucket summer season pricing analysis",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Massachusetts",
                      "locality": "Nantucket"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "gte": 3
                      },
                      "amenities": {
                        "any": [
                          "beach_access",
                          "ocean_view",
                          "private_deck"
                        ]
                      }
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "barcelonaNeighborhoods": {
                  "summary": "Barcelona neighborhood pricing comparison",
                  "value": {
                    "market": {
                      "country": "Spain",
                      "region": "Catalonia",
                      "locality": "Barcelona"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "range": [
                          1,
                          2
                        ]
                      },
                      "min_nights": {
                        "lte": 7
                      },
                      "instant_book": {
                        "eq": true
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved average daily rate data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetricTimeSeriesResponse"
                },
                "examples": {
                  "adrExample": {
                    "summary": "Monthly ADR trends for Barcelona market",
                    "value": {
                      "market": {
                        "country": "Spain",
                        "region": "Catalonia",
                        "locality": "Barcelona"
                      },
                      "results": [
                        {
                          "date": "2024-01-01",
                          "avg": 125.5,
                          "p25": 75,
                          "p50": 110,
                          "p75": 165,
                          "p90": 225
                        },
                        {
                          "date": "2024-02-01",
                          "avg": 132,
                          "p25": 78,
                          "p50": 115,
                          "p75": 172,
                          "p90": 238
                        },
                        {
                          "date": "2024-03-01",
                          "avg": 145.75,
                          "p25": 85,
                          "p50": 125,
                          "p75": 185,
                          "p90": 265
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/revpar": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market RevPAR",
        "description": "Analyze vacation rental revenue per available rental (RevPAR) metrics for comprehensive market performance insights. This endpoint combines occupancy and pricing data to show the average revenue generated per available listing in any Airbnb market. Essential for investment analysis, portfolio optimization, and understanding true market earning potential in the short-term rental sector.\n\nReturns RevPAR time-series data that helps investors and property managers evaluate market profitability, compare investment opportunities, and track revenue performance trends.\n",
        "operationId": "getMarketRevPar",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "laVegasRevpar": {
                  "summary": "Las Vegas strip RevPAR analysis",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Nevada",
                      "locality": "Las Vegas"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "gte": 2
                      },
                      "amenities": {
                        "any": [
                          "pool",
                          "hot_tub",
                          "gym"
                        ]
                      }
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "londonBoroughComparison": {
                  "summary": "London high-end property RevPAR metrics",
                  "value": {
                    "market": {
                      "country": "United Kingdom",
                      "region": "England",
                      "locality": "London"
                    },
                    "filter": {
                      "bedrooms": {
                        "gte": 3
                      },
                      "ttm_revenue": {
                        "gt": 100000
                      },
                      "superhost": {
                        "eq": true
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved RevPAR data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetricTimeSeriesResponse"
                },
                "examples": {
                  "revParExample": {
                    "summary": "Monthly RevPAR (Currency)",
                    "value": {
                      "market": {
                        "country": "United States",
                        "region": "Nevada",
                        "locality": "Las Vegas"
                      },
                      "results": [
                        {
                          "date": "2024-01-01",
                          "avg": 185.5,
                          "p25": 95,
                          "p50": 160,
                          "p75": 240,
                          "p90": 350
                        },
                        {
                          "date": "2024-02-01",
                          "avg": 192,
                          "p25": 98,
                          "p50": 165,
                          "p75": 245,
                          "p90": 360
                        },
                        {
                          "date": "2024-03-01",
                          "avg": 210.75,
                          "p25": 110,
                          "p50": 180,
                          "p75": 270,
                          "p90": 390
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/revenue": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Revenue",
        "description": "Access comprehensive vacation rental revenue analytics showing total market earnings and income trends for any Airbnb market. This endpoint provides aggregated revenue data demonstrating the overall market size and earning potential for short-term rentals. Valuable for market sizing, investment planning, and understanding the economic impact of vacation rentals in specific locations.\n\nReturns historical revenue time-series data with seasonal patterns and growth trends to support market analysis and investment decisions in the short-term rental industry.\n",
        "operationId": "getMarketRevenue",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "cancunTourismRevenue": {
                  "summary": "Cancun beachfront vacation rental revenues",
                  "value": {
                    "market": {
                      "country": "Mexico",
                      "region": "Quintana Roo",
                      "locality": "Cancun"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "amenities": {
                        "any": [
                          "beach_access",
                          "ocean_view",
                          "pool"
                        ]
                      },
                      "bedrooms": {
                        "gte": 2
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                },
                "denverSkiSeasonRevenue": {
                  "summary": "Denver area revenue during ski season",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Colorado",
                      "locality": "Denver"
                    },
                    "filter": {
                      "ttm_revenue": {
                        "gte": 50000
                      },
                      "guests": {
                        "gte": 6
                      },
                      "amenities": {
                        "any": [
                          "hot_tub",
                          "indoor_fireplace"
                        ]
                      }
                    },
                    "num_months": 36,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved revenue data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetricTimeSeriesResponse"
                },
                "examples": {
                  "revenueExample": {
                    "summary": "Monthly revenue trends for Denver market",
                    "value": {
                      "market": {
                        "country": "United States",
                        "region": "Colorado",
                        "locality": "Denver"
                      },
                      "results": [
                        {
                          "date": "2024-01-01",
                          "avg": 4250,
                          "p25": 1800,
                          "p50": 3500,
                          "p75": 5800,
                          "p90": 9200
                        },
                        {
                          "date": "2024-02-01",
                          "avg": 4680,
                          "p25": 2100,
                          "p50": 3900,
                          "p75": 6200,
                          "p90": 9800
                        },
                        {
                          "date": "2024-03-01",
                          "avg": 5320,
                          "p25": 2400,
                          "p50": 4500,
                          "p75": 7100,
                          "p90": 11500
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/booking-lead-time": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Booking Lead Time",
        "description": "Understand guest booking behavior with detailed booking lead time analytics for vacation rental markets. This endpoint reveals how far in advance guests typically book short-term rentals in your target market. Critical for revenue management, marketing timing, and inventory planning in the Airbnb ecosystem.\n\nReturns booking lead time patterns showing the average days between booking and check-in, helping property managers optimize availability calendars, adjust pricing strategies, and plan marketing campaigns.\n",
        "operationId": "getMarketBookingLeadTime",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "businessTravelMarkets": {
                  "summary": "San Francisco business travel booking patterns",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "California",
                      "locality": "San Francisco"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "lte": 1
                      },
                      "instant_book": {
                        "eq": true
                      }
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "lastMinuteBeachMarkets": {
                  "summary": "Miami Beach spontaneous booking analysis",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Florida",
                      "locality": "Miami Beach"
                    },
                    "filter": {
                      "amenities": {
                        "any": [
                          "beach_access",
                          "pool"
                        ]
                      },
                      "min_nights": {
                        "lte": 3
                      },
                      "superhost": {
                        "eq": true
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved booking lead time data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetricTimeSeriesResponse"
                },
                "examples": {
                  "bookingLeadTimeExample": {
                    "summary": "Monthly booking lead time (days)",
                    "value": {
                      "market": {
                        "country": "United States",
                        "region": "Florida",
                        "locality": "Miami"
                      },
                      "results": [
                        {
                          "date": "2024-01-01",
                          "avg": 42.5,
                          "p25": 14,
                          "p50": 30,
                          "p75": 60,
                          "p90": 95
                        },
                        {
                          "date": "2024-02-01",
                          "avg": 45,
                          "p25": 15,
                          "p50": 32,
                          "p75": 65,
                          "p90": 100
                        },
                        {
                          "date": "2024-03-01",
                          "avg": 38,
                          "p25": 12,
                          "p50": 28,
                          "p75": 55,
                          "p90": 90
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/length-of-stay": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Length of Stay",
        "description": "Analyze guest stay duration patterns and average length of stay metrics for vacation rental markets worldwide. This endpoint provides insights into typical booking durations, helping understand whether markets cater to short weekend trips or extended stays. Essential for property setup, amenity planning, and pricing strategy optimization in the short-term rental industry.\n\nReturns length of stay distribution data showing average nights per booking, enabling property managers to tailor their offerings and minimum stay requirements to match market demand.\n",
        "operationId": "getMarketLengthOfStay",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "monthlyRentalMarkets": {
                  "summary": "Austin extended stay rental patterns",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Texas",
                      "locality": "Austin"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "gte": 2
                      },
                      "min_nights": {
                        "gte": 28
                      },
                      "amenities": {
                        "all": [
                          "kitchen",
                          "washer",
                          "dedicated_workspace"
                        ]
                      }
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "weekendGetawayMarkets": {
                  "summary": "Napa Valley weekend trip analysis",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "California",
                      "locality": "Napa"
                    },
                    "filter": {
                      "amenities": {
                        "any": [
                          "hot_tub",
                          "pool",
                          "vineyard_view"
                        ]
                      },
                      "min_nights": {
                        "lte": 3
                      },
                      "guests": {
                        "gte": 4
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved length of stay data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetricTimeSeriesResponse"
                },
                "examples": {
                  "lengthOfStayExample": {
                    "summary": "Monthly length of stay (nights)",
                    "value": {
                      "market": {
                        "country": "United States",
                        "region": "California",
                        "locality": "San Francisco"
                      },
                      "results": [
                        {
                          "date": "2024-01-01",
                          "avg": 4.2,
                          "p25": 2,
                          "p50": 3,
                          "p75": 5,
                          "p90": 7
                        },
                        {
                          "date": "2024-02-01",
                          "avg": 4.5,
                          "p25": 2,
                          "p50": 3,
                          "p75": 6,
                          "p90": 8
                        },
                        {
                          "date": "2024-03-01",
                          "avg": 3.8,
                          "p25": 2,
                          "p50": 3,
                          "p75": 5,
                          "p90": 6
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/min-nights": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Min Nights",
        "description": "Analyze average minimum stay requirements for vacation rental markets worldwide. This endpoint shows how restrictive a market is by month, helping operators understand whether a market is optimized for short getaways or longer stays. Essential for competitive positioning, stay-rule benchmarking, and aligning listing policies with local demand.\n\nReturns monthly minimum-stay distributions so property managers and investors can compare their stay rules against prevailing market behavior.\n",
        "operationId": "getMarketMinNights",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "urbanWeekendMarkets": {
                  "summary": "Short-stay urban market analysis",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Illinois",
                      "locality": "Chicago"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "lte": 2
                      },
                      "instant_book": {
                        "eq": true
                      }
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "destinationResorts": {
                  "summary": "Resort markets with longer stay restrictions",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Hawaii",
                      "locality": "Maui"
                    },
                    "filter": {
                      "bedrooms": {
                        "gte": 2
                      },
                      "amenities": {
                        "any": [
                          "ocean_view",
                          "pool",
                          "beach_access"
                        ]
                      }
                    },
                    "num_months": 24,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved minimum nights data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetricTimeSeriesResponse"
                },
                "examples": {
                  "minNightsExample": {
                    "summary": "Monthly average minimum nights by market",
                    "value": {
                      "market": {
                        "country": "United States",
                        "region": "California",
                        "locality": "San Diego"
                      },
                      "results": [
                        {
                          "date": "2024-01-01",
                          "avg": 2.8,
                          "p25": 2,
                          "p50": 2,
                          "p75": 3,
                          "p90": 5
                        },
                        {
                          "date": "2024-02-01",
                          "avg": 3.1,
                          "p25": 2,
                          "p50": 3,
                          "p75": 4,
                          "p90": 5
                        },
                        {
                          "date": "2024-03-01",
                          "avg": 3.4,
                          "p25": 2,
                          "p50": 3,
                          "p75": 4,
                          "p90": 6
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/active-listings": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Active Listings Count",
        "description": "Monitor vacation rental market supply and competition levels with active listing counts for any Airbnb market. This endpoint tracks the total number of available short-term rentals, providing crucial supply-side intelligence for market analysis. Essential for understanding market saturation, competitive landscape, and growth opportunities in the vacation rental sector.\n\nReturns current and historical active listing counts to help investors assess market competition, identify emerging markets, and track supply growth trends over time.\n",
        "operationId": "getMarketActiveListingsCount",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "competitiveLandscape": {
                  "summary": "Manhattan luxury market competition analysis",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "New York",
                      "locality": "New York"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "gte": 2
                      },
                      "ttm_avg_rate": {
                        "gt": 500
                      },
                      "amenities": {
                        "all": [
                          "doorman",
                          "gym",
                          "air_conditioning"
                        ]
                      }
                    },
                    "num_months": 12,
                    "currency": "native"
                  }
                },
                "emergingMarkets": {
                  "summary": "Portugal coastal towns supply growth",
                  "value": {
                    "market": {
                      "country": "Portugal",
                      "region": "Algarve"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "amenities": {
                        "any": [
                          "pool",
                          "ocean_view",
                          "beach_access"
                        ]
                      },
                      "superhost": {
                        "eq": true
                      }
                    },
                    "num_months": 60,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved the count of active listings.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActiveListingsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/markets/metrics/future/pacing": {
      "post": {
        "tags": [
          "Markets"
        ],
        "summary": "Get Market Future Pacing",
        "description": "Forecast vacation rental market performance with forward-looking pacing data and booking trends for Airbnb markets. This endpoint provides visibility into future occupancy and demand patterns based on current bookings on the books. Critical for revenue forecasting, seasonal planning, and proactive market strategy in the short-term rental industry.\n\nReturns future pacing metrics showing booked occupancy rates for upcoming periods, helping property managers and investors anticipate market demand and adjust strategies accordingly.\n",
        "operationId": "getMarketFuturePacing",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarketQueryRequest"
              },
              "examples": {
                "summerSeasonForecast": {
                  "summary": "Cape Cod summer season pacing",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Massachusetts",
                      "locality": "Cape Cod"
                    },
                    "filter": {
                      "room_type": {
                        "eq": "entire_home"
                      },
                      "bedrooms": {
                        "gte": 3
                      },
                      "amenities": {
                        "any": [
                          "beach_access",
                          "ocean_view",
                          "outdoor_shower"
                        ]
                      }
                    },
                    "num_months": 6,
                    "currency": "native"
                  }
                },
                "winterHolidayPacing": {
                  "summary": "Park City holiday season booking pace",
                  "value": {
                    "market": {
                      "country": "United States",
                      "region": "Utah",
                      "locality": "Park City"
                    },
                    "filter": {
                      "guests": {
                        "gte": 8
                      },
                      "amenities": {
                        "all": [
                          "hot_tub",
                          "indoor_fireplace",
                          "ski_access"
                        ]
                      },
                      "ttm_revenue": {
                        "gt": 100000
                      }
                    },
                    "num_months": 3,
                    "currency": "native"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully retrieved future pacing data.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FuturePacingResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/calculator/estimate": {
      "get": {
        "tags": [
          "Calculator"
        ],
        "summary": "Estimate Listing Revenue Potential",
        "description": "Use our Airbnb revenue calculator and vacation rental income estimator to generate comprehensive STR profit projections for potential short-term rental properties. This powerful short-term rental ROI calculator serves as your complete property investment analysis tool based on location and property characteristics.\n\n**Location Input:** Specify the property location using either geographic coordinates (`lat` + `lng`) or a physical `address`. These are mutually exclusive — provide one or the other, not both.\n\nOur vacation rental income estimator analyzes comparable properties in the area to provide:\n- Projected annual occupancy rate using STR profit projection models\n- Expected Average Daily Rate (ADR) from our Airbnb revenue calculator\n- Monthly revenue distribution across the year\n- Full percentile breakdown (p25, p50, p75, p90) for revenue, ADR, and occupancy\n- A list of comparable listings used to generate the estimate\n\nThe response includes root-level average values for quick access, plus a `percentiles` object with full statistical breakdown (p25, p50, p75, p90) for detailed analysis. A `location` object with the resolved latitude and longitude is always included in the response.\n",
        "operationId": "calculateEstimate",
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Property latitude for revenue estimation.\nRequired if `address` is not provided. Mutually exclusive with `address`.\n",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": -90,
              "maximum": 90
            },
            "example": 34.052235
          },
          {
            "name": "lng",
            "in": "query",
            "required": false,
            "description": "Property longitude for revenue estimation.\nRequired if `address` is not provided. Mutually exclusive with `address`.\n",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": -180,
              "maximum": 180
            },
            "example": -118.243683
          },
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "Physical address of the property for revenue estimation.\nThe address is geocoded to latitude/longitude coordinates using Google Geocoding API.\nRequired if `lat` and `lng` are not provided. Mutually exclusive with `lat`/`lng`.\n",
            "schema": {
              "type": "string"
            },
            "example": "1234 Ocean Drive, Miami Beach, FL 33139"
          },
          {
            "name": "radius",
            "in": "query",
            "required": false,
            "description": "Search radius in miles for comparable listings. Default: 3 miles.\nIncrease the radius in low-density areas (e.g. rural locations or\nlarge homes with few similar properties nearby) to find more\ncomparables.\n",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": 1,
              "maximum": 10,
              "default": 3
            },
            "example": 5
          },
          {
            "name": "room_type",
            "in": "query",
            "required": false,
            "description": "Restrict comparable listings to a single room type. By default all\nroom types are searched. For whole-property revenue estimates,\n`entire_home` is recommended — it excludes private/shared rooms that\ncan otherwise appear as weak comparables in low-density areas.\n",
            "schema": {
              "type": "string",
              "enum": [
                "entire_home",
                "private_room",
                "shared_room"
              ]
            },
            "example": "entire_home"
          },
          {
            "name": "bedrooms",
            "in": "query",
            "required": true,
            "description": "Number of bedrooms (use 0 for studios)",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 20
            },
            "example": 2
          },
          {
            "name": "baths",
            "in": "query",
            "required": true,
            "description": "Number of bathrooms (supports decimals for half baths)",
            "schema": {
              "type": "number",
              "format": "double",
              "minimum": 0.5,
              "maximum": 20
            },
            "example": 2
          },
          {
            "name": "guests",
            "in": "query",
            "required": true,
            "description": "Maximum guest capacity",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 30
            },
            "example": 4
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "description": "Currency for financial data conversion. Default: native currency.\nAllowed currency values are 'usd' (US Dollars) or 'native' (local currency).\nFor example, 'native' automatically uses EUR in France, JPY in Japan, or BRL in Brazil etc.\n",
            "schema": {
              "type": "string",
              "enum": [
                "usd",
                "native"
              ],
              "default": "native"
            },
            "example": "usd"
          }
        ],
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "Coordinates Query",
            "source": "curl -X GET \"https://api.airroi.com/calculator/estimate?lat=34.052235&lng=-118.243683&bedrooms=2&baths=2.0&guests=4&currency=native\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          },
          {
            "lang": "Shell",
            "label": "Address Query",
            "source": "curl -X GET \"https://api.airroi.com/calculator/estimate?address=1234+Ocean+Drive,+Miami+Beach,+FL+33139&bedrooms=2&baths=2.0&guests=4&currency=usd\" \\\n  -H \"x-api-key: your-airroi-api-key\"\n"
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully calculated revenue estimates",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalculatorEstimateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          }
        }
      }
    },
    "/price-recommendation/base-price": {
      "post": {
        "tags": [
          "Price Recommendation"
        ],
        "summary": "Recommend a Base Price",
        "description": "Estimate a property's year-round nightly starting price, before date-specific\nadjustments, fees, and taxes. Nothing is saved or published.\n\n### Property details\n\nProvide the property's coordinates, bedroom and bathroom counts, and guest\ncapacity. Optional details—such as amenities, reviews, and cleaning fees—can\nrefine the estimate. Leave out details you do not know.\n\n### Understanding the estimate\n\nThe response includes a balanced recommendation, conservative and aggressive\nalternatives, a typical local price range, and an itemized explanation.\nThe range is context, not a price limit or a guarantee.\n\nUse the recommendation and its returned currency with\n[Recommend Calendar Prices](#tag/Price-Recommendation/operation/recommendCalendarPrices)\nto calculate nightly rates for individual dates. Amounts are whole currency\nunits, not cents. Currency defaults to USD, including when an unrecognized\ncode is supplied, so check the returned currency.\n\n### Errors\n\nError bodies from this endpoint are simpler than those of Calendar Prices:\na flat `code` and `message` object on 400, and an `errors` list on\n422, with no `error` envelope and no `request_id` field. The `X-Request-ID`\nheader is still returned; quote it when contacting support.\n\nFor deeper context and examples, see [choosing a base price](https://www.airroi.com/resources/dynamic-pricing/base-price).\n",
        "operationId": "recommendBasePrice",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BasePriceRecommendationRequest"
              },
              "examples": {
                "simple": {
                  "summary": "Required fields",
                  "description": "Coordinates, bedrooms, bathrooms and guest capacity. Enough for a recommendation.\n",
                  "value": {
                    "location": {
                      "latitude": 25.7907,
                      "longitude": -80.13
                    },
                    "property": {
                      "bedrooms": 3,
                      "baths": 2.5,
                      "guests": 6
                    },
                    "currency": "USD"
                  }
                },
                "withPropertyDetails": {
                  "summary": "With property details",
                  "description": "Every optional field. Only the listed amenity signals change the price; other strings are accepted and echoed in the explanation.\n",
                  "value": {
                    "location": {
                      "latitude": 33.5615,
                      "longitude": -111.9256
                    },
                    "property": {
                      "bedrooms": 3,
                      "baths": 2.5,
                      "guests": 6,
                      "beds": 4,
                      "room_type": "entire_home",
                      "amenities": [
                        "pool",
                        "hot_tub",
                        "dedicated_workspace",
                        "air_conditioning",
                        "washer",
                        "dryer"
                      ],
                      "num_reviews": 42,
                      "star_rating": 4.88,
                      "superhost": true,
                      "photos_count": 31,
                      "cleaning_fee": 95
                    },
                    "currency": "USD"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Balanced Base Price, conservative and aggressive options, typical local range, and explanation",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasePriceRecommendationResponse"
                },
                "examples": {
                  "simple": {
                    "summary": "Base price recommendation",
                    "description": "Illustrative result for the required-fields request. The explanation amounts sum to 200; actual prices depend on the property and current model.\n",
                    "value": {
                      "location": {
                        "latitude": 25.7907,
                        "longitude": -80.13
                      },
                      "currency": "USD",
                      "recommended_base_price": 200,
                      "price_options": {
                        "conservative": 184,
                        "balanced": 200,
                        "aggressive": 216
                      },
                      "typical_market_range": {
                        "low": 150,
                        "high": 260
                      },
                      "explanation": [
                        {
                          "code": "market_baseline",
                          "label": "Market baseline",
                          "amount": 172
                        },
                        {
                          "code": "bedrooms",
                          "label": "3 bedrooms",
                          "amount": 20
                        },
                        {
                          "code": "bathrooms",
                          "label": "2.5 bathrooms",
                          "amount": 6
                        },
                        {
                          "code": "guest_capacity",
                          "label": "Sleeps 6",
                          "amount": 4
                        },
                        {
                          "code": "current_market_level",
                          "label": "Current market adjustment",
                          "amount": -2
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON, a field with the wrong JSON type, or a cleaning fee above 10,000 USD-equivalent",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasePriceErrorMessage"
                },
                "examples": {
                  "malformedJson": {
                    "summary": "Malformed JSON",
                    "value": {
                      "code": 400,
                      "message": "Unable to process JSON"
                    }
                  },
                  "wrongJsonType": {
                    "summary": "Wrong JSON type on a known field",
                    "value": {
                      "code": 400,
                      "message": "Invalid request JSON",
                      "field": null,
                      "hint": null
                    }
                  },
                  "cleaningFeeCap": {
                    "summary": "Cleaning fee above 10,000 USD-equivalent",
                    "value": {
                      "code": 400,
                      "message": "cleaning_fee must be 0-10000"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          },
          "422": {
            "description": "One or more request fields are missing, out of range, or not in the allowed set; an empty body is also a 422",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BasePriceValidationError"
                },
                "example": {
                  "errors": [
                    "property.guests property.guests is required",
                    "property.bedrooms property.bedrooms is required"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/price-recommendation/calendar-prices": {
      "post": {
        "tags": [
          "Price Recommendation"
        ],
        "summary": "Recommend Calendar Prices",
        "description": "Calculate nightly prices from a base price, automatically accounting for seasonality,\nweekdays, holidays/events, and market demand. Optional rules let you tailor the result.\nNothing is saved or published; send your settings with each request.\n\nEvery example below is a real response for a 200 USD base price in Nashville, Tennessee,\ncalculated on **Mon Sep 14, 2026** (America/Chicago). Dates in the snippets are relative to that day;\nreplace them with your own. Each example turns on only the rule it explains, and the\nprice strip shows the night's price **without the rule → with the rule**.\n\n### How a night is priced\n\nEvery night goes through the same seven stages, in this order. Each stage adds its lines\nto that night's `explanation`, and the lines always add up to `price`. Here is a real\nSaturday that is a one-night gap between two reservations, with a last-minute rule, a gap\nrule, a Saturday uplift, a +10% override and a 260 ceiling all switched on:\n\n| Stage | Receipt line | Amount |\n|---|---|---|\n| 1. Base price | Base price | 200 |\n| 2. Model effects | Seasonality (+10.32%) | 20.64 |\n| 2. Model effects | Day of week (+10.52%) | 23.22 |\n| 2. Model effects | Holiday/event (+0%) | 0 |\n| 2. Model effects | Market demand (+0%) | 0 |\n| 3. Automatic rules | Last-minute rule (−10%) | -24.38 |\n| 3. Automatic rules | Gap-night rule (−15%) | -36.58 |\n| 4. Custom weekday | Custom Saturday rule (+10%) | 18.29 |\n| 5. Percentage overrides | Percentage price override (+10%) | 20.11 |\n| | **Price for Sat Sep 26** | **221.30** |\n\nStages 2, 4 and 5 compound: each multiplies the running price. Stage 3 does not: the automatic rules' percentages are added together (−10 − 15 = −25%) and applied once against the running total after stage 2, with no combined cap. The ceiling was never reached, so stage 6 left no line.\n\n### Presets at a glance\n\nThree rules ship with presets. A preset takes no `settings`; `custom` requires the full\nsettings shown in each rule below. Every other rule is `custom` only.\n\n| Rule | conservative | balanced | aggressive |\n|---|---|---|---|\n| Last minute | opens 7 days out, down to −8% | opens 21 days out, down to −15% | opens 45 days out, down to −25% |\n| Far future | +0% at 270 days out, rising to +5% at one year | +0% at 180 days, rising to +10% at one year | +0% at 120 days, rising to +15% at one year |\n| Gap day | −4% / −2% / 0% for 1 / 2 / 3-night gaps | −8% / −4% / −2% | −12% / −8% / −4% |\n\nGap-day presets cover gaps of one to three nights; longer gaps are left alone unless you define your own bands.\n\n### Rules cookbook\n\nFragments below drop into `pricing_rules` (or the top-level key named in the heading).\nEach rule has three examples that build on each other: the first is the smallest working request, the last shows the rule interacting with overrides or other rules. Each example gives the request fragment and what it did to real nights.\n\n#### Last minute\n\nDiscount (or raise) nights that are close to arrival and still unsold.\n\n| Field | Values | What it does |\n|---|---|---|\n| `mode` | `disabled` `conservative` `balanced` `aggressive` `custom` | Presets need nothing else. |\n| `settings.start_days` | 1 – 90 | Window opens this many days before arrival (inclusive). |\n| `settings.adjustment_percent` | > −100 | The full percentage. Negative discounts, positive raises. |\n| `settings.adjustment_type` | `flat` `gradual` | Same every night, or ramping toward arrival. |\n| `settings.end_days` | 0 – `start_days` − 1, default 0 | Where a `gradual` ramp reaches the full percentage; nights closer to arrival keep it. |\n| `overrides` | `months` / `date_ranges` | Different settings for certain nights. Custom mode only. |\n\n**Example 1 · Start with a preset: Turn on the balanced preset**\n\n```json\n{\n  \"pricing_rules\": {\n    \"last_minute\": { \"mode\": \"balanced\" }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Mon Sep 14 | −15% (−28.51) | 190.09 → 161.58 |\n| Sat Sep 19 | −9.98% (−24.87) | 249.15 → 224.28 |\n| Thu Sep 24 | −5.69% (−13.59) | 238.77 → 225.18 |\n| Sun Oct 4 | −0.16% (−0.33) | 208.05 → 207.72 |\n| Mon Oct 5 | no adjustment | 194.42 → 194.42 |\n\nTonight gets the full discount. The cut shrinks quickly as you move away from today (the balanced curve is convex), and from 21 days out nothing is applied.\n\n**Example 2 · Custom settings: a flat discount: Discount the last two weeks by a flat 10%**\n\n```json\n{\n  \"pricing_rules\": {\n    \"last_minute\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"start_days\": 14,\n        \"adjustment_percent\": -10,\n        \"adjustment_type\": \"flat\"\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Mon Sep 14 | −10% (−19.01) | 190.09 → 171.08 |\n| Mon Sep 21 | −10% (−19.41) | 194.10 → 174.69 |\n| Mon Sep 28 | −10% (−19.47) | 194.72 → 175.25 |\n| Tue Sep 29 | no adjustment | 198.33 → 198.33 |\n\nEvery night from today through Mon Sep 28 is exactly 10% cheaper; Tue Sep 29 is the first untouched night.\n\n**Example 3 · A gradual ramp, with an override for specific dates: Ramp to −25%, but protect a busy weekend**\n\n```json\n{\n  \"pricing_rules\": {\n    \"last_minute\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"start_days\": 30,\n        \"adjustment_percent\": -25,\n        \"adjustment_type\": \"gradual\"\n      },\n      \"overrides\": {\n        \"date_ranges\": [\n          {\n            \"start_date\": \"2026-10-04\",\n            \"end_date\": \"2026-10-06\",\n            \"settings\": {\n              \"start_days\": 30,\n              \"adjustment_percent\": -5,\n              \"adjustment_type\": \"flat\"\n            }\n          }\n        ]\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Mon Sep 14 | −25% (−47.52) | 190.09 → 142.57 |\n| Tue Sep 29 | −12.5% (−24.79) | 198.33 → 173.54 |\n| Sun Oct 4 | −5% (−10.40) | 208.05 → 197.65 |\n| Tue Oct 6 | −5% (−9.90) | 198.10 → 188.20 |\n| Wed Oct 7 | −5.83% (−12.25) | 210.13 → 197.88 |\n| Wed Oct 14 | no adjustment | 211.53 → 211.53 |\n\nThe ramp runs from 0% at 30 days out to −25% tonight; Tue Sep 29 sits halfway. The three protected nights Sun Oct 4 – Tue Oct 6 get a flat −5% instead, and the ramp resumes on Wed Oct 7. An override replaces the whole settings block for its nights; nothing is inherited from the default.\n\n#### Far future\n\nRaise (or discount) nights that are far from arrival.\n\n| Field | Values | What it does |\n|---|---|---|\n| `mode` | `disabled` `conservative` `balanced` `aggressive` `custom` | Presets ramp linearly, reach full strength one year out and hold it beyond. |\n| `settings.start_days` | 60 or more | Window opens this many days out and runs to the end of the calendar, up to two years out. |\n| `settings.adjustment_percent` | > −100 | The full percentage. Positive raises, negative discounts. |\n| `settings.adjustment_type` | `flat` `gradual` | Same every night, or ramping up from `start_days`. |\n| `settings.end_days` | after `start_days`, default 365 | Where a `gradual` ramp reaches the full percentage; nights further out keep it. |\n| `overrides` | `months` / `date_ranges` | Different settings for certain nights. Custom mode only. |\n\n**Example 1 · Start with a preset: Turn on the balanced preset**\n\n```json\n{\n  \"pricing_rules\": {\n    \"far_future\": { \"mode\": \"balanced\" }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Thu Feb 11 | no adjustment | 172.83 → 172.83 |\n| Sat Mar 13 | no adjustment | 211.83 → 211.83 |\n| Fri Jun 11 | +4.86% (+16.67) | 343 → 359.67 |\n| Tue Sep 14 | +10% (+19.37) | 193.67 → 213.04 |\n| Sat May 6 | +10% (+23.30) | 232.92 → 256.22 |\n\nNothing happens before 180 days out. From there the raise grows linearly, reaches +10% one year out and stays at +10% for anything further.\n\n**Example 2 · Custom settings: a flat raise: Add a flat 8% to anything more than 6 months out**\n\n```json\n{\n  \"pricing_rules\": {\n    \"far_future\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"start_days\": 180,\n        \"adjustment_percent\": 8,\n        \"adjustment_type\": \"flat\"\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Fri Mar 12 | no adjustment | 223.50 → 223.50 |\n| Sat Mar 13 | +8% (+16.95) | 211.83 → 228.78 |\n| Tue Oct 19 | +8% (+16.08) | 200.91 → 216.99 |\n| Sat May 6 | +8% (+18.64) | 232.92 → 251.56 |\n\nEvery night from 180 days out onward gets the same +8%.\n\n#### Gap day\n\nDiscount short runs of open nights that are wedged between bookings.\n\n| Field | Values | What it does |\n|---|---|---|\n| `mode` | `disabled` `conservative` `balanced` `aggressive` `custom` | Presets cover 1, 2 and 3-night gaps and include weekends. |\n| `settings[]` | list of bands | Each band: `min_days`, `max_days` (1 – 30, inclusive) and `adjustment_percent`. Bands must not overlap. |\n| `apply_on_weekends` | `true` / `false` | Whether Friday and Saturday nights may be adjusted. **Required in custom mode.** |\n| `overrides` | `months` / `date_ranges` | Different bands for certain nights. Custom mode only. |\n\nNeeds a `calendar` in the request. Gap lengths that no band covers get no adjustment.\n\n**Example 1 · Start with a preset: Turn on the balanced preset**\n\n```json\n{\n  \"calendar\": [\n    { \"date\": \"2026-09-24\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-25\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-26\", \"status\": \"available\" },\n    { \"date\": \"2026-09-27\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-28\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-29\", \"status\": \"available\" },\n    { \"date\": \"2026-09-30\", \"status\": \"available\" },\n    { \"date\": \"2026-10-01\", \"status\": \"reserved\" },\n    { \"date\": \"2026-10-02\", \"status\": \"reserved\" }\n  ],\n  \"pricing_rules\": {\n    \"gap_day\": { \"mode\": \"balanced\" }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Fri Sep 25 | no adjustment | 257.83 → 257.83 |\n| Sat Sep 26 | −8% (−19.51) | 243.86 → 224.35 |\n| Tue Sep 29 | −4% (−7.93) | 198.33 → 190.40 |\n| Wed Sep 30 | −4% (−8.41) | 210.24 → 201.83 |\n\nThe one-night gap gets −8%, both nights of the two-night gap get −4%. Reserved nights are priced but not adjusted.\n\n**Example 2 · Custom bands, weekends excluded: Deeper cuts, but never on a Friday or Saturday**\n\n```json\n{\n  \"pricing_rules\": {\n    \"gap_day\": {\n      \"mode\": \"custom\",\n      \"apply_on_weekends\": false,\n      \"settings\": [\n        {\n          \"min_days\": 1,\n          \"max_days\": 1,\n          \"adjustment_percent\": -20\n        },\n        {\n          \"min_days\": 2,\n          \"max_days\": 3,\n          \"adjustment_percent\": -10\n        }\n      ]\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Sat Sep 26 | no adjustment | 243.86 → 243.86 |\n| Tue Sep 29 | −10% (−19.83) | 198.33 → 178.50 |\n| Wed Sep 30 | −10% (−21.02) | 210.24 → 189.22 |\n\nSame calendar as above. The one-night gap is a Saturday, and apply_on_weekends is false, so it keeps its price. The two-night gap (Tue Sep 29 – Wed Sep 30) gets −10%.\n\n#### Adjacent day\n\nAdjust the open nights right next to an existing booking, so they get filled.\n\n| Field | Values | What it does |\n|---|---|---|\n| `mode` | `disabled` `custom` | No presets. |\n| `settings.days_before` | 0 – 30 | How many open nights before a reservation to adjust. 0 = none. |\n| `settings.days_after` | 0 – 30 | How many open nights after a reservation to adjust. 0 = none. |\n| `settings.adjustment_percent` | > −100 | Applied once per night, even if it is adjacent on both sides. |\n| `apply_on_weekends` | `true` / `false` | Whether Friday and Saturday nights may be adjusted. **Required.** |\n| `overrides` | `months` / `date_ranges` | Different settings for certain nights. |\n\nNeeds a `calendar`. If a night also qualifies for a nonzero gap-day adjustment, gap day wins and this rule is skipped for it.\n\n**Example 1 · The basic setup: Nudge the night before and after each booking**\n\n```json\n{\n  \"calendar\": [\n    { \"date\": \"2026-09-23\", \"status\": \"available\" },\n    { \"date\": \"2026-09-24\", \"status\": \"available\" },\n    { \"date\": \"2026-09-25\", \"status\": \"available\" },\n    { \"date\": \"2026-09-26\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-27\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-28\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-29\", \"status\": \"available\" },\n    { \"date\": \"2026-09-30\", \"status\": \"available\" },\n    { \"date\": \"2026-10-01\", \"status\": \"available\" }\n  ],\n  \"pricing_rules\": {\n    \"adjacent_day\": {\n      \"mode\": \"custom\",\n      \"apply_on_weekends\": true,\n      \"settings\": {\n        \"days_before\": 1,\n        \"days_after\": 1,\n        \"adjustment_percent\": -5\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Thu Sep 24 | no adjustment | 238.77 → 238.77 |\n| Fri Sep 25 | −5% (−12.90) | 257.83 → 244.93 |\n| Sat Sep 26 | no adjustment | 243.86 → 243.86 |\n| Tue Sep 29 | −5% (−9.92) | 198.33 → 188.41 |\n| Wed Sep 30 | no adjustment | 210.24 → 210.24 |\n\nExactly one open night on each side of the reservation is adjusted. Two nights away, nothing.\n\n**Example 2 · One side only, and a raise instead of a cut: Reach two nights before, and raise instead of cut**\n\n```json\n{\n  \"pricing_rules\": {\n    \"adjacent_day\": {\n      \"mode\": \"custom\",\n      \"apply_on_weekends\": true,\n      \"settings\": {\n        \"days_before\": 2,\n        \"days_after\": 0,\n        \"adjustment_percent\": 8\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Wed Sep 23 | no adjustment | 210.17 → 210.17 |\n| Thu Sep 24 | +8% (+19.10) | 238.77 → 257.87 |\n| Fri Sep 25 | +8% (+20.62) | 257.83 → 278.45 |\n| Tue Sep 29 | no adjustment | 198.33 → 198.33 |\n\nPositive percentages work too. days_after: 0 switches that side off, so the night after the reservation is untouched.\n\n#### Occupancy pacing\n\nPrice by how booked you already are for a given lead time: discount when the near term is empty, raise when it is filling up.\n\n| Field | Values | What it does |\n|---|---|---|\n| `mode` | `disabled` `custom` | No presets. |\n| `settings.lead_time_ranges[]` | `{min_days, max_days}` 0 – 365 | Columns: how far out the night is. Ascending, non-overlapping. |\n| `settings.occupancy_ranges[]` | `{min_percent, max_percent}` 0 – 100 | Rows: how booked the column's window already is. Ascending, non-overlapping. |\n| `settings.adjustment_percent` | `[[row0col0, row0col1…], [row1…]]` | One inner list per row, one number per column. |\n| `overrides` | `months` / `date_ranges` | Different matrix for certain nights. |\n\nNeeds a `calendar` that covers every night of each column's window. Blocked nights are left out of the ratio.\n\n**Example 1 · The smallest grid: one column, two rows: Discount when the next two weeks are quiet**\n\n```json\n{\n  \"calendar\": [\n    { \"date\": \"2026-09-14\", \"status\": \"available\" },\n    { \"date\": \"2026-09-15\", \"status\": \"available\" },\n    { \"date\": \"2026-09-16\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-17\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-18\", \"status\": \"available\" },\n    { \"date\": \"2026-09-19\", \"status\": \"available\" },\n    { \"date\": \"2026-09-20\", \"status\": \"available\" },\n    { \"date\": \"2026-09-21\", \"status\": \"available\" },\n    { \"date\": \"2026-09-22\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-23\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-24\", \"status\": \"available\" },\n    { \"date\": \"2026-09-25\", \"status\": \"available\" },\n    { \"date\": \"2026-09-26\", \"status\": \"available\" },\n    { \"date\": \"2026-09-27\", \"status\": \"available\" },\n    { \"date\": \"2026-09-28\", \"status\": \"available\" }\n  ],\n  \"pricing_rules\": {\n    \"occupancy_pacing\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"lead_time_ranges\": [\n          { \"min_days\": 0, \"max_days\": 14 }\n        ],\n        \"occupancy_ranges\": [\n          { \"min_percent\": 0, \"max_percent\": 49 },\n          { \"min_percent\": 50, \"max_percent\": 100 }\n        ],\n        \"adjustment_percent\": [\n          [-10],\n          [5]\n        ]\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Mon Sep 14 | −10% (−19.01) | 190.09 → 171.08 |\n| Wed Sep 16 | no adjustment | 207.06 → 207.06 |\n| Mon Sep 21 | −10% (−19.41) | 194.10 → 174.69 |\n| Mon Sep 28 | −10% (−19.47) | 194.72 → 175.25 |\n| Tue Sep 29 | no adjustment | 198.33 → 198.33 |\n\nThe window is 27% booked, so every open night in the next 14 days gets the top row's −10%. Day 15 is outside every column: no adjustment, no warning.\n\n**Example 2 · Reading the 3 × 3 grid from the illustration: A full pacing grid**\n\n```json\n{\n  \"pricing_rules\": {\n    \"occupancy_pacing\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"lead_time_ranges\": [\n          { \"min_days\": 0, \"max_days\": 7 },\n          { \"min_days\": 8, \"max_days\": 30 },\n          { \"min_days\": 31, \"max_days\": 90 }\n        ],\n        \"occupancy_ranges\": [\n          { \"min_percent\": 0, \"max_percent\": 39 },\n          { \"min_percent\": 40, \"max_percent\": 69 },\n          { \"min_percent\": 70, \"max_percent\": 100 }\n        ],\n        \"adjustment_percent\": [\n          [-15, -5, 0],\n          [-5, 0, 5],\n          [5, 10, 15]\n        ]\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Mon Sep 14 | +5% (+9.51) | 190.09 → 199.60 |\n| Mon Sep 21 | +5% (+9.71) | 194.10 → 203.81 |\n| Thu Sep 24 | −5% (−11.94) | 238.77 → 226.83 |\n| Fri Oct 9 | −5% (−22.12) | 442.49 → 420.37 |\n| Thu Dec 3 | +15% (+30.01) | 200.03 → 230.04 |\n| Sun Dec 13 | +15% (+26.54) | 176.98 → 203.52 |\n\nReading the grid: adjustment_percent[row][column]. Nights 0 – 7 days out sit in a window that is 6 of 8 booked (75%) → bottom row, first column → +5%. Nights 8 – 30 days out sit in a window 7 of 23 booked (30%) → top row, second column → −5%, the ringed cell in the illustration. Nights 31 – 90 days out sit in a window 45 of 60 booked (75%) → bottom row, third column → +15%.\n\n#### Day of week\n\nAdd your own weekday pattern.\n\n| Field | Values | What it does |\n|---|---|---|\n| `mode` | `disabled` `custom` | No presets. |\n| `settings.adjustment_percent` | object, **all seven** lowercase weekday keys | −75 to 500 each. Weekday is the property's local weekday. |\n| `overrides` | `months` / `date_ranges` | Different percentages for certain nights. |\n\n**Example 1 · The basic setup: Weekend uplift**\n\n```json\n{\n  \"pricing_rules\": {\n    \"day_of_week\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"adjustment_percent\": {\n          \"monday\": 0,\n          \"tuesday\": 0,\n          \"wednesday\": 0,\n          \"thursday\": 0,\n          \"friday\": 5,\n          \"saturday\": 10,\n          \"sunday\": 0\n        }\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Tue Sep 22 | no adjustment | 198.01 → 198.01 |\n| Fri Sep 25 | +5% (+12.89) | 257.83 → 270.72 |\n| Sat Sep 26 | +10% (+24.39) | 243.86 → 268.25 |\n| Sun Sep 27 | no adjustment | 208.41 → 208.41 |\n\nZero is a valid value and all seven keys are required. The receipt line is labelled by the weekday it hit, e.g. Custom Saturday rule.\n\n**Example 2 · Discounts and premiums together: Midweek discount, weekend premium**\n\n```json\n{\n  \"pricing_rules\": {\n    \"day_of_week\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"adjustment_percent\": {\n          \"monday\": -8,\n          \"tuesday\": -8,\n          \"wednesday\": -8,\n          \"thursday\": -8,\n          \"friday\": 5,\n          \"saturday\": 12,\n          \"sunday\": 0\n        }\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Tue Sep 22 | −8% (−15.84) | 198.01 → 182.17 |\n| Fri Sep 25 | +5% (+12.89) | 257.83 → 270.72 |\n| Sat Sep 26 | +12% (+29.27) | 243.86 → 273.13 |\n| Sun Sep 27 | no adjustment | 208.41 → 208.41 |\n\n#### Stay rules\n\nMinimum nights and allowed check-in / check-out weekdays.\n\n| Rule | Fields | What it does |\n|---|---|---|\n| `min_stay` | `settings.min_nights` 1 – 365 | Minimum nights for a stay starting on that night. |\n| `check_in_out` | `settings.allowed_check_in_days`, `settings.allowed_check_out_days` | Lists of lowercase weekdays, at least one each. |\n| `length_of_stay` | `settings[]` of `{min_nights, adjustment_percent}` | Accepted and validated, **not applied**: nightly prices cannot know the guest's stay length. Apply these in your booking system. |\n\nAll three take `mode: disabled` or `custom` and accept `overrides`. AirROI returns the restrictions; your PMS or channel manager has to enforce them.\n\n**Example 1 · Minimum stay: Two-night minimum**\n\n```json\n{\n  \"stay_rules\": {\n    \"min_stay\": {\n      \"mode\": \"custom\",\n      \"settings\": { \"min_nights\": 2 }\n    }\n  }\n}\n```\n\n| Night | Returned on the night | Price |\n|---|---|---|\n| Thu Sep 24 | min_stay 2 · check-in yes · check-out yes | 238.77 |\n| Fri Sep 25 | min_stay 2 · check-in yes · check-out yes | 257.83 |\n\n**Example 2 · Check-in and check-out days: Weekend check-ins only**\n\n```json\n{\n  \"stay_rules\": {\n    \"min_stay\": {\n      \"mode\": \"custom\",\n      \"settings\": { \"min_nights\": 2 }\n    },\n    \"check_in_out\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"allowed_check_in_days\": [\"friday\", \"saturday\"],\n        \"allowed_check_out_days\": [\"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\", \"saturday\", \"sunday\"]\n      }\n    }\n  }\n}\n```\n\n| Night | Returned on the night | Price |\n|---|---|---|\n| Thu Sep 24 | min_stay 2 · check-in no · check-out yes | 238.77 |\n| Fri Sep 25 | min_stay 2 · check-in yes · check-out yes | 257.83 |\n| Sat Sep 26 | min_stay 2 · check-in yes · check-out yes | 243.86 |\n| Sun Sep 27 | min_stay 2 · check-in no · check-out yes | 208.41 |\n\n#### Price limits and overrides\n\nGuard-rails and hand-set prices for specific dates.\n\n| Key | Fields | What it does |\n|---|---|---|\n| `price_limits` | `min_price`, `max_price` | Either may be omitted or null; each defaults independently. |\n| `price_overrides[]` | `start_date`, `end_date`, `adjustment_type`, `adjustment_amount` | Inclusive, absolute date ranges that must not overlap. |\n| | `adjustment_type: percentage` | Multiplies the running price **before** limits. −100 < amount ≤ 500. |\n| | `adjustment_type: fixed` | Replaces the price **after** limits, ignoring both. A positive amount in the request currency. |\n\n**Example 1 · A floor and a ceiling: Keep every night between 150 and 230**\n\n```json\n{\n  \"price_limits\": { \"min_price\": 150, \"max_price\": 230 }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Tue Sep 15 | inside the limits | 194.52 → 194.52 |\n| Sat Sep 19 | lowered to the ceiling −19.15 | 249.15 → 230 |\n| Sun Sep 20 | inside the limits | 207.52 → 207.52 |\n\nThe receipt shows a maximum_price_limit or minimum_price_limit line only on nights that were actually clamped.\n\n**Example 2 · A percentage override: Add 25% for a three-night event**\n\n```json\n{\n  \"price_overrides\": [\n    {\n      \"start_date\": \"2026-10-14\",\n      \"end_date\": \"2026-10-16\",\n      \"adjustment_type\": \"percentage\",\n      \"adjustment_amount\": 25\n    }\n  ]\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Tue Oct 13 | no adjustment | 199.22 → 199.22 |\n| Wed Oct 14 | +25% (+52.89) | 211.53 → 264.42 |\n| Fri Oct 16 | +25% (+65.04) | 260.19 → 325.23 |\n| Sat Oct 17 | no adjustment | 246.42 → 246.42 |\n\nA percentage override behaves like one more multiplier, applied after all rules and before the limits.\n\n#### Seasonal overrides\n\nDifferent settings for certain months or exact dates, on any custom rule.\n\nEvery custom rule accepts overrides.months (recurring, lowercase month names) and overrides.date_ranges (absolute, inclusive). Date ranges beat months, months beat the default settings. The most specific match wins and replaces the entire settings block; nothing is inherited from the level below.\n\n**Example 1 · Default, month and date-range settings together: Three scopes on one rule**\n\n```json\n{\n  \"pricing_rules\": {\n    \"day_of_week\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"adjustment_percent\": {\n          \"monday\": 0,\n          \"tuesday\": 0,\n          \"wednesday\": 0,\n          \"thursday\": 0,\n          \"friday\": 0,\n          \"saturday\": 10,\n          \"sunday\": 0\n        }\n      },\n      \"overrides\": {\n        \"months\": {\n          \"october\": {\n            \"settings\": {\n              \"adjustment_percent\": {\n                \"monday\": 5,\n                \"tuesday\": 5,\n                \"wednesday\": 5,\n                \"thursday\": 5,\n                \"friday\": 5,\n                \"saturday\": 20,\n                \"sunday\": 5\n              }\n            }\n          }\n        },\n        \"date_ranges\": [\n          {\n            \"start_date\": \"2026-10-10\",\n            \"end_date\": \"2026-10-30\",\n            \"settings\": {\n              \"adjustment_percent\": {\n                \"monday\": 30,\n                \"tuesday\": 30,\n                \"wednesday\": 30,\n                \"thursday\": 30,\n                \"friday\": 30,\n                \"saturday\": 30,\n                \"sunday\": 30\n              }\n            }\n          }\n        ]\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Mon Sep 14 | no adjustment | 190.09 → 190.09 |\n| Wed Oct 7 | +5% (+10.50) | 210.13 → 220.63 |\n| Sat Oct 10 | +30% (+125.64) | 418.81 → 544.45 |\n| Wed Oct 14 | +30% (+63.46) | 211.53 → 274.99 |\n| Fri Oct 30 | +30% (+74.47) | 248.23 → 322.70 |\n| Sat Oct 31 | +20% (+46.70) | 233.52 → 280.22 |\n\nA night outside October uses the default block. An October night uses the month block (+5% weekdays, +20% Saturday). The three-week run Sat Oct 10 – Fri Oct 30 uses the date-range block (+30% every night, Saturdays included) even though those nights are also in October; the day after it ends, Sat Oct 31, drops back to the month block.\n\nThe same shape works on every rule: \"overrides\": {\"months\": {\"december\": {\"settings\": …}}, \"date_ranges\": [{\"start_date\": …, \"end_date\": …, \"settings\": …}]}. Gap-day and adjacent-day scopes also need their own apply_on_weekends.\n\n#### Advanced model controls\n\nTurn the model's own effects up or down.\n\nThink of each dial as a volume knob on one of the model's own effects. 0 mutes it, 100 is the default (exactly what the model computed), 200 doubles it, and anything in between scales it: 50 is half the swing, 150 is one and a half times. The dials never touch your own rules, overrides or limits.\n\n| Field | Values | What it does |\n|---|---|---|\n| `seasonality_sensitivity_percent` | 0 – 200, default 100 | How hard the season, the weekday and holidays/events move the price. 0 gives a flat year, 200 makes every high and low twice as high or low. |\n| `demand_sensitivity_percent` | 0 – 200, default 100 | How hard live market demand moves the price. Whatever you set, the demand line stays within −15% and +400%. |\n| `apply_negative_demand_adjustments` | `true` / `false`, default true | `false` lets demand raise a price but never cut it: on a soft night the `market_demand` line is left off the receipt. |\n\n**Example 1 · Seasonality off: 0: A travel-nurse rental that charges the same all year**\n\nA furnished apartment near the hospital district books 30-night stays from nurses on contract, so the host wants no seasonal or weekday swing at all: the base price, adjusted only for live demand.\n\n```json\n{\n  \"advanced\": { \"seasonality_sensitivity_percent\": 0 }\n}\n```\n\n| Night | Model line on the receipt | Price |\n|---|---|---|\n| Tue Sep 15 | seasonality +0% (0) · day of week +0% (0) | 194.52 → 200 |\n| Sat Sep 26 | seasonality +0% (0) · day of week +0% (0) | 243.86 → 200 |\n\nThe lines stay on the receipt, now at 0%: Tue Sep 15 went from +8.15% seasonality to 0%, Sat Sep 26 from +10.52% on the weekday line to 0%. The weekday and holiday effects sit on the same dial as the season, so all three switch off together.\n\n**Example 2 · Half strength: 50: A first-season host who finds the swings too bold**\n\nA new host in a downtown condo trusts the direction of the model but wants gentler moves until they have a few months of reviews. Halving the dial keeps every high and low, at half the size.\n\n```json\n{\n  \"advanced\": { \"seasonality_sensitivity_percent\": 50 }\n}\n```\n\n| Night | Model line on the receipt | Price |\n|---|---|---|\n| Tue Sep 15 | seasonality +4.07% (+8.15) · day of week −5.03% (−10.48) | 194.52 → 197.67 |\n| Sat Sep 26 | seasonality +5.16% (+10.32) · day of week +5.26% (+11.07) | 243.86 → 221.39 |\n\nEvery model percentage is half its default distance from zero: Tue Sep 15 seasonality +8.15% → +4.07%, Sat Sep 26 weekday +10.52% → +5.26%.\n\n**Example 3 · Double strength: 200: A weekend-and-events house that lives on the peaks**\n\nA four-bedroom house near the venues empties out midweek and sells out for every weekend and festival. The host wants the model's peaks and troughs doubled so slow Tuesdays are cheaper and big Saturdays dearer.\n\n```json\n{\n  \"advanced\": { \"seasonality_sensitivity_percent\": 200 }\n}\n```\n\n| Night | Model line on the receipt | Price |\n|---|---|---|\n| Tue Sep 15 | seasonality +16.29% (+32.59) · day of week −20.14% (−46.84) | 194.52 → 185.75 |\n| Sat Sep 26 | seasonality +20.64% (+41.29) · day of week +21.05% (+50.78) | 243.86 → 292.07 |\n\nEvery model percentage is twice its default distance from zero: Tue Sep 15 seasonality +8.15% → +16.29%, Sat Sep 26 weekday +10.52% → +21.05%.\n\n**Example 4 · Demand at 150, cuts switched off: Ride the hot nights, never discount the soft ones**\n\nA host whose place always fills eventually is happy to chase demand upward when a big weekend lands, but refuses to let a quiet market pull the price below what the season alone would say.\n\n```json\n{\n  \"advanced\": {\n    \"demand_sensitivity_percent\": 150,\n    \"apply_negative_demand_adjustments\": false\n  }\n}\n```\n\n| Night | Model line on the receipt | Price |\n|---|---|---|\n| Sat Oct 31 | line omitted | 233.52 → 245.09 |\n| Fri Oct 9 | +107.5% (+277.03) | 442.49 → 534.84 |\n\nOn Sat Oct 31 the market is soft, so the demand line (−4.7% by default) is dropped from the receipt rather than shown at 0%. On Fri Oct 9 it is strong, and the lift is one and a half times the modeled +71.6%: +107.5%.\n\n#### Calendar input\n\nTell the engine what is already booked so the calendar-aware rules can work.\n\nOne row per night with a status of available, reserved or blocked. A calendar is evidence about your bookings, not a way to choose output dates. A date you do not send is unknown, which is different from open.\n\n| | `available` | `reserved` | `blocked` | not sent |\n|---|---|---|---|---|\n| Priced and returned | yes | yes | yes | yes |\n| Last-minute / far-future | applied | skipped | skipped | applied |\n| Can be a gap night | yes | — | — | no, and it breaks any gap it touches |\n| Bounds a gap | no | yes | yes | no |\n| Anchors adjacent-day | no | yes | no | no |\n| Counted in occupancy | as open | as booked | left out | breaks the window (warning) |\n\n**Example 1 · Reserved stays, one gap, one blocked night, and three rules reading them: Three weeks of a real calendar**\n\nThree weeks starting Mon Sep 14: a guest checks out Tue Sep 15, a three-night stay runs Thu Sep 17 – Sat Sep 19, Wed Sep 23 is blocked for cleaning, a four-night stay runs Thu Sep 24 – Sun Sep 27 and a long weekend Fri Oct 2 – Sun Oct 4 is already sold. A flat last-minute discount, a one-night gap rule and an adjacent-night rule are all on.\n\n```json\n{\n  \"calendar\": [\n    { \"date\": \"2026-09-14\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-15\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-16\", \"status\": \"available\" },\n    { \"date\": \"2026-09-17\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-18\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-19\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-20\", \"status\": \"available\" },\n    { \"date\": \"2026-09-21\", \"status\": \"available\" },\n    { \"date\": \"2026-09-22\", \"status\": \"available\" },\n    { \"date\": \"2026-09-23\", \"status\": \"blocked\" },\n    { \"date\": \"2026-09-24\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-25\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-26\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-27\", \"status\": \"reserved\" },\n    { \"date\": \"2026-09-28\", \"status\": \"available\" },\n    { \"date\": \"2026-09-29\", \"status\": \"available\" },\n    { \"date\": \"2026-09-30\", \"status\": \"available\" },\n    { \"date\": \"2026-10-01\", \"status\": \"available\" },\n    { \"date\": \"2026-10-02\", \"status\": \"reserved\" },\n    { \"date\": \"2026-10-03\", \"status\": \"reserved\" },\n    { \"date\": \"2026-10-04\", \"status\": \"reserved\" }\n  ],\n  \"pricing_rules\": {\n    \"last_minute\": {\n      \"mode\": \"custom\",\n      \"settings\": {\n        \"start_days\": 21,\n        \"adjustment_percent\": -10,\n        \"adjustment_type\": \"flat\"\n      }\n    },\n    \"gap_day\": {\n      \"mode\": \"custom\",\n      \"apply_on_weekends\": true,\n      \"settings\": [\n        {\n          \"min_days\": 1,\n          \"max_days\": 1,\n          \"adjustment_percent\": -15\n        }\n      ]\n    },\n    \"adjacent_day\": {\n      \"mode\": \"custom\",\n      \"apply_on_weekends\": true,\n      \"settings\": {\n        \"days_before\": 1,\n        \"days_after\": 1,\n        \"adjustment_percent\": -5\n      }\n    }\n  }\n}\n```\n\n| Night | What the rule did | Price |\n|---|---|---|\n| Mon Sep 14 | nothing applied | 190.09 → 190.09 |\n| Wed Sep 16 | last-minute rule −10% (−20.70) · gap-night rule −15% (−31.06) | 207.06 → 155.30 |\n| Sun Sep 20 | last-minute rule −10% (−20.75) · adjacent-night rule −5% (−10.38) | 207.52 → 176.39 |\n| Mon Sep 21 | last-minute rule −10% (−19.41) | 194.10 → 174.69 |\n| Wed Sep 23 | nothing applied | 210.17 → 210.17 |\n| Mon Sep 28 | last-minute rule −10% (−19.47) · adjacent-night rule −5% (−9.74) | 194.72 → 165.51 |\n| Thu Oct 1 | last-minute rule −10% (−23.87) · adjacent-night rule −5% (−11.93) | 238.63 → 202.83 |\n| Fri Oct 2 | nothing applied | 257.50 → 257.50 |\n\nMon Sep 14 and Fri Oct 2 are reserved, Wed Sep 23 is blocked: still priced and returned, but every rule steps over them. Wed Sep 16 is a one-night gap between two stays, so it gets the gap cut and the last-minute discount; the adjacent cut is not stacked on top of a gap cut. Sun Sep 20, Mon Sep 28 and Thu Oct 1 each touch one reservation and get the adjacent cut; Mon Sep 21 touches nothing and only sees last-minute. Send up to 1,000 rows, in any order; a calendar-aware rule with no calendar at all still prices every night and adds an INCOMPLETE_CALENDAR warning.\n\n#### Warnings you may see\n\nA `200` can still carry one warning, `INCOMPLETE_CALENDAR`. It means a calendar-aware rule could not do its job: on every night, because no `calendar` was sent, or on some nights, because rows it needed were not sent. `field` names the rule and `message` says which case it is. One entry per rule, so a sparse calendar with all three rules on can produce three.\n\n| Case | What to do |\n|---|---|\n| No `calendar` in the request | Send the calendar. |\n| Gap-day or adjacent-day could not see both sides of an open night | Send contiguous rows around your bookings. |\n| An occupancy-pacing window has a date with no row | Send every night of every column's window; the message names the window and how many dates are missing. |\n\n`affected_date_count` counts the affected nights across the full calculated calendar, not just the rows you asked for.\n\n### Daily recommendations\n\nReturns **one to two years of consecutive dates starting today in the property's timezone**\nwhen `start_date` and `end_date` are omitted or null. Both are optional and\ninclusive: set `start_date` to begin later than today (for example, to sync just\nnext month), set `end_date` to stop earlier, or set both for a window. The same\nday in both returns one row. Past or malformed dates return 422, and so does a\n`start_date` after `end_date` or beyond the available calendar. An `end_date`\nbeyond the available calendar is simply clamped to it. `coverage` reports the\ncalculation date (today), the returned range, the available end date, the row\ncount and the timezone. The boundaries select output rows only: last-minute and\nfar-future lead times still count from today, and full-calendar calculation\nand warnings are unchanged. Reserved and blocked dates are included, so\nrecheck availability before publishing through your integration.\n\nUse your own base price or the [Recommend a Base Price](#tag/Price-Recommendation/operation/recommendBasePrice)\nresult. Amounts are whole currency units, not cents. For longer guides see the\n[Pricing Rules index](https://www.airroi.com/resources/dynamic-pricing/pricing-rules).\n",
        "operationId": "recommendCalendarPrices",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalendarPriceRecommendationRequest"
              },
              "examples": {
                "joshuaTreeFirstCall": {
                  "$ref": "#/components/examples/joshuaTreeFirstCall"
                },
                "miamiBeachLeadTime": {
                  "$ref": "#/components/examples/miamiBeachLeadTime"
                },
                "scottsdalePacing": {
                  "$ref": "#/components/examples/scottsdalePacing"
                },
                "austinWeekends": {
                  "$ref": "#/components/examples/austinWeekends"
                },
                "gatlinburgGaps": {
                  "$ref": "#/components/examples/gatlinburgGaps"
                },
                "charlestonLimits": {
                  "$ref": "#/components/examples/charlestonLimits"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One to 730 nightly prices from start_date (or today in the property's timezone) through end_date, with coverage, warnings and itemized explanations; omitted or null boundaries return the full available calendar",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarPriceRecommendationResponse"
                },
                "examples": {
                  "joshuaTreeFirstCall": {
                    "$ref": "#/components/examples/response-joshuaTreeFirstCall"
                  },
                  "miamiBeachLeadTime": {
                    "$ref": "#/components/examples/response-miamiBeachLeadTime"
                  },
                  "scottsdalePacing": {
                    "$ref": "#/components/examples/response-scottsdalePacing"
                  },
                  "austinWeekends": {
                    "$ref": "#/components/examples/response-austinWeekends"
                  },
                  "gatlinburgGaps": {
                    "$ref": "#/components/examples/response-gatlinburgGaps"
                  },
                  "charlestonLimits": {
                    "$ref": "#/components/examples/response-charlestonLimits"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request body is empty or is not valid JSON",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarPriceRecommendationErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "MALFORMED_JSON",
                    "message": "The request body is not valid JSON. Check commas, quotes, brackets, and braces.",
                    "details": [],
                    "request_id": "req_67fce2a521db08382660691075932041"
                  }
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/ApiKeyError"
          },
          "413": {
            "description": "The calendar contains more than 1,000 rows",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarPriceRecommendationErrorResponse"
                },
                "example": {
                  "error": {
                    "code": "PAYLOAD_TOO_LARGE",
                    "message": "calendar may contain at most 1,000 rows.",
                    "details": [
                      {
                        "code": "TOO_MANY_CALENDAR_ROWS",
                        "field": "calendar",
                        "message": "calendar contains 1001 rows; the maximum is 1,000."
                      }
                    ],
                    "request_id": "req_460d0c9bca3d1dbaa290a02d953e47de"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Invalid request settings, an unsupported location, or a calculated price that rounds to zero; no recommendations are returned",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarPriceRecommendationErrorResponse"
                },
                "examples": {
                  "validationError": {
                    "summary": "Three validation problems in one request",
                    "description": "Lowercase currency, price limits with min above max, and settings sent with a preset mode. Details are sorted by field, then code.\n",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "The request contains invalid pricing settings.",
                        "details": [
                          {
                            "code": "INVALID_CURRENCY",
                            "field": "currency",
                            "message": "currency must be an uppercase three-letter ISO 4217 code such as USD or EUR."
                          },
                          {
                            "code": "INVALID_PRICE_LIMITS",
                            "field": "price_limits",
                            "message": "Effective min_price (300) must not exceed effective max_price (200). Omitted or null bounds default to 70% and 1000% of base_price; set both bounds if needed."
                          },
                          {
                            "code": "CUSTOM_FIELDS_REQUIRE_CUSTOM_MODE",
                            "field": "pricing_rules.last_minute.settings",
                            "message": "settings is accepted only when mode is custom."
                          }
                        ],
                        "request_id": "req_debd05db321fb3f4c2bad730907e6acc"
                      }
                    }
                  },
                  "wrongType": {
                    "summary": "Wrong JSON type",
                    "description": "base_price was sent as the string \"200\". Only the first type error is reported.\n",
                    "value": {
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "The request contains invalid pricing settings.",
                        "details": [
                          {
                            "code": "INVALID_FIELD_TYPE",
                            "field": "base_price",
                            "message": "base_price has the wrong JSON type. Use the type shown in the API contract."
                          }
                        ],
                        "request_id": "req_3008eace549e22c21bdb78e0304591c9"
                      }
                    }
                  },
                  "priceBelowCurrencyMinimum": {
                    "summary": "Calculated price rounds to zero",
                    "description": "Defensive calculation error. Review the affected date's base price,\ndiscounts, and minimum limit before retrying; no partial calendar is returned.\n",
                    "value": {
                      "error": {
                        "code": "PRICE_BELOW_CURRENCY_MINIMUM",
                        "message": "The calculated price rounds to zero for 2026-06-13. No recommendations were returned.",
                        "details": [
                          {
                            "code": "PRICE_BELOW_CURRENCY_MINIMUM",
                            "field": "base_price",
                            "message": "Review the base price, discounts, and minimum price limit for 2026-06-13."
                          }
                        ],
                        "request_id": "req_89b61f3c00acf4131e3d9e987d3e0a67"
                      }
                    }
                  },
                  "unsupportedLocation": {
                    "summary": "Coordinates with no timezone or no pricing data",
                    "description": "Open-ocean coordinates such as 0, 0.\n",
                    "value": {
                      "error": {
                        "code": "UNSUPPORTED_LOCATION",
                        "message": "The coordinates could not be resolved to a supported property timezone.",
                        "details": [
                          {
                            "code": "UNSUPPORTED_LOCATION",
                            "field": "location",
                            "message": "The coordinates could not be resolved to a supported property timezone."
                          }
                        ],
                        "request_id": "req_89b61f3c00acf4131e3d9e987d3e0a67"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The current pricing data cannot serve a continuous calendar of at least 365 dates, or is temporarily unavailable; retry later",
            "headers": {
              "X-Request-ID": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalendarPriceRecommendationErrorResponse"
                },
                "examples": {
                  "staleRelease": {
                    "summary": "Fewer than 365 continuous dates available",
                    "value": {
                      "error": {
                        "code": "STALE_SERVING_RELEASE",
                        "message": "The active pricing release supports only 300 consecutive dates from 2026-09-03; at least 365 days are required. Wait for the next pricing release and retry.",
                        "details": [],
                        "request_id": "req_fc50881ffbecefcc1d5fe73fecefdb08"
                      }
                    }
                  },
                  "dataUnavailable": {
                    "summary": "Pricing data temporarily unavailable",
                    "value": {
                      "error": {
                        "code": "PRICING_DATA_UNAVAILABLE",
                        "message": "A complete, release-consistent pricing bundle is temporarily unavailable.",
                        "details": [],
                        "request_id": "req_0123456789abcdef0123456789abcdef"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key required for all endpoints. Include in header as 'x-api-key'."
      }
    },
    "schemas": {
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "The time the error occurred.",
            "example": "2024-07-30T10:30:00Z"
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code.",
            "example": 400
          },
          "error": {
            "type": "string",
            "description": "A short error description (e.g., Bad Request, Not Found).",
            "example": "Bad Request"
          },
          "message": {
            "type": "string",
            "description": "A detailed error message.",
            "example": "Invalid input for parameter 'latitude'."
          },
          "path": {
            "type": "string",
            "description": "The API path that was called.",
            "example": "/listings/search"
          }
        }
      },
      "ListingInfo": {
        "type": "object",
        "properties": {
          "listing_id": {
            "type": "integer",
            "format": "int64",
            "description": "Original Airbnb listing ID",
            "example": 43036533
          },
          "listing_name": {
            "type": "string",
            "description": "Property title/name",
            "example": "Luxury Downtown Loft with Skyline Views",
            "nullable": true
          },
          "description": {
            "type": "string",
            "description": "Full marketing description shown on the listing page",
            "example": "Spacious villa with ocean views, heated pool, and direct beach access.",
            "nullable": true
          },
          "listing_type": {
            "type": "string",
            "description": "Detailed property type (e.g., \"Entire rental unit\", \"Private room in home\")",
            "example": "Entire rental unit",
            "nullable": true
          },
          "room_type": {
            "type": "string",
            "description": "Room type classification. Values: \"entire_home\", \"private_room\", \"shared_room\"\n",
            "enum": [
              "entire_home",
              "private_room",
              "shared_room"
            ],
            "example": "entire_home"
          },
          "cover_photo_url": {
            "type": "string",
            "format": "uri",
            "description": "URL of main listing photo",
            "example": "https://a0.muscache.com/im/pictures/miso/Hosting-43036533/original/image.jpeg",
            "nullable": true
          },
          "photos_count": {
            "type": "integer",
            "description": "Total number of listing photos",
            "example": 32,
            "nullable": true
          },
          "photo_urls": {
            "type": "array",
            "description": "Additional listing photo URLs in display order",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "example": [
              "https://a0.muscache.com/im/pictures/photo-1.jpeg",
              "https://a0.muscache.com/im/pictures/photo-2.jpeg"
            ]
          },
          "checkin_time": {
            "type": "string",
            "description": "Published check-in time or window",
            "example": "4:00 PM - 10:00 PM",
            "nullable": true
          },
          "checkout_time": {
            "type": "string",
            "description": "Published checkout time",
            "example": "11:00 AM",
            "nullable": true
          },
          "guest_favorite": {
            "type": "boolean",
            "description": "Whether Airbnb marks the property as a guest favorite",
            "example": true,
            "nullable": true
          }
        }
      },
      "HostInfo": {
        "type": "object",
        "properties": {
          "host_id": {
            "type": "integer",
            "format": "int64",
            "description": "Unique host identifier",
            "example": 287465123,
            "nullable": true
          },
          "host_name": {
            "type": "string",
            "description": "Host's display name",
            "example": "Maria",
            "nullable": true
          },
          "cohost_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "List of co-host IDs.",
            "example": [
              12345678,
              87654321
            ]
          },
          "cohost_names": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of co-host names.",
            "example": [
              "John",
              "Sarah"
            ]
          },
          "superhost": {
            "type": "boolean",
            "description": "Whether host has Superhost status",
            "example": true,
            "nullable": true
          },
          "professional_management": {
            "type": "boolean",
            "description": "Whether the listing is managed by a professional property management company",
            "example": false,
            "nullable": true
          }
        }
      },
      "LocationInfo": {
        "type": "object",
        "properties": {
          "country_code": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code",
            "pattern": "^[A-Z]{2}$",
            "example": "US",
            "nullable": true
          },
          "country": {
            "type": "string",
            "description": "Full country name",
            "example": "United States"
          },
          "region": {
            "type": "string",
            "description": "State or region name (full name, not abbreviation)",
            "example": "California",
            "nullable": true
          },
          "locality": {
            "type": "string",
            "description": "City name",
            "example": "Los Angeles",
            "nullable": true
          },
          "district": {
            "type": "string",
            "description": "Neighborhood name",
            "example": "Downtown",
            "nullable": true
          },
          "latitude": {
            "type": "number",
            "format": "double",
            "description": "Property latitude",
            "example": 34.052235,
            "nullable": true
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "description": "Property longitude",
            "example": -118.243683,
            "nullable": true
          },
          "exact_location": {
            "type": "boolean",
            "description": "Whether the listing exposes an exact map pin rather than an approximate area",
            "example": false,
            "nullable": true
          }
        }
      },
      "PropertyDetails": {
        "type": "object",
        "properties": {
          "guests": {
            "type": "integer",
            "description": "Maximum guest capacity",
            "minimum": 1,
            "example": 6,
            "nullable": true
          },
          "bedrooms": {
            "type": "integer",
            "description": "Number of bedrooms",
            "minimum": 0,
            "example": 2,
            "nullable": true
          },
          "beds": {
            "type": "integer",
            "description": "Total number of beds",
            "minimum": 0,
            "example": 3,
            "nullable": true
          },
          "baths": {
            "type": "number",
            "format": "double",
            "description": "Number of bathrooms (supports half baths as decimals)",
            "minimum": 0,
            "example": 2,
            "nullable": true
          },
          "registration": {
            "type": "boolean",
            "description": "Whether property has local registration/license",
            "example": true,
            "nullable": true
          },
          "registration_details": {
            "type": "string",
            "description": "Details of the registration",
            "nullable": true
          },
          "amenities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "List of available amenities",
            "example": [
              "wifi",
              "kitchen",
              "air_conditioning",
              "washer",
              "dryer",
              "pool",
              "gym"
            ]
          }
        }
      },
      "BookingSettings": {
        "type": "object",
        "properties": {
          "instant_book": {
            "type": "boolean",
            "description": "Whether instant booking is enabled",
            "example": true,
            "nullable": true
          },
          "min_nights": {
            "type": "integer",
            "description": "Minimum stay requirement in nights",
            "minimum": 1,
            "example": 2,
            "nullable": true
          },
          "cancellation_policy": {
            "type": "string",
            "description": "Cancellation policy type",
            "example": "moderate",
            "nullable": true
          }
        }
      },
      "PricingInfo": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency code for all financial fields in the response.\nReturns \"USD\" when requested with currency=usd, or the listing's local currency code (e.g. \"EUR\", \"JPY\", \"GBP\") when requested with currency=native.\n",
            "example": "USD",
            "nullable": true
          },
          "cleaning_fee": {
            "type": "integer",
            "description": "One-time cleaning fee",
            "minimum": 0,
            "example": 125,
            "nullable": true
          },
          "short_stay_cleaning_fee": {
            "type": "integer",
            "description": "The cleaning fee the host set for stays of 1–2 nights. Equals `cleaning_fee` when the host has one fee. Null when unknown.",
            "minimum": 0,
            "example": 95,
            "nullable": true
          },
          "extra_guest_fee": {
            "type": "integer",
            "description": "Fee per additional guest",
            "minimum": 0,
            "example": 35,
            "nullable": true
          },
          "single_fee_structure": {
            "type": "boolean",
            "description": "Whether the listing uses a single combined fee structure instead of separate fee components",
            "example": false,
            "nullable": true
          }
        }
      },
      "Ratings": {
        "type": "object",
        "properties": {
          "num_reviews": {
            "type": "integer",
            "description": "Total number of guest reviews",
            "minimum": 0,
            "example": 247,
            "nullable": true
          },
          "rating_overall": {
            "type": "number",
            "format": "double",
            "description": "Detailed overall rating",
            "minimum": 0,
            "maximum": 5,
            "example": 4.92,
            "nullable": true
          },
          "rating_accuracy": {
            "type": "number",
            "format": "double",
            "description": "Accuracy rating",
            "minimum": 0,
            "maximum": 5,
            "example": 4.95,
            "nullable": true
          },
          "rating_checkin": {
            "type": "number",
            "format": "double",
            "description": "Check-in process rating",
            "minimum": 0,
            "maximum": 5,
            "example": 4.93,
            "nullable": true
          },
          "rating_cleanliness": {
            "type": "number",
            "format": "double",
            "description": "Cleanliness rating",
            "minimum": 0,
            "maximum": 5,
            "example": 4.91,
            "nullable": true
          },
          "rating_communication": {
            "type": "number",
            "format": "double",
            "description": "Host communication rating",
            "minimum": 0,
            "maximum": 5,
            "example": 4.94,
            "nullable": true
          },
          "rating_location": {
            "type": "number",
            "format": "double",
            "description": "Location rating",
            "minimum": 0,
            "maximum": 5,
            "example": 4.96,
            "nullable": true
          },
          "rating_value": {
            "type": "number",
            "format": "double",
            "description": "Value for money rating",
            "minimum": 0,
            "maximum": 5,
            "example": 4.88,
            "nullable": true
          }
        }
      },
      "PerformanceMetrics": {
        "type": "object",
        "properties": {
          "ttm_revenue": {
            "type": "number",
            "format": "double",
            "description": "Total revenue over trailing twelve months",
            "minimum": 0,
            "example": 85650.5,
            "nullable": true
          },
          "ttm_avg_rate": {
            "type": "number",
            "format": "double",
            "description": "Average Daily Rate (ADR) over trailing twelve months",
            "minimum": 0,
            "example": 285.75,
            "nullable": true
          },
          "ttm_occupancy": {
            "type": "number",
            "format": "double",
            "description": "Occupancy rate (0.0-1.0) over trailing twelve months",
            "minimum": 0,
            "maximum": 1,
            "example": 0.82,
            "nullable": true
          },
          "ttm_adjusted_occupancy": {
            "type": "number",
            "format": "double",
            "description": "Adjusted occupancy excluding owner blocks over TTM",
            "minimum": 0,
            "maximum": 1,
            "example": 0.8,
            "nullable": true
          },
          "ttm_revpar": {
            "type": "number",
            "format": "double",
            "description": "Revenue per available room over TTM",
            "minimum": 0,
            "example": 234.32,
            "nullable": true
          },
          "ttm_adjusted_revpar": {
            "type": "number",
            "format": "double",
            "description": "Adjusted RevPAR based on adjusted occupancy over TTM",
            "minimum": 0,
            "example": 228.6,
            "nullable": true
          },
          "ttm_total_days": {
            "type": "integer",
            "description": "Total days in TTM period (typically 365)",
            "example": 365,
            "nullable": true
          },
          "ttm_available_days": {
            "type": "integer",
            "description": "Days available for booking in TTM",
            "example": 340,
            "nullable": true
          },
          "ttm_blocked_days": {
            "type": "integer",
            "description": "Days blocked by owner in TTM",
            "example": 25,
            "nullable": true
          },
          "ttm_days_reserved": {
            "type": "integer",
            "description": "Days with confirmed bookings in TTM",
            "example": 279,
            "nullable": true
          },
          "ttm_avg_min_nights": {
            "type": "number",
            "format": "double",
            "description": "Average minimum stay requirement over trailing twelve months",
            "minimum": 0,
            "example": 3.4,
            "nullable": true
          },
          "ttm_avg_length_of_stay": {
            "type": "number",
            "format": "double",
            "description": "Average booked length of stay over trailing twelve months",
            "minimum": 0,
            "example": 4.8,
            "nullable": true
          },
          "l90d_revenue": {
            "type": "number",
            "format": "double",
            "description": "Total revenue over last 90 days",
            "minimum": 0,
            "example": 24500,
            "nullable": true
          },
          "l90d_avg_rate": {
            "type": "number",
            "format": "double",
            "description": "Average Daily Rate over last 90 days",
            "minimum": 0,
            "example": 295,
            "nullable": true
          },
          "l90d_occupancy": {
            "type": "number",
            "format": "double",
            "description": "Occupancy rate over last 90 days",
            "minimum": 0,
            "maximum": 1,
            "example": 0.85,
            "nullable": true
          },
          "l90d_adjusted_occupancy": {
            "type": "number",
            "format": "double",
            "description": "Adjusted occupancy over last 90 days",
            "minimum": 0,
            "maximum": 1,
            "example": 0.83,
            "nullable": true
          },
          "l90d_revpar": {
            "type": "number",
            "format": "double",
            "description": "RevPAR over last 90 days",
            "minimum": 0,
            "example": 250.75,
            "nullable": true
          },
          "l90d_adjusted_revpar": {
            "type": "number",
            "format": "double",
            "description": "Adjusted RevPAR over last 90 days",
            "minimum": 0,
            "example": 244.85,
            "nullable": true
          },
          "l90d_total_days": {
            "type": "integer",
            "description": "Total days in L90D period (typically 90)",
            "example": 90,
            "nullable": true
          },
          "l90d_available_days": {
            "type": "integer",
            "description": "Days available in last 90 days",
            "example": 87,
            "nullable": true
          },
          "l90d_blocked_days": {
            "type": "integer",
            "description": "Days blocked in last 90 days",
            "example": 3,
            "nullable": true
          },
          "l90d_days_reserved": {
            "type": "integer",
            "description": "Days reserved in last 90 days",
            "example": 74,
            "nullable": true
          },
          "l90d_avg_min_nights": {
            "type": "number",
            "format": "double",
            "description": "Average minimum stay requirement over the last 90 days",
            "minimum": 0,
            "example": 2.7,
            "nullable": true
          },
          "l90d_avg_length_of_stay": {
            "type": "number",
            "format": "double",
            "description": "Average booked length of stay over the last 90 days",
            "minimum": 0,
            "example": 4.1,
            "nullable": true
          }
        }
      },
      "ListingDetailsResponse": {
        "type": "object",
        "title": "Listing Details",
        "description": "Comprehensive property information including characteristics, host details,\npricing, reviews, and performance metrics (TTM and L90D).\n",
        "properties": {
          "listing_info": {
            "$ref": "#/components/schemas/ListingInfo"
          },
          "host_info": {
            "$ref": "#/components/schemas/HostInfo"
          },
          "location_info": {
            "$ref": "#/components/schemas/LocationInfo"
          },
          "property_details": {
            "$ref": "#/components/schemas/PropertyDetails"
          },
          "booking_settings": {
            "$ref": "#/components/schemas/BookingSettings"
          },
          "pricing_info": {
            "$ref": "#/components/schemas/PricingInfo"
          },
          "ratings": {
            "$ref": "#/components/schemas/Ratings"
          },
          "performance_metrics": {
            "$ref": "#/components/schemas/PerformanceMetrics"
          }
        }
      },
      "GatewayErrorResponse": {
        "type": "object",
        "description": "Error body returned by the API gateway before a request reaches an endpoint (for example a rejected API key).",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Short error name.",
            "example": "Forbidden"
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation.",
            "example": "A valid and active API key is required."
          }
        }
      },
      "BatchListingsRequest": {
        "type": "object",
        "title": "Batch Listings Request",
        "description": "Request multiple listing details by their unique identifiers",
        "properties": {
          "listing_ids": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "type": "integer",
                  "format": "int64"
                },
                {
                  "type": "string",
                  "pattern": "^\\d+$"
                }
              ],
              "description": "Unique listing identifier. String form is recommended for JavaScript clients to avoid 64-bit precision loss."
            },
            "minItems": 1,
            "maxItems": 25,
            "description": "List of Airbnb listing IDs to retrieve. Maximum 25 per request.\n",
            "example": [
              43036533,
              20609252,
              52847291
            ]
          },
          "currency": {
            "type": "string",
            "description": "Optional currency for financial data conversion. If omitted, returns each listing's native currency.\nAllowed currency values are 'usd' (US Dollars) or 'native' (local currency).\nFor example, 'native' automatically uses EUR in France, JPY in Japan, or BRL in Brazil etc.\n",
            "enum": [
              "usd",
              "native"
            ],
            "default": "native",
            "example": "usd"
          }
        },
        "required": [
          "listing_ids"
        ]
      },
      "BatchListingError": {
        "type": "object",
        "title": "Batch Listing Error",
        "description": "Error information for a listing that could not be retrieved",
        "properties": {
          "listing_id": {
            "type": "integer",
            "format": "int64",
            "description": "ID of the listing that could not be retrieved"
          },
          "message": {
            "type": "string",
            "description": "Error message explaining why the listing could not be retrieved",
            "example": "Listing not found. This may be due to an invalid ID, or the listing has not been added to our system."
          }
        },
        "required": [
          "listing_id",
          "message"
        ]
      },
      "BatchListingsResponse": {
        "type": "object",
        "title": "Batch Listings Response",
        "description": "Response containing successfully retrieved listings and errors for missing ones",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListingDetailsResponse"
            },
            "description": "Array of successfully retrieved listing details"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchListingError"
            },
            "description": "Array of errors for listings that could not be retrieved"
          }
        },
        "required": [
          "results",
          "errors"
        ]
      },
      "ComparableListingsResponse": {
        "type": "object",
        "title": "Comparable Listings Response",
        "description": "List of properties similar to the subject property, ranked by relevance",
        "properties": {
          "listings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListingDetailsResponse"
            },
            "maxItems": 25,
            "description": "Array of up to 25 comparable listings with full details, sorted by similarity score.\n"
          }
        }
      },
      "PaginationRequest": {
        "type": "object",
        "description": "Pagination parameters for listing search requests.",
        "properties": {
          "page_size": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "default": 10,
            "description": "The number of items to return per page."
          },
          "offset": {
            "type": "integer",
            "minimum": 0,
            "default": 0,
            "description": "The starting offset for pagination."
          }
        }
      },
      "StandardQueryRequest": {
        "type": "object",
        "description": "Base request object for listing search endpoints.",
        "properties": {
          "filter": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "eq": {
                  "description": "Exact match"
                },
                "gt": {
                  "description": "Greater than"
                },
                "gte": {
                  "description": "Greater than or equal to"
                },
                "lt": {
                  "description": "Less than"
                },
                "lte": {
                  "description": "Less than or equal to"
                },
                "range": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  },
                  "minItems": 2,
                  "maxItems": 2,
                  "description": "Range of values [min, max]"
                },
                "any": {
                  "type": "array",
                  "description": "Match any value in list"
                },
                "all": {
                  "type": "array",
                  "description": "Match all values in list"
                },
                "none": {
                  "type": "array",
                  "description": "Match none of the values in list"
                }
              }
            },
            "description": "A filter object where each field maps to its condition(s). Multiple filters are ANDed together.\n\nFor most fields, each field condition must contain exactly one operator.\n\nThe `amenities` field is the exception. It may combine `all`, `any`, and\n`none` in the same object:\n- `all`: the listing must include every amenity in the list\n- `any`: the listing must include at least one amenity in the list\n- `none`: the listing must include none of the amenities in the list\n\nIf you provide more than one of these operators, the listing must satisfy\nall of them.\n\n**Available Operators:**\n- `eq`: Exact match\n- `gt`, `gte`, `lt`, `lte`: Numeric comparisons\n- `range`: Two-value array [min, max]\n- `any`: Match any value in list\n- `all`: Match all values in list\n- `none`: Match none of the values in list\n\n**Example:**\n```json\n{\n  \"bedrooms\": { \"gte\": 2 },\n  \"amenities\": {\n    \"all\": [\"wifi\", \"kitchen\"],\n    \"any\": [\"pool\", \"hot_tub\"],\n    \"none\": [\"smoking_allowed\"]\n  },\n  \"ttm_revenue\": { \"gt\": 50000 },\n  \"superhost\": { \"eq\": true }\n}\n```\nThis means the listing must have `wifi` and `kitchen`, must have `pool`\nor `hot_tub`, and must not have `smoking_allowed`.\n<details>\n<summary>View Filterable Fields</summary>\n\n**Location**\n| Field | Type | Operators |\n|---|---|---|\n| `latitude` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `longitude` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `country` | String | `eq` |\n| `region` | String | `eq` |\n| `locality` | String | `eq` |\n| `district` | String | `eq` |\n| `exact_location` | Boolean | `eq` |\n\n**Property Details**\n| Field | Type | Operators |\n|---|---|---|\n| `amenities` | List | `any`, `all`, `none` (can be combined on the same field) |\n| `baths` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `bedrooms` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `beds` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `guests` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `listing_id` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `listing_type` | String | `eq` |\n| `min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `photos_count` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `room_type` | String | `eq` |\n| `guest_favorite` | Boolean | `eq` |\n\n**Host**\n| Field | Type | Operators |\n|---|---|---|\n| `cohost_ids` | List | `any`, `all`, `none` |\n| `cohost_names` | List | `any`, `all`, `none` |\n| `host_id` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `host_name` | String | `eq` |\n| `professional_management` | Boolean | `eq` |\n| `superhost` | Boolean | `eq` |\n\n**Booking & Pricing**\n| Field | Type | Operators |\n|---|---|---|\n| `cleaning_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `extra_guest_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `instant_book` | Boolean | `eq` |\n| `short_stay_cleaning_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `single_fee_structure` | Boolean | `eq` |\n\n**Ratings**\n| Field | Type | Operators |\n|---|---|---|\n| `num_reviews` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_accuracy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_checkin` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_cleanliness` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_communication` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_location` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_overall` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_value` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n\n**Performance Metrics (Last 90 Days)**\n| Field | Type | Operators |\n|---|---|---|\n| `l90d_adjusted_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_adjusted_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_rate` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_length_of_stay` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_available_days` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_days_booked` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_revenue` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n\n**Performance Metrics (Trailing Twelve Months)**\n| Field | Type | Operators |\n|---|---|---|\n| `ttm_adjusted_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_adjusted_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_rate` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_length_of_stay` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_available_days` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_days_booked` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_revenue` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n</details>\n"
          },
          "sort": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            },
            "description": "A map of field names to sort directions. Order is preserved, with the first field having highest priority.\n\n**Example:**\n```json\n{\n  \"ttm_revenue\": \"desc\",\n  \"rating_overall\": \"desc\",\n  \"cleaning_fee\": \"asc\"\n}\n```\n<details>\n<summary>View Sortable Fields</summary>\n\n**Location**\n| Field | Type |\n|---|---|\n| `latitude` | Numeric |\n| `longitude` | Numeric |\n\n**Property Details**\n| Field | Type |\n|---|---|\n| `baths` | Numeric |\n| `bedrooms` | Numeric |\n| `beds` | Numeric |\n| `guests` | Numeric |\n| `listing_id` | Numeric |\n| `listing_type` | String |\n| `min_nights` | Numeric |\n| `photos_count` | Numeric |\n| `room_type` | String |\n| `guest_favorite` | Boolean |\n\n**Host**\n| Field | Type |\n|---|---|\n| `host_id` | Numeric |\n| `host_name` | String |\n| `professional_management` | Boolean |\n| `superhost` | Boolean |\n\n**Booking & Pricing**\n| Field | Type |\n|---|---|\n| `cleaning_fee` | Numeric |\n| `extra_guest_fee` | Numeric |\n| `instant_book` | Boolean |\n| `short_stay_cleaning_fee` | Numeric |\n\n**Ratings**\n| Field | Type |\n|---|---|\n| `num_reviews` | Numeric |\n| `rating_accuracy` | Numeric |\n| `rating_checkin` | Numeric |\n| `rating_cleanliness` | Numeric |\n| `rating_communication` | Numeric |\n| `rating_location` | Numeric |\n| `rating_overall` | Numeric |\n| `rating_value` | Numeric |\n\n**Performance Metrics (Last 90 Days)**\n| Field | Type |\n|---|---|\n| `l90d_adjusted_occupancy` | Numeric |\n| `l90d_adjusted_revpar` | Numeric |\n| `l90d_avg_rate` | Numeric |\n| `l90d_avg_min_nights` | Numeric |\n| `l90d_avg_length_of_stay` | Numeric |\n| `l90d_available_days` | Numeric |\n| `l90d_days_booked` | Numeric |\n| `l90d_occupancy` | Numeric |\n| `l90d_revenue` | Numeric |\n| `l90d_revpar` | Numeric |\n\n**Performance Metrics (Trailing Twelve Months)**\n| Field | Type |\n|---|---|\n| `ttm_adjusted_occupancy` | Numeric |\n| `ttm_adjusted_revpar` | Numeric |\n| `ttm_avg_rate` | Numeric |\n| `ttm_avg_min_nights` | Numeric |\n| `ttm_avg_length_of_stay` | Numeric |\n| `ttm_available_days` | Numeric |\n| `ttm_days_booked` | Numeric |\n| `ttm_occupancy` | Numeric |\n| `ttm_revenue` | Numeric |\n| `ttm_revpar` | Numeric |\n</details>\n"
          },
          "pagination": {
            "$ref": "#/components/schemas/PaginationRequest",
            "example": {
              "page_size": 10,
              "offset": 20
            }
          },
          "currency": {
            "type": "string",
            "enum": [
              "usd",
              "native"
            ],
            "default": "native",
            "description": "Currency for financial data conversion.\nAllowed currency values are 'usd' (US Dollars) or 'native' (local currency).\nFor example, 'native' automatically uses EUR in France, JPY in Japan, or BRL in Brazil etc.\n"
          }
        }
      },
      "Market": {
        "type": "object",
        "title": "Market",
        "description": "Internal representation of a geographic market used for encoding/decoding market identifiers.\n",
        "properties": {
          "country": {
            "type": "string",
            "description": "The country code where the market is located (e.g., \"US\", \"FR\").",
            "example": "United States"
          },
          "region": {
            "type": "string",
            "description": "The primary administrative division, such as a state or province (e.g., \"California\", \"Ile-de-France\").",
            "example": "California"
          },
          "locality": {
            "type": "string",
            "description": "The city, town, or other municipality (e.g., \"Los Angeles\", \"Paris\").",
            "example": "Los Angeles"
          },
          "district": {
            "type": "string",
            "description": "A neighborhood, borough, or other sub-city area (e.g., \"90292\", \"18th Arrondissement\").",
            "example": "90292",
            "nullable": true
          }
        }
      },
      "ListingSearchMarketRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/StandardQueryRequest"
          },
          {
            "type": "object",
            "properties": {
              "market": {
                "$ref": "#/components/schemas/Market"
              },
              "pagination": {
                "$ref": "#/components/schemas/PaginationRequest"
              }
            }
          }
        ]
      },
      "PaginationResponse": {
        "type": "object",
        "properties": {
          "total_count": {
            "type": "integer",
            "format": "int64"
          },
          "page_size": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          }
        }
      },
      "ListingSearchResponse": {
        "type": "object",
        "title": "Search Listings Response",
        "description": "Results from listing search including summaries and total count",
        "properties": {
          "pagination": {
            "$ref": "#/components/schemas/PaginationResponse"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListingDetailsResponse"
            },
            "description": "Array of listing summaries matching search criteria"
          }
        }
      },
      "ListingSearchRadiusRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/StandardQueryRequest"
          },
          {
            "type": "object",
            "properties": {
              "latitude": {
                "type": "number",
                "format": "double",
                "minimum": -90,
                "maximum": 90
              },
              "longitude": {
                "type": "number",
                "format": "double",
                "minimum": -180,
                "maximum": 180
              },
              "radius_miles": {
                "type": "number",
                "format": "double",
                "minimum": 1,
                "maximum": 100,
                "default": 3
              },
              "pagination": {
                "$ref": "#/components/schemas/PaginationRequest"
              }
            },
            "required": [
              "latitude",
              "longitude"
            ]
          }
        ]
      },
      "PolygonCoordinate": {
        "type": "object",
        "properties": {
          "latitude": {
            "type": "number",
            "format": "double",
            "minimum": -90,
            "maximum": 90
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "minimum": -180,
            "maximum": 180
          }
        },
        "required": [
          "latitude",
          "longitude"
        ]
      },
      "ListingSearchPolygonRequest": {
        "allOf": [
          {
            "$ref": "#/components/schemas/StandardQueryRequest"
          },
          {
            "type": "object",
            "properties": {
              "polygon": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/PolygonCoordinate"
                },
                "minItems": 3,
                "maxItems": 1000
              },
              "pagination": {
                "$ref": "#/components/schemas/PaginationRequest"
              }
            },
            "required": [
              "polygon"
            ]
          }
        ]
      },
      "ListingMonthlyMetrics": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "yyyy-MM"
          },
          "occupancy": {
            "type": "number",
            "format": "double"
          },
          "average_daily_rate": {
            "type": "number",
            "format": "double"
          },
          "rev_par": {
            "type": "number",
            "format": "double"
          },
          "revenue": {
            "type": "number",
            "format": "double"
          },
          "min_nights": {
            "type": "integer",
            "description": "Average minimum stay requirement for the month",
            "example": 3,
            "nullable": true
          }
        }
      },
      "ListingTimeSeriesResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListingMonthlyMetrics"
            }
          }
        }
      },
      "DailyRate": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "yyyy-MM-dd"
          },
          "available": {
            "type": "boolean"
          },
          "rate": {
            "type": "number",
            "format": "double",
            "nullable": true,
            "description": "Nightly rate, excluding the cleaning fee, in the response `currency`."
          },
          "min_nights": {
            "type": "integer",
            "description": "Minimum stay requirement in nights for this date",
            "nullable": true,
            "example": 2
          }
        }
      },
      "FutureRatesResponse": {
        "type": "object",
        "properties": {
          "rates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DailyRate"
            }
          },
          "currency": {
            "type": "string",
            "description": "ISO currency code for all rate values in the response.\nReturns \"USD\" when requested with currency=usd, or the listing's local currency code when requested with currency=native.\n",
            "example": "USD"
          }
        }
      },
      "LiveError": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable error code.",
            "example": "invalid_request"
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation."
          }
        }
      },
      "CalendarDay": {
        "type": "object",
        "required": [
          "date",
          "available",
          "rate",
          "min_nights"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "description": "Night of stay (YYYY-MM-DD)."
          },
          "available": {
            "type": "boolean",
            "description": "Whether the night is open for booking. `false` covers both booked\nnights and nights the host has blocked.\n"
          },
          "rate": {
            "type": "number",
            "nullable": true,
            "description": "Nightly rate, excluding the cleaning fee, in the response `currency`."
          },
          "min_nights": {
            "type": "integer",
            "minimum": 1,
            "nullable": true,
            "description": "Minimum stay, in nights, for a stay starting on this date. Null when unknown."
          }
        }
      },
      "CalendarResponse": {
        "type": "object",
        "required": [
          "currency",
          "cleaning_fee",
          "short_stay_cleaning_fee",
          "results"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "example": "USD",
            "description": "ISO 4217 code for every `rate` and cleaning fee in the response."
          },
          "cleaning_fee": {
            "type": "number",
            "nullable": true,
            "example": 85,
            "description": "The cleaning fee set by the host, in the response `currency`. Null when unknown."
          },
          "short_stay_cleaning_fee": {
            "type": "number",
            "nullable": true,
            "example": 60,
            "description": "The cleaning fee the host set for stays of 1–2 nights, in the response `currency`. Equals `cleaning_fee` when the host has one fee. Null when unknown."
          },
          "results": {
            "type": "array",
            "description": "One entry per night, in date order.",
            "items": {
              "$ref": "#/components/schemas/CalendarDay"
            }
          }
        },
        "example": {
          "currency": "EUR",
          "cleaning_fee": 60,
          "short_stay_cleaning_fee": 45,
          "results": [
            {
              "date": "2026-09-22",
              "available": false,
              "rate": 142,
              "min_nights": 2
            },
            {
              "date": "2026-09-23",
              "available": true,
              "rate": 138,
              "min_nights": 2
            },
            {
              "date": "2026-09-24",
              "available": true,
              "rate": null,
              "min_nights": 2
            },
            {
              "date": "2026-09-25",
              "available": true,
              "rate": 165,
              "min_nights": 3
            }
          ]
        }
      },
      "RatesResponse": {
        "type": "object",
        "required": [
          "currency",
          "results"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "example": "USD",
            "description": "ISO 4217 code for every `rate` in the response."
          },
          "results": {
            "type": "array",
            "description": "One entry per night, in date order.",
            "items": {
              "type": "object",
              "required": [
                "date",
                "rate"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "description": "Night of stay (YYYY-MM-DD)."
                },
                "rate": {
                  "type": "number",
                  "nullable": true,
                  "description": "Nightly rate, excluding the cleaning fee, in the response `currency`."
                }
              }
            }
          }
        },
        "example": {
          "currency": "EUR",
          "results": [
            {
              "date": "2026-09-22",
              "rate": 142
            },
            {
              "date": "2026-09-23",
              "rate": 138
            },
            {
              "date": "2026-09-24",
              "rate": null
            },
            {
              "date": "2026-09-25",
              "rate": 165
            }
          ]
        }
      },
      "AvailabilityResponse": {
        "type": "object",
        "required": [
          "results"
        ],
        "properties": {
          "results": {
            "type": "array",
            "description": "One entry per night, in date order.",
            "items": {
              "type": "object",
              "required": [
                "date",
                "available",
                "min_nights",
                "available_for_checkin",
                "available_for_checkout"
              ],
              "properties": {
                "date": {
                  "type": "string",
                  "format": "date",
                  "description": "Night of stay (YYYY-MM-DD)."
                },
                "available": {
                  "type": "boolean",
                  "description": "Whether the night is open for booking. `false` covers both\nbooked nights and nights the host has blocked.\n"
                },
                "min_nights": {
                  "type": "integer",
                  "minimum": 1,
                  "nullable": true,
                  "description": "Minimum stay, in nights, for a stay starting on this date. Null when unknown."
                },
                "max_nights": {
                  "type": "integer",
                  "minimum": 1,
                  "nullable": true,
                  "description": "Maximum stay, in nights. Null or omitted when the host hasn't set one or it's unknown."
                },
                "available_for_checkin": {
                  "type": "boolean",
                  "nullable": true,
                  "description": "Whether a guest can arrive on this date. Null when unknown."
                },
                "available_for_checkout": {
                  "type": "boolean",
                  "nullable": true,
                  "description": "Whether a guest can leave on this date. Null when unknown."
                }
              }
            }
          }
        },
        "example": {
          "results": [
            {
              "date": "2026-09-22",
              "available": false,
              "min_nights": 2,
              "max_nights": 28,
              "available_for_checkin": false,
              "available_for_checkout": true
            },
            {
              "date": "2026-09-23",
              "available": true,
              "min_nights": 2,
              "max_nights": 28,
              "available_for_checkin": true,
              "available_for_checkout": false
            },
            {
              "date": "2026-09-24",
              "available": true,
              "min_nights": 2,
              "max_nights": null,
              "available_for_checkin": null,
              "available_for_checkout": null
            }
          ]
        }
      },
      "Bounds": {
        "type": "object",
        "required": [
          "south",
          "west",
          "north",
          "east"
        ],
        "additionalProperties": false,
        "description": "A latitude/longitude rectangle in WGS84 degrees.\n\n- `south` must be less than `north`, and `west` less than `east`.\n- Latitudes must be between -85 and 85.\n- The rectangle can't cross the antimeridian (±180° longitude).\n- The area can be at most 10,000 km², and neither side can be longer than 200 km.\n",
        "properties": {
          "south": {
            "type": "number",
            "minimum": -85,
            "maximum": 85,
            "description": "Southern edge (minimum latitude)."
          },
          "west": {
            "type": "number",
            "minimum": -180,
            "maximum": 180,
            "description": "Western edge (minimum longitude)."
          },
          "north": {
            "type": "number",
            "minimum": -85,
            "maximum": 85,
            "description": "Northern edge (maximum latitude)."
          },
          "east": {
            "type": "number",
            "minimum": -180,
            "maximum": 180,
            "description": "Eastern edge (maximum longitude)."
          }
        },
        "example": {
          "south": 51.28676,
          "west": -0.51036,
          "north": 51.69188,
          "east": 0.33404
        }
      },
      "RankingRequest": {
        "type": "object",
        "required": [
          "bounds"
        ],
        "additionalProperties": false,
        "properties": {
          "bounds": {
            "$ref": "#/components/schemas/Bounds"
          }
        }
      },
      "ListingId": {
        "type": "object",
        "required": [
          "listing_id"
        ],
        "properties": {
          "listing_id": {
            "type": "string",
            "pattern": "^[1-9][0-9]{0,19}$",
            "example": "43036533",
            "description": "Airbnb listing ID, as a string because it can exceed JavaScript's safe integer range."
          }
        }
      },
      "RankingResponse": {
        "type": "object",
        "required": [
          "results",
          "count"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 270,
            "description": "Number of listings in `results`, not the total in the area."
          },
          "results": {
            "type": "array",
            "maxItems": 270,
            "description": "Listings in search order, starting with rank 1.",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/ListingId"
                },
                {
                  "type": "object",
                  "required": [
                    "rank"
                  ],
                  "properties": {
                    "rank": {
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 270,
                      "description": "Position in this response, from 1 to `count`."
                    }
                  }
                }
              ]
            }
          }
        }
      },
      "ScanPolygon": {
        "type": "array",
        "minItems": 3,
        "maxItems": 1000,
        "description": "The area to scan, as an ordered list of `{latitude, longitude}` points.\n\n- Use 3 to 1,000 points. The shape is closed for you, so repeating the first point is optional.\n- Edges can't cross each other, and holes aren't supported.\n- Latitudes must be between -85 and 85.\n- The polygon's bounding rectangle can be at most 10,000 km², with no side longer than 200 km.\n",
        "items": {
          "$ref": "#/components/schemas/PolygonCoordinate"
        }
      },
      "ScanRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "polygon"
        ],
        "properties": {
          "polygon": {
            "$ref": "#/components/schemas/ScanPolygon"
          },
          "pagination": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "page_size": {
                "type": "integer",
                "minimum": 1,
                "maximum": 100,
                "default": 100,
                "description": "Maximum number of IDs to return on this page. You can change it between pages."
              },
              "cursor": {
                "type": "string",
                "nullable": true,
                "maxLength": 1048576,
                "description": "Omit to start a scan; otherwise the previous response's `next_cursor`. Opaque, up to 1 MiB."
              }
            }
          }
        }
      },
      "ScanResponse": {
        "type": "object",
        "required": [
          "results",
          "pagination"
        ],
        "properties": {
          "results": {
            "type": "array",
            "maxItems": 100,
            "description": "Listing IDs found on this page, in no particular order. May be empty.",
            "items": {
              "$ref": "#/components/schemas/ListingId"
            }
          },
          "pagination": {
            "type": "object",
            "required": [
              "page_size",
              "next_cursor"
            ],
            "properties": {
              "page_size": {
                "type": "integer",
                "minimum": 0,
                "maximum": 100,
                "description": "Number of IDs on this page. Can be less than requested even when more pages follow."
              },
              "next_cursor": {
                "type": "string",
                "nullable": true,
                "description": "Cursor for the next page. Null when the scan is finished."
              }
            }
          }
        }
      },
      "MarketEntry": {
        "type": "object",
        "title": "Market Entry",
        "description": "Detailed information about a short-term rental market including its unique identifier,\ngeographic location, and market statistics.\n",
        "properties": {
          "full_name": {
            "type": "string",
            "description": "Human-readable market name formatted as \"City, State, Country\" or with neighborhood/subdivision if applicable",
            "example": "Los Angeles, California, US"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "example": "United States"
          },
          "region": {
            "type": "string",
            "description": "Full state or region name (not abbreviations)",
            "example": "California",
            "nullable": true
          },
          "locality": {
            "type": "string",
            "description": "City name",
            "example": "Los Angeles",
            "nullable": true
          },
          "district": {
            "type": "string",
            "description": "Neighborhood name for neighborhood-level markets",
            "example": "Hollywood",
            "nullable": true
          },
          "native_currency": {
            "type": "string",
            "description": "ISO 4217 currency code predominantly used in this market (e.g. \"USD\", \"EUR\", \"JPY\")",
            "example": "EUR",
            "nullable": true
          },
          "active_listings_count": {
            "type": "integer",
            "format": "int64",
            "description": "Approximate count of currently active short-term rental listings in this market",
            "example": 42000,
            "minimum": 0
          }
        }
      },
      "SearchMarketResponse": {
        "type": "object",
        "title": "Search Market Response",
        "description": "Response containing markets matching the search query. Each market includes its unique base64-encoded identifier,\ngeographic hierarchy, active listing count, and native currency.\n",
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketEntry"
            },
            "description": "List of markets matching the search criteria, ordered by relevance"
          }
        },
        "required": [
          "entries"
        ]
      },
      "MarketLookupResponse": {
        "type": "object",
        "properties": {
          "full_name": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "locality": {
            "type": "string"
          },
          "district": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "filter": {
        "type": "object",
        "additionalProperties": {
          "type": "object",
          "properties": {
            "eq": {
              "description": "Exact match"
            },
            "gt": {
              "description": "Greater than"
            },
            "gte": {
              "description": "Greater than or equal to"
            },
            "lt": {
              "description": "Less than"
            },
            "lte": {
              "description": "Less than or equal to"
            },
            "range": {
              "type": "array",
              "items": {
                "type": "number"
              },
              "minItems": 2,
              "maxItems": 2,
              "description": "Range of values [min, max]"
            },
            "any": {
              "type": "array",
              "description": "Match any value in list"
            },
            "all": {
              "type": "array",
              "description": "Match all values in list"
            },
            "none": {
              "type": "array",
              "description": "Match none of the values in list"
            }
          }
        },
        "description": "A filter object where each field maps to its condition(s). Multiple filters are ANDed together.\n\nFor most fields, each field condition must contain exactly one operator.\n\nThe `amenities` field is the exception. It may combine `all`, `any`, and\n`none` in the same object:\n- `all`: the listing must include every amenity in the list\n- `any`: the listing must include at least one amenity in the list\n- `none`: the listing must include none of the amenities in the list\n\nIf you provide more than one of these operators, the listing must satisfy\nall of them.\n\n**Available Operators:**\n- `eq`: Exact match\n- `gt`, `gte`, `lt`, `lte`: Numeric comparisons\n- `range`: Two-value array [min, max]\n- `any`: Match any value in list\n- `all`: Match all values in list\n- `none`: Match none of the values in list\n\n**Example:**\n```json\n{\n  \"bedrooms\": { \"gte\": 2 },\n  \"amenities\": {\n    \"all\": [\"wifi\", \"kitchen\"],\n    \"any\": [\"pool\", \"hot_tub\"],\n    \"none\": [\"smoking_allowed\"]\n  },\n  \"ttm_revenue\": { \"gt\": 50000 },\n  \"superhost\": { \"eq\": true }\n}\n```\nThis means the listing must have `wifi` and `kitchen`, must have `pool`\nor `hot_tub`, and must not have `smoking_allowed`.\n<details>\n<summary>View Filterable Fields</summary>\n\n**Location**\n| Field | Type | Operators |\n|---|---|---|\n| `latitude` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `longitude` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `country` | String | `eq` |\n| `region` | String | `eq` |\n| `locality` | String | `eq` |\n| `district` | String | `eq` |\n| `exact_location` | Boolean | `eq` |\n\n**Property Details**\n| Field | Type | Operators |\n|---|---|---|\n| `amenities` | List | `any`, `all`, `none` (can be combined on the same field) |\n| `baths` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `bedrooms` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `beds` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `guests` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `listing_id` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `listing_type` | String | `eq` |\n| `min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `photos_count` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `room_type` | String | `eq` |\n| `guest_favorite` | Boolean | `eq` |\n\n**Host**\n| Field | Type | Operators |\n|---|---|---|\n| `cohost_ids` | List | `any`, `all`, `none` |\n| `cohost_names` | List | `any`, `all`, `none` |\n| `host_id` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `host_name` | String | `eq` |\n| `professional_management` | Boolean | `eq` |\n| `superhost` | Boolean | `eq` |\n\n**Booking & Pricing**\n| Field | Type | Operators |\n|---|---|---|\n| `cleaning_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `extra_guest_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `instant_book` | Boolean | `eq` |\n| `short_stay_cleaning_fee` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `single_fee_structure` | Boolean | `eq` |\n\n**Ratings**\n| Field | Type | Operators |\n|---|---|---|\n| `num_reviews` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_accuracy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_checkin` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_cleanliness` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_communication` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_location` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_overall` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `rating_value` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n\n**Performance Metrics (Last 90 Days)**\n| Field | Type | Operators |\n|---|---|---|\n| `l90d_adjusted_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_adjusted_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_rate` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_avg_length_of_stay` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_available_days` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_days_booked` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_revenue` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `l90d_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n\n**Performance Metrics (Trailing Twelve Months)**\n| Field | Type | Operators |\n|---|---|---|\n| `ttm_adjusted_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_adjusted_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_rate` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_min_nights` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_avg_length_of_stay` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_available_days` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_days_booked` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_occupancy` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_revenue` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n| `ttm_revpar` | Numeric | `eq`, `lt`, `lte`, `gt`, `gte`, `range` |\n</details>\n"
      },
      "currency": {
        "type": "string",
        "enum": [
          "usd",
          "native"
        ],
        "default": "native",
        "description": "Currency for financial data conversion.\nAllowed currency values are 'usd' (US Dollars) or 'native' (local currency).\nFor example, 'native' automatically uses EUR in France, JPY in Japan, or BRL in Brazil etc.\n"
      },
      "MarketQueryRequest": {
        "type": "object",
        "description": "Request body for market analytics endpoints.\nSupports market filters, currency conversion, and historical window selection via `num_months`.\nSorting and pagination are not supported because market responses are aggregated analytics, not paginated listing results.\n",
        "properties": {
          "market": {
            "$ref": "#/components/schemas/Market"
          },
          "filter": {
            "$ref": "#/components/schemas/filter"
          },
          "currency": {
            "$ref": "#/components/schemas/currency"
          },
          "num_months": {
            "type": "integer",
            "minimum": 0,
            "maximum": 60,
            "default": 12,
            "description": "The number of months of historical data to retrieve for time-series queries."
          }
        },
        "required": [
          "market"
        ]
      },
      "MarketSummaryResponse": {
        "type": "object",
        "properties": {
          "market": {
            "$ref": "#/components/schemas/Market"
          },
          "occupancy": {
            "type": "number",
            "format": "double",
            "example": 0.72
          },
          "average_daily_rate": {
            "type": "number",
            "format": "double",
            "example": 285.5
          },
          "rev_par": {
            "type": "number",
            "format": "double",
            "example": 205.56
          },
          "revenue": {
            "type": "number",
            "format": "double",
            "example": 125000
          },
          "booking_lead_time": {
            "type": "number",
            "format": "double",
            "example": 42.5
          },
          "length_of_stay": {
            "type": "number",
            "format": "double",
            "example": 3.8
          },
          "min_nights": {
            "type": "number",
            "format": "double",
            "example": 3.2
          },
          "active_listings_count": {
            "type": "number",
            "format": "double",
            "example": 2458
          }
        }
      },
      "MetricStats": {
        "type": "object",
        "properties": {
          "avg": {
            "type": "number",
            "format": "double"
          },
          "p25": {
            "type": "number",
            "format": "double"
          },
          "p50": {
            "type": "number",
            "format": "double"
          },
          "p75": {
            "type": "number",
            "format": "double"
          },
          "p90": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "MarketMonthlyMetrics": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "occupancy": {
            "$ref": "#/components/schemas/MetricStats"
          },
          "average_daily_rate": {
            "$ref": "#/components/schemas/MetricStats"
          },
          "revpar": {
            "$ref": "#/components/schemas/MetricStats"
          },
          "revenue": {
            "$ref": "#/components/schemas/MetricStats"
          },
          "booking_lead_time": {
            "$ref": "#/components/schemas/MetricStats"
          },
          "length_of_stay": {
            "$ref": "#/components/schemas/MetricStats"
          },
          "min_nights": {
            "$ref": "#/components/schemas/MetricStats"
          },
          "active_listings_count": {
            "type": "integer"
          }
        }
      },
      "CombinedMetricsResponse": {
        "type": "object",
        "properties": {
          "market": {
            "$ref": "#/components/schemas/Market"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketMonthlyMetrics"
            }
          }
        },
        "example": {
          "market": {
            "country": "United States",
            "region": "California",
            "locality": "Los Angeles"
          },
          "results": [
            {
              "date": "2024-01-01",
              "occupancy": {
                "avg": 0.68,
                "p25": 0.55,
                "p50": 0.69,
                "p75": 0.82,
                "p90": 0.91
              },
              "average_daily_rate": {
                "avg": 275,
                "p25": 150,
                "p50": 225,
                "p75": 350,
                "p90": 500
              },
              "revpar": {
                "avg": 187,
                "p25": 82.5,
                "p50": 155.25,
                "p75": 287,
                "p90": 455
              },
              "revenue": {
                "avg": 5797,
                "p25": 2557.5,
                "p50": 4812.75,
                "p75": 8897,
                "p90": 14105
              },
              "booking_lead_time": {
                "avg": 38.5,
                "p25": 14,
                "p50": 28,
                "p75": 56,
                "p90": 90
              },
              "length_of_stay": {
                "avg": 4.2,
                "p25": 2,
                "p50": 3,
                "p75": 5,
                "p90": 8
              },
              "min_nights": {
                "avg": 3.1,
                "p25": 2,
                "p50": 3,
                "p75": 4,
                "p90": 5
              },
              "active_listings_count": 3245
            },
            {
              "date": "2024-02-01",
              "occupancy": {
                "avg": 0.72,
                "p25": 0.58,
                "p50": 0.73,
                "p75": 0.85,
                "p90": 0.93
              },
              "average_daily_rate": {
                "avg": 285,
                "p25": 155,
                "p50": 235,
                "p75": 365,
                "p90": 525
              },
              "revpar": {
                "avg": 205.2,
                "p25": 89.9,
                "p50": 171.55,
                "p75": 310.25,
                "p90": 488.25
              },
              "revenue": {
                "avg": 5745.6,
                "p25": 2517.2,
                "p50": 4803.4,
                "p75": 8687,
                "p90": 13671
              },
              "booking_lead_time": {
                "avg": 42,
                "p25": 15,
                "p50": 30,
                "p75": 60,
                "p90": 95
              },
              "length_of_stay": {
                "avg": 4.5,
                "p25": 2,
                "p50": 3,
                "p75": 6,
                "p90": 10
              },
              "min_nights": {
                "avg": 3.4,
                "p25": 2,
                "p50": 3,
                "p75": 4,
                "p90": 6
              },
              "active_listings_count": 3289
            },
            {
              "date": "2024-03-01",
              "occupancy": {
                "avg": 0.82,
                "p25": 0.7,
                "p50": 0.83,
                "p75": 0.92,
                "p90": 0.97
              },
              "average_daily_rate": {
                "avg": 310,
                "p25": 165,
                "p50": 255,
                "p75": 385,
                "p90": 555
              },
              "revpar": {
                "avg": 254.2,
                "p25": 115.5,
                "p50": 211.65,
                "p75": 354.2,
                "p90": 538.35
              },
              "revenue": {
                "avg": 7626,
                "p25": 3465,
                "p50": 6349.5,
                "p75": 10626,
                "p90": 16150.5
              },
              "booking_lead_time": {
                "avg": 48.5,
                "p25": 18,
                "p50": 35,
                "p75": 65,
                "p90": 105
              },
              "length_of_stay": {
                "avg": 4.8,
                "p25": 3,
                "p50": 4,
                "p75": 6,
                "p90": 12
              },
              "min_nights": {
                "avg": 3.6,
                "p25": 2,
                "p50": 3,
                "p75": 4,
                "p90": 7
              },
              "active_listings_count": 3350
            }
          ]
        }
      },
      "MetricDataPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "avg": {
            "type": "number",
            "format": "double"
          },
          "p25": {
            "type": "number",
            "format": "double"
          },
          "p50": {
            "type": "number",
            "format": "double"
          },
          "p75": {
            "type": "number",
            "format": "double"
          },
          "p90": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "MetricTimeSeriesResponse": {
        "type": "object",
        "properties": {
          "market": {
            "$ref": "#/components/schemas/Market"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MetricDataPoint"
            }
          }
        },
        "example": {
          "market": {
            "country": "United States",
            "region": "Florida",
            "locality": "Miami"
          },
          "results": [
            {
              "date": "2024-01-01",
              "avg": 0.75,
              "p25": 0.62,
              "p50": 0.76,
              "p75": 0.88,
              "p90": 0.94
            },
            {
              "date": "2024-02-01",
              "avg": 0.78,
              "p25": 0.65,
              "p50": 0.79,
              "p75": 0.9,
              "p90": 0.95
            },
            {
              "date": "2024-03-01",
              "avg": 0.82,
              "p25": 0.7,
              "p50": 0.83,
              "p75": 0.92,
              "p90": 0.97
            }
          ]
        }
      },
      "ActiveListingsDataPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "count": {
            "type": "integer"
          }
        }
      },
      "ActiveListingsResponse": {
        "type": "object",
        "properties": {
          "market": {
            "$ref": "#/components/schemas/Market"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ActiveListingsDataPoint"
            }
          }
        },
        "example": {
          "market": {
            "country": "United States",
            "region": "Texas",
            "locality": "Austin"
          },
          "results": [
            {
              "date": "2024-01-01",
              "count": 5678
            },
            {
              "date": "2024-02-01",
              "count": 5823
            },
            {
              "date": "2024-03-01",
              "count": 5945
            },
            {
              "date": "2024-04-01",
              "count": 6102
            },
            {
              "date": "2024-05-01",
              "count": 6287
            }
          ]
        }
      },
      "PacingDataPoint": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "yyyy-MM-dd"
          },
          "booked_count": {
            "type": "integer"
          },
          "available_count": {
            "type": "integer"
          },
          "booked_rate_avg": {
            "type": "number",
            "format": "double"
          },
          "available_rate_avg": {
            "type": "number",
            "format": "double"
          },
          "fill_rate": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "FuturePacingResponse": {
        "type": "object",
        "properties": {
          "market": {
            "$ref": "#/components/schemas/Market"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PacingDataPoint"
            }
          }
        },
        "example": {
          "market": {
            "country": "United States",
            "region": "Utah",
            "locality": "Park City"
          },
          "results": [
            {
              "date": "2025-02-01",
              "booked_count": 2345,
              "available_count": 878,
              "booked_rate_avg": 425.5,
              "available_rate_avg": 389,
              "fill_rate": 0.728
            },
            {
              "date": "2025-02-02",
              "booked_count": 2389,
              "available_count": 834,
              "booked_rate_avg": 435,
              "available_rate_avg": 395,
              "fill_rate": 0.741
            },
            {
              "date": "2025-02-03",
              "booked_count": 2298,
              "available_count": 925,
              "booked_rate_avg": 418.75,
              "available_rate_avg": 380,
              "fill_rate": 0.713
            },
            {
              "date": "2025-02-04",
              "booked_count": 2156,
              "available_count": 1067,
              "booked_rate_avg": 398,
              "available_rate_avg": 365,
              "fill_rate": 0.669
            },
            {
              "date": "2025-02-05",
              "booked_count": 2089,
              "available_count": 1134,
              "booked_rate_avg": 385.5,
              "available_rate_avg": 355,
              "fill_rate": 0.648
            },
            {
              "date": "2025-02-06",
              "booked_count": 2134,
              "available_count": 1089,
              "booked_rate_avg": 392.25,
              "available_rate_avg": 360,
              "fill_rate": 0.662
            },
            {
              "date": "2025-02-07",
              "booked_count": 2412,
              "available_count": 811,
              "booked_rate_avg": 445,
              "available_rate_avg": 405,
              "fill_rate": 0.748
            },
            {
              "date": "2025-02-08",
              "booked_count": 2456,
              "available_count": 767,
              "booked_rate_avg": 455.5,
              "available_rate_avg": 415,
              "fill_rate": 0.762
            },
            {
              "date": "2025-02-14",
              "booked_count": 2245,
              "available_count": 978,
              "booked_rate_avg": 485,
              "available_rate_avg": 435,
              "fill_rate": 0.697
            },
            {
              "date": "2025-02-15",
              "booked_count": 2289,
              "available_count": 934,
              "booked_rate_avg": 495.5,
              "available_rate_avg": 445,
              "fill_rate": 0.71
            },
            {
              "date": "2025-02-21",
              "booked_count": 1856,
              "available_count": 1367,
              "booked_rate_avg": 425,
              "available_rate_avg": 385,
              "fill_rate": 0.576
            },
            {
              "date": "2025-02-28",
              "booked_count": 1678,
              "available_count": 1545,
              "booked_rate_avg": 405,
              "available_rate_avg": 365,
              "fill_rate": 0.521
            },
            {
              "date": "2025-03-15",
              "booked_count": 1234,
              "available_count": 1989,
              "booked_rate_avg": 375,
              "available_rate_avg": 335,
              "fill_rate": 0.383
            },
            {
              "date": "2025-03-31",
              "booked_count": 978,
              "available_count": 2245,
              "booked_rate_avg": 355,
              "available_rate_avg": 315,
              "fill_rate": 0.303
            },
            {
              "date": "2025-04-15",
              "booked_count": 756,
              "available_count": 2467,
              "booked_rate_avg": 335,
              "available_rate_avg": 295,
              "fill_rate": 0.235
            },
            {
              "date": "2025-04-30",
              "booked_count": 589,
              "available_count": 2634,
              "booked_rate_avg": 315,
              "available_rate_avg": 275,
              "fill_rate": 0.183
            }
          ]
        }
      },
      "Location": {
        "type": "object",
        "title": "Location",
        "description": "Geographic coordinates for the property used in the estimate.",
        "properties": {
          "latitude": {
            "type": "number",
            "format": "double",
            "description": "Latitude of the property location.",
            "minimum": -90,
            "maximum": 90,
            "example": 34.052235
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "description": "Longitude of the property location.",
            "minimum": -180,
            "maximum": 180,
            "example": -118.243683
          }
        }
      },
      "QuantileMap": {
        "type": "object",
        "title": "Quantile Map",
        "description": "Statistical distribution values including average and percentiles.",
        "properties": {
          "avg": {
            "type": "number",
            "format": "double",
            "description": "Average (mean) prediction value."
          },
          "p25": {
            "type": "number",
            "format": "double",
            "description": "25th percentile (first quartile)."
          },
          "p50": {
            "type": "number",
            "format": "double",
            "description": "50th percentile (median)."
          },
          "p75": {
            "type": "number",
            "format": "double",
            "description": "75th percentile (third quartile)."
          },
          "p90": {
            "type": "number",
            "format": "double",
            "description": "90th percentile."
          }
        }
      },
      "PercentileBreakdown": {
        "type": "object",
        "title": "Percentile Breakdown",
        "description": "Statistical distribution of predictions for revenue, ADR, and occupancy.\nEach metric contains avg (mean) and percentile values (p25, p50, p75, p90).\n",
        "properties": {
          "revenue": {
            "$ref": "#/components/schemas/QuantileMap",
            "description": "Revenue percentiles in the requested currency."
          },
          "average_daily_rate": {
            "$ref": "#/components/schemas/QuantileMap",
            "description": "Average Daily Rate percentiles in the requested currency."
          },
          "occupancy": {
            "$ref": "#/components/schemas/QuantileMap",
            "description": "Occupancy rate percentiles (0-1 range)."
          }
        },
        "example": {
          "revenue": {
            "avg": 50000,
            "p25": 40000,
            "p50": 48000,
            "p75": 55000,
            "p90": 62000
          },
          "average_daily_rate": {
            "avg": 200,
            "p25": 170,
            "p50": 195,
            "p75": 220,
            "p90": 250
          },
          "occupancy": {
            "avg": 0.68,
            "p25": 0.55,
            "p50": 0.65,
            "p75": 0.75,
            "p90": 0.82
          }
        }
      },
      "CalculatorEstimateResponse": {
        "type": "object",
        "title": "Revenue Estimate Response",
        "description": "Comprehensive revenue projection for a short-term rental property including key performance\nindicators and the comparable listings used to generate the estimate.\n\nThe response provides both summary values and detailed statistical distributions:\n- Root-level fields (`revenue`, `average_daily_rate`, `occupancy`) contain the average (mean) predictions\n- The `percentiles` object contains full statistical breakdowns with avg, p25, p50, p75, and p90 values\n",
        "properties": {
          "location": {
            "$ref": "#/components/schemas/Location",
            "description": "The geographic coordinates used for the estimate. When an address is provided,\nthis contains the geocoded latitude and longitude. When coordinates are provided directly,\nthis echoes them back.\n"
          },
          "revenue": {
            "type": "number",
            "format": "double",
            "description": "Projected annual revenue in the requested currency.\nThis is the average (mean) prediction. For the full distribution including percentiles,\nsee the `percentiles.revenue` object.\n",
            "minimum": 0,
            "example": 50000,
            "nullable": true
          },
          "average_daily_rate": {
            "type": "number",
            "format": "double",
            "description": "Projected Average Daily Rate (ADR) in the requested currency.\nThis is the expected average nightly rate across all booked nights for the year.\nThis is the average (mean) prediction. For the full distribution including percentiles,\nsee the `percentiles.average_daily_rate` object.\n",
            "minimum": 0,
            "example": 200,
            "nullable": true
          },
          "occupancy": {
            "type": "number",
            "format": "double",
            "description": "Projected annual occupancy rate (0.0 to 1.0).\nRepresents the expected percentage of nights booked throughout the year.\nThis is the average (mean) prediction. For the full distribution including percentiles,\nsee the `percentiles.occupancy` object.\n",
            "minimum": 0,
            "maximum": 1,
            "example": 0.68,
            "nullable": true
          },
          "percentiles": {
            "$ref": "#/components/schemas/PercentileBreakdown",
            "description": "Full statistical breakdown of predictions including average and percentile values (p25, p50, p75, p90)\nfor revenue, ADR, and occupancy. Use this for detailed analysis of prediction ranges.\n"
          },
          "currency": {
            "type": "string",
            "description": "The currency code for the average_daily_rate value.\nReturns \"USD\" when currency parameter is \"USD\", or the native currency code (e.g., \"EUR\", \"GBP\")\nwhen currency parameter is \"native\". The native currency is determined from the location of comparable listings.\n",
            "example": "USD",
            "nullable": false
          },
          "monthly_revenue_distributions": {
            "type": "array",
            "items": {
              "type": "number",
              "format": "double",
              "nullable": true
            },
            "description": "Array of 12 monthly revenue distribution ratios ordered by month from January to December.\n- Index 0: January\n- Index 1: February\n- Index 2: March\n- Index 3: April\n- Index 4: May\n- Index 5: June\n- Index 6: July\n- Index 7: August\n- Index 8: September\n- Index 9: October\n- Index 10: November\n- Index 11: December\n\nEach value represents the proportion of annual revenue expected in that month.\nAll values sum to 1.0. Captures seasonal variations and peak earning periods.\n",
            "minItems": 12,
            "maxItems": 12,
            "example": [
              0.05,
              0.05,
              0.07,
              0.08,
              0.09,
              0.11,
              0.13,
              0.12,
              0.1,
              0.08,
              0.06,
              0.06
            ]
          },
          "comparable_listings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListingDetailsResponse"
            },
            "maxItems": 25,
            "description": "A list of up to 25 comparable listings used to generate the revenue estimate.\n"
          }
        },
        "example": {
          "location": {
            "latitude": 34.052235,
            "longitude": -118.243683
          },
          "revenue": 50000,
          "average_daily_rate": 200,
          "occupancy": 0.68,
          "percentiles": {
            "revenue": {
              "avg": 50000,
              "p25": 40000,
              "p50": 48000,
              "p75": 55000,
              "p90": 62000
            },
            "average_daily_rate": {
              "avg": 200,
              "p25": 170,
              "p50": 195,
              "p75": 220,
              "p90": 250
            },
            "occupancy": {
              "avg": 0.68,
              "p25": 0.55,
              "p50": 0.65,
              "p75": 0.75,
              "p90": 0.82
            }
          },
          "currency": "USD",
          "monthly_revenue_distributions": [
            0.05,
            0.05,
            0.07,
            0.08,
            0.09,
            0.11,
            0.13,
            0.12,
            0.1,
            0.08,
            0.06,
            0.06
          ],
          "comparable_listings": [
            {
              "listing_info": {
                "listing_id": 43036533,
                "listing_name": "Beachfront Villa with Private Pool",
                "listing_type": "Entire villa",
                "room_type": "entire_home",
                "cover_photo_url": "https://a0.muscache.com/im/pictures/miso/Hosting-43036533/original/cover.jpeg",
                "photos_count": 45
              },
              "host_info": {
                "host_id": 156789234,
                "host_name": "Alexandra",
                "cohost_ids": [
                  12345678,
                  87654321
                ],
                "cohost_names": [
                  "John",
                  "Sarah"
                ],
                "superhost": true,
                "professional_management": false
              },
              "location_info": {
                "country_code": "US",
                "country": "United States",
                "region": "California",
                "locality": "Malibu",
                "district": "Malibu Beach",
                "latitude": 34.0259,
                "longitude": -118.7798
              },
              "property_details": {
                "guests": 8,
                "bedrooms": 4,
                "beds": 5,
                "baths": 3.5,
                "registration": true,
                "amenities": [
                  "wifi",
                  "kitchen",
                  "free_parking_on_premises",
                  "pool",
                  "hot_tub",
                  "beach_access",
                  "bbq_grill",
                  "outdoor_shower",
                  "fire_pit",
                  "dedicated_workspace"
                ]
              },
              "booking_settings": {
                "instant_book": false,
                "min_nights": 3,
                "cancellation_policy": "strict"
              },
              "pricing_info": {
                "currency": "usd",
                "cleaning_fee": 350,
                "extra_guest_fee": 75
              },
              "ratings": {
                "num_reviews": 89,
                "rating_overall": 4.96,
                "rating_accuracy": 4.98,
                "rating_checkin": 4.97,
                "rating_cleanliness": 4.95,
                "rating_communication": 4.98,
                "rating_location": 5,
                "rating_value": 4.92
              },
              "performance_metrics": {
                "ttm_revenue": 285000,
                "ttm_avg_rate": 1250,
                "ttm_occupancy": 0.625,
                "ttm_adjusted_occupancy": 0.61,
                "ttm_revpar": 781.25,
                "ttm_adjusted_revpar": 762.5,
                "ttm_total_days": 365,
                "ttm_available_days": 350,
                "ttm_blocked_days": 15,
                "ttm_days_reserved": 219,
                "l90d_revenue": 95000,
                "l90d_avg_rate": 1500,
                "l90d_occupancy": 0.7,
                "l90d_adjusted_occupancy": 0.68,
                "l90d_revpar": 1050,
                "l90d_adjusted_revpar": 1020,
                "l90d_total_days": 90,
                "l90d_available_days": 88,
                "l90d_blocked_days": 2,
                "l90d_days_reserved": 62
              }
            }
          ]
        }
      },
      "PriceRecommendationLocation": {
        "type": "object",
        "title": "Property location",
        "description": "Property coordinates used to find pricing data. Where local data is unavailable,\nthe estimate falls back to broader regional or global data.\n",
        "required": [
          "latitude",
          "longitude"
        ],
        "properties": {
          "latitude": {
            "type": "number",
            "format": "double",
            "minimum": -90,
            "maximum": 90,
            "example": 25.7907,
            "description": "Latitude in decimal degrees."
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "minimum": -180,
            "maximum": 180,
            "example": -80.13,
            "description": "Longitude in decimal degrees."
          }
        }
      },
      "BasePriceProperty": {
        "type": "object",
        "title": "Property details",
        "description": "Bedrooms, bathrooms, and guest capacity are required. Optional fields refine\nthe estimate when supported by the current model. Omission means unknown.\n",
        "required": [
          "bedrooms",
          "baths",
          "guests"
        ],
        "properties": {
          "bedrooms": {
            "type": "integer",
            "minimum": 0,
            "maximum": 30,
            "description": "Number of bedrooms; use 0 for a studio. Values above 12 are accepted\nbut priced identically to 12.\n",
            "example": 3
          },
          "baths": {
            "type": "number",
            "format": "double",
            "minimum": 0,
            "maximum": 30,
            "description": "Number of bathrooms; half bathrooms are supported (e.g. 2.5). Values\nabove 15 are accepted but priced identically to 15.\n",
            "example": 2.5
          },
          "guests": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "description": "Maximum guest capacity. Values above 30 are accepted but priced\nidentically to 30.\n",
            "example": 6
          },
          "beds": {
            "type": "number",
            "format": "double",
            "minimum": 0,
            "maximum": 30,
            "description": "Total sleeping surfaces advertised by the property.",
            "example": 4
          },
          "room_type": {
            "type": "string",
            "description": "Booking arrangement offered to the guest.",
            "enum": [
              "entire_home",
              "private_room",
              "shared_room",
              "hotel_room",
              "other"
            ],
            "example": "entire_home"
          },
          "amenities": {
            "type": "array",
            "maxItems": 200,
            "description": "Recognized pricing signals (case-insensitive; display names also work):\n`pool`; `hot_tub`; `waterfront` or `lake_access`; `beach_access` or\n`beach_essentials`; `ski_in_ski_out`; `ocean_view`, `pool_view`,\n`river_view`, or `garden_view`; `free_parking_on_premises` or\n`free_street_parking`; `air_conditioning`; `washer` or `dryer`;\n`kitchen`; `dedicated_workspace`; `ev_charger`.\n\nOther strings are accepted but do not affect pricing; for example, use\n`free_parking_on_premises`, not `parking`. Duplicates are collapsed.\nSend [] only to indicate no notable amenities; omit the field if unknown.\nEach item must be nonblank and at most 100 characters.\n",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "pattern": "\\S"
            },
            "example": [
              "pool",
              "hot_tub",
              "dedicated_workspace"
            ]
          },
          "num_reviews": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000,
            "description": "Current number of guest reviews.",
            "example": 42
          },
          "star_rating": {
            "type": "number",
            "format": "double",
            "minimum": 1,
            "maximum": 5,
            "description": "Current overall guest rating on a 1 to 5 scale.",
            "example": 4.88
          },
          "superhost": {
            "type": "boolean",
            "description": "Whether the host currently has Airbnb Superhost status.",
            "example": true
          },
          "photos_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000,
            "description": "Number of published listing photos.",
            "example": 31
          },
          "cleaning_fee": {
            "type": "number",
            "format": "double",
            "minimum": 0,
            "description": "Per-stay cleaning charge in currency. Used to refine the estimate when local\nstay-length data is available; not added to the nightly rate. Must not exceed\n10,000 USD-equivalent after conversion (HTTP 400 if exceeded).\n",
            "example": 95
          }
        }
      },
      "BasePriceRecommendationRequest": {
        "type": "object",
        "title": "Base Price request",
        "description": "Property facts used to estimate a year-round nightly rate before date-specific\nadjustments. Omit optional details you do not know.\n",
        "required": [
          "location",
          "property"
        ],
        "properties": {
          "location": {
            "$ref": "#/components/schemas/PriceRecommendationLocation"
          },
          "property": {
            "$ref": "#/components/schemas/BasePriceProperty"
          },
          "currency": {
            "type": "string",
            "nullable": true,
            "pattern": "^[A-Za-z]{3}$",
            "minLength": 3,
            "maxLength": 3,
            "default": "USD",
            "example": "USD",
            "description": "Currency for cleaning_fee and all returned amounts. Accepts either case;\nomitted, null, or unrecognized codes resolve to USD. Check the response\ncurrency before using the recommendation.\n"
          }
        }
      },
      "BasePriceResponseCurrency": {
        "type": "string",
        "title": "Response currency",
        "pattern": "^[A-Z]{3}$",
        "minLength": 3,
        "maxLength": 3,
        "example": "USD",
        "description": "Uppercase currency code used for every returned amount. May be USD if the\nrequested code was omitted, null, or unrecognized. Pass this value with\nrecommended_base_price when calling Calendar Prices.\n"
      },
      "BasePriceOptions": {
        "type": "object",
        "additionalProperties": false,
        "title": "Pricing posture options",
        "description": "Alternative starting prices, not confidence bounds. Conservative and aggressive\nare 8% below and above the unrounded balanced estimate, rounded independently.\n",
        "required": [
          "conservative",
          "balanced",
          "aggressive"
        ],
        "properties": {
          "conservative": {
            "type": "integer",
            "minimum": 1,
            "description": "Lower Base Price for a more occupancy-oriented posture (8% below\nthe unrounded balanced value, rounded to an integer).\n",
            "example": 184
          },
          "balanced": {
            "type": "integer",
            "minimum": 1,
            "description": "Default Base Price recommendation. Equal to `recommended_base_price`.\n",
            "example": 200
          },
          "aggressive": {
            "type": "integer",
            "minimum": 1,
            "description": "Higher Base Price for a more rate-oriented posture (8% above the\nunrounded balanced value, rounded to an integer).\n",
            "example": 216
          }
        }
      },
      "BasePriceMoneyRange": {
        "type": "object",
        "additionalProperties": false,
        "title": "Typical local range",
        "description": "Local price variation around the estimate, in whole currency units.\nNot a confidence interval, absolute market percentile, or limit on calendar prices.\n",
        "required": [
          "low",
          "high"
        ],
        "properties": {
          "low": {
            "type": "integer",
            "minimum": 1,
            "example": 150
          },
          "high": {
            "type": "integer",
            "minimum": 1,
            "example": 260
          }
        }
      },
      "BasePriceExplanationLine": {
        "type": "object",
        "additionalProperties": false,
        "title": "Base Price explanation line",
        "description": "One signed contribution to the recommendation. Lines appear in this order:\nmarket_baseline, bedrooms, bathrooms, guest_capacity, optional property_details,\ncurrent_market_level.\n\nMarket baseline is the market-based starting estimate, before adjustments\nfor your property and current market conditions.\n",
        "required": [
          "code",
          "label",
          "amount"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable identifier for the contribution. property_details appears\nonly when optional property facts were supplied.\n",
            "enum": [
              "market_baseline",
              "bedrooms",
              "bathrooms",
              "guest_capacity",
              "property_details",
              "current_market_level"
            ],
            "example": "bedrooms"
          },
          "label": {
            "type": "string",
            "description": "Display label for this contribution, such as Market baseline.\nUse code for programmatic identification and amount for the contribution.\n",
            "example": "3 bedrooms"
          },
          "amount": {
            "type": "integer",
            "description": "Signed monetary contribution in the response currency. Can be negative\nor zero. All amounts sum exactly to `recommended_base_price`.\n",
            "example": 20
          },
          "details": {
            "type": "array",
            "description": "Optional context: property inputs considered, or unavailable/unverified\ncurrent-market data. Display these strings as supplied;\ndo not parse them for pricing logic.\n",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "BasePriceRecommendationResponse": {
        "type": "object",
        "additionalProperties": false,
        "title": "Base Price recommendation",
        "description": "A nightly estimate, pricing alternatives, and an itemized explanation.\nAll amounts are whole currency units, including for currencies with decimals.\n",
        "required": [
          "location",
          "currency",
          "recommended_base_price",
          "price_options",
          "typical_market_range",
          "explanation"
        ],
        "properties": {
          "location": {
            "$ref": "#/components/schemas/PriceRecommendationLocation"
          },
          "currency": {
            "$ref": "#/components/schemas/BasePriceResponseCurrency"
          },
          "recommended_base_price": {
            "type": "integer",
            "minimum": 1,
            "description": "Recommended year-round nightly rate, equal to price_options.balanced.\nExcludes cleaning fees, taxes, platform fees, and other one-time charges.\nUse as base_price for Calendar Prices.\n",
            "example": 200
          },
          "price_options": {
            "$ref": "#/components/schemas/BasePriceOptions"
          },
          "typical_market_range": {
            "$ref": "#/components/schemas/BasePriceMoneyRange"
          },
          "explanation": {
            "type": "array",
            "minItems": 5,
            "maxItems": 6,
            "description": "Signed line items that sum exactly to `recommended_base_price`. Always\n5 or 6 lines in fixed order. The `property_details` line (line 5) is\npresent only when at least one optional property field was sent.\n",
            "items": {
              "$ref": "#/components/schemas/BasePriceExplanationLine"
            }
          }
        }
      },
      "BasePriceErrorMessage": {
        "type": "object",
        "title": "Base Price error",
        "description": "Error body for HTTP 400 responses from the Base Price endpoint.\nThe shape differs from the calendar-prices error envelope: there is no\n`error` wrapper, no `details` array, and no `request_id` field. The\nwrong-JSON-type 400 also carries `field` and `hint`, both `null`.\n",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "integer",
            "description": "HTTP status code.",
            "example": 400
          },
          "message": {
            "type": "string",
            "description": "Human-readable error description.",
            "example": "Unable to process JSON"
          },
          "field": {
            "type": "string",
            "nullable": true,
            "description": "Present only on the wrong-JSON-type 400, where it is always `null`."
          },
          "hint": {
            "type": "string",
            "nullable": true,
            "description": "Present only on the wrong-JSON-type 400, where it is always `null`."
          }
        },
        "example": {
          "code": 400,
          "message": "Unable to process JSON"
        }
      },
      "BasePriceValidationError": {
        "type": "object",
        "title": "Base Price validation error",
        "description": "Validation failures returned with HTTP 422. Each message identifies a field\nand its constraint. An empty body returns \"The request body must not be null\".\n",
        "required": [
          "errors"
        ],
        "properties": {
          "errors": {
            "type": "array",
            "description": "One message per violation, in no guaranteed order.\n",
            "items": {
              "type": "string"
            },
            "example": [
              "property.guests property.guests is required"
            ]
          }
        },
        "example": {
          "errors": [
            "property.guests property.guests is required",
            "property.bedrooms property.bedrooms is required"
          ]
        }
      },
      "CalendarPricingLocation": {
        "type": "object",
        "title": "Property location",
        "description": "Exact property coordinates. AirROI uses them to resolve local pricing curves and the property's local timezone.",
        "required": [
          "latitude",
          "longitude"
        ],
        "properties": {
          "latitude": {
            "type": "number",
            "format": "double",
            "minimum": -90,
            "maximum": 90,
            "description": "Latitude in decimal degrees. Must be a finite number from -90 through 90 inclusive.",
            "example": 25.7907
          },
          "longitude": {
            "type": "number",
            "format": "double",
            "minimum": -180,
            "maximum": 180,
            "description": "Longitude in decimal degrees. Must be a finite number from -180 through 180 inclusive.",
            "example": -80.13
          }
        }
      },
      "PriceRecommendationCurrency": {
        "type": "string",
        "title": "Currency",
        "description": "Supported uppercase ISO 4217 currency code for every monetary input and output. No currency conversion is performed. Lowercase codes are rejected; unsupported codes return UNSUPPORTED_CURRENCY.",
        "example": "USD",
        "minLength": 3,
        "maxLength": 3,
        "pattern": "^[A-Z]{3}$"
      },
      "CalendarPricingDate": {
        "type": "string",
        "format": "date",
        "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
        "description": "Property-local Gregorian calendar date in locale-independent `YYYY-MM-DD` form. Must be a real calendar date; formats such as `MM/DD/YYYY` and invalid dates such as `2026-02-29` are rejected.",
        "example": "2026-12-20"
      },
      "CalendarPricingCalendarDay": {
        "type": "object",
        "title": "Calendar day",
        "description": "Known state of one property-local stay date. Only `date` and `status` are required. Rows need not be sorted, contiguous, or future-dated. Duplicate dates are rejected.",
        "required": [
          "date",
          "status"
        ],
        "properties": {
          "date": {
            "$ref": "#/components/schemas/CalendarPricingDate"
          },
          "status": {
            "type": "string",
            "enum": [
              "available",
              "reserved",
              "blocked"
            ],
            "x-enumDescriptions": {
              "available": "The date can be sold. Calendar-dependent pricing rules apply only to available dates.",
              "reserved": "The date belongs to a confirmed reservation. Last-minute and far-future rules are suppressed.",
              "blocked": "The date is unavailable for a non-reservation reason. Like `reserved` it suppresses last-minute and far-future rules and bounds a gap, but it does not anchor the adjacent-day rule and is excluded from the occupancy ratio."
            },
            "description": "Case-sensitive booking state. Calendar-dependent pricing rules (gap day, adjacent day, occupancy pacing) require the stay date to be `available`.",
            "example": "available"
          },
          "price": {
            "type": "number",
            "format": "double",
            "exclusiveMinimum": true,
            "minimum": 0,
            "description": "Optional current nightly price in the request currency. Must be positive with valid minor-unit precision. Accepted and validated but not used by any pricing rule in this release.",
            "example": 225
          },
          "min_stay": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "description": "Current minimum-stay requirement for check-in on this date. Used only as a fallback when the gap-day rule tests whether a gap can be booked, and only when no custom minimum-stay rule is configured.",
            "example": 2
          },
          "reservation_id": {
            "type": "string",
            "minLength": 1,
            "description": "Stable identifier linking consecutive nights of the same reservation. Allowed only when status is `reserved` or `blocked`; rejected on `available` rows. Must not be blank (whitespace-only values are rejected). Accepted and validated but not used by any pricing rule in this release."
          },
          "check_in_allowed": {
            "type": "boolean",
            "description": "Whether a reservation may begin on this date. Used only when the gap-day rule tests whether a gap can be booked. Defaults to true when omitted or when the row is absent."
          },
          "check_out_allowed": {
            "type": "boolean",
            "description": "Whether a reservation may depart on this date. Used only when the gap-day rule tests whether a gap can be booked. Defaults to true when omitted or when the row is absent."
          }
        }
      },
      "CalendarPricingCustomOnlyMode": {
        "type": "string",
        "enum": [
          "disabled",
          "custom"
        ],
        "x-enumDescriptions": {
          "disabled": "The rule is off and contributes nothing.",
          "custom": "Requires the rule's complete `settings`. Scoped `overrides` and (for adjacent day) `apply_on_weekends` are accepted only in this mode."
        },
        "description": "Case-sensitive lowercase mode. `disabled` applies nothing; `custom` requires the rule's complete `settings`."
      },
      "CalendarPricingDayOfWeekSettings": {
        "type": "object",
        "title": "Day of Week settings",
        "required": [
          "adjustment_percent"
        ],
        "properties": {
          "adjustment_percent": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "monday",
              "tuesday",
              "wednesday",
              "thursday",
              "friday",
              "saturday",
              "sunday"
            ],
            "properties": {
              "monday": {
                "type": "number",
                "minimum": -75,
                "maximum": 500,
                "description": "Signed percentage. At most two decimal places.",
                "example": 0
              },
              "tuesday": {
                "type": "number",
                "minimum": -75,
                "maximum": 500,
                "description": "Signed percentage. At most two decimal places.",
                "example": 0
              },
              "wednesday": {
                "type": "number",
                "minimum": -75,
                "maximum": 500,
                "description": "Signed percentage. At most two decimal places.",
                "example": 0
              },
              "thursday": {
                "type": "number",
                "minimum": -75,
                "maximum": 500,
                "description": "Signed percentage. At most two decimal places.",
                "example": 0
              },
              "friday": {
                "type": "number",
                "minimum": -75,
                "maximum": 500,
                "description": "Signed percentage. At most two decimal places.",
                "example": 0
              },
              "saturday": {
                "type": "number",
                "minimum": -75,
                "maximum": 500,
                "description": "Signed percentage. At most two decimal places.",
                "example": 8
              },
              "sunday": {
                "type": "number",
                "minimum": -75,
                "maximum": 500,
                "description": "Signed percentage. At most two decimal places.",
                "example": 0
              }
            },
            "description": "Signed percentage adjustment for each property-local weekday. All seven lowercase weekday keys are required. Each value is from -75 through 500 with at most two decimal places."
          }
        }
      },
      "CalendarPricingMonthScopeDayOfWeek": {
        "type": "object",
        "required": [
          "settings"
        ],
        "description": "Complete replacement settings for this month. No partial inheritance from the top-level settings.",
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingDayOfWeekSettings"
          }
        }
      },
      "CalendarPricingMonthsDayOfWeek": {
        "type": "object",
        "title": "Monthly Day of Week overrides",
        "description": "Lowercase English month names as keys. Each scope completely replaces the top-level settings for stay dates in that month every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeDayOfWeek"
          }
        }
      },
      "CalendarPricingDateRangeBase": {
        "type": "object",
        "required": [
          "start_date",
          "end_date"
        ],
        "description": "Absolute inclusive date range. `start_date` must be on or before `end_date`. Date ranges within one rule must not overlap (sharing one day is an overlap). Ranges do not repeat yearly.",
        "properties": {
          "start_date": {
            "$ref": "#/components/schemas/CalendarPricingDate"
          },
          "end_date": {
            "$ref": "#/components/schemas/CalendarPricingDate"
          }
        }
      },
      "CalendarPricingDateRangeDayOfWeek": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings"
            ],
            "properties": {
              "settings": {
                "$ref": "#/components/schemas/CalendarPricingDayOfWeekSettings"
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesDayOfWeek": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsDayOfWeek"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeDayOfWeek"
            }
          }
        }
      },
      "CalendarPricingDayOfWeekRule": {
        "type": "object",
        "title": "Day of Week rule",
        "required": [
          "mode"
        ],
        "description": "Adds a custom weekday percentage after model effects and the automatic-rule\nadjustments. Custom mode requires all seven weekdays.\n",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingCustomOnlyMode"
          },
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingDayOfWeekSettings"
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesDayOfWeek"
          }
        }
      },
      "CalendarPricingProfileMode": {
        "type": "string",
        "enum": [
          "disabled",
          "conservative",
          "balanced",
          "aggressive",
          "custom"
        ],
        "x-enumDescriptions": {
          "disabled": "The rule is off and contributes nothing.",
          "conservative": "Smallest preset. Last minute: 7 days, -8% (power 2.0). Far future: ramps from 0% at 270 days to +5% at 365 days, then holds +5%. Gap day: -4/-2/0% for 1/2/3-night gaps.",
          "balanced": "Middle preset. Last minute: 21 days, -15% (power 1.5). Far future: ramps from 0% at 180 days to +10% at 365 days, then holds +10%. Gap day: -8/-4/-2% for 1/2/3-night gaps.",
          "aggressive": "Largest preset. Last minute: 45 days, -25% (power 1.2). Far future: ramps from 0% at 120 days to +15% at 365 days, then holds +15%. Gap day: -12/-8/-4% for 1/2/3-night gaps.",
          "custom": "Requires the rule's complete `settings`. Scoped `overrides` and (for gap day) `apply_on_weekends` are accepted only in this mode."
        },
        "description": "Case-sensitive lowercase mode. Named presets use complete AirROI defaults; `custom` requires the rule's `settings`."
      },
      "CalendarPricingTimedAdjustmentSettings": {
        "type": "object",
        "title": "Lead-time adjustment settings",
        "required": [
          "start_days",
          "adjustment_percent",
          "adjustment_type"
        ],
        "properties": {
          "start_days": {
            "type": "integer",
            "description": "Days out (stay date minus the property's local today) at which the rule's window opens, inclusive. For `flat`, the full percentage applies on this day. For `gradual`, the adjustment is exactly zero on this day and ramps toward the maximum."
          },
          "adjustment_percent": {
            "type": "number",
            "minimum": -100,
            "exclusiveMinimum": true,
            "description": "Signed percentage: the full flat adjustment, or the strongest gradual adjustment. Greater than -100 with at most two decimal places. Negative values discount; positive values increase.",
            "example": -15
          },
          "adjustment_type": {
            "type": "string",
            "enum": [
              "flat",
              "gradual"
            ],
            "x-enumDescriptions": {
              "flat": "Applies the full `adjustment_percent` on every day in the window, including the `start_days` boundary.",
              "gradual": "Zero at `start_days`, the full `adjustment_percent` at `end_days`, held from there on. Custom gradual is linear. Last-minute presets use a convex power curve (exponent 2.0 conservative, 1.5 balanced, 1.2 aggressive); far-future presets are linear."
            },
            "description": "How `adjustment_percent` is applied across the window. Case-sensitive lowercase."
          },
          "end_days": {
            "type": "integer",
            "description": "Where a `gradual` ramp reaches the full `adjustment_percent`; the full value holds from there on (toward arrival for last minute, further out for far future). Ignored for `flat`. See each rule's settings for the range and default."
          }
        }
      },
      "CalendarPricingLastMinuteSettings": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingTimedAdjustmentSettings"
          },
          {
            "type": "object",
            "properties": {
              "start_days": {
                "type": "integer",
                "minimum": 1,
                "maximum": 90,
                "description": "Days out at which the window opens, from 1 through 90, inclusive. The window covers 0 through `start_days` days out.",
                "example": 21
              },
              "end_days": {
                "type": "integer",
                "minimum": 0,
                "maximum": 89,
                "default": 0,
                "description": "Days before arrival at which a `gradual` ramp reaches the full percentage, from 0 (arrival day) through `start_days - 1`. Nights closer than this keep the full percentage. Defaults to 0.",
                "example": 3
              }
            }
          }
        ]
      },
      "CalendarPricingMonthScopeLastMinute": {
        "type": "object",
        "required": [
          "settings"
        ],
        "description": "Complete replacement settings for this month.",
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingLastMinuteSettings"
          }
        }
      },
      "CalendarPricingMonthsLastMinute": {
        "type": "object",
        "title": "Monthly Last Minute overrides",
        "description": "Lowercase English month names as keys, recurring every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLastMinute"
          }
        }
      },
      "CalendarPricingDateRangeLastMinute": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings"
            ],
            "properties": {
              "settings": {
                "$ref": "#/components/schemas/CalendarPricingLastMinuteSettings"
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesLastMinute": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsLastMinute"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeLastMinute"
            }
          }
        }
      },
      "CalendarPricingLastMinuteRule": {
        "type": "object",
        "title": "Last Minute rule",
        "required": [
          "mode"
        ],
        "description": "Adjusts eligible nights close to arrival. Use a preset without settings,\nor custom mode with complete settings and optional scoped overrides.\n",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingProfileMode"
          },
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingLastMinuteSettings"
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesLastMinute"
          }
        }
      },
      "CalendarPricingFarFutureSettings": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingTimedAdjustmentSettings"
          },
          {
            "type": "object",
            "properties": {
              "start_days": {
                "type": "integer",
                "minimum": 60,
                "maximum": 728,
                "description": "Days out at which the window opens, at least 60. The window runs from `start_days` to the end of the available calendar, up to two years out.",
                "example": 180
              },
              "end_days": {
                "type": "integer",
                "minimum": 61,
                "maximum": 729,
                "default": 365,
                "description": "Days out at which a `gradual` ramp reaches the full percentage. Must be after `start_days`; defaults to 365, one year out. Nights further out keep the full percentage.",
                "example": 365
              }
            }
          }
        ]
      },
      "CalendarPricingMonthScopeFarFuture": {
        "type": "object",
        "required": [
          "settings"
        ],
        "description": "Complete replacement settings for this month.",
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingFarFutureSettings"
          }
        }
      },
      "CalendarPricingMonthsFarFuture": {
        "type": "object",
        "title": "Monthly Far Future overrides",
        "description": "Lowercase English month names as keys, recurring every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeFarFuture"
          }
        }
      },
      "CalendarPricingDateRangeFarFuture": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings"
            ],
            "properties": {
              "settings": {
                "$ref": "#/components/schemas/CalendarPricingFarFutureSettings"
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesFarFuture": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsFarFuture"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeFarFuture"
            }
          }
        }
      },
      "CalendarPricingFarFutureRule": {
        "type": "object",
        "title": "Far Future rule",
        "required": [
          "mode"
        ],
        "description": "Adjusts eligible nights far from arrival. Use a preset without settings,\nor custom mode with complete settings and optional scoped overrides.\n",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingProfileMode"
          },
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingFarFutureSettings"
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesFarFuture"
          }
        }
      },
      "CalendarPricingGapDaySettingsRow": {
        "type": "object",
        "title": "Gap-length adjustment",
        "required": [
          "min_days",
          "max_days",
          "adjustment_percent"
        ],
        "properties": {
          "min_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30,
            "description": "Shortest covered gap in nights, inclusive.",
            "example": 1
          },
          "max_days": {
            "type": "integer",
            "minimum": 1,
            "maximum": 30,
            "description": "Longest covered gap in nights, inclusive. Must be greater than or equal to `min_days`.",
            "example": 1
          },
          "adjustment_percent": {
            "type": "number",
            "minimum": -100,
            "exclusiveMinimum": true,
            "description": "Signed percentage for stay dates inside this gap-length band. Greater than -100 with at most two decimal places.",
            "example": -12
          }
        },
        "description": "Gap-length bands must be ascending by min_days and non-overlapping.\nUncovered lengths receive no adjustment. Inclusive endpoints cannot be shared.\n"
      },
      "CalendarPricingMonthScopeGapDay": {
        "type": "object",
        "required": [
          "settings",
          "apply_on_weekends"
        ],
        "description": "Complete replacement settings for this month. `apply_on_weekends` is required and does not inherit from the top-level gap-day rule.",
        "properties": {
          "settings": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingGapDaySettingsRow"
            }
          },
          "apply_on_weekends": {
            "type": "boolean"
          }
        }
      },
      "CalendarPricingMonthsGapDay": {
        "type": "object",
        "title": "Monthly Gap Day overrides",
        "description": "Lowercase English month names as keys, recurring every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeGapDay"
          }
        }
      },
      "CalendarPricingDateRangeGapDay": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings",
              "apply_on_weekends"
            ],
            "properties": {
              "settings": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "$ref": "#/components/schemas/CalendarPricingGapDaySettingsRow"
                }
              },
              "apply_on_weekends": {
                "type": "boolean"
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesGapDay": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsGapDay"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeGapDay"
            }
          }
        }
      },
      "CalendarPricingGapDayRule": {
        "type": "object",
        "title": "Gap Day rule",
        "required": [
          "mode"
        ],
        "description": "Adjusts available nights bounded by known reserved or blocked dates, only\nwhen the gap is bookable under the effective stay restrictions. Custom stay\nrules take precedence over calendar-row restrictions, then defaults.\nGap length counts remaining nights from today onward. Each adjusted night\nmust fit at least one allowed stay within that gap.\nCustom mode requires settings and apply_on_weekends; presets include weekends.\n",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingProfileMode"
          },
          "settings": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingGapDaySettingsRow"
            },
            "description": "Gap-length bands. Required (and accepted) only with `mode: custom`."
          },
          "apply_on_weekends": {
            "type": "boolean",
            "description": "Whether Friday and Saturday stay dates may receive this adjustment. Required in custom mode; rejected in all other modes. Named presets always apply on weekends."
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesGapDay"
          }
        }
      },
      "CalendarPricingAdjacentDaySettings": {
        "type": "object",
        "title": "Adjacent Day settings",
        "required": [
          "days_before",
          "days_after",
          "adjustment_percent"
        ],
        "properties": {
          "days_before": {
            "type": "integer",
            "minimum": 0,
            "maximum": 30,
            "description": "Number of contiguous available nights before a reservation to adjust. 0 disables this direction.",
            "example": 2
          },
          "days_after": {
            "type": "integer",
            "minimum": 0,
            "maximum": 30,
            "description": "Number of contiguous available nights after a reservation to adjust. 0 disables this direction.",
            "example": 2
          },
          "adjustment_percent": {
            "type": "number",
            "minimum": -100,
            "exclusiveMinimum": true,
            "description": "Signed percentage for every qualifying adjacent night. Greater than -100 with at most two decimal places. Applied once even when reservations exist on both sides.",
            "example": -5
          }
        },
        "description": "At least one of `days_before` and `days_after` must be greater than zero."
      },
      "CalendarPricingMonthScopeAdjacentDay": {
        "type": "object",
        "required": [
          "settings",
          "apply_on_weekends"
        ],
        "description": "Complete replacement settings for this month. `apply_on_weekends` is required and does not inherit from the top-level adjacent-day rule.",
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingAdjacentDaySettings"
          },
          "apply_on_weekends": {
            "type": "boolean"
          }
        }
      },
      "CalendarPricingMonthsAdjacentDay": {
        "type": "object",
        "title": "Monthly Adjacent Day overrides",
        "description": "Lowercase English month names as keys, recurring every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeAdjacentDay"
          }
        }
      },
      "CalendarPricingDateRangeAdjacentDay": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings",
              "apply_on_weekends"
            ],
            "properties": {
              "settings": {
                "$ref": "#/components/schemas/CalendarPricingAdjacentDaySettings"
              },
              "apply_on_weekends": {
                "type": "boolean"
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesAdjacentDay": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsAdjacentDay"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeAdjacentDay"
            }
          }
        }
      },
      "CalendarPricingAdjacentDayRule": {
        "type": "object",
        "title": "Adjacent Day rule",
        "required": [
          "mode"
        ],
        "description": "Adjusts available nights before or after a known reservation. Blocked or\nunknown dates interrupt the search. A nonzero gap-day adjustment takes priority.\nCustom mode requires complete settings and apply_on_weekends.\n",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingCustomOnlyMode"
          },
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingAdjacentDaySettings"
          },
          "apply_on_weekends": {
            "type": "boolean",
            "description": "Whether Friday and Saturday stay dates may receive this adjustment. Required in custom mode; rejected in all other modes."
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesAdjacentDay"
          }
        }
      },
      "CalendarPricingLeadTimeRange": {
        "type": "object",
        "title": "Lead-time range",
        "required": [
          "min_days",
          "max_days"
        ],
        "properties": {
          "min_days": {
            "type": "integer",
            "minimum": 0,
            "maximum": 365,
            "example": 0
          },
          "max_days": {
            "type": "integer",
            "minimum": 0,
            "maximum": 365,
            "example": 14
          }
        },
        "description": "Inclusive lead-time range in days. `min_days` must be less than or equal to `max_days`."
      },
      "CalendarPricingOccupancyRange": {
        "type": "object",
        "title": "Occupancy range",
        "required": [
          "min_percent",
          "max_percent"
        ],
        "properties": {
          "min_percent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "example": 0
          },
          "max_percent": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "example": 39
          }
        },
        "description": "Inclusive booked-occupancy percentage range. `min_percent` must be less than or equal to `max_percent`."
      },
      "CalendarPricingOccupancyPacingSettings": {
        "type": "object",
        "title": "Occupancy Pacing settings",
        "description": "Occupancy is reserved / (reserved + available), rounded to a whole percentage;\nblocked dates are excluded. Every date in the matching lead-time\nrange must be supplied, with at least one reserved or available date.\nSelect the matrix row by occupancy and column by lead time. Unmatched bands\napply no adjustment.\n",
        "required": [
          "lead_time_ranges",
          "occupancy_ranges",
          "adjustment_percent"
        ],
        "properties": {
          "lead_time_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingLeadTimeRange"
            },
            "description": "Matrix columns, ordered from shorter to longer lead time. Ranges must be ascending by `min_days` and non-overlapping. Need not cover 0 through 365."
          },
          "occupancy_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingOccupancyRange"
            },
            "description": "Matrix rows, ordered from lower to higher booked occupancy. Ranges must be ascending by `min_percent` and non-overlapping. Need not cover 0 through 100."
          },
          "adjustment_percent": {
            "type": "array",
            "minItems": 1,
            "description": "A grid of percentages: one inner list per occupancy band, in the order of `occupancy_ranges`; inside each list, one value per days-out band, in the order of `lead_time_ranges`. Each value is a signed percentage greater than -100 with at most two decimal places.",
            "items": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "number",
                "minimum": -100,
                "exclusiveMinimum": true
              }
            }
          }
        },
        "example": {
          "lead_time_ranges": [
            {
              "min_days": 0,
              "max_days": 14
            },
            {
              "min_days": 15,
              "max_days": 60
            }
          ],
          "occupancy_ranges": [
            {
              "min_percent": 0,
              "max_percent": 49
            },
            {
              "min_percent": 50,
              "max_percent": 100
            }
          ],
          "adjustment_percent": [
            [
              -10,
              -5
            ],
            [
              0,
              5
            ]
          ]
        }
      },
      "CalendarPricingMonthScopeOccupancyPacing": {
        "type": "object",
        "required": [
          "settings"
        ],
        "description": "Complete replacement settings for this month.",
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingOccupancyPacingSettings"
          }
        }
      },
      "CalendarPricingMonthsOccupancyPacing": {
        "type": "object",
        "title": "Monthly Occupancy Pacing overrides",
        "description": "Lowercase English month names as keys, recurring every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeOccupancyPacing"
          }
        }
      },
      "CalendarPricingDateRangeOccupancyPacing": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings"
            ],
            "properties": {
              "settings": {
                "$ref": "#/components/schemas/CalendarPricingOccupancyPacingSettings"
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesOccupancyPacing": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsOccupancyPacing"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeOccupancyPacing"
            }
          }
        }
      },
      "CalendarPricingOccupancyPacingRule": {
        "type": "object",
        "title": "Occupancy Pacing rule",
        "required": [
          "mode"
        ],
        "description": "Adjusts eligible available nights using an occupancy/lead-time matrix.\nCustom mode requires complete settings. Every lead-time window that an\navailable night falls into needs a calendar row for each of its dates;\na window with missing rows is skipped with an INCOMPLETE_CALENDAR warning\nand its nights are priced without the rule. Dates outside every lead-time\ncolumn receive no adjustment or warning.\n",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingCustomOnlyMode"
          },
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingOccupancyPacingSettings"
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesOccupancyPacing"
          }
        }
      },
      "CalendarPricingRules": {
        "type": "object",
        "title": "Pricing rules",
        "description": "Optional adjustments; omitted rules are disabled. Each supplied rule needs\na mode. Only custom mode accepts settings, overrides, or apply_on_weekends.\nEach automatic-rule percentage is rounded HALF_UP to two decimal places before\nuse. The five automatic rules then add their signed percentages against the same\npost-model price, without a combined cap. Custom day_of_week follows; price limits apply later.\n",
        "properties": {
          "day_of_week": {
            "$ref": "#/components/schemas/CalendarPricingDayOfWeekRule"
          },
          "last_minute": {
            "$ref": "#/components/schemas/CalendarPricingLastMinuteRule"
          },
          "far_future": {
            "$ref": "#/components/schemas/CalendarPricingFarFutureRule"
          },
          "gap_day": {
            "$ref": "#/components/schemas/CalendarPricingGapDayRule"
          },
          "adjacent_day": {
            "$ref": "#/components/schemas/CalendarPricingAdjacentDayRule"
          },
          "occupancy_pacing": {
            "$ref": "#/components/schemas/CalendarPricingOccupancyPacingRule"
          }
        }
      },
      "CalendarPricingMinStaySettings": {
        "type": "object",
        "title": "Minimum Stay settings",
        "required": [
          "min_nights"
        ],
        "properties": {
          "min_nights": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "description": "Required stay length in nights.",
            "example": 2
          }
        }
      },
      "CalendarPricingMonthScopeMinStay": {
        "type": "object",
        "required": [
          "settings"
        ],
        "description": "Complete replacement settings for this month.",
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingMinStaySettings"
          }
        }
      },
      "CalendarPricingMonthsMinStay": {
        "type": "object",
        "title": "Monthly Minimum Stay overrides",
        "description": "Lowercase English month names as keys, recurring every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeMinStay"
          }
        }
      },
      "CalendarPricingDateRangeMinStay": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings"
            ],
            "properties": {
              "settings": {
                "$ref": "#/components/schemas/CalendarPricingMinStaySettings"
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesMinStay": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsMinStay"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeMinStay"
            }
          }
        }
      },
      "CalendarPricingMinStayRule": {
        "type": "object",
        "title": "Minimum Stay rule",
        "required": [
          "mode"
        ],
        "description": "Returns the minimum nights required for check-in on each applicable stay date and informs gap eligibility. Your booking integration must support and enforce the restriction. Accepts only `disabled` and `custom`.",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingCustomOnlyMode"
          },
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingMinStaySettings"
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesMinStay"
          }
        }
      },
      "CalendarPricingLengthOfStaySettingsRow": {
        "type": "object",
        "title": "Length-of-stay discount",
        "required": [
          "min_nights",
          "adjustment_percent"
        ],
        "properties": {
          "min_nights": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "description": "Minimum stay length that qualifies for this row.",
            "example": 7
          },
          "adjustment_percent": {
            "type": "number",
            "minimum": -75,
            "maximum": 0,
            "description": "Discount percentage from 0 through -75; positive values are rejected. At most two decimal places.",
            "example": -8
          }
        },
        "description": "Rows must use strictly increasing `min_nights`."
      },
      "CalendarPricingMonthScopeLengthOfStay": {
        "type": "object",
        "required": [
          "settings"
        ],
        "description": "Complete replacement settings for this month.",
        "properties": {
          "settings": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingLengthOfStaySettingsRow"
            }
          }
        }
      },
      "CalendarPricingMonthsLengthOfStay": {
        "type": "object",
        "title": "Monthly Length of Stay overrides",
        "description": "Lowercase English month names as keys, recurring every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeLengthOfStay"
          }
        }
      },
      "CalendarPricingDateRangeLengthOfStay": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings"
            ],
            "properties": {
              "settings": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "$ref": "#/components/schemas/CalendarPricingLengthOfStaySettingsRow"
                }
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesLengthOfStay": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsLengthOfStay"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeLengthOfStay"
            }
          }
        }
      },
      "CalendarPricingLengthOfStayRule": {
        "type": "object",
        "title": "Length of Stay rule",
        "required": [
          "mode"
        ],
        "description": "Longer-stay discount tiers, accepted and validated but currently unused:\nthey change no price, explanation line, or output field.\nThis endpoint returns nightly recommendations, not a guest-specific stay\nquote. Configure these discounts separately in a supporting booking\nintegration that evaluates the guest's selected dates and stay length.\n",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingCustomOnlyMode"
          },
          "settings": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingLengthOfStaySettingsRow"
            }
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesLengthOfStay"
          }
        }
      },
      "CalendarPricingWeekdayList": {
        "type": "array",
        "minItems": 1,
        "maxItems": 7,
        "uniqueItems": true,
        "description": "Unique property-local weekdays as lowercase English names. At least one day is required. Duplicates are rejected.",
        "items": {
          "type": "string",
          "enum": [
            "monday",
            "tuesday",
            "wednesday",
            "thursday",
            "friday",
            "saturday",
            "sunday"
          ]
        }
      },
      "CalendarPricingCheckInOutSettings": {
        "type": "object",
        "title": "Check-in/out settings",
        "required": [
          "allowed_check_in_days",
          "allowed_check_out_days"
        ],
        "properties": {
          "allowed_check_in_days": {
            "$ref": "#/components/schemas/CalendarPricingWeekdayList"
          },
          "allowed_check_out_days": {
            "$ref": "#/components/schemas/CalendarPricingWeekdayList"
          }
        }
      },
      "CalendarPricingMonthScopeCheckInOut": {
        "type": "object",
        "required": [
          "settings"
        ],
        "description": "Complete replacement settings for this month.",
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingCheckInOutSettings"
          }
        }
      },
      "CalendarPricingMonthsCheckInOut": {
        "type": "object",
        "title": "Monthly Check-in/out overrides",
        "description": "Lowercase English month names as keys, recurring every year.",
        "minProperties": 1,
        "maxProperties": 12,
        "additionalProperties": false,
        "properties": {
          "january": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "february": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "march": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "april": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "may": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "june": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "july": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "august": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "september": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "october": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "november": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          },
          "december": {
            "$ref": "#/components/schemas/CalendarPricingMonthScopeCheckInOut"
          }
        }
      },
      "CalendarPricingDateRangeCheckInOut": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarPricingDateRangeBase"
          },
          {
            "type": "object",
            "required": [
              "settings"
            ],
            "properties": {
              "settings": {
                "$ref": "#/components/schemas/CalendarPricingCheckInOutSettings"
              }
            }
          }
        ]
      },
      "CalendarPricingOverridesCheckInOut": {
        "type": "object",
        "description": "Custom-mode overrides; include months, date_ranges, or both.\nOne complete scope wins: date range, then recurring month, then default.\nSettings are replaced, not merged.\n",
        "properties": {
          "months": {
            "$ref": "#/components/schemas/CalendarPricingMonthsCheckInOut"
          },
          "date_ranges": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingDateRangeCheckInOut"
            }
          }
        }
      },
      "CalendarPricingCheckInOutRule": {
        "type": "object",
        "title": "Check-in/out rule",
        "required": [
          "mode"
        ],
        "description": "Returns permitted arrival/departure weekdays and informs gap eligibility. Your booking integration must support and enforce these restrictions. Weekdays use the property's timezone. Accepts only `disabled` and `custom`.",
        "properties": {
          "mode": {
            "$ref": "#/components/schemas/CalendarPricingCustomOnlyMode"
          },
          "settings": {
            "$ref": "#/components/schemas/CalendarPricingCheckInOutSettings"
          },
          "overrides": {
            "$ref": "#/components/schemas/CalendarPricingOverridesCheckInOut"
          }
        }
      },
      "CalendarPricingStayRules": {
        "type": "object",
        "title": "Stay rules",
        "description": "Optional stay restrictions; each rule accepts disabled or custom.\nEnabled minimum-stay and check-in/out rules appear in recommendations and\ninform gap eligibility. To govern actual bookings, these restrictions must\nbe supported and enforced by your channel manager, PMS, or OTA integration;\nAirROI does not publish or enforce them on booking channels.\nlength_of_stay is accepted but not applied. Configure longer-stay discounts\nseparately in a supporting booking integration, which can evaluate the\nguest's selected dates and stay length.\n",
        "properties": {
          "min_stay": {
            "$ref": "#/components/schemas/CalendarPricingMinStayRule"
          },
          "length_of_stay": {
            "$ref": "#/components/schemas/CalendarPricingLengthOfStayRule"
          },
          "check_in_out": {
            "$ref": "#/components/schemas/CalendarPricingCheckInOutRule"
          }
        },
        "example": {
          "min_stay": {
            "mode": "custom",
            "settings": {
              "min_nights": 2
            }
          },
          "check_in_out": {
            "mode": "custom",
            "settings": {
              "allowed_check_in_days": [
                "friday",
                "saturday"
              ],
              "allowed_check_out_days": [
                "monday",
                "tuesday",
                "wednesday",
                "thursday",
                "friday",
                "saturday",
                "sunday"
              ]
            }
          }
        }
      },
      "CalendarPricingPriceLimits": {
        "type": "object",
        "title": "Price limits",
        "description": "Nightly floor and ceiling, applied after percentage adjustments.\nEach omitted or null bound defaults independently: minimum to 70% of\nbase_price, maximum to 1000% (10 times) base_price, rounded HALF_UP\nto the currency's precision. An explicit bound replaces only that default.\nThe effective minimum must not exceed the effective maximum; otherwise\nHTTP 422 returns INVALID_PRICE_LIMITS in the error details.\nFixed price overrides bypass both default and explicit limits.\n",
        "properties": {
          "min_price": {
            "type": "number",
            "format": "double",
            "minimum": 0,
            "exclusiveMinimum": true,
            "nullable": true,
            "description": "Lowest allowed nightly recommendation in `currency`. Omitted or null: 70% of base_price. An explicit value must be positive with valid minor-unit precision.",
            "example": 150
          },
          "max_price": {
            "type": "number",
            "format": "double",
            "minimum": 0,
            "exclusiveMinimum": true,
            "nullable": true,
            "description": "Highest allowed nightly recommendation in `currency`. Omitted or null: 1000% (10 times) base_price. An explicit value must be positive with valid minor-unit precision. Must be at least the effective minimum, including its default.",
            "example": 400
          }
        }
      },
      "CalendarPricingPriceOverride": {
        "type": "object",
        "title": "Price override",
        "required": [
          "start_date",
          "end_date",
          "adjustment_type",
          "adjustment_amount"
        ],
        "description": "Price instruction for an inclusive, absolute date range.\nPercentage overrides apply before price limits; fixed overrides replace the\nprice afterward and bypass both default and explicit limits. Ranges must not overlap or share a day.\n",
        "properties": {
          "start_date": {
            "$ref": "#/components/schemas/CalendarPricingDate"
          },
          "end_date": {
            "$ref": "#/components/schemas/CalendarPricingDate"
          },
          "adjustment_type": {
            "type": "string",
            "enum": [
              "percentage",
              "fixed"
            ],
            "x-enumDescriptions": {
              "percentage": "Multiplies the running price by `(1 + adjustment_amount / 100)` before price limits.",
              "fixed": "Replaces the price with `adjustment_amount` after price limits, bypassing min and max in both directions."
            },
            "description": "How `adjustment_amount` is interpreted. Case-sensitive lowercase."
          },
          "adjustment_amount": {
            "type": "number",
            "description": "For `percentage`: a signed value greater than -100 and at most 500 with at most two decimal places. For `fixed`: a positive amount in the request currency with valid ISO minor-unit precision."
          }
        },
        "example": {
          "start_date": "2026-12-31",
          "end_date": "2026-12-31",
          "adjustment_type": "fixed",
          "adjustment_amount": 550
        }
      },
      "CalendarPricingAdvanced": {
        "type": "object",
        "title": "Advanced model controls",
        "description": "Controls the strength of model effects, independently of custom rules.\nDefaults apply when omitted.\n",
        "properties": {
          "seasonality_sensitivity_percent": {
            "type": "number",
            "minimum": 0,
            "maximum": 200,
            "default": 100,
            "description": "Scales seasonality, modeled weekday, and holiday/event effects.\n0 removes them, 100 keeps them unchanged, and 200 doubles each effect's\ndistance from neutral. At most two decimal places.\nValues above 100 can return 503 PRICING_DATA_UNAVAILABLE if a scaled\nmodel factor becomes zero or negative.\n",
            "example": 100
          },
          "demand_sensitivity_percent": {
            "type": "number",
            "minimum": 0,
            "maximum": 200,
            "default": 100,
            "description": "Scales the Market Demand Adjustment. 0 removes it, 100 uses the model as trained, 200 doubles its distance from neutral. At most two decimal places. Regardless of this setting the effective demand adjustment is always bounded between -15% and +400%.",
            "example": 100
          },
          "apply_negative_demand_adjustments": {
            "type": "boolean",
            "default": true,
            "description": "When false, a below-neutral Market Demand factor is neutralized and the `market_demand` receipt line is omitted entirely for that date. The test is on the sensitivity-scaled factor before clamping."
          }
        }
      },
      "CalendarPriceRecommendationRequest": {
        "type": "object",
        "title": "Calendar Price request",
        "required": [
          "location",
          "currency",
          "base_price"
        ],
        "description": "Send location, currency, and base_price. Omitted rules are disabled.\nUse JSON numbers and booleans, not strings. Unknown fields are ignored.\nOmit unused fields. start_date, end_date and price_limits.min_price/max_price\naccept null, which selects their defaults.\n",
        "properties": {
          "location": {
            "$ref": "#/components/schemas/CalendarPricingLocation"
          },
          "currency": {
            "$ref": "#/components/schemas/PriceRecommendationCurrency"
          },
          "base_price": {
            "type": "number",
            "format": "double",
            "exclusiveMinimum": true,
            "minimum": 0,
            "description": "Year-round nightly rate before date-specific adjustments, in currency.\nUse your own value or recommended_base_price from the Base Price endpoint.\nExclude cleaning fees, taxes, and platform fees. Must be positive and use\nthe currency's decimal precision (2 places for USD, 0 for JPY, 3 for BHD).\n",
            "example": 200
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
            "description": "Optional inclusive first output date (YYYY-MM-DD). Omitted or null starts\ntoday in the property's timezone. Must not be after end_date (422\nINVALID_DATE_RANGE). A past date returns 422 START_DATE_IN_PAST; a date\nafter the available calendar returns 422 START_DATE_BEYOND_AVAILABLE_HORIZON.\nEmpty string, impossible date, or wrong JSON type returns 422. Only selects\nreturned rows: lead-time rules still count from today, and calculation,\nevidence and warnings cover the full available calendar.\n",
            "example": "2026-12-01"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$",
            "description": "Optional inclusive output end date (YYYY-MM-DD). Omitted or null returns\nthe full available calendar (one to two years from start_date or today).\nstart_date and end_date on the same day return one row. A past date, empty\nstring, impossible date, or wrong JSON type returns 422. A date beyond\nthe available calendar is clamped; coverage.end_date reports the last date returned.\nOnly limits returned rows: calculation, evidence and warnings still cover\nthe full available calendar.\n",
            "example": "2026-12-31"
          },
          "calendar": {
            "type": "array",
            "maxItems": 1000,
            "description": "Booking and availability data, not the requested output dates. Required for\ngap-day, adjacent-day, and occupancy-pacing adjustments. Include consecutive\ndates and surrounding reservations or blocks. Missing dates are unknown;\nnights a calendar-dependent rule cannot evaluate are skipped with an\nINCOMPLETE_CALENDAR warning, and so is every night when calendar is\nomitted or [] while such a rule is enabled.\nReserved and blocked rows also suppress last-minute and far-future adjustments.\n",
            "items": {
              "$ref": "#/components/schemas/CalendarPricingCalendarDay"
            }
          },
          "pricing_rules": {
            "$ref": "#/components/schemas/CalendarPricingRules"
          },
          "stay_rules": {
            "$ref": "#/components/schemas/CalendarPricingStayRules"
          },
          "price_limits": {
            "$ref": "#/components/schemas/CalendarPricingPriceLimits"
          },
          "price_overrides": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CalendarPricingPriceOverride"
            },
            "description": "Explicit percentage or fixed-price instructions for\ninclusive stay-date ranges. Applied after model and\nautomatic pricing-rule adjustments. An empty array is\naccepted. Date ranges across the entire list must not\noverlap (inclusive of endpoints).\n"
          },
          "advanced": {
            "$ref": "#/components/schemas/CalendarPricingAdvanced"
          }
        }
      },
      "CalendarPricingCoverage": {
        "type": "object",
        "additionalProperties": false,
        "description": "The date range actually returned.",
        "required": [
          "calculation_date",
          "start_date",
          "end_date",
          "recommendation_count",
          "timezone"
        ],
        "properties": {
          "calculation_date": {
            "type": "string",
            "format": "date",
            "description": "Today in the property's timezone: the first date of the calculated calendar and day zero for last-minute and far-future lead times."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "description": "First returned date; the requested start_date, or calculation_date when omitted."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "description": "Last returned date, inclusive: the requested end_date, or, when it was omitted or beyond the available calendar, the last available date (one to two years after calculation_date)."
          },
          "recommendation_count": {
            "type": "integer",
            "minimum": 1,
            "maximum": 730,
            "description": "Number of returned recommendations."
          },
          "timezone": {
            "type": "string",
            "description": "Resolved property timezone used to determine today.",
            "example": "America/New_York"
          }
        }
      },
      "CalendarPricingWarning": {
        "type": "object",
        "additionalProperties": false,
        "title": "Warning",
        "required": [
          "code",
          "field",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Warning code. The only current code is `INCOMPLETE_CALENDAR`: a calendar-dependent rule could not be applied, either on every night because no `calendar` was sent, or on some nights because the rows it needed were not sent (a neighboring night for gap day and adjacent day, any date of a lead-time window for occupancy pacing). `field` names the rule and `message` says which. New codes may be added; treat an unknown code as informational.",
            "example": "INCOMPLETE_CALENDAR"
          },
          "field": {
            "type": "string",
            "description": "Request field or calculation area associated with the warning.",
            "example": "pricing_rules.gap_day"
          },
          "message": {
            "type": "string",
            "description": "Human-readable explanation of the recoverable issue."
          },
          "affected_date_count": {
            "type": "integer",
            "minimum": 1,
            "description": "Number of stay dates affected across the full calculated calendar, including dates outside the start_date–end_date selection. Omitted when the warning is about a missing calendar rather than specific nights."
          }
        }
      },
      "CalendarPricingExplanationLine": {
        "type": "object",
        "additionalProperties": false,
        "title": "Price explanation line",
        "required": [
          "code",
          "label",
          "amount"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable identifier, in calculation order: base_price, seasonality,\nday_of_week, known_holiday_event, market_demand, last_minute_rule, far_future_rule,\ngap_night_rule, adjacent_night_rule, occupancy_pacing_rule,\ncustom_day_of_week_rule, percentage_price_override, minimum_price_limit,\nmaximum_price_limit, fixed_price_override.\n\nBase and model lines appear even when their amount is zero, except\nmarket_demand may be omitted when negative demand adjustments are disabled.\nRule and limit lines appear when applied; a fixed override always has a line.\nNew codes may be added.\n",
            "example": "seasonality"
          },
          "label": {
            "type": "string",
            "description": "Human-readable label suitable for an itemized pricing receipt.",
            "example": "Seasonality"
          },
          "adjustment_percent": {
            "type": "number",
            "description": "Signed percentage for this line. Market demand is rounded HALF_UP to one decimal place for display; other lines use at most two decimal places. Trailing zeros may be stripped. Automatic-rule percentages are rounded HALF_UP before application; model percentages are rounded for display only. Present on model, pricing-rule, custom day-of-week, and percentage-override lines. Omitted on base_price, minimum_price_limit, maximum_price_limit, and fixed_price_override.",
            "example": 10
          },
          "amount": {
            "type": "number",
            "description": "Signed currency contribution rounded to the currency's ISO minor unit. Receipt amounts always sum exactly to `price`. Each amount is the difference of consecutive HALF_UP-rounded cumulative totals, so it can differ from `adjustment_percent` times the prior line's total because displayed model percentages are rounded. Prices use the full model factor, including adjustments that round to 0.0% for display.",
            "example": 20
          },
          "details": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "A holiday/event name or a notice that a default minimum/maximum price limit applied. Omitted for all other lines, including market-demand adjustments. Unavailable demand within the coverage window is reported in response-level warnings instead."
          }
        }
      },
      "CalendarPricingRecommendation": {
        "type": "object",
        "additionalProperties": false,
        "title": "Daily recommendation",
        "required": [
          "date",
          "price",
          "explanation"
        ],
        "properties": {
          "date": {
            "$ref": "#/components/schemas/CalendarPricingDate"
          },
          "price": {
            "type": "number",
            "minimum": 0,
            "exclusiveMinimum": true,
            "description": "Final nightly price rounded HALF_UP to the currency's ISO minor unit (2 decimals for USD, 0 for JPY, 3 for BHD).",
            "example": 231
          },
          "min_stay": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "description": "Effective minimum nights for a stay checking in on this date. Present only when `stay_rules.min_stay` is configured with `mode: custom`. Calendar-row `min_stay` is never echoed here."
          },
          "check_in_allowed": {
            "type": "boolean",
            "description": "Whether check-in is permitted on this date's weekday. Present only when `stay_rules.check_in_out` is configured with `mode: custom`. Calendar-row `check_in_allowed` is never echoed here."
          },
          "check_out_allowed": {
            "type": "boolean",
            "description": "Whether check-out is permitted on this date's weekday. Present only when `stay_rules.check_in_out` is configured with `mode: custom`. Calendar-row `check_out_allowed` is never echoed here."
          },
          "explanation": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/CalendarPricingExplanationLine"
            },
            "description": "Ordered signed line items whose `amount` values sum exactly to `price`. Lines appear in pipeline order."
          }
        }
      },
      "CalendarPriceRecommendationResponse": {
        "type": "object",
        "additionalProperties": false,
        "title": "Calendar Price recommendations",
        "description": "Consecutive property-local nightly prices with signed explanations and\nenabled custom stay restrictions. Read warnings even on HTTP 200.\n",
        "required": [
          "location",
          "currency",
          "coverage",
          "warnings",
          "recommendations"
        ],
        "properties": {
          "location": {
            "$ref": "#/components/schemas/CalendarPricingLocation"
          },
          "currency": {
            "$ref": "#/components/schemas/PriceRecommendationCurrency"
          },
          "coverage": {
            "$ref": "#/components/schemas/CalendarPricingCoverage"
          },
          "warnings": {
            "type": "array",
            "description": "Recoverable issues across the full calculated calendar, including dates before start_date and after end_date. Output selection preserves these warnings and their counts. An empty array means no warnings were produced.",
            "items": {
              "$ref": "#/components/schemas/CalendarPricingWarning"
            }
          },
          "recommendations": {
            "type": "array",
            "minItems": 1,
            "maxItems": 730,
            "description": "Consecutive property-local dates from start_date (or today) through end_date inclusive, limited to available coverage. Omitted or null boundaries return the full one- to two-year calendar; explicit boundaries can return as few as one row. coverage.start_date and coverage.end_date report the range actually returned.",
            "items": {
              "$ref": "#/components/schemas/CalendarPricingRecommendation"
            }
          }
        }
      },
      "CalendarPricingErrorDetail": {
        "type": "object",
        "additionalProperties": false,
        "title": "Validation detail",
        "required": [
          "code",
          "field",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Detail code. Current codes: `REQUIRED_FIELD`, `OUT_OF_RANGE`, `INVALID_FIELD_TYPE`, `INVALID_REQUEST_TYPE`, `NULL_VALUE`, `INVALID_CURRENCY`, `UNSUPPORTED_CURRENCY`, `NONPOSITIVE_MONEY`, `INVALID_MONEY_PRECISION`, `TOO_MUCH_PRECISION`, `INVALID_DATE_FORMAT`, `INVALID_DATE_RANGE`, `START_DATE_IN_PAST`, `END_DATE_IN_PAST`, `START_DATE_BEYOND_AVAILABLE_HORIZON`, `OVERLAPPING_DATE_RANGES`, `TOO_MANY_CALENDAR_ROWS` (HTTP 413), `DUPLICATE_CALENDAR_DATE`, `INVALID_CALENDAR_STATUS`, `EMPTY_RESERVATION_ID`, `CONTRADICTORY_CALENDAR_STATE`, `UNSUPPORTED_MODE`, `CUSTOM_FIELDS_REQUIRE_CUSTOM_MODE`, `INVALID_WEEKDAY_MAP`, `INVALID_ADJUSTMENT_TYPE`, `UNSORTED_RANGES`, `OVERLAPPING_RANGES`, `INVALID_RANGE`, `EMPTY_ADJACENCY_REACH`, `MATRIX_DIMENSION_MISMATCH`, `UNSORTED_THRESHOLDS`, `EMPTY_OVERRIDES`, `EMPTY_OVERRIDE_SCOPE`, `INVALID_MONTH`, `UNSUPPORTED_FIELD`, `INVALID_PRICE_LIMITS`, `PRICE_BELOW_CURRENCY_MINIMUM` (under the matching top-level code), `INVALID_WEEKDAY`, `DUPLICATE_WEEKDAY`, `UNSUPPORTED_LOCATION` (only under error code `UNSUPPORTED_LOCATION`). Use `field` and `message` to identify and correct the input. New codes may be added.",
            "example": "REQUIRED_FIELD"
          },
          "field": {
            "type": "string",
            "description": "Dot-separated field path with array indexes, e.g. `calendar[0].date` or `pricing_rules.gap_day.overrides.months.august.settings[0].min_days`."
          },
          "message": {
            "type": "string",
            "description": "Human-readable validation message."
          }
        }
      },
      "CalendarPriceRecommendationErrorResponse": {
        "type": "object",
        "additionalProperties": false,
        "title": "Calendar Price error",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "code",
              "message",
              "details",
              "request_id"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Top-level error code. Known codes are listed below.",
                "enum": [
                  "MALFORMED_JSON",
                  "VALIDATION_ERROR",
                  "PRICE_BELOW_CURRENCY_MINIMUM",
                  "PAYLOAD_TOO_LARGE",
                  "UNSUPPORTED_LOCATION",
                  "STALE_SERVING_RELEASE",
                  "PRICING_DATA_UNAVAILABLE"
                ],
                "x-enumDescriptions": {
                  "MALFORMED_JSON": "400. The request body is missing, blank, or not valid JSON.",
                  "VALIDATION_ERROR": "422. One or more request fields failed validation. Details list each problem.",
                  "PRICE_BELOW_CURRENCY_MINIMUM": "422. A positive calculated price rounds to zero. Review the base price, discounts, and minimum limit. No recommendations are returned; prices are not silently raised to the smallest currency unit.",
                  "PAYLOAD_TOO_LARGE": "413. The calendar contains more than 1,000 rows.",
                  "UNSUPPORTED_LOCATION": "422. The coordinates could not be resolved to a supported timezone or pricing region.",
                  "STALE_SERVING_RELEASE": "503. The active pricing release has an internal date gap or fewer than 365 continuous dates.",
                  "PRICING_DATA_UNAVAILABLE": "503. A pricing data dependency is temporarily unavailable or invalid."
                }
              },
              "message": {
                "type": "string",
                "description": "Human-readable error description."
              },
              "details": {
                "type": "array",
                "maxItems": 100,
                "description": "Field-level reasons for validation failures, sorted by field then code\nand capped at 100 entries. Empty when no field details apply.\n",
                "items": {
                  "$ref": "#/components/schemas/CalendarPricingErrorDetail"
                }
              },
              "request_id": {
                "type": "string",
                "pattern": "^req_[0-9a-f]{32}$",
                "description": "Same value as the `X-Request-ID` response header."
              }
            }
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request was unacceptable, often due to missing a required parameter or invalid parameter values. \nThe response body will contain more details on the specific error.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "missingParameter": {
                "summary": "Example of a missing required parameter",
                "value": {
                  "timestamp": "2024-07-30T10:32:15Z",
                  "status": 400,
                  "error": "Bad Request",
                  "message": "Required request parameter 'queryType' for method parameter type String is not present",
                  "path": "/listings/search"
                }
              },
              "invalidValue": {
                "summary": "Example of an invalid parameter value",
                "value": {
                  "timestamp": "2024-07-30T10:33:45Z",
                  "status": 400,
                  "error": "Bad Request",
                  "message": "Invalid value for 'bedrooms'. Must be a positive integer.",
                  "path": "/calculator/estimate"
                }
              }
            }
          }
        }
      },
      "ApiKeyError": {
        "description": "The API key is missing, invalid, revoked, or inactive. Send your key in the\n`X-API-KEY` header. This response comes from the API gateway, so the body\nis the gateway's error shape, not the endpoint's own error envelope.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/GatewayErrorResponse"
            },
            "examples": {
              "missingOrInvalidApiKey": {
                "summary": "API key missing or invalid",
                "value": {
                  "error": "Forbidden",
                  "message": "A valid and active API key is required."
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "The requested resource could not be found. \nThis could be an invalid listing ID, market ID, or an incorrect API path.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "examples": {
              "listingNotFound": {
                "summary": "Listing ID not found",
                "value": {
                  "timestamp": "2024-07-30T10:37:20Z",
                  "status": 404,
                  "error": "Not Found",
                  "message": "Listing with ID 'invalid-listing-id' not found.",
                  "path": "/listings/invalid-listing-id/details"
                }
              },
              "marketNotFound": {
                "summary": "Market data not found",
                "value": {
                  "timestamp": "2024-07-30T10:37:20Z",
                  "status": 404,
                  "error": "Not Found",
                  "message": "No market data matches your search criteria. This issue can occur for three reasons: the filters are too restrictive, the market fields (country, region, locality, district) contain misspells, or the market has fewer than 25 listings. If your filters are too restrictive, try loosening them. If you suspect a misspelling, use the /lookup or /search endpoint to find the correct market spellings.",
                  "path": "/markets/summary"
                }
              }
            }
          }
        }
      },
      "ListingNotFound": {
        "description": "The listing ID does not exist or the listing has been taken offline by the platform.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/LiveError"
            },
            "example": {
              "code": "listing_not_found",
              "message": "The listing ID does not exist or the listing has been taken offline by the platform. Please double-check your listing ID."
            }
          }
        }
      }
    },
    "parameters": {
      "listingIdParameter": {
        "name": "listing_id",
        "in": "query",
        "required": true,
        "description": "Airbnb listing ID.",
        "example": 43036533,
        "schema": {
          "type": "integer",
          "format": "int64",
          "minimum": 1
        }
      },
      "currencyParameter": {
        "name": "currency",
        "in": "query",
        "description": "`native` returns rates in the local currency of the listing's country (for\nexample EUR in France or JPY in Japan). `usd` returns US dollars.\n",
        "schema": {
          "type": "string",
          "enum": [
            "native",
            "usd"
          ],
          "default": "native"
        }
      }
    },
    "headers": {
      "RequestIdHeader": {
        "description": "Server-generated identifier for troubleshooting application responses.\nClient-supplied request IDs are ignored. Calendar error bodies also include\nthis value as error.request_id.\n",
        "schema": {
          "type": "string",
          "pattern": "^req_[0-9a-f]{32}$",
          "example": "req_0123456789abcdef0123456789abcdef"
        }
      }
    },
    "examples": {
      "joshuaTreeFirstCall": {
        "summary": "Joshua Tree casita · first call, base price only",
        "description": "A one-bedroom casita outside Joshua Tree National Park, listed at 180 a night. The host wants to\nsee what the model does before adding any rules: coordinates, currency and the base price,\nnothing else. With no dates set, the response is the full available calendar from today in the\nproperty's timezone, and the default limits (126 to 1,800) apply.\n",
        "value": {
          "location": {
            "latitude": 34.1347,
            "longitude": -116.3131
          },
          "currency": "USD",
          "base_price": 180
        }
      },
      "miamiBeachLeadTime": {
        "summary": "Miami Beach condo · early bookers and last minute",
        "description": "A two-bedroom condo on Miami Beach at 320 a night. Snowbirds book months ahead and are not\nprice-sensitive, so anything more than four months out ramps up to +12% by 300 days out. Nights\nstill open two weeks before arrival ramp down to −15%, reaching the full discount two days\nbefore arrival. No calendar is needed: both rules work from lead time alone.\n",
        "value": {
          "location": {
            "latitude": 25.7907,
            "longitude": -80.13
          },
          "currency": "USD",
          "base_price": 320,
          "pricing_rules": {
            "last_minute": {
              "mode": "custom",
              "settings": {
                "start_days": 14,
                "adjustment_percent": -15,
                "adjustment_type": "gradual",
                "end_days": 2
              }
            },
            "far_future": {
              "mode": "custom",
              "settings": {
                "start_days": 120,
                "adjustment_percent": 12,
                "adjustment_type": "gradual",
                "end_days": 300
              }
            }
          }
        }
      },
      "scottsdalePacing": {
        "summary": "Scottsdale condo · occupancy pacing",
        "description": "A three-bedroom condo in Scottsdale at 275 a night. The next week is mostly empty while the rest\nof the month is filling up nicely, and the host wants prices to react to that automatically. A\npacing grid with two lead-time columns (0–7 and 8–30 days) and three occupancy rows does it:\ndiscount hardest when a window is under 40% booked, raise when it is over 70%. The calendar\ncovers every night of both windows; `end_date` returns the first ten nights.\n",
        "value": {
          "location": {
            "latitude": 33.4942,
            "longitude": -111.9261
          },
          "currency": "USD",
          "base_price": 275,
          "end_date": "2026-09-23",
          "calendar": [
            {
              "date": "2026-09-14",
              "status": "available"
            },
            {
              "date": "2026-09-15",
              "status": "available"
            },
            {
              "date": "2026-09-16",
              "status": "reserved"
            },
            {
              "date": "2026-09-17",
              "status": "reserved"
            },
            {
              "date": "2026-09-18",
              "status": "available"
            },
            {
              "date": "2026-09-19",
              "status": "available"
            },
            {
              "date": "2026-09-20",
              "status": "available"
            },
            {
              "date": "2026-09-21",
              "status": "available"
            },
            {
              "date": "2026-09-22",
              "status": "available"
            },
            {
              "date": "2026-09-23",
              "status": "reserved"
            },
            {
              "date": "2026-09-24",
              "status": "reserved"
            },
            {
              "date": "2026-09-25",
              "status": "reserved"
            },
            {
              "date": "2026-09-26",
              "status": "reserved"
            },
            {
              "date": "2026-09-27",
              "status": "available"
            },
            {
              "date": "2026-09-28",
              "status": "available"
            },
            {
              "date": "2026-09-29",
              "status": "available"
            },
            {
              "date": "2026-09-30",
              "status": "reserved"
            },
            {
              "date": "2026-10-01",
              "status": "reserved"
            },
            {
              "date": "2026-10-02",
              "status": "reserved"
            },
            {
              "date": "2026-10-03",
              "status": "reserved"
            },
            {
              "date": "2026-10-04",
              "status": "reserved"
            },
            {
              "date": "2026-10-05",
              "status": "reserved"
            },
            {
              "date": "2026-10-06",
              "status": "available"
            },
            {
              "date": "2026-10-07",
              "status": "reserved"
            },
            {
              "date": "2026-10-08",
              "status": "reserved"
            },
            {
              "date": "2026-10-09",
              "status": "reserved"
            },
            {
              "date": "2026-10-10",
              "status": "reserved"
            },
            {
              "date": "2026-10-11",
              "status": "reserved"
            },
            {
              "date": "2026-10-12",
              "status": "reserved"
            },
            {
              "date": "2026-10-13",
              "status": "reserved"
            },
            {
              "date": "2026-10-14",
              "status": "available"
            }
          ],
          "pricing_rules": {
            "occupancy_pacing": {
              "mode": "custom",
              "settings": {
                "lead_time_ranges": [
                  {
                    "min_days": 0,
                    "max_days": 7
                  },
                  {
                    "min_days": 8,
                    "max_days": 30
                  }
                ],
                "occupancy_ranges": [
                  {
                    "min_percent": 0,
                    "max_percent": 39
                  },
                  {
                    "min_percent": 40,
                    "max_percent": 69
                  },
                  {
                    "min_percent": 70,
                    "max_percent": 100
                  }
                ],
                "adjustment_percent": [
                  [
                    -15,
                    -5
                  ],
                  [
                    -5,
                    0
                  ],
                  [
                    5,
                    10
                  ]
                ]
              }
            }
          }
        }
      },
      "austinWeekends": {
        "summary": "Austin loft · weekends and a concert override",
        "description": "A downtown Austin loft at 240 a night that lives on bachelorette parties and weekend trips.\nFriday and Saturday carry their own uplift on top of the weekday effect the model already\napplies, midweek is a little cheaper, stays are two nights minimum and check-in is Thursday to\nSaturday only. A sold-out concert weekend (Fri Oct 16 – Sat Oct 17) gets a hand-set +40% on top.\n`start_date` and `end_date` return just that Thursday to Sunday.\n",
        "value": {
          "location": {
            "latitude": 30.2672,
            "longitude": -97.7431
          },
          "currency": "USD",
          "base_price": 240,
          "start_date": "2026-10-15",
          "end_date": "2026-10-18",
          "pricing_rules": {
            "day_of_week": {
              "mode": "custom",
              "settings": {
                "adjustment_percent": {
                  "monday": -5,
                  "tuesday": -5,
                  "wednesday": -5,
                  "thursday": 0,
                  "friday": 15,
                  "saturday": 25,
                  "sunday": 5
                }
              }
            }
          },
          "stay_rules": {
            "min_stay": {
              "mode": "custom",
              "settings": {
                "min_nights": 2
              }
            },
            "check_in_out": {
              "mode": "custom",
              "settings": {
                "allowed_check_in_days": [
                  "thursday",
                  "friday",
                  "saturday"
                ],
                "allowed_check_out_days": [
                  "monday",
                  "tuesday",
                  "wednesday",
                  "thursday",
                  "friday",
                  "saturday",
                  "sunday"
                ]
              }
            }
          },
          "price_overrides": [
            {
              "start_date": "2026-10-16",
              "end_date": "2026-10-17",
              "adjustment_type": "percentage",
              "adjustment_amount": 40
            }
          ]
        }
      },
      "gatlinburgGaps": {
        "summary": "Gatlinburg cabin · fill the gaps",
        "description": "A cabin above Gatlinburg at 210 a night with a busy fortnight: bookings on Sat Sep 19, Mon Sep\n21 – Wed Sep 23, Sat Sep 26 and Wed Sep 30, leaving a one-night hole, a two-night hole and a\nthree-night run of open nights. The host wants the holes filled: −20% on a one-night gap, −10%\non a two-night gap, and −5% on any open night touching a booking. The calendar starts and ends\non a reserved night so every open run has known boundaries.\n",
        "value": {
          "location": {
            "latitude": 35.7143,
            "longitude": -83.5102
          },
          "currency": "USD",
          "base_price": 210,
          "start_date": "2026-09-20",
          "end_date": "2026-09-27",
          "calendar": [
            {
              "date": "2026-09-19",
              "status": "reserved"
            },
            {
              "date": "2026-09-20",
              "status": "available"
            },
            {
              "date": "2026-09-21",
              "status": "reserved"
            },
            {
              "date": "2026-09-22",
              "status": "reserved"
            },
            {
              "date": "2026-09-23",
              "status": "reserved"
            },
            {
              "date": "2026-09-24",
              "status": "available"
            },
            {
              "date": "2026-09-25",
              "status": "available"
            },
            {
              "date": "2026-09-26",
              "status": "reserved"
            },
            {
              "date": "2026-09-27",
              "status": "available"
            },
            {
              "date": "2026-09-28",
              "status": "available"
            },
            {
              "date": "2026-09-29",
              "status": "available"
            },
            {
              "date": "2026-09-30",
              "status": "reserved"
            }
          ],
          "pricing_rules": {
            "gap_day": {
              "mode": "custom",
              "apply_on_weekends": true,
              "settings": [
                {
                  "min_days": 1,
                  "max_days": 1,
                  "adjustment_percent": -20
                },
                {
                  "min_days": 2,
                  "max_days": 2,
                  "adjustment_percent": -10
                }
              ]
            },
            "adjacent_day": {
              "mode": "custom",
              "apply_on_weekends": true,
              "settings": {
                "days_before": 1,
                "days_after": 1,
                "adjustment_percent": -5
              }
            }
          }
        }
      },
      "charlestonLimits": {
        "summary": "Charleston house · limits and a fixed price",
        "description": "A carriage house in downtown Charleston at 350 a night. Over the holiday week the owner wants a\ntight band, 325 to 375, whatever the model says about quiet Tuesdays or busy Fridays, except New\nYear's Eve, which is always sold by hand at exactly 750. A floor and a ceiling do the first\npart; a fixed override on Thu Dec 31 does the second. The window returns Tue Dec 29 through Fri\nJan 1.\n",
        "value": {
          "location": {
            "latitude": 32.7765,
            "longitude": -79.9311
          },
          "currency": "USD",
          "base_price": 350,
          "start_date": "2026-12-29",
          "end_date": "2027-01-01",
          "price_limits": {
            "min_price": 325,
            "max_price": 375
          },
          "price_overrides": [
            {
              "start_date": "2026-12-31",
              "end_date": "2026-12-31",
              "adjustment_type": "fixed",
              "adjustment_amount": 750
            }
          ]
        }
      },
      "response-joshuaTreeFirstCall": {
        "summary": "Joshua Tree casita · first call, base price only",
        "description": "Three of the 730 rows are shown, the Friday to Sunday 11 days out; the rest are omitted here.\nEach night carries the base price and the four model lines (seasonality, weekday, holiday/event,\nmarket demand), and the amounts always sum to `price`. `coverage` gives the calculation date and\nthe returned range; with no `end_date` sent, that range is the whole available calendar.\n`warnings` is empty.\n",
        "value": {
          "location": {
            "latitude": 34.1347,
            "longitude": -116.3131
          },
          "currency": "USD",
          "coverage": {
            "calculation_date": "2026-09-14",
            "start_date": "2026-09-14",
            "end_date": "2028-09-12",
            "recommendation_count": 730,
            "timezone": "America/Los_Angeles"
          },
          "warnings": [],
          "recommendations": [
            {
              "date": "2026-09-25",
              "price": 183.74,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 180
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -8.26,
                  "amount": -14.87
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 9.97,
                  "amount": 16.47
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 1.2,
                  "amount": 2.14
                }
              ]
            },
            {
              "date": "2026-09-26",
              "price": 180.49,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 180
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -7.91,
                  "amount": -14.24
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 7.31,
                  "amount": 12.11
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 1.5,
                  "amount": 2.62
                }
              ]
            },
            {
              "date": "2026-09-27",
              "price": 161.53,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 180
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -7.57,
                  "amount": -13.63
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -2.91,
                  "amount": -4.84
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            }
          ]
        }
      },
      "response-miamiBeachLeadTime": {
        "summary": "Miami Beach condo · early bookers and last minute",
        "description": "Six of the 730 rows are shown: three from the last-minute window (Mon Sep 14, Sun Sep 20, Sun\nSep 27) and three from far out (Tue Jan 12, 2027, Mon Apr 12, 2027, Tue Sep 14, 2027); the rest\nare omitted here. Tonight gets the full −15%, a week out is −10%, and Sun Sep 27 at the edge of\nthe window gets −1.25%. Tue Jan 12, 2027 is the first day of the far-future window (0% on a\ngradual ramp, so no line), Mon Apr 12, 2027 is partway up at +6%, and Tue Sep 14, 2027 holds the\nfull +12%. Nights between the two windows get neither.\n",
        "value": {
          "location": {
            "latitude": 25.7907,
            "longitude": -80.13
          },
          "currency": "USD",
          "coverage": {
            "calculation_date": "2026-09-14",
            "start_date": "2026-09-14",
            "end_date": "2028-09-12",
            "recommendation_count": 730,
            "timezone": "America/New_York"
          },
          "warnings": [],
          "recommendations": [
            {
              "date": "2026-09-14",
              "price": 224,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 320
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -23.4,
                  "amount": -74.87
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -4.16,
                  "amount": -10.2
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "last_minute_rule",
                  "label": "Last-minute rule",
                  "adjustment_percent": -15,
                  "amount": -35.24
                },
                {
                  "code": "minimum_price_limit",
                  "label": "Minimum price limit",
                  "amount": 24.31,
                  "details": [
                    "Default minimum: 70% of base price."
                  ]
                }
              ]
            },
            {
              "date": "2026-09-20",
              "price": 224,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 320
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -22.3,
                  "amount": -71.35
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -1.86,
                  "amount": -4.63
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "last_minute_rule",
                  "label": "Last-minute rule",
                  "adjustment_percent": -10,
                  "amount": -24.4
                },
                {
                  "code": "minimum_price_limit",
                  "label": "Minimum price limit",
                  "amount": 4.38,
                  "details": [
                    "Default minimum: 70% of base price."
                  ]
                }
              ]
            },
            {
              "date": "2026-09-27",
              "price": 247.5,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 320
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -20.31,
                  "amount": -64.98
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -1.86,
                  "amount": -4.75
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0.1,
                  "amount": 0.37
                },
                {
                  "code": "last_minute_rule",
                  "label": "Last-minute rule",
                  "adjustment_percent": -1.25,
                  "amount": -3.14
                }
              ]
            },
            {
              "date": "2027-01-12",
              "price": 336.91,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 320
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 9.17,
                  "amount": 29.36
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -3.56,
                  "amount": -12.45
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            },
            {
              "date": "2027-04-12",
              "price": 346.65,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 320
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 6.63,
                  "amount": 21.22
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -4.16,
                  "amount": -14.19
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "far_future_rule",
                  "label": "Far-future rule",
                  "adjustment_percent": 6,
                  "amount": 19.62
                }
              ]
            },
            {
              "date": "2027-09-14",
              "price": 264.76,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 320
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -23.4,
                  "amount": -74.87
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -3.56,
                  "amount": -8.74
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "far_future_rule",
                  "label": "Far-future rule",
                  "adjustment_percent": 12,
                  "amount": 28.37
                }
              ]
            }
          ]
        }
      },
      "response-scottsdalePacing": {
        "summary": "Scottsdale condo · occupancy pacing",
        "description": "The 0–7 day window is 25% booked, so its open nights (Mon Sep 14, Tue Sep 15, Fri Sep 18, Sat\nSep 19, Sun Sep 20, Mon Sep 21) get the top-left cell, −15%. The 8–30 day window is 74% booked,\nso its open nights in the output (Tue Sep 22) get the bottom-right cell, +10%. Reserved nights\nare priced but not adjusted. Read the grid as `adjustment_percent[occupancy row][lead-time\ncolumn]`.\n",
        "value": {
          "location": {
            "latitude": 33.4942,
            "longitude": -111.9261
          },
          "currency": "USD",
          "coverage": {
            "calculation_date": "2026-09-14",
            "start_date": "2026-09-14",
            "end_date": "2026-09-23",
            "recommendation_count": 10,
            "timezone": "America/Phoenix"
          },
          "warnings": [],
          "recommendations": [
            {
              "date": "2026-09-14",
              "price": 192.5,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -16.52,
                  "amount": -45.43
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -5.77,
                  "amount": -13.25
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "occupancy_pacing_rule",
                  "label": "Occupancy pacing rule",
                  "adjustment_percent": -15,
                  "amount": -32.45
                },
                {
                  "code": "minimum_price_limit",
                  "label": "Minimum price limit",
                  "amount": 8.63,
                  "details": [
                    "Default minimum: 70% of base price."
                  ]
                }
              ]
            },
            {
              "date": "2026-09-15",
              "price": 192.5,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -16.08,
                  "amount": -44.22
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -4.14,
                  "amount": -9.55
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "occupancy_pacing_rule",
                  "label": "Occupancy pacing rule",
                  "adjustment_percent": -15,
                  "amount": -33.19
                },
                {
                  "code": "minimum_price_limit",
                  "label": "Minimum price limit",
                  "amount": 4.46,
                  "details": [
                    "Default minimum: 70% of base price."
                  ]
                }
              ]
            },
            {
              "date": "2026-09-16",
              "price": 231.02,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -15.65,
                  "amount": -43.03
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -0.41,
                  "amount": -0.95
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            },
            {
              "date": "2026-09-17",
              "price": 243.99,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -15.22,
                  "amount": -41.87
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 4.66,
                  "amount": 10.86
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            },
            {
              "date": "2026-09-18",
              "price": 213.16,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -14.81,
                  "amount": -40.73
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 6.97,
                  "amount": 16.33
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0.1,
                  "amount": 0.18
                },
                {
                  "code": "occupancy_pacing_rule",
                  "label": "Occupancy pacing rule",
                  "adjustment_percent": -15,
                  "amount": -37.62
                }
              ]
            },
            {
              "date": "2026-09-19",
              "price": 207.98,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -14.4,
                  "amount": -39.61
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 3.87,
                  "amount": 9.11
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0.1,
                  "amount": 0.18
                },
                {
                  "code": "occupancy_pacing_rule",
                  "label": "Occupancy pacing rule",
                  "adjustment_percent": -15,
                  "amount": -36.7
                }
              ]
            },
            {
              "date": "2026-09-20",
              "price": 192.5,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -14.01,
                  "amount": -38.52
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -4.41,
                  "amount": -10.42
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "occupancy_pacing_rule",
                  "label": "Occupancy pacing rule",
                  "adjustment_percent": -15,
                  "amount": -33.91
                },
                {
                  "code": "minimum_price_limit",
                  "label": "Minimum price limit",
                  "amount": 0.35,
                  "details": [
                    "Default minimum: 70% of base price."
                  ]
                }
              ]
            },
            {
              "date": "2026-09-21",
              "price": 192.5,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -13.62,
                  "amount": -37.46
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -5.77,
                  "amount": -13.71
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "occupancy_pacing_rule",
                  "label": "Occupancy pacing rule",
                  "adjustment_percent": -15,
                  "amount": -33.57
                },
                {
                  "code": "minimum_price_limit",
                  "label": "Minimum price limit",
                  "amount": 2.24,
                  "details": [
                    "Default minimum: 70% of base price."
                  ]
                }
              ]
            },
            {
              "date": "2026-09-22",
              "price": 251.58,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -13.24,
                  "amount": -36.42
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -4.14,
                  "amount": -9.87
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "occupancy_pacing_rule",
                  "label": "Occupancy pacing rule",
                  "adjustment_percent": 10,
                  "amount": 22.87
                }
              ]
            },
            {
              "date": "2026-09-23",
              "price": 238.62,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 275
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -12.88,
                  "amount": -35.41
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -0.41,
                  "amount": -0.97
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            }
          ]
        }
      },
      "response-austinWeekends": {
        "summary": "Austin loft · weekends and a concert override",
        "description": "Thu Oct 15 has a 0% weekday value, so no custom line. Fri Oct 16 gets the custom Friday rule\n(+15%) and then the +40% override; Sat Oct 17 gets +25% and the same override, finishing at\n590.23. Sun Oct 18 gets +5% and no override. Every row carries `min_stay` 2 and the check-in\nflags: allowed on Thu Oct 15, Fri Oct 16 and Sat Oct 17, not on Sun Oct 18. The stay rules never\nchange the price.\n",
        "value": {
          "location": {
            "latitude": 30.2672,
            "longitude": -97.7431
          },
          "currency": "USD",
          "coverage": {
            "calculation_date": "2026-09-14",
            "start_date": "2026-10-15",
            "end_date": "2026-10-18",
            "recommendation_count": 4,
            "timezone": "America/Chicago"
          },
          "warnings": [],
          "recommendations": [
            {
              "date": "2026-10-15",
              "price": 335.37,
              "min_stay": 2,
              "check_in_allowed": true,
              "check_out_allowed": true,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 240
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 30.06,
                  "amount": 72.15
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 7.44,
                  "amount": 23.22
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            },
            {
              "date": "2026-10-16",
              "price": 572.63,
              "min_stay": 2,
              "check_in_allowed": true,
              "check_out_allowed": true,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 240
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 29.88,
                  "amount": 71.71
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 14.11,
                  "amount": 43.96
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "custom_day_of_week_rule",
                  "label": "Custom Friday rule",
                  "adjustment_percent": 15,
                  "amount": 53.35
                },
                {
                  "code": "percentage_price_override",
                  "label": "Percentage price override",
                  "adjustment_percent": 40,
                  "amount": 163.61
                }
              ]
            },
            {
              "date": "2026-10-17",
              "price": 590.23,
              "min_stay": 2,
              "check_in_allowed": true,
              "check_out_allowed": true,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 240
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 29.51,
                  "amount": 70.81
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 8.51,
                  "amount": 26.46
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "custom_day_of_week_rule",
                  "label": "Custom Saturday rule",
                  "adjustment_percent": 25,
                  "amount": 84.32
                },
                {
                  "code": "percentage_price_override",
                  "label": "Percentage price override",
                  "adjustment_percent": 40,
                  "amount": 168.64
                }
              ]
            },
            {
              "date": "2026-10-18",
              "price": 300.14,
              "min_stay": 2,
              "check_in_allowed": false,
              "check_out_allowed": true,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 240
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 28.95,
                  "amount": 69.48
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -5.93,
                  "amount": -18.35
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": -1.8,
                  "amount": -5.28
                },
                {
                  "code": "custom_day_of_week_rule",
                  "label": "Custom Sunday rule",
                  "adjustment_percent": 5,
                  "amount": 14.29
                }
              ]
            }
          ]
        }
      },
      "response-gatlinburgGaps": {
        "summary": "Gatlinburg cabin · fill the gaps",
        "description": "Sun Sep 20 is a one-night gap: −20%. Thu Sep 24 and Fri Sep 25 are the two-night gap: −10% each.\nSun Sep 27 opens a three-night run that no band covers, so it is not a gap, and the adjacent\nrule takes it instead at −5%. The reserved nights in between are priced but untouched. When a\nnight qualifies for both rules, gap day wins and the adjacent percentage is not stacked on top.\n",
        "value": {
          "location": {
            "latitude": 35.7143,
            "longitude": -83.5102
          },
          "currency": "USD",
          "coverage": {
            "calculation_date": "2026-09-14",
            "start_date": "2026-09-20",
            "end_date": "2026-09-27",
            "recommendation_count": 8,
            "timezone": "America/New_York"
          },
          "warnings": [],
          "recommendations": [
            {
              "date": "2026-09-20",
              "price": 159.53,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 210
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -1.76,
                  "amount": -3.7
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -3.33,
                  "amount": -6.88
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "gap_night_rule",
                  "label": "Gap-night rule",
                  "adjustment_percent": -20,
                  "amount": -39.89
                }
              ]
            },
            {
              "date": "2026-09-21",
              "price": 198.85,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 210
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -1.25,
                  "amount": -2.63
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -4.11,
                  "amount": -8.52
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            },
            {
              "date": "2026-09-22",
              "price": 201.5,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 210
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -0.71,
                  "amount": -1.49
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -3.37,
                  "amount": -7.01
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            },
            {
              "date": "2026-09-23",
              "price": 206.27,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 210
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -0.12,
                  "amount": -0.26
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -1.65,
                  "amount": -3.47
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            },
            {
              "date": "2026-09-24",
              "price": 196,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 210
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 0.49,
                  "amount": 1.04
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 2.44,
                  "amount": 5.14
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0.7,
                  "amount": 1.59
                },
                {
                  "code": "gap_night_rule",
                  "label": "Gap-night rule",
                  "adjustment_percent": -10,
                  "amount": -21.77
                }
              ]
            },
            {
              "date": "2026-09-25",
              "price": 203.92,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 210
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 1.15,
                  "amount": 2.41
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 6.21,
                  "amount": 13.18
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0.4,
                  "amount": 0.99
                },
                {
                  "code": "gap_night_rule",
                  "label": "Gap-night rule",
                  "adjustment_percent": -10,
                  "amount": -22.66
                }
              ]
            },
            {
              "date": "2026-09-26",
              "price": 223.12,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 210
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 1.83,
                  "amount": 3.83
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 4.34,
                  "amount": 9.29
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                }
              ]
            },
            {
              "date": "2026-09-27",
              "price": 197.73,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 210
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": 2.53,
                  "amount": 5.32
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -3.33,
                  "amount": -7.18
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "adjacent_night_rule",
                  "label": "Adjacent-night rule",
                  "adjustment_percent": -5,
                  "amount": -10.41
                }
              ]
            }
          ]
        }
      },
      "response-charlestonLimits": {
        "summary": "Charleston house · limits and a fixed price",
        "description": "Thu Dec 31 returns 750, far above the 375 ceiling: a fixed override is applied last and ignores\nthe limits. Its receipt still shows the model's own lines, then one `fixed_price_override` line\nthat closes the difference. The other three nights show the limits at work: Fri Jan 1, 2027 was\nlowered to the ceiling; Tue Dec 29, Wed Dec 30 were raised to the floor. A limit line appears\nonly on a night that was actually clamped.\n",
        "value": {
          "location": {
            "latitude": 32.7765,
            "longitude": -79.9311
          },
          "currency": "USD",
          "coverage": {
            "calculation_date": "2026-09-14",
            "start_date": "2026-12-29",
            "end_date": "2027-01-01",
            "recommendation_count": 4,
            "timezone": "America/New_York"
          },
          "warnings": [],
          "recommendations": [
            {
              "date": "2026-12-29",
              "price": 325,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 350
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -2.35,
                  "amount": -8.21
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -12.42,
                  "amount": -42.47
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 1.73,
                  "amount": 5.18,
                  "details": [
                    "New Year's Day"
                  ]
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "minimum_price_limit",
                  "label": "Minimum price limit",
                  "amount": 20.5
                }
              ]
            },
            {
              "date": "2026-12-30",
              "price": 325,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 350
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -2.86,
                  "amount": -10.02
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": -7.33,
                  "amount": -24.91
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 1.94,
                  "amount": 6.1,
                  "details": [
                    "New Year's Day"
                  ]
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "minimum_price_limit",
                  "label": "Minimum price limit",
                  "amount": 3.83
                }
              ]
            },
            {
              "date": "2026-12-31",
              "price": 750,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 350
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -3.48,
                  "amount": -12.17
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 8.77,
                  "amount": 29.64
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": 1.39,
                  "amount": 5.11,
                  "details": [
                    "New Year's Day"
                  ]
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "fixed_price_override",
                  "label": "Fixed price override",
                  "amount": 377.42
                }
              ]
            },
            {
              "date": "2027-01-01",
              "price": 375,
              "explanation": [
                {
                  "code": "base_price",
                  "label": "Base price",
                  "amount": 350
                },
                {
                  "code": "seasonality",
                  "label": "Seasonality",
                  "adjustment_percent": -4.38,
                  "amount": -15.32
                },
                {
                  "code": "day_of_week",
                  "label": "Day of week",
                  "adjustment_percent": 19.72,
                  "amount": 66
                },
                {
                  "code": "known_holiday_event",
                  "label": "Holiday/event",
                  "adjustment_percent": -0.27,
                  "amount": -1.07,
                  "details": [
                    "New Year's Day"
                  ]
                },
                {
                  "code": "market_demand",
                  "label": "Market demand",
                  "adjustment_percent": 0,
                  "amount": 0
                },
                {
                  "code": "maximum_price_limit",
                  "label": "Maximum price limit",
                  "amount": -24.61
                }
              ]
            }
          ]
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "General",
      "tags": [
        "Authentication",
        "Filtering",
        "Sorting",
        "Pagination"
      ]
    },
    {
      "name": "API Endpoints",
      "tags": [
        "Listings",
        "Markets",
        "Calculator",
        "Price Recommendation"
      ]
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ]
}
