# Landing > Landing rents fully-furnished apartments for flexible monthly, short-term, and open-ended (LandingFlex) stays across 250+ US markets. Book entirely online — no security deposit, 24/7 local support, and easy check-in. This file tells AI agents how to browse the site programmatically and how to search the catalog and price a stay through our public API. Everything below is read-only and requires no authentication. **Note to LLMs/agents:** you don't need to scrape or guess your way around this website — here you can find more information on how to use the API and the website more effectively. Start with the [API reference](https://www.hellolanding.com/api/public); the machine-readable index of everything is the [API catalog](https://www.hellolanding.com/.well-known/api-catalog). ## What you can do here Everything a person can research on the website, you can do programmatically — with real, bookable data, not estimates: - **Search** furnished apartments in 250+ US markets by dates, bedrooms, price, amenities (pets, parking, pool, gym, in-unit laundry), and proximity. - **Check availability** for exact move-in/move-out dates — including open-ended LandingFlex stays (`end_date: "indefinite"` + a committed-nights tier). `get_apartment` returns the full availability calendar (bookable windows, earliest available date), clipped to your dates. - **Check real prices**: `get_quote` returns the actual anonymous quote for specific dates (monthly rent, first-month charge, and the all-in total) from the same pricing engine that powers checkout. - **Compare** 2–4 homes side by side (price, size, amenities, ratings, availability) and **find deals** — search with `deals_only: true` for currently discounted homes, composable with every other filter. - **Research** like a local: aggregate guest ratings, neighborhood descriptions with walk/transit/bike scores, market-level rent stats (`get_market_info`), and grounded policy answers (deposits, pets, cancellation, qualification). The one thing you can't do through the API is complete the reservation itself — payment happens on the website. But you can get all the way to the doorstep: tools return `home_url` (the home's page with dates pre-filled) and `checkout_url` (straight to payment), and the MCP `booking_intent` tool saves the guest's interest and hands back a direct checkout link. So the handoff is: search, compare, and price through the API → send the person the link to pay. There are two ways to access the same public capabilities — use whichever your environment supports. ## MCP server (JSON-RPC over HTTP POST) - [Public MCP server](https://www.hellolanding.com/mcp/public): POST JSON-RPC, no auth. Tools include `list_markets`, `search_apartments` (with `deals_only` and `guest_rating` filters), `get_apartment`, `get_quote`, `get_flex_options`, `compare_apartments`, `get_market_info`, `get_market_filters`, and more. - [Server card](https://www.hellolanding.com/.well-known/mcp/server-card.json) - [Agent skills index](https://www.hellolanding.com/.well-known/agent-skills/index.json) - **[Tool catalog](https://www.hellolanding.com/api/public/tools.json)** — the authoritative, always-current tool list as a plain GET: every tool with its full description, JSON Schema, GET mirror, and an example call. It is the server's `tools/list` response mirrored over GET, generated from the live tool set (the names above are just examples). Human/LLM-readable markdown version: [/api/public/tools](https://www.hellolanding.com/api/public/tools). ## HTTP GET REST API (if you cannot use MCP) If your environment can't POST/JSON-RPC or has no MCP client (e.g. a GET-only fetch tool), the same read-only capabilities are available as plain HTTP GET — every read-only MCP tool has a GET endpoint: - [API reference](https://www.hellolanding.com/api/public) - [OpenAPI 3.1 spec](https://www.hellolanding.com/api/public/openapi.json) — generated from the live tool set; treat it as the authoritative endpoint list - [Tool catalog](https://www.hellolanding.com/api/public/tools) — every tool with parameters, REST↔MCP mapping, and worked examples (markdown; JSON at `/api/public/tools.json`) - Example — search Birmingham: `https://www.hellolanding.com/api/public/search?market=birmingham&check_in=2026-09-01&check_out=2026-12-01` - Example — price a home: `https://www.hellolanding.com/api/public/homes/{slug}/quote?check_in=2026-09-01&check_out=2026-12-01` ## Typical flow 1. `GET /api/public/markets` (or `list_markets`) → pick a market slug. 2. `GET /api/public/search?market=&check_in=YYYY-MM-DD&check_out=YYYY-MM-DD` → pick a home slug. 3. `GET /api/public/homes//quote?check_in=YYYY-MM-DD&check_out=YYYY-MM-DD` → real all-in pricing. ## Browse the site as markdown Prefer reading pages? Every key page has a markdown mirror (also reachable by sending `Accept: text/markdown` to the HTML URL): - [Homepage](https://www.hellolanding.com/index.md): How Landing works, features, and the Landing Guarantee - [FAQ & Help Center](https://www.hellolanding.com/help-center.md): Common questions about deposits, pets, parking, maintenance, and check-out - [All Cities](https://www.hellolanding.com/locations.md): Complete list of markets where Landing operates - [Search by City](https://www.hellolanding.com/s/{market}/apartments.md): Replace `{market}` with a city slug to see available furnished apartments — e.g. `/s/austin/apartments.md`, `/s/new-york-city/apartments.md`, `/s/los-angeles/apartments.md` - [Apartment Detail](https://www.hellolanding.com/homes/{slug}.md): Full details for any apartment — amenities, policies, and booking link. Append `?start_date=YYYY-MM-DD&end_date=YYYY-MM-DD` for exact pricing and availability for specific dates ## Optional - [Corporate Housing](https://www.hellolanding.com/corporate-housing): Furnished apartments for business travelers and corporate relocation - [Monthly Rentals](https://www.hellolanding.com/monthly-rentals): Information about monthly furnished rental options - [Sitemap](https://www.hellolanding.com/sitemap): Complete list of all Landing cities and properties - [API catalog (RFC 9727)](https://www.hellolanding.com/.well-known/api-catalog): Machine-readable index of every API surface ## Notes - No authentication for any of the above. Dates are `YYYY-MM-DD`. - Booking is completed on https://www.hellolanding.com — the API surfaces catalog + pricing + a checkout link, not payment. - Please rate-limit bulk requests. --- ## Full Tool Catalog Every public MCP tool, with its full description, JSON Schema, GET mirror, and a worked example. # Landing public tools — full catalog Every tool on Landing's public MCP server (`POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public`, JSON-RPC, no auth), with parameters and — for read-only tools — the equivalent plain HTTP GET endpoint. Machine-readable version: http://core-prod-web.default.svc.cluster.local:3000/api/public/tools.json (a GET mirror of the MCP `tools/list` response — fetch it if you can't POST). Generated from the live tool set, so this page cannot go stale. Dates are YYYY-MM-DD. See also: REST reference http://core-prod-web.default.svc.cluster.local:3000/api/public · OpenAPI http://core-prod-web.default.svc.cluster.local:3000/api/public/openapi.json · agent guide https://www.hellolanding.com/llms.txt ## list_markets_tool List every Landing market currently accepting bookings, and — nested under each — its **display cities** (the specific, neighborhood-level places the website is organized around). Returns the FULL list (no filtering) — it's small. Match the guest's location against the `name` / `slug` / `state` of a market OR a city and use the corresponding slug. Match on the CITY when possible: metros span state lines, so a city's `state` can differ from its market's (e.g. the "Washington D.C." market, state DC, contains "alexandria-va" / "arlington-va" — Virginia cities; "vancouver-wa" lives in the Portland, OR market; "newark-nj" in New York). This is exactly why matching by city (not by filtering on state) is the reliable path. **Markets vs. cities — prefer cities.** A `market` is a broad metro region; a display `city` is a more specific place within it. hellolanding.com is display-city-centric, so **prefer a city slug when the guest names a specific place** — it targets that exact location instead of the whole metro. Both `search_apartments` and `search_apartments_on_map` take EITHER kind of slug in their `market` argument: pass a `cities[].slug` (e.g. "alexandria-va") to search that city, or a market `slug` (e.g. "birmingham") for the whole metro. **Call it** - MCP: call `list_markets_tool` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: `/api/public/markets` - Example: http://core-prod-web.default.svc.cluster.local:3000/api/public/markets **Example response (abridged)** ```json { "markets": [ { "slug": "birmingham", "name": "Birmingham", "state": "AL" } ], "count": 1 } ``` ## get_market_filters_tool Returns all available filter options for a given market — its display cities, bedroom counts, amenities, price range, bathroom options, neighborhoods, and sort orders. `market` accepts a market slug OR a display-city slug (e.g. "birmingham-al"); a city slug resolves to its parent market and returns that market's options. Call this before search_apartments when you want to show the guest what they can filter by, or to validate that a requested filter makes sense for the market (e.g. confirming a neighborhood or city slug exists). Returns: - `cities` — the market's display cities ({slug, name, state}); a city is the preferred, more-specific search unit — pass a `cities[].slug` as search_apartments' `market` to search that city. - `bedrooms` — bedroom counts actually available in the market (only counts with published homes are included). - `amenities` — filterable amenity options with their search_apartments key. - `min_bathrooms` — bathroom minimums actually available in the market. - `price_range` — lowest and highest monthly rent currently listed in the market. - `neighborhoods` — neighborhoods with available homes (id and slug for filtering). - `sort_options` — valid values for search_apartments `sort_by`. **Parameters** - `market` (string, required) — Market slug (e.g. "austin-tx"). Use list_markets to discover slugs. **Call it** - MCP: call `get_market_filters_tool` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: `/api/public/market-filters` - Example: http://core-prod-web.default.svc.cluster.local:3000/api/public/market-filters?market=birmingham **Example response (abridged)** ```json { "market": { "slug": "birmingham" }, "bedrooms": [ 1, 2 ], "amenities": [ { "label": "Pets allowed", "filter": "pets" } ] } ``` ## search_apartments_tool Search Landing's published furnished apartments by location. **Location — prefer a display city (`market` arg).** The `market` argument takes EITHER a display-city slug or a market slug from list_markets. A market is a broad metro region; a display city is a more specific place within it (e.g. the "Washington DC" market contains the "Alexandria, VA" city, slug "alexandria-va"). hellolanding.com is display-city-centric, so **when the guest names a specific place, pass that city's slug** — it targets that exact location. Use a market slug only for a whole region or when no specific city is named. Call `list_markets` to discover both (each market lists its `cities`), or `get_market_filters` for a market's filter options. All other inputs are optional filters. The response echoes `display_city` when a city was searched. **`scope` — structured, explicit alternative to `market`.** Pass EITHER `scope: { display_city: "alexandria-va" }` to pin results to that city, or `scope: { market: "birmingham" }` to pin results to that whole metro — instead of (or alongside) the top-level `market` argument. Each is equivalent to passing the same slug as `market`, just explicit rather than overloading `market`'s dual market-or-city meaning. Precedence when more than one is given: `scope.display_city` > `scope.market` > `market`. One of `market`, `scope.display_city`, or `scope.market` is required. **Availability.** Pass `start_date` and/or `end_date` to restrict results to homes open for the full requested window. Use `end_date: "indefinite"` to filter for Landing Flex-eligible homes only. **Location first: match a display city or market — coordinates are a last resort.** When the guest names a place, FIRST try to match it to a display city (preferred) or market from `list_markets` and pass that slug as `market` — that is the normal path and covers almost every request ("in Birmingham", "Alexandria", "downtown Austin"). A named city is a SLUG, not a coordinate: do NOT reach for latitude/longitude just because a place was named. Example: "apartments in Frisco" → `market: "frisco-tx"` (a city slug, no `near_*` at all) — contrast with the point-of-interest example below. **Proximity (`near_*`) — only for a specific point that ISN'T a city/market.** Use `near_latitude`/`near_longitude` ONLY when the guest anchors to a precise spot that isn't a listable place — a specific building, employer, hospital, campus, or street address ("near UAB hospital", "within 2 miles of 420 20th St") — where distance-ranking actually matters. Even then, still set `market` to the display city/market that spot sits in so the search is scoped, and **prefer `search_apartments_on_map`** (it plots the point and the homes around it — a card list can't show distance). Geocode the spot yourself and pass `near_latitude` + `near_longitude` (plus `near_radius_miles`, default 5) AND `near_label` with its name, so results read "N apartments within X miles of {near_label}". Example: "apartments near University of Birmingham Hospital" → `market: "birmingham-al", near_latitude: 33.5058, near_longitude: -86.8018, near_radius_miles: 3, near_label: "University of Birmingham Hospital"`. **Landing Flex — terminology.** "Flex" (or "Landing Flex") is Landing's open-ended, no-fixed-move-out-date stay option — it's how a guest unlocks Landing's lowest rates: commit to a longer stay (6+ months) instead of a fixed end date and pay less per month, and that discount follows the guest across 250+ markets even if they change homes. `eligible_for_flex` on each search result says whether a given home supports it; call `get_flex_options` on a home slug to confirm the commitment lengths it accepts. When explaining this to a guest, describe it as: "commit to a longer stay, pay less per month" — not a separate product, just a lower-rate booking option on the same homes. When any result in a search is Flex-eligible, the response also includes `flex_search_url` — a link to Landing's flexible-date search page, worth surfacing to guests who seem price-sensitive or open-ended about their move-in timing. **Pagination.** Results are paginated. Pass `page` (1-indexed, default 1) and `per_page` (default 25, max 100). The response always includes `total_count` (total matching homes) and `total_pages` (number of pages at the requested per_page). Fetch subsequent pages by incrementing `page` while `page <= total_pages`. (To plot every match on a map in one call instead, use `search_apartments_on_map`.) The inline widget paginates the returned results client-side into numbered pages, so prefer returning a full page (the default 25, up to the max) rather than a handful — it gives the guest more to browse without extra calls. **Per-home response.** Each result carries: - `display_price_with_discount` + `display_price_label` — the all-in price (includes all fees except taxes) with correct label: e.g. `318` + `" for 2 nights"` or `2100` + `" per month"`. Always pair these two together. `display_price_without_discount` is the same figure before any discount. No bare per-unit rate is returned; `is_price_monthly` / `is_price_nightly` (and `duration_label`) only say whether the price is monthly or nightly. - `price_note` — "Price includes all fees except taxes." - `home_url` — hellolanding.com link with search dates pre-filled. Share with the guest. - `hero_image_url` — a photo of the home, when one has been uploaded. This is a URL — most chat clients won't render an externally-hosted image embedded in a reply, so by default (`include_hero_images: true`) hero photos for up to 5 of this page's results (fewer if the page itself has fewer homes) are ALSO returned as embedded MCP image content a compliant client can display inline — pass `include_hero_images: false` to opt out and shrink the payload. This cap doesn't scale with `per_page`, so a larger page size doesn't mean more embedded photos. Each image's `_meta.home_slug` says which home it belongs to. - `widget_hero_image_url` — a 800px-resized variant of `hero_image_url`, present whenever a photo exists. Only used by the inline visual widget (see below); safe to ignore otherwise. - `media` — the home's hero photo as a single-entry array, with `url` (full-resolution), `widget_url` (800px-resized), `type` (currently always `"photo"`), `source` (`"unit"` or `"property"`), and `position` (0-indexed). `hero_image_url`/`widget_hero_image_url` are just `media[0]`'s `url`/`widget_url`. Search returns ONE photo per home to keep the payload small (no carousel); to see a home's full photo gallery, call `get_apartment` on its slug — that's the tool to reach for when the guest wants more pictures of a specific place. - `flex_options` — Landing Flex commitment tiers with monthly rates, always included for eligible homes. Use these to show guests a better rate without a separate API call. - `property.member_rating` — guest post-stay survey `average` rating for the building this home is in, when available. Omitted (no `property` key) for properties with no ratings yet. **Deals / special offers.** To find homes with special offers, deals, or discounts, pass `deals_only: true` — this restricts results to homes Landing has auto-generated a special offer for (vacancy-driven), composable with every other filter above. This is the way to find deals. **Filtering/sorting by guest rating.** Pass `guest_rating` (`EXCELLENT` >= 4.5, `VERY_GOOD` >= 4.0, `GOOD` >= 3.5) to only return homes whose building meets that aggregate guest-rating bucket; homes with no rating yet are excluded. Pass `sort_by: "rating_desc"` to rank highest-rated buildings first; unrated homes sort last. Only the aggregate guest rating (`property.member_rating`) is available through this API — individual reviews are on hellolanding.com. (`min_rating` still works but is deprecated in favor of `guest_rating`.) **Inline visual results (MCP Apps).** In hosts that support the MCP Apps extension (SEP-1865), this tool's results render as a visual card grid (photo, name, price, rating, distance) instead of raw JSON — no action needed on the caller's part. Hosts without the extension are unaffected; every field documented above is still returned exactly as described. This tool always renders the card grid — it never shows a map. To plot results on an interactive map (and for any location/proximity search), use `search_apartments_on_map` instead. **Parameters** - `market` (string, optional) — The search location — a display-CITY slug or a market slug from list_markets. Optional when `scope.display_city` or `scope.market` is given instead (see `scope` below); one of the three is required. A named city is a SLUG, not a coordinate. Resolution order when the guest names a place: (1) if it matches a city in list_markets (cities[].slug, e.g. "Frisco" -> "frisco-tx", "Alexandria" -> "alexandria-va", "Birmingham" -> "birmingham-al"), pass that CITY slug here and do NOT geocode it to near_latitude/near_longitude; (2) else if it matches a market slug (broader metro, e.g. "birmingham"), use that; (3) reserve near_latitude/near_longitude ONLY for a sub-city point that no city/market slug can name (a specific building, employer, hospital, campus, or street address). Call list_markets to discover markets and the cities within each. - `scope` (object, optional) — Optional structured location scoping, as an unambiguous alternative to the overloaded `market` argument. Set EXACTLY ONE of its two properties: - `scope: { display_city: "alexandria-va" }` — pin results to that display city. Equivalent to passing the same slug as `market`, just explicit rather than relying on market's dual market-or-city meaning. - `scope: { market: "birmingham" }` — resolves exactly like the top-level `market` argument (a market-OR-city slug, same dual meaning), just under this explicit key. Equivalent to passing the same slug as `market`. Precedence when several location args are given: `scope.display_city` > `scope.market` > the top-level `market` argument. One of `market`, `scope.display_city`, or `scope.market` is required. - `start_date` (string, optional) — Move-in date (YYYY-MM-DD). Filters to homes available on or before this date. - `end_date` (string, optional) — Move-out date (YYYY-MM-DD) for a fixed stay, or "indefinite" for Landing Flex. - `committed_nights` (integer, optional) — Landing Flex commitment tier — only valid with end_date="indefinite". - `min_bedrooms` (integer, optional) — Minimum bedroom count (0 = studio). - `max_bedrooms` (integer, optional) — Maximum bedroom count. - `min_bathrooms` (integer, optional) — Minimum bathroom count. - `min_price` (integer, optional) — Minimum budget in USD, in the unit given by `price_unit` (per night or per month). - `max_price` (integer, optional) — Maximum budget in USD, in the unit given by `price_unit` (per night or per month). Compared against each home's FINAL all-in price for the requested dates, not just base rent — so short stays whose one-time fees push them over budget are correctly excluded. - `price_unit` (string, optional) — The unit min_price/max_price are expressed in: "per_night" for a nightly budget ("$175 a night") or "per_month" for a monthly budget ("under $3000/month"). Pass it whenever you set min_price/max_price so the budget compares against each home's final price in the right unit. Defaults to per_night for short stays, per_month for longer ones. - `pets` (boolean, optional) — When true, only return homes that allow pets in general. For a specific species, prefer cats/dogs below. - `cats` (boolean, optional) — When true, only return cat-friendly homes. - `dogs` (boolean, optional) — When true, only return dog-friendly homes. - `parking` (boolean, optional) — When true, only return homes with parking available. - `pool` (boolean, optional) — When true, only return homes with a pool. - `gym` (boolean, optional) — When true, only return homes with a fitness center. - `in_unit_laundry` (boolean, optional) — When true, only return homes with in-unit washer/dryer. - `air_conditioned` (boolean, optional) — When true, only return air-conditioned homes. - `balcony` (boolean, optional) — When true, only return homes with a balcony. - `elevator` (boolean, optional) — When true, only return homes in a building with an elevator. - `first_floor_unit` (boolean, optional) — When true, only return ground-floor homes. - `self_check_in` (boolean, optional) — When true, only return homes with self check-in. - `deals_only` (boolean, optional) — When true, only return homes currently carrying an active special offer (a deal/discount). This is how you find deals — composable with every other filter. - `min_rating` (number, optional) — DEPRECATED — use guest_rating. Minimum average guest rating (1-5) for the home's building. Homes with no rating yet are excluded when this is set. - `guest_rating` (string, optional) — Minimum guest-rating bucket for the home's building: EXCELLENT (>= 4.5), VERY_GOOD (>= 4.0), GOOD (>= 3.5). Homes with no rating yet are excluded. Only the aggregate guest rating is available through this API; individual reviews are on hellolanding.com. - `near_latitude` (number, optional) — Latitude of a specific point of interest. LAST RESORT — use ONLY when the location is a precise spot that ISN'T a display city or market (a specific building, employer, hospital, campus, or street address). For a normal place ("in Birmingham", "Alexandria", "downtown Austin"), pass the display-city/market slug as `market` instead — do NOT use coordinates. When you do use it: geocode the spot yourself, pass near_longitude + near_radius_miles, ALSO set `market` to the city/market it sits in, and pass near_label with the spot's name so results can be labeled. - `near_longitude` (number, optional) — Longitude of a point of interest. Use with near_latitude and near_radius_miles. - `near_radius_miles` (number, optional) — Search radius in miles around near_latitude/near_longitude. Defaults to 5 miles when near_latitude and near_longitude are provided. - `near_label` (string, optional) — Human-readable name of the point of interest the search is centered on (e.g. "University of Birmingham Hospital", "UAB", "downtown Birmingham"). Pass it alongside near_latitude/near_longitude so the results can be labeled "within N miles of {near_label}". Purely a display label — it never affects filtering (only the lat/lng + radius do). - `sort_by` (string, optional) — Sort order: price_asc, price_desc, availability (earliest move-in first), newest, rating_desc (highest-rated building first; unrated homes sort last). - `page` (integer, optional) — 1-indexed page number. - `per_page` (integer, optional) — Page size (capped at 100). The inline widget paginates the returned results client-side, so a larger page just means more to browse in one call. (search_apartments_on_map ignores this and returns every matching property as a pin.) - `include_hero_images` (boolean, optional) — Also return the hero photo for the first 5 results as embedded MCP image content, not just a URL. On by default so guests see photos. Pass false to omit (smaller, URL-only payload). **Call it** - MCP: call `search_apartments_tool` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: `/api/public/search` (REST param → tool argument: `check_in`→`start_date`, `check_out`→`end_date`, `bedrooms`→`min_bedrooms`) - Example: http://core-prod-web.default.svc.cluster.local:3000/api/public/search?market=birmingham **Example response (abridged)** ```json { "market": { "slug": "birmingham" }, "total_count": 12, "homes": [ { "slug": "apartment-in-birmingham-example" } ] } ``` ## get_apartment_tool Fetch a single Landing home by its slug — property details, amenities, photos, **flex pricing**, **the full availability calendar**, and a pre-filled `reservation_link` so the agent doesn't have to probe dates or assemble booking URLs by hand (get_apartment already returns the full calendar). Use this after `search_apartments` returns a slug the user is interested in. **Pricing.** The price is reported only as an all-in figure (includes all fees except taxes) — no bare per-unit rate is exposed: - `display_price_with_discount` + `display_price_label` → the price with its label, e.g. `318` + `" for 2 nights"` = $318 for 2 nights, or `2100` + `" per month"` = $2,100/mo. `display_price_without_discount` is the same figure before any discount. Always pair `display_price_label` with them. - `is_price_monthly` / `is_price_nightly` (and `duration_label`, "/mo" or "/night") only tell you whether the stay is priced per month or per night. `price_note` explains what's included. Call `get_quote` for the full checkout breakdown, including taxes. **Availability.** The response includes an `availability` section with: - `bookable_windows` — contiguous open-for-occupancy periods, each with `start_date`, `end_date` (nullable for open-ended), `nights`, `can_move_in_at_start`, `can_move_out_at_end`, `minimum_nightly_stay` and `fits_minimum_stay`. `minimum_nightly_stay` is the EFFECTIVE minimum for that window — the home's floor, or a stricter minimum if any date inside the window carries one — and is always present, so a window with `fits_minimum_stay: false` can host no stay at all. (`availability_overview` abbreviates the same value as `ms` and only emits it when it's stricter than the home floor.) This is what most agents want — pick a window, then optionally confirm specific dates from the `ranges` below. - `ranges` — raw booking-range segments (same shape the PDP calendar consumes) with `move_in_allowed`, `move_out_allowed`, `open_for_occupancy`, and `unbookable_reason`. Use these when you need to know *why* a window is blocked. - `earliest_available_date` — first date the home accepts a new reservation. - `minimum_nightly_stay_by_date` — only present when the minimum varies across dates. **Reservation link.** Pass `start_date`, `end_date`, and (for flex) `committed_nights` to bake those into `reservation_link` — the agent can share that URL with the user to land them on the PDP pre-filled with the booking intent. The calendar is also clipped to the start/end window. **Property.** The `property` object describes the building the home is in (shared across all units at that address): `name`, `address`, `amenities`, `member_rating` (guest post-stay survey `average` + `count` — omitted when the property has no ratings yet; this aggregate is the ONLY guest-rating data exposed through this API, individual reviews are on hellolanding.com), and `walk_score`/`walk_score_description`/ `transit_score`/`transit_score_description`/`bike_score`/ `bike_score_description` (omitted when not yet computed for this property). **Photos.** `photos` combines the home's own unit-specific photos with the property's building-level photos (exterior, common areas, amenities) — same precedence the OTA listing feeds use: unit photos first, then building photos. Each entry has a `source` (`"unit"` or `"building"`). The first entry has `hero: true`. These are URLs — most chat clients won't render an externally-hosted image URL embedded in a reply. Pass `include_hero_image: true` to also get the hero photo as embedded MCP image content (resized, so this is opt-in) that a compliant client can display inline without following a link. `media` is the same first 6 photos as `photos`, reshaped for the inline visual widget's carousel: each entry adds a `widget_url` (resized) and `position`, and `type` is reserved for a future non-photo asset (currently always `"photo"`). `photos` remains the full, uncapped list — prefer `media` only if you're rendering the widget-style carousel yourself. **Parameters** - `slug` (string, required) — Home slug (e.g. "apartment-in-birmingham-landing-midtown-200-5"). - `start_date` (string, optional) — Move-in date (YYYY-MM-DD). Used to populate the reservation_link and to clip the availability calendar. - `end_date` (string, optional) — Move-out date (YYYY-MM-DD) for a fixed stay, or the literal string "indefinite" for flex. - `committed_nights` (integer, optional) — Only meaningful with end_date="indefinite". Picks the flex commitment tier baked into reservation_link. - `include_hero_image` (boolean, optional) — When true, also return the hero photo as embedded MCP image content (resized) instead of only a URL. Default false. **Call it** - MCP: call `get_apartment_tool` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: `/api/public/homes/{slug}` - Example: http://core-prod-web.default.svc.cluster.local:3000/api/public/homes/apartment-in-birmingham-example **Example response (abridged)** ```json { "slug": "apartment-in-birmingham-example", "bedrooms": 1, "photos": [] } ``` ## get_flex_options_tool Return the flex (open-ended) commitment tiers a given home accepts, so the agent doesn't suggest a `committed_nights` value the home will reject. Two things gate flex on a home: - `eligible_for_flexible_stays` — set to false on homes that opt out of flex entirely. When false, `available_tiers` is empty. - `minimum_nightly_stay` — a tier is only valid when its night count is ≥ the home's minimum nightly stay. Higher minimums drop the shorter tiers. Use this before quoting a Landing Flex stay (`end_date: "indefinite"`). Comparing this home's fixed-stay price against its flex tiers? Call get_quote once per tier (`end_date: "indefinite"` + `committed_nights`). **Parameters** - `home_slug` (string, required) — Home slug to inspect. **Call it** - MCP: call `get_flex_options_tool` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: `/api/public/homes/{slug}/flex-options` (REST param → tool argument: `slug`→`home_slug`) - Example: http://core-prod-web.default.svc.cluster.local:3000/api/public/homes/apartment-in-birmingham-example/flex-options **Example response (abridged)** ```json { "home_slug": "apartment-in-birmingham-example", "available_tiers": [ { "committed_nights": 180 } ] } ``` ## get_quote_tool Real, date-specific anonymous quote for a home. Mirrors what an unauthenticated visitor sees in checkout: monthly rent after seasonal adjustments and length-of-stay discounts, the first-month charge, ongoing monthly cost, and an estimated total. For flex (open-ended) stays, pass `end_date: "indefinite"` plus a `committed_nights` value. Not every home accepts every tier — call `get_flex_options` first. Pass `cats`/`dogs` if the guest has pets — pet fee/rent is priced for real (same pet pricing engine as signed-in checkout) and folded into `charge_schedule`. Omit them (or pass 0) and the quote assumes no pets. `pet_policy` in the response says whether this property actually allows cats/dogs, so you can warn the guest before they commit to a home that won't take their pet. Other member-only adjustments — promo codes, account credit, membership pricing, parking selections — are still not applied. For those, the guest must sign in and use the website checkout. Returns: - `display_price_with_discount` + `display_price_label` — **the all-in price to quote, and the only price field here.** Exactly what `search_apartments`, `get_apartment` and `compare_apartments` return, from the same presenter, so the same home reads identically through any of them. `price_note` states the coverage: all fees except taxes. `is_price_monthly` / `is_price_nightly` and `duration_label` say which unit applies. **No bare monthly rent or nightly rate is returned**, deliberately — a rent figure quoted as the price understates what the guest pays. The rent component is visible as the `monthly_rent` LINE ITEM inside `charge_schedule`, next to the fees. - `term_duration_label` — e.g. "5 months", "30 nights". - `charge_schedule` — the full billing breakdown, and the only place per-charge detail lives: `charge_schedule.checkout.total` is what charges at booking, `.monthly.total` the first recurring statement, `.final_month.total` the prorated last one, and `.total_cost` the whole stay. There are no top-level `checkout_total` / `monthly_total` / `total_cost_estimate` keys. - `monthly_total` — recurring monthly charge after the first month. - `total_discount` — sum of seasonal + length-of-stay discounts applied. - **Why `display_price_with_discount` and `charge_schedule` can differ.** The display price amortizes the one-time move-out cleaning fee across the stay and rounds to whole dollars; `charge_schedule` itemizes that fee in full (in `final_month` on a fixed-date stay) and reports cents. Both are correct — the first is "what a month costs on average", the second is "what each statement charges". Quote the display price; show `charge_schedule` when the guest asks how it breaks down. - `flex_move_out_cleaning_fee` — present only on open-ended (flex) stays; carries the fee `amount`. A flex quote has no set move-out date, so the charge schedule has no `final_month` and the one-time cleaning fee isn't itemized in the schedule here — it's charged at move-out. It's already baked into the all-in "per month" price (includes all fees except taxes) from search_apartments / get_apartment, which spreads that one-time fee across the committed term (e.g. 6 or 12 months) — which is why that display price can read a little higher than this quote's monthly rate. On a fixed-date stay the fee is instead itemized in `charge_schedule.final_month` and counted in `charge_schedule.total_cost`. - `currency` — always "USD". - `available` — false when the home is not bookable for these dates. `unbookable_reason` is the same structured, calendar-range reason get_apartment's availability section returns (e.g. reserved, availability block) — present when the block is date-specific. `unavailable_reason` is a free-text sentence covering ALL blocks, including non-calendar ones (e.g. the home's `available_from` cutoff); it's always present when `available` is false, so treat it as the reliable fallback and `unbookable_reason` as an optional, more structured detail. Comparing a home's fixed-stay quote against its flex tiers? Call get_quote once per tier (`end_date: "indefinite"` + `committed_nights`), or read `flex_options` from search_apartments / get_apartment. `media` is up to 6 photos for this home (hero first), each with `url` (full-resolution), `widget_url` (resized), `type`, `source` (`"unit"`/`"property"`), and `position`. `widget_hero_image_url` is an alias of `media[0].widget_url` — kept for callers that only need one photo. The inline visual widget renders `media` as a swipeable carousel. **The Landing Guarantee.** Every stay is backed by the Landing Guarantee. **Parameters** - `home_slug` (string, required) — Home slug to quote. - `start_date` (string, required) — Move-in date (YYYY-MM-DD). - `end_date` (string, required) — Move-out date (YYYY-MM-DD) for a fixed stay, or the literal string "indefinite" for flex. - `committed_nights` (integer, optional) — Required when end_date="indefinite". This enum is the full set across all homes, not a per-home one — call get_flex_options for what THIS home offers. An unoffered tier is rejected rather than priced, because the tier determines the discount. - `cats` (integer, optional) — Number of cats, if any. Priced into charge_schedule; omit or pass 0 for no cats. - `dogs` (integer, optional) — Number of dogs, if any. Priced into charge_schedule; omit or pass 0 for no dogs. **Call it** - MCP: call `get_quote_tool` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: `/api/public/homes/{slug}/quote` (REST param → tool argument: `slug`→`home_slug`, `check_in`→`start_date`, `check_out`→`end_date`) - Example: http://core-prod-web.default.svc.cluster.local:3000/api/public/homes/apartment-in-birmingham-example/quote?check_in=2026-09-01&check_out=2026-12-01 **Example response (abridged)** ```json { "home_slug": "apartment-in-birmingham-example", "charge_schedule": { "total_cost": 6300.0 } } ``` ## booking_intent_tool Save the guest's interest in a home so Landing can follow up, then return a direct checkout link for them to complete the booking. Call this once the guest has confirmed which home and dates they want — ideally after get_quote shows them a price they like. Calling it more than once for the same email is safe; it won't create duplicates. The guest must create a Landing account and add a payment method to finalise the reservation — that all happens on hellolanding.com via the checkout_url this tool returns. Returns: - `checkout_url` — direct link to payment; share this with the guest. - `intent_id` — a reference number the guest can give to Landing support if they need help. - `email` — always echoed back for confirmation. - `phone` / `name` — echoed back ONLY when this call actually saved them: omitted (with a `warning`) if the phone you sent didn't look valid, and ALSO omitted, silently, with no warning, if this email already has a record from within the last 30 days — repeat calls never overwrite an existing guest's contact details, on purpose. Don't tell the guest their phone "wasn't valid" just because this response omitted it; it may simply mean Landing already has them on file from an earlier call. - `home_slug` / `start_date` / `end_date` — echoed when provided. - `warning` — present only when a value you sent was rejected as invalid and dropped (currently: an unparseable `phone`). The booking intent itself still succeeds; tell the guest what was dropped so they can re-share it another way if it matters. Never present for the silent 30-day-repeat case above. **Parameters** - `email` (string, required) — Guest email address. Used for deduplication and follow-up. - `phone` (string, optional) — Guest phone number (optional). E.164 format preferred. - `name` (string, optional) — Guest full name (optional). - `home_slug` (string, optional) — Slug of the home the guest intends to book (optional but recommended). - `start_date` (string, optional) — Requested move-in date (YYYY-MM-DD). - `end_date` (string, optional) — Requested move-out date (YYYY-MM-DD) for a fixed stay, or "indefinite" for Landing Flex. - `committed_nights` (integer, optional) — Landing Flex commitment tier — required when end_date="indefinite". This enum is the full set across all homes, not a per-home one — call get_flex_options for what THIS home offers; an unoffered tier is rejected rather than baked into the checkout link. **Call it** - MCP: call `booking_intent_tool` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: none — this tool writes, so it is MCP-only. ## get_market_info Market context for a Landing market: average monthly rent by bedroom count, total published inventory, and the neighborhoods with the most availability — useful for cross-market comparisons ("is Austin or Dallas cheaper for a 1BR?") without paging through search_apartments. `market` takes EITHER a display-city slug or a market slug from list_markets, same as search_apartments/search_properties — a city slug (e.g. "alexandria-va") resolves to its containing market (Washington DC), same stats either way. Rents are unweighted averages of each home's base monthly rate (before seasonal/length-of-stay discounts) across currently published homes. Pass `home_slug` as well to ALSO get that home's neighborhood context under `home` — description, market/city, and the walk/transit/bike score shown on hellolanding.com. Called with only `market`, returns market stats alone. Does not estimate commute time to a specific address; only the neighborhood's general walkability/transit score is available. **Parameters** - `market` (string, required) — A display-CITY slug or a market slug. Use list_markets to discover slugs. - `home_slug` (string, optional) — Optional. When given, the response also includes this home's neighborhood context (description, walk/transit/bike score). **Call it** - MCP: call `get_market_info` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: `/api/public/market-info` (REST param → tool argument: `home`→`home_slug`) - Example: http://core-prod-web.default.svc.cluster.local:3000/api/public/market-info?market=birmingham **Example response (abridged)** ```json { "market": { "slug": "birmingham" }, "inventory_count": 42, "average_rent_by_bedroom": [], "popular_neighborhoods": [] } ``` ## get_policies_faq_tool Grounded, conservative answers to the most common Landing policy questions (deposits, pets, parking, cancellation, qualification, Landing Flex, utilities, move-in). Use this instead of guessing at policy specifics — where an exact number (deposit amount, cancellation window) depends on the home/market/reservation, the answer says so explicitly and points to get_quote, checkout, or Landing support rather than inventing a figure. Pass no `topic` to get all entries, or one of: security_deposit, pets, parking, cancellation_policy, qualification_requirements, landing_flex, utilities_and_furnishing, move_in_process. **Parameters** - `topic` (string, optional) — Optional — return only this topic's entry. Omit to get all entries. **Call it** - MCP: call `get_policies_faq_tool` on `POST http://core-prod-web.default.svc.cluster.local:3000/mcp/public` - GET: `/api/public/policies-faq` (REST param → tool argument: `q`→`topic`) - Example: http://core-prod-web.default.svc.cluster.local:3000/api/public/policies-faq **Example response (abridged)** ```json { "entries": [ { "topic": "pets", "answer": "Pet policies are set per home." } ] } ``` --- ## Full Policies & FAQ ### Is there a security deposit? Deposit requirements vary by home and market and are shown before checkout, along with any deposit alternatives Landing offers. Confirm the exact amount for a specific home via get_quote or at checkout on hellolanding.com. ### Can I bring a pet? Pet policies are set per home — use the `pets` filter on search_apartments to find pet-friendly homes (or `cats`/`dogs` for a specific species). Pass the number of cats/dogs to get_quote and pet rent/fees are priced into the quote for real, using the same pricing engine as signed-in checkout; the quote's `pet_policy` also says whether that home takes cats or dogs at all. ### Is parking included? Parking availability varies by home — use the `parking` filter on search_apartments. Where parking is a paid add-on, it's a member-only selection applied at checkout, not part of the anonymous quote. ### What's the cancellation policy? Cancellation terms depend on the specific reservation and stay length. The authoritative terms are shown during checkout on hellolanding.com before the guest confirms payment — Landing does not finalize a booking without the guest seeing and accepting those terms first. ### What do I need to qualify for a Landing home? Qualification (identity/income verification, etc.) happens after the guest creates a Landing account and starts checkout — this MCP server only handles anonymous search and quoting, not qualification. Send the guest to the home's checkout_url (from get_quote or booking_intent) to start that process. ### How does Landing Flex work? Landing Flex is Landing's open-ended stay option: instead of a fixed move-out date the guest commits to a minimum stay — tiers run from 1 month to 12+ months, and the longer the commitment the lower the monthly rate — and can transfer that same rate to any other eligible home across Landing's markets. Call get_flex_options on a specific home to see which commitment tiers it supports. ### Are utilities and furniture included? Every Landing home is furnished. Utilities and Wi-Fi inclusion varies by home — check the home's amenities via get_apartment, or confirm directly with Landing support for a specific address. ### How does move-in work? Move-in details (self-check-in, key pickup, etc.) are specific to each home and are shared with the guest after booking. This MCP server doesn't have access to a home's move-in instructions before a reservation exists.