Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Redfin

Redfin does not have a public developer API, but you can build real estate search tools in Bolt.new using ATTOM Data, Estated, or SimplyRETS for MLS listings. Prompt Bolt to generate an API route that queries one of these services, displays property listings with map integration, and stores saved searches in Supabase. All outbound API calls work in Bolt's WebContainer preview — deploy to Netlify or Bolt Cloud for full production functionality.

What you'll learn

  • Why Redfin has no public API and which alternative property data APIs work in Bolt.new
  • How to use ATTOM Data or Estated to fetch property records, valuations, and neighborhood data
  • How to build a property search UI with map integration in Bolt.new
  • How to store saved property searches and favorites in Supabase
  • How to deploy a real estate app from Bolt to Netlify or Bolt Cloud
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate17 min read30 minutesOtherApril 2026RapidDev Engineering Team
TL;DR

Redfin does not have a public developer API, but you can build real estate search tools in Bolt.new using ATTOM Data, Estated, or SimplyRETS for MLS listings. Prompt Bolt to generate an API route that queries one of these services, displays property listings with map integration, and stores saved searches in Supabase. All outbound API calls work in Bolt's WebContainer preview — deploy to Netlify or Bolt Cloud for full production functionality.

Build a Real Estate Search App in Bolt.new Without the Redfin API

Redfin is one of the most-visited real estate websites in the United States, but it does not offer a public API for developers. Like Zillow (which deprecated its public API in 2021), Redfin keeps its property data proprietary. If you need real estate data in your Bolt.new app, you have several legitimate alternatives that offer proper REST APIs with developer access.

The best options for Bolt.new projects are ATTOM Data (comprehensive property records, school data, neighborhood analytics, and automated valuations), Estated (clean and affordable property data API with a generous free tier), SimplyRETS (MLS listing data for licensed real estate agents and brokers), and RapidAPI's collection of property data endpoints including unofficial Redfin and Zillow scrapers for non-commercial prototyping. For property value estimates specifically, the ATTOM API and Estated both provide automated valuation models (AVMs) that are legitimate alternatives to Zillow's Zestimate.

In Bolt.new, the integration pattern is the same for all these services: a Next.js API route or Supabase edge function queries the property data API using credentials stored in your .env file, formats the response, and returns it to a React component that renders listings in a grid or on an interactive map. Bolt's WebContainer can make outbound API calls during development, so you can test search results in the preview before deploying. The full production app with user accounts, saved searches, and favorites persistence works best with Supabase as the backend.

Integration method

Bolt Chat + API Route

Redfin does not offer a public REST API for developers, so building real estate features in Bolt.new requires using third-party property data APIs. ATTOM Data and Estated provide comprehensive property records, school data, and valuations via REST APIs. SimplyRETS provides MLS listing data (requires a real estate license or broker partnership). RapidAPI hosts unofficial Redfin and Zillow endpoints as a fallback for non-commercial projects. Bolt generates an API route that queries these services, with your API key stored in the .env file, and returns listing data to a React map or grid component.

Prerequisites

  • An ATTOM Data API key (free trial at api.developer.attomdata.com) or an Estated API key (free tier at estated.com/developers)
  • A Bolt.new project with Supabase connected for saving searches and user data
  • A Mapbox or Google Maps API key if you want map visualization of property locations
  • For MLS listings via SimplyRETS: a real estate license or broker partnership is required
  • A deployed URL on Netlify or Bolt Cloud for production use

Step-by-step guide

1

Choose Your Property Data API and Get Credentials

The first decision is which property data API to use. Each has different strengths, pricing, and access requirements. ATTOM Data (api.developer.attomdata.com) is the most comprehensive option. Their database covers over 155 million US properties with records, valuations, neighborhood data, school ratings, and environmental risk scores. The free developer trial gives 100 API calls per day, which is enough for building and testing. ATTOM's API uses header-based authentication — you send your API key in the `apikey` header with every request. Estated (estated.com/developers) is simpler and more affordable, focused on clean property records and valuations. Their Sandbox environment is free and returns data for 27 sample properties for testing. The Production API costs $0.002-$0.01 per request. Estated is a good choice if you need quick, reliable property data without ATTOM's full feature set. SimplyRETS (simplyrets.com) provides live MLS listing data but requires a real estate broker or agent relationship to access real MLS data — the free sandbox returns 3,000 simulated listings for development. If your app is for licensed real estate professionals, SimplyRETS is the best choice for current active listings. For non-commercial prototyping, RapidAPI (rapidapi.com) hosts several unofficial Redfin and Zillow data endpoints. These are scraped data sources that violate Redfin's and Zillow's terms of service for commercial use — use them only for learning and personal projects, not production apps. Once you have your chosen API key, add it to your .env file.

.env
1# .env file add your chosen property data API credentials
2ATTOM_API_KEY=your_attom_api_key_here
3# OR
4ESTATED_API_KEY=your_estated_token_here
5# OR
6SIMPLYRETS_API_KEY=your_simplyrets_username
7SIMPLYRETS_SECRET=your_simplyrets_password
8
9# Optional: for map visualization
10NEXT_PUBLIC_MAPBOX_TOKEN=your_mapbox_token_here

Pro tip: Start with Estated's free sandbox for prototyping — their API is simple, well-documented, and the sandbox returns consistent test data. Once your UI is built, switch to ATTOM or SimplyRETS for production data.

Expected result: You have API credentials for your chosen property data service stored in .env, and understand which endpoints to query.

2

Prompt Bolt to Generate the Property Search API Route

With credentials in place, prompt Bolt to generate the property search API route. The API route accepts search parameters from the frontend (location, price range, bedrooms), queries the property data API using your credentials from `process.env`, and returns formatted listing data to the React component. For Next.js projects, Bolt generates an API route at `app/api/properties/search/route.ts`. For Vite projects, use a Supabase edge function to proxy the property API request — this avoids CORS issues since ATTOM and Estated may not whitelist browser origins directly. The edge function pattern is also more secure because your API key never reaches the client bundle. The key architectural decision is whether to query the property API on every search or to cache results. For development, direct API calls on every search are fine. For production, consider caching property search results in Supabase for 24 hours — property data doesn't change minute-by-minute, and API calls cost money. A simple caching strategy: store search results in a `property_cache` table with a `cached_at` timestamp, and return cached results if they are less than 24 hours old before making a new API call. Bolt can also generate the full search form UI — location input with autocomplete, price range sliders, bedroom/bathroom filters, and property type checkboxes. Request the full component in the same prompt to get a working search flow in one generation.

Bolt.new Prompt

Build a property search feature for my real estate app. Create an API route at app/api/properties/search/route.ts that accepts query parameters: location (city or ZIP), minPrice, maxPrice, bedrooms, propertyType. Use the Estated API to fetch property data (https://apis.estated.com/v4/property?token=ESTATED_API_KEY&address=LOCATION). Return an array of properties with: address, estimated_value, bedrooms, bathrooms, square_footage, lot_size, year_built, last_sale_price, last_sale_date. Create a SearchForm component with fields for location, price range (slider), min bedrooms (dropdown), and property type (radio: Any, Single Family, Condo, Multi-Family). Display results as PropertyCard components in a responsive grid showing the key stats.

Paste this in Bolt.new chat

app/api/properties/search/route.ts
1// app/api/properties/search/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3
4const ATTOM_API_KEY = process.env.ATTOM_API_KEY;
5const ATTOM_BASE_URL = 'https://api.gateway.attomdata.com/propertyapi/v1.0.0';
6
7export async function GET(request: NextRequest) {
8 const { searchParams } = new URL(request.url);
9 const zipCode = searchParams.get('zip');
10 const city = searchParams.get('city');
11 const state = searchParams.get('state');
12 const minPrice = searchParams.get('minPrice');
13 const maxPrice = searchParams.get('maxPrice');
14
15 if (!ATTOM_API_KEY) {
16 return NextResponse.json({ error: 'Property API not configured' }, { status: 500 });
17 }
18
19 // Build ATTOM property search query
20 const params = new URLSearchParams();
21 if (zipCode) params.set('postalcode', zipCode);
22 if (city) params.set('city', city);
23 if (state) params.set('state', state);
24 if (minPrice) params.set('minestimatedvalue', minPrice);
25 if (maxPrice) params.set('maxestimatedvalue', maxPrice);
26 params.set('pagesize', '20');
27
28 const response = await fetch(
29 `${ATTOM_BASE_URL}/property/basicprofile?${params.toString()}`,
30 {
31 headers: {
32 'apikey': ATTOM_API_KEY,
33 'Accept': 'application/json',
34 },
35 }
36 );
37
38 if (!response.ok) {
39 const error = await response.text();
40 return NextResponse.json(
41 { error: `Property API error: ${response.status}` },
42 { status: response.status }
43 );
44 }
45
46 const data = await response.json();
47 const properties = (data.property || []).map((p: any) => ({
48 id: p.identifier?.attomId,
49 address: `${p.address?.line1}, ${p.address?.locality}, ${p.address?.countrySubd} ${p.address?.postal1}`,
50 estimatedValue: p.avm?.amount?.value,
51 bedrooms: p.building?.rooms?.beds,
52 bathrooms: p.building?.rooms?.bathsTotal,
53 squareFootage: p.building?.size?.livingSize,
54 yearBuilt: p.summary?.yearbuilt,
55 propertyType: p.summary?.proptype,
56 latitude: p.location?.latitude,
57 longitude: p.location?.longitude,
58 }));
59
60 return NextResponse.json({ properties });
61}

Pro tip: ATTOM's API requires both a city+state OR a ZIP code in the query. Passing neither returns an error. Add validation in your API route to ensure at least one location parameter is present before calling ATTOM.

Expected result: The API route returns an array of property objects with address, valuation, bedrooms, bathrooms, and coordinates from ATTOM Data.

3

Build the Property Listings UI with Map Integration

A real estate app's value is in how properties are presented. The most effective UI pattern combines a searchable list view with an interactive map — users see properties both spatially and as sortable cards. Bolt can generate this split-panel layout from a prompt. For the map, Mapbox GL JS (`mapbox-gl`) and React Map GL (`react-map-gl`) are the recommended choices for Bolt.new projects. They work via npm install without native dependencies — both use WebGL for rendering, which is fully compatible with the WebContainer. Google Maps JavaScript API is also compatible. Add property pins to the map using GeoJSON coordinates from your API response. When a user clicks a pin, show a popup with the property address and estimated value. Clicking through opens the property detail panel. The list view should show PropertyCard components with key stats: address, estimated value formatted as currency, bedrooms, bathrooms, square footage, and year built. Sort controls (price high/low, newest, closest) and filter chips (bedrooms, price range, property type) let users narrow down results without re-querying the API. For the property detail view, a slide-in panel or modal works well — it keeps the map visible while showing full property details. Include: full address, all property characteristics from the API response, an estimated value with a note that values are automated estimates (important for liability reasons), last sale price and date, and a Save to Favorites button that stores the property in Supabase linked to the user's account.

Bolt.new Prompt

Build a split-panel real estate search UI. Left panel: PropertyCard grid showing 12 results with address, estimated value (formatted as $X,XXX), bedrooms, bathrooms, sqft, year built. Right panel: Mapbox map showing property pins using react-map-gl and my NEXT_PUBLIC_MAPBOX_TOKEN. Clicking a pin highlights the corresponding card and vice versa. Add a sort dropdown (price high/low, sqft, year built) and filter chips for bedrooms (any, 1+, 2+, 3+, 4+). Add a Save button on each card that requires login and saves the property to a Supabase favorites table.

Paste this in Bolt.new chat

components/PropertyCard.tsx
1// components/PropertyCard.tsx
2interface Property {
3 id: string;
4 address: string;
5 estimatedValue?: number;
6 bedrooms?: number;
7 bathrooms?: number;
8 squareFootage?: number;
9 yearBuilt?: number;
10 propertyType?: string;
11}
12
13interface PropertyCardProps {
14 property: Property;
15 isHighlighted?: boolean;
16 onSave?: (propertyId: string) => void;
17 onClick?: () => void;
18}
19
20export function PropertyCard({ property, isHighlighted, onSave, onClick }: PropertyCardProps) {
21 const formatValue = (value?: number) =>
22 value ? `$${value.toLocaleString()}` : 'Est. N/A';
23
24 return (
25 <div
26 onClick={onClick}
27 className={`p-4 border rounded-lg cursor-pointer transition-all hover:shadow-md ${
28 isHighlighted ? 'border-blue-500 shadow-md bg-blue-50' : 'border-gray-200 bg-white'
29 }`}
30 >
31 <div className="flex justify-between items-start mb-2">
32 <p className="font-semibold text-sm leading-tight flex-1 mr-2">{property.address}</p>
33 <span className="text-blue-600 font-bold whitespace-nowrap">
34 {formatValue(property.estimatedValue)}
35 </span>
36 </div>
37 <div className="flex gap-3 text-sm text-gray-600">
38 {property.bedrooms && <span>{property.bedrooms} bed</span>}
39 {property.bathrooms && <span>{property.bathrooms} bath</span>}
40 {property.squareFootage && <span>{property.squareFootage.toLocaleString()} sqft</span>}
41 {property.yearBuilt && <span>Built {property.yearBuilt}</span>}
42 </div>
43 {property.propertyType && (
44 <span className="inline-block mt-2 text-xs bg-gray-100 text-gray-500 rounded px-2 py-0.5">
45 {property.propertyType}
46 </span>
47 )}
48 {onSave && (
49 <button
50 onClick={(e) => { e.stopPropagation(); onSave(property.id); }}
51 className="mt-3 w-full text-sm border border-gray-300 rounded py-1 hover:bg-gray-50"
52 >
53 Save Property
54 </button>
55 )}
56 </div>
57 );
58}

Pro tip: Add a disclaimer below estimated property values: 'Estimated values are provided by automated valuation models and may differ from actual market value. Consult a licensed appraiser for accurate valuations.' This is important for legal liability when displaying AVM data.

Expected result: The search results page shows a split view with property cards on the left and a Mapbox map with pins on the right. Clicking a pin highlights the corresponding card.

4

Save Searches and Favorites with Supabase

A real estate app becomes much more useful when users can save properties they are interested in and set up saved searches that notify them of new listings matching their criteria. Bolt can generate the full favorites and saved search system from a prompt. The data model in Supabase requires two tables: `favorites` (user_id, property_id, property_address, estimated_value, saved_at) for saved individual properties, and `saved_searches` (user_id, search_name, location, min_price, max_price, bedrooms, property_type, created_at) for recurring searches. Both tables need RLS policies ensuring users can only access their own saved data. For the favorites feature, the Save button on each property card calls a Supabase insert. Since property data comes from an external API and not your own database, you store a snapshot of the key property fields alongside the external property ID — this way, favorites remain displayable even if the external API data changes or becomes unavailable. Saved searches with email notifications require deployment since email sending (via SendGrid or Resend) happens from a server-side function. The notification trigger can be a scheduled Supabase function (via pg_cron) that runs daily, queries the property API for each saved search, compares against the last known results stored in Supabase, and emails the user about new listings. This is an advanced feature — build it after the core search and favorites are working.

Bolt.new Prompt

Add a favorites system to the real estate app. Create a Supabase table called favorites with columns: id, user_id (references auth.users), attom_id (text), address (text), estimated_value (numeric), bedrooms (integer), bathrooms (integer), sqft (integer), saved_at (timestamptz). Enable RLS so users can only see and modify their own favorites. Add a heart icon button to each PropertyCard that toggles the saved state. Create a /favorites page that shows all saved properties with an unsave button. Show a toast notification when a property is saved or removed.

Paste this in Bolt.new chat

hooks/useFavorites.ts
1// hooks/useFavorites.ts
2import { useState, useEffect } from 'react';
3import { createClient } from '@supabase/supabase-js';
4
5const supabase = createClient(
6 process.env.NEXT_PUBLIC_SUPABASE_URL!,
7 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
8);
9
10export function useFavorites(userId?: string) {
11 const [favorites, setFavorites] = useState<Set<string>>(new Set());
12 const [loading, setLoading] = useState(false);
13
14 useEffect(() => {
15 if (!userId) return;
16 supabase
17 .from('favorites')
18 .select('attom_id')
19 .eq('user_id', userId)
20 .then(({ data }) => {
21 if (data) setFavorites(new Set(data.map((f) => f.attom_id)));
22 });
23 }, [userId]);
24
25 async function toggleFavorite(property: {
26 attomId: string;
27 address: string;
28 estimatedValue?: number;
29 bedrooms?: number;
30 bathrooms?: number;
31 squareFootage?: number;
32 }) {
33 if (!userId) return;
34 setLoading(true);
35
36 if (favorites.has(property.attomId)) {
37 await supabase
38 .from('favorites')
39 .delete()
40 .eq('user_id', userId)
41 .eq('attom_id', property.attomId);
42 setFavorites((prev) => { const next = new Set(prev); next.delete(property.attomId); return next; });
43 } else {
44 await supabase.from('favorites').insert({
45 user_id: userId,
46 attom_id: property.attomId,
47 address: property.address,
48 estimated_value: property.estimatedValue,
49 bedrooms: property.bedrooms,
50 bathrooms: property.bathrooms,
51 sqft: property.squareFootage,
52 });
53 setFavorites((prev) => new Set([...prev, property.attomId]));
54 }
55 setLoading(false);
56 }
57
58 return { favorites, toggleFavorite, loading };
59}

Pro tip: Store a snapshot of property data (address, value, bedrooms) when saving a favorite — not just the external ID. Property APIs can change their data structure or become unavailable, and you want favorites to remain displayable regardless.

Expected result: Users can save and unsave properties, their favorites persist across sessions in Supabase, and the /favorites page shows all saved properties.

5

Deploy and Test in Production

Property search apps need to be tested in a real deployment environment, not just in Bolt's WebContainer preview. While outbound API calls to ATTOM or Estated work in the preview, the full experience — user authentication, saved favorites, map rendering with a real Mapbox token — works best on a deployed URL. Deploy to Netlify or Bolt Cloud by clicking the Publish button in Bolt's top navigation. After deployment, configure environment variables in your hosting platform. In Netlify, go to Site Configuration → Environment Variables and add: `ATTOM_API_KEY` (or `ESTATED_API_KEY`), `NEXT_PUBLIC_MAPBOX_TOKEN`, `NEXT_PUBLIC_SUPABASE_URL`, and `NEXT_PUBLIC_SUPABASE_ANON_KEY`. In Bolt Cloud, use the Secrets panel. After deployment, test the full flow: search for properties in a specific ZIP code, view them on the map, save a favorite, log out and log back in to confirm favorites persist. Check browser DevTools for any 403 errors (Supabase RLS policies blocking access) or CORS errors from the property API. For production apps, set up API rate limiting in your API route to prevent excessive ATTOM or Estated API calls. Both providers charge per request, and a popular app without rate limiting can accumulate significant API costs. Add request caching using Supabase as a cache store — save API responses with a `cached_at` timestamp and return cached data if it's less than 24 hours old.

Bolt.new Prompt

Add caching to the property search API route. Before calling ATTOM, check the Supabase table property_cache for a recent result (cached within last 24 hours) matching the same search parameters. If found, return the cached result. If not found, call ATTOM, save the response to property_cache with the current timestamp, then return the fresh data. Add a cache_hit field to the response so I can see when results are served from cache.

Paste this in Bolt.new chat

Pro tip: ATTOM's free tier limits requests per day. Add a cache layer early — even a simple Supabase table caching results for 24 hours dramatically reduces API call volume and cost in production.

Expected result: The deployed app serves real property data, user favorites persist in Supabase, and the map renders correctly with the production Mapbox token.

Common use cases

Neighborhood Property Search Tool

Users search for properties in a neighborhood by entering a city, ZIP code, or address. The app queries ATTOM Data or Estated for active listings and recent sales, displays them on an interactive map, and shows key details like price, square footage, bedrooms, bathrooms, and days on market.

Bolt.new Prompt

Build a real estate property search tool. Create a search form where users can enter a city or ZIP code. Fetch property listings from the ATTOM API (https://api.gateway.attomdata.com/propertyapi/v1.0.0/property/basicprofile) using the API key from process.env.ATTOM_API_KEY. Display results as property cards showing address, price, bedrooms, bathrooms, and square footage. Add a Mapbox map showing property locations as pins. When a user clicks a property card, show a detail panel with all available data.

Copy this prompt to try it in Bolt.new

Investment Property Analyzer

Real estate investors input an address to get a full property report: current valuation, historical price trends, rental estimate, neighborhood stats, school ratings, and comparable sales. The report helps investors evaluate potential acquisitions without manual research.

Bolt.new Prompt

Create a property investment analyzer. Users enter a full street address and the app fetches property data from the Estated API (https://apis.estated.com/v4/property) using the token from process.env.ESTATED_API_KEY. Display: estimated value, lot size, year built, last sale price and date, property tax amount, and neighborhood data (median income, crime rate if available). Show a section for comparable sales in the same ZIP code over the last 12 months. Add a 'Save Analysis' button that stores the report in Supabase.

Copy this prompt to try it in Bolt.new

Agent Lead Generation Portal

A real estate agent builds a custom property search portal with their branding that clients use to browse listings. The agent captures client email addresses when they save a property or request a showing, building a CRM of interested buyers.

Bolt.new Prompt

Build a branded real estate portal for a buyer's agent. Use SimplyRETS API (https://api.simplyrets.com/properties) with credentials from process.env.SIMPLYRETS_API_KEY and process.env.SIMPLYRETS_SECRET. Show active listings with filters for price range, bedrooms, and property type. When a user clicks 'Request Showing' or 'Save Property', show a modal asking for their name and email, then save their contact and the property MLS ID to Supabase. Send a notification email to the agent using SendGrid. Add pagination — show 12 listings per page.

Copy this prompt to try it in Bolt.new

Troubleshooting

ATTOM API returns 401 Unauthorized

Cause: The ATTOM_API_KEY environment variable is missing from the .env file, or the API key is being accessed with the wrong variable name. ATTOM requires the key in the request header as 'apikey', not as a query parameter.

Solution: Verify ATTOM_API_KEY is set in your .env file for local development and in your hosting platform's environment variables for production. Check that your API route reads `process.env.ATTOM_API_KEY` and passes it as a request header: `headers: { 'apikey': ATTOM_API_KEY }`. Do not pass the key as a URL query parameter.

typescript
1// Correct ATTOM API call pattern
2const response = await fetch(`${ATTOM_BASE_URL}/property/basicprofile?postalcode=${zip}`, {
3 headers: {
4 'apikey': process.env.ATTOM_API_KEY!, // header, not query param
5 'Accept': 'application/json',
6 },
7});

Property search returns empty results for valid US addresses

Cause: ATTOM and Estated require specific query parameter formats. City searches require both city and state parameters. ZIP code searches require a valid 5-digit US ZIP. Partial or malformatted location queries return empty result sets.

Solution: For city searches, always include both the city and state abbreviation as separate parameters. For ATTOM: `?city=Austin&state=TX`. For ZIP code searches, use the full 5-digit ZIP: `?postalcode=78701`. Add input validation in your search form that requires either a valid 5-digit ZIP or a city + state combination before submitting.

Mapbox map does not render in Bolt's WebContainer preview

Cause: The NEXT_PUBLIC_MAPBOX_TOKEN environment variable is either missing or not prefixed correctly for client-side access. In Next.js, client-side variables require the NEXT_PUBLIC_ prefix. In Vite, they require the VITE_ prefix.

Solution: Ensure the Mapbox token variable is named NEXT_PUBLIC_MAPBOX_TOKEN (Next.js) or VITE_MAPBOX_TOKEN (Vite) so it is included in the client bundle. Access it as process.env.NEXT_PUBLIC_MAPBOX_TOKEN or import.meta.env.VITE_MAPBOX_TOKEN in your map component. Mapbox GL JS also requires HTTPS in production — the deployed URL on Netlify or Bolt Cloud uses HTTPS automatically.

typescript
1// Next.js map component — correct env var access
2import Map from 'react-map-gl';
3
4export function PropertyMap() {
5 return (
6 <Map
7 mapboxAccessToken={process.env.NEXT_PUBLIC_MAPBOX_TOKEN}
8 initialViewState={{ longitude: -97, latitude: 38, zoom: 4 }}
9 style={{ width: '100%', height: '100%' }}
10 mapStyle="mapbox://styles/mapbox/streets-v12"
11 />
12 );
13}

Supabase favorites inserts fail with 'new row violates row-level security policy'

Cause: The favorites table has RLS enabled but the INSERT policy is missing or incorrectly configured. RLS blocks all operations by default — you must explicitly create policies for each operation type.

Solution: In Supabase Dashboard → Table Editor → favorites → RLS Policies, add a policy for INSERT: WITH CHECK (auth.uid() = user_id). Also add policies for SELECT: USING (auth.uid() = user_id) and DELETE: USING (auth.uid() = user_id). Ensure the user is authenticated before calling the insert — check the Supabase auth session in the component before calling toggleFavorite.

Best practices

  • Never use Redfin or Zillow's unofficial API scrapers from RapidAPI in commercial apps — they violate those platforms' terms of service. Use ATTOM Data or Estated for production real estate applications.
  • Always display a disclaimer next to automated property valuations: 'Estimated values are provided by automated valuation models and may not reflect actual market value'
  • Cache property API responses in Supabase for at least 24 hours — property data changes slowly, and per-request API costs add up quickly in production
  • Store property data snapshots in your favorites table rather than just external IDs, so favorites remain displayable if the external API is unavailable
  • Use private Supabase buckets for any user-uploaded property photos rather than linking directly to listing photos from external services
  • For production MLS listing data, use SimplyRETS or Bridge Interactive — they provide licensed, accurate MLS data through proper real estate industry channels
  • Test your property search app on mobile — real estate browsing happens predominantly on mobile devices. Ensure the map and property cards work well on small screens.
  • Add rate limiting to your property search API route to prevent excessive API calls from web scrapers or automated tools hitting your deployed app

Alternatives

Frequently asked questions

Does Redfin have a developer API?

No. Redfin does not offer a public API for developers. Their property data is proprietary and only accessible through their website. For property search and valuation data in Bolt.new apps, use ATTOM Data, Estated, or SimplyRETS (for MLS listings with a real estate license). These are the legitimate, production-ready alternatives.

Can I use unofficial Redfin API scrapers from RapidAPI in my Bolt app?

Technically these endpoints work in Bolt.new, but using them in commercial apps violates Redfin's terms of service. Redfin explicitly prohibits scraping their data. For personal learning projects, they work as a prototype — for any app you plan to launch or monetize, use ATTOM Data or Estated instead.

Does property search work in Bolt's WebContainer preview?

Yes. Outbound API calls to ATTOM, Estated, and SimplyRETS work in Bolt's WebContainer during development. You can build and test the full search flow in the preview. The map (Mapbox or Google Maps) also renders correctly in the preview with a valid API token.

How accurate are automated property valuations from ATTOM or Estated?

Automated Valuation Models (AVMs) from ATTOM and Estated are typically within 5-15% of actual market value for standard residential properties in well-documented markets. Accuracy drops significantly for rural properties, unique homes, and markets with limited comparable sales data. Always display a disclaimer and recommend professional appraisals for significant financial decisions.

Can I display live MLS listings (active listings for sale) in my Bolt app?

Live MLS listings require a data partnership with an MLS provider. SimplyRETS is the easiest option — it requires a real estate broker or agent relationship and costs $99+/month. Bridge Interactive (by Zillow) is another MLS data provider. Without a licensing agreement, you can display AVM data and property records from ATTOM or Estated, but not active listing data from the MLS.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.