# How to Integrate Bolt.new with Realtor.com / Real Estate Listings

- Tool: Bolt.new
- Difficulty: Intermediate
- Time required: 25 minutes
- Last updated: April 2026

## TL;DR

Realtor.com has no official public API, but you can access residential property listings through RapidAPI's unofficial Realtor.com endpoint or use SimplyRETS/RESO Web API for MLS-sourced data. RapidAPI access is immediate with a free tier. Full MLS data requires RESO certification. Build your property search UI in Bolt using an API route to keep your RapidAPI key server-side.

## Real Estate Listings in Bolt.new: RapidAPI and MLS Data Options

Realtor.com has no official public API. The site licenses MLS data under agreements that restrict redistribution, so there's no developer portal or API documentation. For Bolt.new developers, two practical paths exist: RapidAPI's unofficial Realtor.com endpoint for quick prototyping (free tier, immediate access, unofficial) or certified MLS data providers like SimplyRETS for production apps (licensed data, proper API, subscription required).

This tutorial covers both options. Start with RapidAPI to build and test your property search UI quickly. Evaluate the SimplyRETS path if your app needs reliable, officially licensed listing data.

All real estate API calls must go through Next.js API routes — the APIs don't include browser CORS headers, and keeping your API key server-side protects your usage quota.

## Before you start

- A Bolt.new account with a Next.js project created
- A RapidAPI account at rapidapi.com (free registration required)
- Subscription to the 'Realty in US' API on RapidAPI (free basic tier available, paid tiers for higher request limits)
- Your RapidAPI key from the RapidAPI dashboard
- Understanding that this uses an unofficial API — data availability and structure may change

## Step-by-step guide

### 1. Subscribe to the Realtor.com API on RapidAPI

Go to rapidapi.com and create a free account if you don't have one. In the search bar, search for 'Realty in US' — the result by APIdojo is the most widely used Realtor.com data API on RapidAPI. Click through to the API listing and click 'Subscribe to Test'.

The free Basic plan provides 500 requests per month at no cost — enough for development and light production use. The Pro plan ($10/month) provides 10,000 requests. Subscribe to the Basic plan to start.

After subscribing, navigate to the 'Endpoints' tab. You'll see the available endpoints: /buy/list-for-sale (property search for sale listings), /for-sale/detail (full listing details by property_id), /buy/list-for-rent (rental listings), and /finance/estimate-payment (mortgage calculator). Click any endpoint and look for the 'Code Snippets' panel on the right side — this shows your RapidAPI key embedded in example code. Copy your RapidAPI key (the X-RapidAPI-Key header value).

Also note the host header value: 'realty-in-us.p.rapidapi.com'. Both the key and host are required for authentication.

**Expected result:** You have a RapidAPI account subscribed to the 'Realty in US' API and have copied your RapidAPI key and noted the host header value.

### 2. Configure Environment Variables and Create the Listings API Route

Add your RapidAPI credentials to your Bolt.new project's .env file. Both the API key and the host are server-side only values — never use NEXT_PUBLIC_ prefix on either. If your key were exposed in client-side code, anyone could scrape it and consume your API quota.

Create a Next.js API route that accepts search parameters from your frontend, calls the RapidAPI endpoint, normalizes the response, and returns clean listing data. The normalization layer is important: RapidAPI's Realtor.com response has a complex nested structure — extract only what your UI needs to keep the response lightweight.

The RapidAPI endpoint accepts: city (e.g., 'New York City'), state_code (e.g., 'NY'), offset and limit for pagination, sort (price-desc, price-asc, newest, etc.), price_min, price_max, beds_min, baths_min, prop_type (single_family, condo, townhouse, land, multi_family).

```
# .env file additions
# RapidAPI credentials — server-side only, never NEXT_PUBLIC_
RAPIDAPI_KEY=your_rapidapi_key_here
RAPIDAPI_HOST=realty-in-us.p.rapidapi.com
```

**Expected result:** Environment variables are configured. The /api/listings route is created and TypeScript compiles without errors.

### 3. Build the API Route with RapidAPI Integration

The RapidAPI call follows a specific pattern: your API route sends a GET request to the RapidAPI endpoint URL with three required headers: X-RapidAPI-Key (your key), X-RapidAPI-Host (the specific API's host), and optionally Accept: application/json.

The Realtor.com endpoint returns listings in a nested structure: response → properties → []. Each property has location (address, coordinates), list_price, description (beds, baths, sqft, property_type), photos (array of href URLs), and property_id. Some fields may be null if the listing doesn't include that data — always use optional chaining.

Map query parameters from your route to the RapidAPI URL parameters. The city parameter should be URL-encoded. Pagination uses offset (starting position) and limit (count per page) — useful for infinite scroll or 'Load more' buttons.

```
// app/api/listings/route.ts
import { NextResponse } from 'next/server';

interface RapidAPIProperty {
  property_id?: string;
  location?: { address?: { line?: string; city?: string; state_code?: string; postal_code?: string }; coordinate?: { lat?: number; lon?: number } };
  list_price?: number;
  description?: { beds?: number; baths_consolidated?: number; sqft?: number; type?: string };
  photos?: Array<{ href?: string }>;
  href?: string;
  list_date?: string;
}

export async function GET(request: Request) {
  const url = new URL(request.url);
  const city = url.searchParams.get('city') ?? 'New York City';
  const stateCode = url.searchParams.get('stateCode') ?? 'NY';
  const priceMin = url.searchParams.get('priceMin');
  const priceMax = url.searchParams.get('priceMax');
  const bedsMin = url.searchParams.get('bedsMin');
  const bathsMin = url.searchParams.get('bathsMin');
  const limit = Math.min(Number(url.searchParams.get('limit') ?? 20), 42);
  const page = Number(url.searchParams.get('page') ?? 1);
  const offset = (page - 1) * limit;

  const params = new URLSearchParams({
    city,
    state_code: stateCode,
    offset: String(offset),
    limit: String(limit),
    sort: 'newest',
    ...(priceMin ? { price_min: priceMin } : {}),
    ...(priceMax ? { price_max: priceMax } : {}),
    ...(bedsMin ? { beds_min: bedsMin } : {}),
    ...(bathsMin ? { baths_min: bathsMin } : {}),
  });

  try {
    const apiUrl = `https://realty-in-us.p.rapidapi.com/properties/v3/list?${params}`;
    const response = await fetch(apiUrl, {
      method: 'GET',
      headers: {
        'X-RapidAPI-Key': process.env.RAPIDAPI_KEY ?? '',
        'X-RapidAPI-Host': process.env.RAPIDAPI_HOST ?? 'realty-in-us.p.rapidapi.com',
        'Accept': 'application/json',
      },
    });

    if (response.status === 429) {
      return NextResponse.json({ error: 'Rate limit reached. Please try again later.' }, { status: 429 });
    }
    if (!response.ok) {
      return NextResponse.json({ error: `API error: ${response.status}` }, { status: response.status });
    }

    const data = await response.json();
    const properties: RapidAPIProperty[] = data?.data?.home_search?.results ?? data?.properties ?? [];
    const total: number = data?.data?.home_search?.total ?? data?.matching_rows ?? properties.length;

    const listings = properties.map((p) => ({
      propertyId: p.property_id ?? '',
      address: `${p.location?.address?.line ?? ''}, ${p.location?.address?.city ?? ''}, ${p.location?.address?.state_code ?? ''} ${p.location?.address?.postal_code ?? ''}`.trim(),
      price: p.list_price ?? null,
      beds: p.description?.beds ?? null,
      baths: p.description?.baths_consolidated ?? null,
      sqft: p.description?.sqft ?? null,
      propertyType: p.description?.type ?? 'unknown',
      latitude: p.location?.coordinate?.lat ?? null,
      longitude: p.location?.coordinate?.lon ?? null,
      photos: (p.photos ?? []).slice(0, 3).map((ph) => ph.href).filter(Boolean),
      listingUrl: p.href ?? '',
    }));

    return NextResponse.json({ listings, total, page, limit });
  } catch (error) {
    console.error('Listings API error:', error);
    return NextResponse.json({ error: 'Failed to fetch listings' }, { status: 500 });
  }
}
```

**Expected result:** The /api/listings endpoint returns an array of normalized property listings. Test in Bolt's WebContainer preview with a US city name — you should see real listing data from Realtor.com.

### 4. Build the Property Search UI

With the API route working, build the React UI that powers the property search experience. A well-designed property search has two main views: a search/filter panel and a results grid (or map view). Start with the grid view — it's more straightforward to build and test.

The listing card should show: the primary photo (use a placeholder if no photos), the price prominently (formatted as currency), the address, and key specs (beds, baths, sqft) in a row. Clicking the card should link to the Realtor.com listing URL (target='_blank'). Add a loading skeleton state while data is being fetched to prevent layout shift.

For the search form, debounce the city input by 500ms before making API calls — you don't want a request for every keystroke. Connect the filter controls (price range, beds, baths) to re-fetch listings when changed.

**Expected result:** The property search page loads with a city search. Entering a US city and clicking Search displays listing cards with photos, prices, and property details.

### 5. Consider SimplyRETS for Production MLS Data

For production applications that need reliable, officially licensed listing data, SimplyRETS is a well-regarded option. SimplyRETS aggregates data from participating MLSes and provides a documented REST API at api.simplyrets.com. They have a test mode with fictional listing data for development, and paid plans start at $49/month for access to real MLS listings in their coverage areas.

The SimplyRETS API uses HTTP Basic Authentication (username:password, base64 encoded) rather than API keys. Search parameters are similar: address, city, county, postal code, min/max price, min/max beds, and property type. The response format is cleaner and more consistent than scraped data.

If your app serves real estate agents or buyers and needs official MLS data, SimplyRETS or the RESO Web API (accessed through an MLS data vendor) is the correct path. RESO certification requires demonstrating a valid real estate business purpose — contact your local MLS for certified data access options.

For the code change from RapidAPI to SimplyRETS, you'd replace the RapidAPI headers and URL with Basic Auth headers and SimplyRETS's endpoint URLs — the API route structure remains the same.

```
// Switching from RapidAPI to SimplyRETS:
// SimplyRETS uses HTTP Basic Auth
const credentials = Buffer.from(
  `${process.env.SIMPLYRETS_API_USER}:${process.env.SIMPLYRETS_API_SECRET}`
).toString('base64');

const response = await fetch('https://api.simplyrets.com/properties?city=Austin&q=&minprice=200000&maxprice=500000', {
  headers: {
    'Authorization': `Basic ${credentials}`,
    'Accept': 'application/json',
  },
});
// SimplyRETS test credentials: simplyrets:simplyrets
```

**Expected result:** The SimplyRETS route returns property listings using their test credentials. The frontend can switch between RapidAPI and SimplyRETS data by changing the /api/listings endpoint it calls.

## Best practices

- Store RAPIDAPI_KEY server-side only — never use NEXT_PUBLIC_ prefix, as exposing the key allows others to consume your API quota
- All real estate API calls must go through Next.js API routes — third-party real estate APIs do not include browser CORS headers
- Cache search results for 15-30 minutes using a database or in-memory cache — listing data doesn't change frequently and caching dramatically reduces API calls
- Be transparent with users that listing data comes from a third-party source and may not be complete or current — especially if using unofficial APIs
- For production apps serving real estate professionals, use officially licensed MLS data via SimplyRETS or a certified RESO provider rather than unofficial API wrappers
- Handle API failures gracefully with cached or placeholder data — real estate search pages should degrade gracefully rather than showing empty screens
- Add analytics to track which cities users search most — this informs upgrade decisions for API tier limits and potential expansion of data coverage

## Use cases

### Property Search by City with Filters

Build a residential property search page where users enter a city name and apply filters for price range, number of bedrooms, and property type (single family, condo, townhouse). Results display as a card grid with photos, key specs, and price. Clicking a card links to the Realtor.com listing.

Prompt example:

```
Build a property search page using the Realtor.com RapidAPI endpoint. Create a search form with city/state input, min/max price sliders, and bedroom count selector. The /api/listings endpoint should call RapidAPI with these filters and return listings as an array with address, price, beds, baths, sqft, photos, and listingUrl. Display results as a responsive card grid with the first photo, price prominently, and key specs.
```

### Neighborhood Price Comparison Tool

Show median listing prices across multiple zip codes in a city to help buyers understand neighborhood price ranges. This tool fetches listings for several zip codes and calculates average and median prices, displayed as a comparison table or chart.

Prompt example:

```
Create a neighborhood price comparison tool. Accept a comma-separated list of zip codes and fetch listings from each using the RapidAPI Realtor.com endpoint. Calculate the median and average listing price per zip code. Display as a sortable table with zip code, median price, average price, listing count, and average price per sqft. Add a bar chart showing median prices side by side.
```

### Saved Property Watchlist

Let users search for properties and save listings to a personal watchlist stored in a database. Users can add notes to saved properties and track price changes over time by re-fetching listing data periodically. This is a core feature for buyers actively monitoring the market.

Prompt example:

```
Build a property watchlist feature. Add a 'Save Property' button to each listing card that saves the property ID, address, and current price to a database table called saved_properties with user_id and saved_at. Create a /watchlist page that displays all saved properties with the option to remove them or add notes. Show if the price has changed since the property was saved.
```

## Troubleshooting

### RapidAPI returns 403 Forbidden or 'You are not subscribed to this API'

Cause: Your RapidAPI account is not subscribed to the 'Realty in US' API, or you're using an API key from a different RapidAPI app that isn't subscribed.

Solution: Go to rapidapi.com, search for 'Realty in US' by APIdojo, and click Subscribe to Test (choose the Basic free plan). Verify you're using the API key from the correct RapidAPI application.

### API returns empty listings array for a valid US city

Cause: The RapidAPI response structure may have changed (scraper-based APIs are fragile), or the city name format doesn't match what the API expects.

Solution: Log the full raw response from the API call to inspect the actual structure. Try different city name formats: 'Austin' vs 'Austin, TX' vs 'Austin City'. Check the RapidAPI endpoint documentation for any recent parameter changes.

```
// Debug by logging the raw response
const data = await response.json();
console.log('Raw API response:', JSON.stringify(data, null, 2));
```

### 429 Too Many Requests error during development

Cause: You've exhausted the RapidAPI free tier's 500 requests per month quota for the current billing cycle.

Solution: Upgrade to a paid RapidAPI plan ($10/month for 10,000 requests) or wait for the monthly reset. During development, cache API responses to avoid re-fetching the same searches repeatedly.

### Property photos not loading — broken images in listing cards

Cause: Realtor.com's CDN URLs for listing photos may be protected with referrer checks or may be temporary URLs that expire.

Solution: Test by opening the photo URL directly in a browser to see if it loads. If photos work in browser but not in img tags, add referrerpolicy='no-referrer' to the img element. If URLs are expired, re-fetch listing data.

```
<img src={photo} alt="Property" referrerPolicy="no-referrer" />
```

## Frequently asked questions

### Does Realtor.com have an official public API?

No. Realtor.com does not have an official public API for third-party developers. The site licenses MLS data under agreements that restrict redistribution. The RapidAPI endpoint used in this tutorial is an unofficial third-party scraper, not endorsed by Realtor.com. For officially licensed listing data, use SimplyRETS, RESO Web API, or Zillow's Bridge Interactive Data.

### How do I connect Bolt.new to real estate listings?

Subscribe to the 'Realty in US' API on RapidAPI (rapidapi.com), copy your RapidAPI key, add it to your .env file as RAPIDAPI_KEY (server-side only), and create a Next.js API route that passes X-RapidAPI-Key and X-RapidAPI-Host headers. For production apps, SimplyRETS offers officially licensed MLS data with a test mode for development using test credentials simplyrets:simplyrets.

### Can I display Realtor.com listings in a commercial app?

Using unofficial RapidAPI scrapers in a commercial app carries legal risk — the data is not licensed for redistribution. For commercial applications, use SimplyRETS, which has a licensed data agreement with participating MLSes, or contact your regional MLS directly for certified data access. These options cost money but provide legally sound data use rights.

### What's RESO Web API and do I need it?

RESO (Real Estate Standards Organization) Web API is the industry standard protocol for accessing MLS data. MLS vendors implement this protocol, providing a consistent way to query property listings. Access requires working with a licensed real estate professional or obtaining RESO certification demonstrating a valid real estate business purpose. You need RESO if you're building a production app that requires complete, officially licensed MLS coverage.

### How much does real estate listing API access cost?

RapidAPI's free tier gives 500 requests/month at no cost, with paid plans at $10-$100/month. SimplyRETS starts at $49/month for access to real MLS data in their coverage areas, with test credentials free for development. Direct MLS data access pricing varies by region and data provider, often requiring data fees and potentially MLS membership.

---

Source: https://www.rapidevelopers.com/bolt-ai-integrations/realtor-com
© RapidDev — https://www.rapidevelopers.com/bolt-ai-integrations/realtor-com
