Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.15.4] - 2026-07-02

### Added

- **Realtor client** (`client.realtor`) — real-estate listings across realtor.com (US) and realtor.ca (Canada) behind a single `market` param. Four endpoints: `search.search()`, `search.autocomplete()`, `properties.getProperty()`, `reference.listMarkets()`, with `Realtor*`-prefixed exported types (`RealtorSearchResponse`, `RealtorPropertyDetail`, …). (SCR-98)

## [0.15.3] - 2026-06-30

### Added
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "scrapebadger",
"version": "0.15.3",
"version": "0.15.4",
"description": "Official Node.js SDK for ScrapeBadger - Async web scraping APIs for Twitter, Google, Vinted, Reddit, and more",
"type": "module",
"main": "./dist/index.js",
Expand Down
5 changes: 5 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ShopeeClient } from "./shopee/client.js";
import { TikTokClient } from "./tiktok/client.js";
import { EbayClient } from "./ebay/client.js";
import { YoutubeClient } from "./youtube/client.js";
import { RealtorClient } from "./realtor/client.js";

/**
* ScrapeBadger API client.
Expand Down Expand Up @@ -82,6 +83,9 @@ export class ScrapeBadger {
/** YouTube scraper API client — 39 endpoints */
readonly youtube: YoutubeClient;

/** Realtor scraper API client — 4 endpoints across 2 markets (us, ca) */
readonly realtor: RealtorClient;

/**
* Create a new ScrapeBadger client.
*
Expand Down Expand Up @@ -131,5 +135,6 @@ export class ScrapeBadger {
this.tiktok = new TikTokClient(this.baseClient);
this.ebay = new EbayClient(this.baseClient);
this.youtube = new YoutubeClient(this.baseClient);
this.realtor = new RealtorClient(this.baseClient);
}
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export * from "./ebay/index.js";

// Re-export YouTube module — YoutubeClient + Youtube*-prefixed sub-clients and types
export * from "./youtube/index.js";
export * from "./realtor/index.js";

// Re-export Google module — GoogleClient is exposed directly; sub-clients
// are aliased with a Google* prefix to avoid collisions with other modules
Expand Down
59 changes: 59 additions & 0 deletions src/realtor/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Realtor API client.
*
* Provides access to all Realtor API endpoints through specialized sub-clients.
*/

import type { BaseClient } from "../internal/client.js";
import { SearchClient } from "./search.js";
import { PropertiesClient } from "./properties.js";
import { ReferenceClient } from "./reference.js";

/**
* Realtor API client with access to all Realtor endpoints.
*
* Unified real-estate API over realtor.com (US) + realtor.ca (Canada).
*
* Provides sub-clients for different resource types:
* - `search` - Property search and location autocomplete
* - `properties` - Full property detail
* - `reference` - Reference data (markets)
*
* @example
* ```typescript
* const client = new ScrapeBadger({ apiKey: "key" });
*
* // Search properties
* const results = await client.realtor.search.search("Austin, TX");
*
* // Location autocomplete
* const suggestions = await client.realtor.search.autocomplete("Miami");
*
* // Get property detail
* const detail = await client.realtor.properties.getProperty("1234567890");
*
* // Reference data
* const markets = await client.realtor.reference.listMarkets();
* ```
*/
export class RealtorClient {
/** Client for property search and location autocomplete */
readonly search: SearchClient;

/** Client for full property detail */
readonly properties: PropertiesClient;

/** Client for reference data (markets) */
readonly reference: ReferenceClient;

/**
* Create a new Realtor client.
*
* @param client - The base HTTP client for making requests.
*/
constructor(client: BaseClient) {
this.search = new SearchClient(client);
this.properties = new PropertiesClient(client);
this.reference = new ReferenceClient(client);
}
}
47 changes: 47 additions & 0 deletions src/realtor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Realtor API module.
*
* @module realtor
*/

export { RealtorClient } from "./client.js";
export { SearchClient as RealtorSearchClient } from "./search.js";
export { PropertiesClient as RealtorPropertiesClient } from "./properties.js";
export { ReferenceClient as RealtorReferenceClient } from "./reference.js";

// Export all types
export type {
// Shared
Coordinate as RealtorCoordinate,
Address as RealtorAddress,
Photo as RealtorPhoto,
Phone as RealtorPhone,
Office as RealtorOffice,
Agent as RealtorAgent,
OpenHouse as RealtorOpenHouse,
School as RealtorSchool,
TaxRecord as RealtorTaxRecord,
PriceEvent as RealtorPriceEvent,
Estimate as RealtorEstimate,
DetailGroup as RealtorDetailGroup,
Flags as RealtorFlags,
// Property
Property as RealtorProperty,
PropertyDetail as RealtorPropertyDetail,
// Autocomplete
Suggestion as RealtorSuggestion,
// Reference
MarketInfo as RealtorMarketInfo,
// Response envelopes
AutocompleteResponse as RealtorAutocompleteResponse,
SearchResponse as RealtorSearchResponse,
MarketsResponse as RealtorMarketsResponse,
// Param enums
RealtorMarket,
RealtorStatus,
RealtorSort,
// Request params
RealtorSearchOptions,
RealtorAutocompleteOptions,
RealtorPropertyOptions,
} from "./types.js";
44 changes: 44 additions & 0 deletions src/realtor/properties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Realtor Properties API client.
*
* Provides a method for fetching full property detail.
*/

import type { BaseClient } from "../internal/client.js";
import type { RealtorPropertyOptions, PropertyDetail } from "./types.js";

/**
* Client for the realtor property detail endpoint.
*
* @example
* ```typescript
* const client = new ScrapeBadger({ apiKey: "key" });
*
* const detail = await client.realtor.properties.getProperty("1234567890");
* console.log(detail.address?.line, detail.list_price);
* ```
*/
export class PropertiesClient {
private readonly client: BaseClient;

constructor(client: BaseClient) {
this.client = client;
}

/**
* Get a single property's full detail.
*
* @param propertyId - The property id.
* @param options - Optional parameters (market).
* @returns Property detail including details, amenities, and history.
* @throws NotFoundError - If the property doesn't exist.
*/
async getProperty(
propertyId: string,
options: RealtorPropertyOptions = {}
): Promise<PropertyDetail> {
return this.client.request<PropertyDetail>(`/v1/realtor/properties/${propertyId}`, {
params: { market: options.market },
});
}
}
38 changes: 38 additions & 0 deletions src/realtor/reference.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Realtor Reference Data API client.
*
* Provides a method for fetching the static market list.
*/

import type { BaseClient } from "../internal/client.js";
import type { MarketsResponse } from "./types.js";

/**
* Client for realtor reference data endpoints (markets).
*
* @example
* ```typescript
* const client = new ScrapeBadger({ apiKey: "key" });
*
* const markets = await client.realtor.reference.listMarkets();
* for (const m of markets.markets) {
* console.log(`${m.code}: ${m.domain} (${m.currency})`);
* }
* ```
*/
export class ReferenceClient {
private readonly client: BaseClient;

constructor(client: BaseClient) {
this.client = client;
}

/**
* Get all supported realtor markets.
*
* @returns Markets response with all supported markets.
*/
async listMarkets(): Promise<MarketsResponse> {
return this.client.request<MarketsResponse>("/v1/realtor/markets");
}
}
86 changes: 86 additions & 0 deletions src/realtor/search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Realtor Search API client.
*
* Provides methods for property search and location autocomplete.
*/

import type { BaseClient } from "../internal/client.js";
import type {
RealtorSearchOptions,
RealtorAutocompleteOptions,
SearchResponse,
AutocompleteResponse,
} from "./types.js";

/**
* Client for realtor search and autocomplete endpoints.
*
* @example
* ```typescript
* const client = new ScrapeBadger({ apiKey: "key" });
*
* const results = await client.realtor.search.search("Austin, TX");
* for (const p of results.results) {
* console.log(`${p.address?.line} — ${p.list_price_formatted}`);
* }
*
* const suggestions = await client.realtor.search.autocomplete("Miami");
* ```
*/
export class SearchClient {
private readonly client: BaseClient;

constructor(client: BaseClient) {
this.client = client;
}

/**
* Search a market for properties.
*
* @param location - Freetext location ("Austin, TX" / ZIP / "Toronto, ON").
* Required unless a CA bounding box is provided.
* @param options - Filters, sorting, and pagination.
* @returns Search results with pagination metadata.
* @throws AuthenticationError - If the API key is invalid.
* @throws ValidationError - If the parameters are invalid.
*/
async search(location?: string, options: RealtorSearchOptions = {}): Promise<SearchResponse> {
return this.client.request<SearchResponse>("/v1/realtor/search", {
params: {
location,
market: options.market,
status: options.status,
price_min: options.priceMin,
price_max: options.priceMax,
beds_min: options.bedsMin,
baths_min: options.bathsMin,
sqft_min: options.sqftMin,
sqft_max: options.sqftMax,
property_type: options.propertyType,
sort: options.sort,
page: options.page,
limit: options.limit,
lat_min: options.latMin,
lat_max: options.latMax,
lng_min: options.lngMin,
lng_max: options.lngMax,
},
});
}

/**
* Get location autocomplete suggestions.
*
* @param query - Partial location query.
* @param options - Optional parameters (market, limit).
* @returns Autocomplete suggestions.
*/
async autocomplete(
query: string,
options: RealtorAutocompleteOptions = {}
): Promise<AutocompleteResponse> {
return this.client.request<AutocompleteResponse>("/v1/realtor/autocomplete", {
params: { query, market: options.market, limit: options.limit },
});
}
}
Loading
Loading