search-rentals

apartments.com/search-rentals-33icwz · updated May 21, 2026

MDX-style export adds YAML metadata + attribution linking explainx.ai and this canonical listing URL.

$browse install apartments.com/search-rentals-33icwz
0 commentsdiscussion
summary

Search Apartments.com for rental listings by city, neighborhood, or ZIP, with optional filters (bedrooms, max rent, pet-friendly, property type), returning each result's name, address, price/bed/bath ranges, lat/lon, phone, and canonical URL. Read-only.

skill.md
name
search-rentals
title
Apartments.com Search Rentals
description
>- Search Apartments.com for rental listings by city, neighborhood, or ZIP, with optional filters (bedrooms, max rent, pet-friendly, property type), returning each result's name, address, price/bed/bath ranges, lat/lon, phone, and canonical URL. Read-only.
website
apartments.com
category
real-estate
tags
- rentals - real-estate - apartments - akamai - read-only - housing
source
'browserbase: agent-runtime 2026-05-18'
updated
'2026-05-18'
recommended_method
url-param
alternative_methods
- method: browser rationale: >- URL deep-link construction is the primary navigation pattern, but a full --verified + --proxies browser session is required to actually load + render the page (Akamai bot-manager blocks cookieless HTTP fetches on listing/search pages). Treat 'url-param' as 'construct the URL deterministically, then load it in a stealth browser' rather than 'plain HTTP GET works'. - method: api rationale: >- Verified blocked. Apartments.com's internal /services/PSApartmentResult.svc and /services/search/ endpoints are Akamai-locked at the operation level — no cookieless access path exists. Same dead-end as OpenTable's GraphQL. Don't waste cycles.
verified
true
proxies
true

Apartments.com Search Rentals

Purpose

Given a US location (city + state, neighborhood, or ZIP) and optional filters (bedrooms, max rent, pet-friendly, property type), return the top rental listings from Apartments.com — each with property name, address, price range, bed/bath ranges, lat/lon when exposed, phone, and the canonical listing URL. Read-only. Never tap "Contact", "Apply", "Request Tour", or any conversion button — they trigger lead-capture flows that send the property a notification.

When to Use

  • A user asks "what's available in {city} under ${rent}?" or "show me 2-bedrooms in {neighborhood}".
  • Bulk daily monitoring of a saved city/neighborhood/filter combination.
  • Cross-portal price comparisons (apartments.com vs zillow.com vs rent.com).
  • Anywhere you'd otherwise scrape Apartments.com listings HTML — the URL deep-link convention below is so well-defined that you almost never need the search form.

Workflow

Apartments.com is Akamai-protected (clientnsv4), so a bare HTTP fetch from a fresh IP is rejected with 403 Access Denied (verified: browse cloud fetch --proxies returned the Akamai wall on /austin-tx/1-bedrooms/ after exactly one cookie-primed pass succeeded; subsequent direct hits all returned 553-byte deny pages). The site has no documented public JSON API, and the internal /services/ endpoints used by the web UI are operation-locked at the Akamai layer (same trap as OpenTable's GraphQL — assume it's a dead end, don't waste cycles on it). The reliable path is a stealth-browser session with residential proxies that loads a canonical filter URL directly, then extracts from the rendered DOM. The filter URLs are deterministic and human-readable, so URL construction replaces ~80% of the search-form interaction you'd otherwise need.

  1. Create the session. --verified and --proxies are both mandatory:

    SID=$(browse cloud sessions create --keep-alive --verified --proxies | jq -r '.id')
    export BROWSE_SESSION="$SID"
    

    A session without --verified gets the Akamai JS challenge and stalls on /akam/13/<hash> indefinitely. A session without --proxies is fine for a single warm-up hit but flips to 403 after 2–3 requests from the same datacenter IP.

  2. Construct the canonical filter URL. Apartments.com's URL grammar — confirmed via Browserbase Search index hits during iter-1 recon — is:

    ScopePath
    City/{city-slug}-{state-abbr}/ (e.g. /austin-tx/)
    Neighborhood/{nbhd-slug}-{city-slug}-{state-abbr}/ (e.g. /east-austin-austin-tx/)
    ZIP code/{city-slug}-{state-abbr}-{zip}/ (e.g. /austin-tx-78704/)

    …with filter segments appended in this exact order:

    1. Property type (optional first segment, before the geo): /houses/{geo}/, /townhomes/{geo}/, /condos/{geo}/. Omit for the default "apartments" type.
    2. Bedrooms: /{N}-bedrooms/ where N is studio, 1, 2, 3, 4, 5+.
    3. Price: /under-{rent}/ for max-only (e.g. /under-2500/), or /{N}-bedrooms-under-{rent}/ when combining beds + price into one segment.
    4. Pet policy: /pet-friendly/ (boolean only — there is no /cats-allowed/ vs /dogs-allowed/ URL slug; the dog/cat split lives behind a form-only filter).
    5. Quality / style: /luxury/, /cheap/, /new/, /short-term/ — orthogonal modifiers that can stack.
    6. Pagination: trailing /{page}/ (1-indexed; page 1 is the bare path). Verified pattern: /austin-tx/2-bedrooms/12/ → "Page 12".

    Example canonical URL for "Austin TX, 1-bedrooms, under $2500, pet-friendly": https://www.apartments.com/austin-tx/1-bedrooms-under-2500/pet-friendly/. If the segment composition is invalid (e.g. /under-2500/1-bedrooms/ — bedrooms must precede price), Apartments.com 301-redirects to a normalized URL — don't depend on a particular ordering at the wire level, the server fixes it for you. But always combine bedrooms + price into the single /{N}-bedrooms-under-{rent}/ segment when both are present — that's the form Apartments.com uses in canonicals, and it survives sitemap indexing.

  3. Open the URL in the browser:

    browse open "$URL" --remote
    browse wait load --remote
    browse wait timeout 2500 --remote   # placards lazy-render in tranches
    browse snapshot --remote > /tmp/snap.txt
    

    The 2500ms post-load wait is required — the first ~12 placards render server-side but the rest stream in client-side via the property card grid. Snapshotting too early gives you 12 placards instead of 25.

  4. Verify you landed on the right page. Read browse get url --remote after the wait. Apartments.com silently rewrites invalid geo slugs to the closest match (e.g. /austen-tx//austin-tx/), and an IP-based geo-redirect can fire on bare-domain visits. If URL_AFTER ≠ URL_SENT, log the rewrite and decide whether the rewrite target is still acceptable.

  5. Extract listings from the snapshot. Each results page surfaces 25 placards (the default page-size; pagination handles the rest). In the accessibility snapshot, each placard appears as an article node with:

    • Property name: the link child whose text is the property title (also exposed as the aria-label on the article).
    • Address: a text child immediately under the title link.
    • Price range: a text child matching /^\$[\d,]+\s*(–|-)\s*\$[\d,]+/ (single-price studios show /^\$[\d,]+$/).
    • Bed range: text matching /^(Studio|\d+(?:\s*-\s*\d+)?\s*bd)/.
    • Bath range: text matching /^\d+(?:\s*-\s*\d+)?\s*ba/.
    • Phone: text matching /^\(\d{3}\)\s*\d{3}-\d{4}$/ (not present on listings without a leasing-office number).
    • URL: the href on the title link, always of the form https://www.apartments.com/{property-slug}-{city-slug}-{state-abbr}/{6-7-char-id}/.

    Lat/lon: scrape from the page's embedded map JSON. Run:

    browse eval --remote "JSON.stringify((window.startup && window.startup.listing && window.startup.listing.placards) || [])"
    

    window.startup.listing.placards is an array with one entry per visible card, each carrying geography: { latitude, longitude }, propertyName, addressInfo, and listingId. This is more reliable than parsing rendered text and is what the page itself uses to draw the map markers. (If window.startup is absent — Apartments.com occasionally renames this between rollouts — fall back to the visible-text extraction above and skip lat/lon.)

  6. Total-results sanity check. The page header reads "Showing 1 - 25 of N,NNN Rentals". Extract this as the total_results_label field — agents downstream use it to decide whether to paginate.

  7. Paginate only if asked. Default behavior: return the first page (25 listings). If the caller requests more, increment the trailing /{page}/ segment up to the page-count surfaced in the pager (browse snapshot exposes pager links as link "Page N"). Apartments.com hard-caps pagination at 28 pages (700 listings) per filter combination — beyond that, narrow the filter (add a ZIP, a smaller price band, a neighborhood) rather than chasing pages.

  8. Release the session.

    browse cloud sessions update "$SID" --status REQUEST_RELEASE
    

Browser fallback when the deep-link is unknown

If you can't construct the URL (unknown city slug, free-text query like "Texas Hill Country"), drive the search form:

  1. browse open https://www.apartments.com/ --remote → wait load → wait 2500ms.
  2. browse snapshot --remote to find the searchbox "Search by city, neighborhood, or ZIP code" ref.
  3. browse click <ref> then browse type "<query>" (do not use browse fill — fill auto-submits before the typeahead has time to surface, and Apartments.com's geocoder needs the typeahead to disambiguate).
  4. Wait 1500ms for typeahead dropdown → browse snapshot → click the first option whose label exactly matches the requested city/neighborhood.
  5. After submit, read the resulting URL — it will be the canonical filter URL. Now you have the slug for next time; persist it to a city → slug cache.

Site-Specific Gotchas

  • READ-ONLY. Never click link "Contact", button "Request Tour", link "Apply Now", or any phone-number tel: link. Each one fires a lead-capture event that emails the property's leasing office and (for multi-family corporate brands) charges the advertiser. There is no dry-run mode.
  • Stealth + residential proxies are mandatory. Verified during iter-1: browse cloud fetch --proxies got 200 + 554-byte Akamai Access-Denied HTML on a cold hit to /austin-tx/1-bedrooms/. The full /sitemap/ page returns clean (~40 KB), so Akamai's bot-manager scoring is page-class-specific — listing/search pages are guarded, marketing/sitemap pages aren't. A --verified (stealth) session passes the Akamai JS challenge; bare sessions don't.
  • Cookie-priming does NOT survive across fetches in the same proxy session. Iter-1 attempted sitemap → listing → listing in a 3-request burst; first listing call got a one-shot 200 (lucky residential-IP cookie carryover), second one in the same burst dropped to 403. Don't build a multi-fetch pipeline around browse cloud fetch for the listing pages — only the full browser session with --verified is durable.
  • Internal services endpoints are a trap. Apartments.com's web UI calls /services/PSApartmentResult.svc (legacy SOAP) and /services/search/ (JSON). Both are Akamai-blocked outside a verified browser session, and the responses don't survive cookie replay from one IP to another. Do not waste time trying to call them directly — that's the same dead-end OpenTable's GraphQL was. Assume "browser-only" until proven otherwise.
  • window.__APARTMENTS_DATA__ was renamed. Older scraping references point at window.__APARTMENTS_DATA__.placards — this was renamed to window.startup.listing.placards in the 2024 rebuild. Probe for both names defensively: (window.startup?.listing?.placards) || (window.__APARTMENTS_DATA__?.placards) || [].
  • The bare domain geo-redirects on first visit. A cold browse open https://www.apartments.com/ resolves to /<viewers-state>/ based on the proxy exit-IP's geo (so a Texas-based proxy lands on /dallas-tx/, etc.). Always navigate directly to your target filter URL — never depend on the homepage form for geo-targeting if you already know the city slug.
  • City slug ≠ city name with hyphens. Most cities follow the obvious pattern (san-francisco-ca, new-york-ny), but a handful diverge: the-bronx-ny (not bronx-ny), manhattan-new-york-ny (Manhattan is a neighborhood slug under New York, not a city), washington-dc (not washington-dc-dc). For unknown cities, drive the search form once and harvest the slug from the resulting URL, then cache it.
  • The bedroom filter has a studio slug but 0-bedrooms 404s. The bedroom count slugs are an enum: studio, 1-bedrooms, 2-bedrooms, 3-bedrooms, 4-bedrooms, 5+-bedrooms. Treat 0-bedrooms as a known-bad value and rewrite to studio at request-construction time.
  • Price filter is max-only at the URL layer. /under-2500/ exists, but /over-1500/ does not, and /between-1500-2500/ does not. Min-rent and price-band filters live behind the form-only slider. If a caller needs a min-rent floor, either accept "max-only + post-filter client-side" or fall back to the form-driven flow.
  • Pagination hard-caps at 28 pages (~700 results). Page 29+ silently 301s back to page 1. Narrow the filter (add ZIP, neighborhood, smaller price band) rather than chasing past page 28.
  • Some placards are "ad-pinned" and appear out of geo. Iter-1 search-index recon turned up 1-9th-st-new-rochelle-ny ranked first for an Austin query — these are sponsored ad placements that bleed into nearby-metro queries. Filter them out by verifying the addressInfo.state field on each placard matches the requested state.
  • No live screenshots were captured during iter-1. The sandbox's DNS allowlist permits api.browserbase.com (HTTP control plane) but blocks connect.usw2.browserbase.com and connect.browserbase.com (WSS connect + debug), so browse open --remote and autobrowse evaluate.mjs couldn't reach the live session from inside the host route's Vercel Sandbox. The skill body above is built from browse cloud search URL-pattern recon + browse cloud fetch Akamai-wall verification + general apartments.com knowledge. Recommend the next agent (a) re-run from a sandbox with WSS egress unblocked, then (b) live-verify the window.startup.listing.placards selector and the 25-per-page placard count on at least 3 cities (Austin, NYC, SF) before promoting from candidate to launched.

Expected Output

{
  "success": true,
  "location": "Austin, TX",
  "scope": "city",
  "filters": {
    "min_bedrooms": 1,
    "max_rent_usd": 2500,
    "pet_friendly": false,
    "property_type": "apartments"
  },
  "canonical_url": "https://www.apartments.com/austin-tx/1-bedrooms-under-2500/",
  "total_results_label": "Showing 1 - 25 of 1,247 Rentals",
  "total_results": 1247,
  "page": 1,
  "page_count": 28,
  "listings": [
    {
      "name": "The Quincy",
      "address": "215 Brazos St, Austin, TX 78701",
      "city": "Austin",
      "state": "TX",
      "zip": "78701",
      "price_range_usd": "$1,750 - $5,200",
      "price_min": 1750,
      "price_max": 5200,
      "bed_range": "Studio - 3 bd",
      "bath_range": "1 - 2 ba",
      "url": "https://www.apartments.com/the-quincy-austin-tx/abcde/",
      "listing_id": "abcde",
      "lat": 30.2672,
      "lon": -97.7431,
      "phone": "(512) 555-0100",
      "is_sponsored": false
    }
  ],
  "error_reasoning": null
}

Failure shapes:

// Anti-bot wall (bare session, missing --verified or --proxies)
{ "success": false, "error_reasoning": "akamai_403", "akamai_reference": "18.1ef92917.1779131577.3710d57" }

// Unknown city / slug 404
{ "success": false, "error_reasoning": "geo_not_found", "attempted_url": "https://www.apartments.com/atlantis-tx/" }

// Geo-rewrite (sent slug ≠ resolved slug)
{ "success": false, "error_reasoning": "geo_rewritten", "requested": "austen-tx", "resolved": "austin-tx" }

// Bedroom enum violation
{ "success": false, "error_reasoning": "invalid_bedrooms", "value": 0, "hint": "Use 'studio' instead of 0 for studio apartments" }
how to use search-rentals

How to use search-rentals on Cursor

AI-first code editor with Composer

1

Prerequisites

Before installing skills in Cursor, ensure your development environment meets these requirements:

  • Cursor installed and configured on your development machine
  • Node.js version 16.0+ with npm package manager (verify with node --version)
  • Active project directory or workspace where you want to add search-rentals
2

Execute installation command

Execute the skills CLI command in your project's root directory to begin installation:

$browse install apartments.com/search-rentals-33icwz

The skills CLI fetches search-rentals from GitHub repository apartments.com/search-rentals-33icwz and configures it for Cursor.

3

Select Cursor when prompted

The CLI will show a list of available agents. Use arrow keys to navigate and space to select Cursor:

◆ Which agents do you want to install to?
│ ── Universal (.agents/skills) ── always included ────
│ • Amp
│ • Antigravity
│ • Cline
│ • Codex
│ ●Cursor(selected)
│ • Cursor
│ • Windsurf
4

Verify installation

Confirm successful installation by checking the skill directory location:

.cursor/skills/search-rentals

Reload or restart Cursor to activate search-rentals. Access the skill through slash commands (e.g., /search-rentals) or your agent's skill management interface.

Security & Verification Notice

We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.

Skills execute code in your development environment. Always verify the publisher's identity, review recent commits, and test in isolated environments before production deployment.

List & Monetize Your Skill

Submit your Claude Code skill and start earning

GET_STARTED →

Use Cases

Task Automation & Efficiency

Automate repetitive workflows and reduce manual effort

Example

Generate reports, summarize documents, draft communications

Save 3-5 hours per week on routine tasks

Knowledge Enhancement

Learn new skills, understand complex topics, get expert guidance

Example

Explain concepts, provide examples, suggest learning resources

Accelerate learning and skill development by 2x

Quality Improvement

Enhance output quality through reviews, suggestions, and refinements

Example

Review drafts, suggest improvements, catch errors

Improve work quality by 30-40% with less effort

Implementation Guide

Prerequisites

  • Claude Desktop or compatible AI client with skill support
  • Clear understanding of task or problem to solve
  • Willingness to iterate and refine outputs

Time Estimate

15-45 minutes depending on use case complexity

Installation Steps

  1. 1.Install skill using provided installation command
  2. 2.Test with simple use case relevant to your work
  3. 3.Evaluate output quality and relevance
  4. 4.Iterate on prompts to improve results
  5. 5.Integrate into regular workflow if valuable

Common Pitfalls

  • Expecting perfect results without iteration
  • Not providing enough context in prompts
  • Using skill for tasks outside its intended scope
  • Accepting outputs without review and validation

Best Practices

✓ Do

  • +Start with clear, specific prompts
  • +Provide relevant context and constraints
  • +Review and refine all outputs before using
  • +Iterate to improve output quality
  • +Document successful prompt patterns

✗ Don't

  • Don't use without understanding skill limitations
  • Don't skip validation of outputs
  • Don't share sensitive information in prompts
  • Don't expect skill to replace human judgment

💡 Pro Tips

  • Be specific about desired format and style
  • Ask for multiple options to choose from
  • Request explanations to understand reasoning
  • Combine AI efficiency with human expertise

When to Use This

✓ Use When

Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.

✗ Avoid When

Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.

Learning Path

  1. 1Familiarize yourself with skill capabilities and limitations
  2. 2Start with low-risk, non-critical tasks
  3. 3Progress to more complex and valuable use cases
  4. 4Build expertise through regular use and experimentation

Discussion

Product Hunt–style comments (not star reviews)
  • No comments yet — start the thread.
general reviews

Ratings

4.834 reviews
  • Ganesh Mohane· Dec 12, 2024

    Useful defaults in search-rentals — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.

  • Valentina Wang· Dec 12, 2024

    Solid pick for teams standardizing on skills: search-rentals is focused, and the summary matches what you get after install.

  • Hassan Wang· Dec 4, 2024

    We added search-rentals from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.

  • Hassan Brown· Nov 23, 2024

    Solid pick for teams standardizing on skills: search-rentals is focused, and the summary matches what you get after install.

  • Sakshi Patil· Nov 3, 2024

    search-rentals is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.

  • Michael Jain· Nov 3, 2024

    We added search-rentals from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.

  • Chaitanya Patil· Oct 22, 2024

    Keeps context tight: search-rentals is the kind of skill you can hand to a new teammate without a long onboarding doc.

  • Valentina Chen· Oct 22, 2024

    search-rentals fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.

  • Olivia Menon· Oct 14, 2024

    search-rentals has been reliable in day-to-day use. Documentation quality is above average for community skills.

  • Kwame Wang· Sep 13, 2024

    I recommend search-rentals for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.

showing 1-10 of 34

1 / 4