DEV Community

Cover image for Building With U.S. Foreclosure Data: A Practical REST API Guide
Alex Morgan
Alex Morgan

Posted on

Building With U.S. Foreclosure Data: A Practical REST API Guide

If you've ever tried to build a real estate application around
foreclosure data, you quickly run into a problem that has very little to
do with writing code.

The data is fragmented.

A foreclosure notice might live in a county recorder system. An upcoming
auction could be published somewhere else. REO properties may come from
another source entirely. Every source can use different field names,
formats, and update schedules.

For a developer, collecting and normalizing the data can become a larger
project than the application you're trying to build.

I recently explored the Foreclosure Data Hub REST
API
, which provides
programmatic access to U.S. foreclosure and REO property data aggregated
from hundreds of public-record and auction sources.

Here is how the API works and what you can build with it.

What Does the API Provide?

Foreclosure Data Hub covers all 50 U.S. states and says its data is
updated daily at 6 AM ET.

From a developer's perspective, the interesting part is that the API
provides two ways to interact with the underlying data.

You can work directly with individual data sources, preserving their
source-specific fields.

Or you can use a normalized search layer that combines records from
multiple sources into a common schema.

That second option is particularly useful when building applications
that need nationwide coverage.

Authentication

The API uses API-key authentication.

Every request includes the key in the x-api-key header:

curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.foreclosuredatahub.com/api/v1/sources"
Enter fullscreen mode Exit fullscreen mode

The base URL is:

https://api.foreclosuredatahub.com/api/v1
Enter fullscreen mode Exit fullscreen mode

Keys are generated from the user dashboard. Keep the API key server-side
rather than exposing it in a browser bundle, mobile app, or public
repository.

The Five Main API Operations

At the time of writing, the API exposes five primary operations:

GET /sources
GET /properties/search
GET /properties/search?mode=unified
GET /properties/data
GET /properties/counts
Enter fullscreen mode Exit fullscreen mode

Each solves a slightly different problem.

1. Discover Available Data Sources

Start with:

GET /sources
Enter fullscreen mode Exit fullscreen mode

This returns the available feeds and tells you which filters each source
supports.

curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.foreclosuredatahub.com/api/v1/sources"
Enter fullscreen mode Exit fullscreen mode

A simplified response looks like this:

{
  "data": [
    {
      "id": "feed-01",
      "name": "Data Feed 01",
      "filters": {
        "county": true,
        "state": true,
        "sale_date": true,
        "owner_name": true,
        "est_value": true
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

This endpoint is more important than it initially appears.

Public-record sources are heterogeneous. One source may contain owner
information while another doesn't. One might support estimated property
values while another only contains auction information.

Instead of pretending every underlying dataset has identical
capabilities, the API exposes those differences programmatically.

That means your application can adapt:

const sources = await getSources();

const ownerSearchable = sources.filter(
  source => source.filters.owner_name
);
Enter fullscreen mode Exit fullscreen mode

You could then expose owner-name search only against compatible feeds.

2. Search Foreclosures Across Multiple Sources

The standard search endpoint is:

GET /properties/search
Enter fullscreen mode Exit fullscreen mode

It searches across data sources simultaneously and returns up to 100
results per source, grouped by source.

At least one location parameter is required:

county
state
zip
address
Enter fullscreen mode Exit fullscreen mode

Additional filters include:

sale_date_start
sale_date_end
owner_name
est_value_min
est_value_max
Enter fullscreen mode Exit fullscreen mode

For example, suppose you're building an application for Florida
investors:

curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.foreclosuredatahub.com/api/v1/properties/search?state=FL&county=Miami-Dade"
Enter fullscreen mode Exit fullscreen mode

A simplified response looks like:

{
  "data": {
    "results": [
      {
        "source": "feed-01",
        "source_name": "Data Feed 01",
        "records": [],
        "count": 45,
        "has_more": false
      }
    ]
  },
  "meta": {
    "total": 312
  }
}
Enter fullscreen mode Exit fullscreen mode

This mode is useful when provenance matters because your application
knows which feed produced each group of records.

3. Use Unified Search for Application Development

For many applications, this is probably the most useful endpoint:

GET /properties/search?mode=unified
Enter fullscreen mode Exit fullscreen mode

Raw public records aren't standardized. One source might call a field
PropertyAddress, another StreetAddress, and another simply
Address.

Unified search solves that problem by returning normalized records in
one flat, paginated result set.

curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.foreclosuredatahub.com/api/v1/properties/search?mode=unified&state=FL&page=1&page_size=25"
Enter fullscreen mode Exit fullscreen mode

Records use standardized fields such as:

{
  "source": "feed-01",
  "address": "123 Main St",
  "city": "Miami",
  "state": "FL",
  "zip": "33101",
  "county": "Miami-Dade",
  "sale_date": "2026-04-15",
  "bid_amount": "250000",
  "owner_first_name": "John",
  "owner_last_name": "Doe"
}
Enter fullscreen mode Exit fullscreen mode

Pagination metadata is returned separately:

{
  "meta": {
    "total": 1250,
    "page": 1,
    "per_page": 25,
    "total_pages": 50
  }
}
Enter fullscreen mode Exit fullscreen mode

Unified search currently supports a maximum page size of 25 records.

Why normalization matters

Imagine building a nationwide foreclosure alert product.

Without normalization, your backend might contain dozens of adapters:

normalizeFloridaRecord(record);
normalizeTexasRecord(record);
normalizeCaliforniaRecord(record);
normalizeArizonaRecord(record);
Enter fullscreen mode Exit fullscreen mode

With a normalized API, your application can operate against one internal
model:

interface ForeclosureProperty {
  source: string;
  address?: string;
  city?: string;
  state?: string;
  zip?: string;
  county?: string;
  sale_date?: string;
  bid_amount?: string;
  owner_first_name?: string;
  owner_last_name?: string;
}
Enter fullscreen mode Exit fullscreen mode

That's a much cleaner starting point for an application.

4. Query a Specific Data Feed

Sometimes you don't want nationwide normalized search. You want one
particular source.

That's what this endpoint is for:

GET /properties/data
Enter fullscreen mode Exit fullscreen mode

Pass the source ID:

curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.foreclosuredatahub.com/api/v1/properties/data?source=feed-01&state=TX&per_page=25"
Enter fullscreen mode Exit fullscreen mode

Supported filters include:

start_date
end_date
county
state
owner_name
est_value_min
est_value_max
Enter fullscreen mode Exit fullscreen mode

Pagination uses page and per_page, with up to 25 records per page.

This endpoint is useful when your application needs the source-specific
representation rather than the normalized abstraction.

5. Get Record Counts Without Downloading Everything

There's also a lightweight counts endpoint:

GET /properties/counts
Enter fullscreen mode Exit fullscreen mode

You can request counts for a single date or date range:

curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.foreclosuredatahub.com/api/v1/properties/counts?start_date=2026-03-15&end_date=2026-03-22"
Enter fullscreen mode Exit fullscreen mode

The response provides counts for individual sources plus the total:

{
  "data": {
    "start_date": "2026-03-15",
    "end_date": "2026-03-22",
    "sources": [
      {
        "id": "feed-01",
        "name": "Data Feed 01",
        "count": 523
      }
    ],
    "total": 4821
  }
}
Enter fullscreen mode Exit fullscreen mode

This is useful for dashboards and analytics because you don't need to
retrieve thousands of property records just to answer a question such
as: How many new records appeared this week?

Property Enrichment

The normalized API goes beyond basic foreclosure information.

Listings scraped from July 18, 2026 onward can contain assessor and
public-record enrichment fields covering the building, previous sale,
mortgage, and estimated equity. Older records and some sources may omit
these fields, so applications should treat them as optional.

Examples include:

building_type
build_quality
num_bedrooms
living_sqft
assessor_year_built
land_use
last_sold_price
last_sold_date
mortgage_amount
mortgage_date
mortgage_term
mortgage_maturity_date
estimated_equity
Enter fullscreen mode Exit fullscreen mode

For example:

{
  "building_type": "Single Family",
  "num_bedrooms": "4",
  "living_sqft": "1,353",
  "assessor_year_built": "1973",
  "land_use": "Single Family Residence",
  "last_sold_price": "$78,000",
  "mortgage_amount": "$76,587",
  "mortgage_term": "30 years",
  "estimated_equity": 367032
}
Enter fullscreen mode Exit fullscreen mode

The documentation notes that estimated_equity is an approximation
calculated from estimated value minus original recorded loan principal.
It is not a payoff figure and does not account for principal already
paid or secondary liens.

For TypeScript, I'd model enrichment fields accordingly:

interface PropertyEnrichment {
  building_type?: string | null;
  num_bedrooms?: string | null;
  living_sqft?: string | null;
  assessor_year_built?: string | null;
  land_use?: string | null;
  last_sold_price?: string | null;
  last_sold_date?: string | null;
  mortgage_amount?: string | null;
  mortgage_date?: string | null;
  mortgage_term?: string | null;
  mortgage_maturity_date?: string | null;
  estimated_equity?: number | null;
}
Enter fullscreen mode Exit fullscreen mode

Don't assume that every property contains every field.

Building a Simple Foreclosure Search in JavaScript

Here's the basic pattern:

async function searchForeclosures({
  state,
  county,
  page = 1
}) {
  const params = new URLSearchParams({
    mode: "unified",
    state,
    page: String(page),
    page_size: "25"
  });

  if (county) {
    params.set("county", county);
  }

  const response = await fetch(
    `https://api.foreclosuredatahub.com/api/v1/properties/search?${params}`,
    {
      headers: {
        "x-api-key": process.env.FORECLOSURE_DATA_HUB_API_KEY
      }
    }
  );

  if (!response.ok) {
    throw new Error(
      `Foreclosure API returned ${response.status}`
    );
  }

  return response.json();
}
Enter fullscreen mode Exit fullscreen mode

Then:

const results = await searchForeclosures({
  state: "FL",
  county: "Miami-Dade"
});

console.log(results.data.records);
console.log(results.meta.total);
Enter fullscreen mode Exit fullscreen mode

One obvious rule: keep the API key server-side.

Handling Pagination

Because unified search returns at most 25 records per page, larger data
jobs need pagination.

A simple iterator might look like this:

async function* getAllProperties(state) {
  let page = 1;

  while (true) {
    const result = await searchForeclosures({
      state,
      page
    });

    for (const property of result.data.records) {
      yield property;
    }

    if (page >= result.meta.total_pages) {
      break;
    }

    page++;
  }
}
Enter fullscreen mode Exit fullscreen mode

You could then process properties incrementally:

for await (const property of getAllProperties("TX")) {
  await processProperty(property);
}
Enter fullscreen mode Exit fullscreen mode

For production ingestion, add retries, exponential backoff,
checkpointing, idempotent writes, and rate-limit awareness.

Rate Limits

The standard API documentation currently lists these limits:

Search:   15 requests/minute
Data:     30 requests/minute
Counts:   15 requests/minute
Sources:  10 requests/minute
Global:   1,000 requests/hour
Trial:    150 total requests
Enter fullscreen mode Exit fullscreen mode

If a limit is exceeded, the API returns HTTP 429 with a Retry-After
header. Licensed keys can use negotiated monthly quotas with higher
ceilings.

Your client should honor rate limiting:

if (response.status === 429) {
  const retryAfter = Number(
    response.headers.get("Retry-After") || 60
  );

  await sleep(retryAfter * 1000);
}
Enter fullscreen mode Exit fullscreen mode

This becomes especially important for scheduled nationwide ingestion
jobs.

Error Handling

The API uses standard HTTP status codes:

400  Invalid or missing parameters
401  Missing or invalid API key
403  Subscription doesn't permit the request
404  No matching data
429  Rate limit exceeded
500  Server error
Enter fullscreen mode Exit fullscreen mode

Errors use a simple JSON representation:

{
  "error": "Description of what went wrong"
}
Enter fullscreen mode Exit fullscreen mode

That makes it straightforward to build a small API wrapper around the
service.

What Could You Build With This?

Once foreclosure data is available through a normalized API, there are
possibilities beyond simply recreating a foreclosure search website.

1. Automated Deal Alerts

Create user-defined buy boxes such as:

State: Arizona
County: Maricopa
Estimated value: $250K-$500K
Auction: Next 30 days
Enter fullscreen mode Exit fullscreen mode

Run the query every morning and notify users when new records appear.

2. Real Estate CRM Enrichment

If you're building software for wholesalers or investors, foreclosure
information could become another signal attached to a property.

A CRM could automatically flag:

FORECLOSURE DETECTED

Auction: September 12
Estimated equity: $184,000
Owner: Jane Smith
Enter fullscreen mode Exit fullscreen mode

3. Investor Dashboards

The counts endpoint lends itself naturally to market-monitoring
dashboards.

You could visualize:

  • New foreclosures by state
  • New records by week
  • Auction volume by county
  • Upcoming auctions
  • Estimated property values

4. Lead Scoring

The normalized and enrichment fields make more sophisticated scoring
possible.

For example:

score =
  equityScore * 0.35 +
  valueDiscountScore * 0.30 +
  auctionUrgencyScore * 0.20 +
  propertyFitScore * 0.15
Enter fullscreen mode Exit fullscreen mode

Instead of showing investors every foreclosure, your application could
surface properties that most closely match their acquisition criteria.

5. AI Property Research

A property record could become the starting point for an automated
research workflow:

Foreclosure Data Hub API
        ↓
Property record
        ↓
Additional public data
        ↓
Comparable sales
        ↓
Rental estimates
        ↓
LLM analysis
        ↓
Investor report
Enter fullscreen mode Exit fullscreen mode

6. Internal Acquisition Tools

Not every application needs to become a SaaS product.

A real estate investment company could build an internal system that:

  1. Fetches new records every morning
  2. Filters properties against its buy box
  3. Evaluates available equity and property fields
  4. Enriches promising properties with additional sources
  5. Assigns qualified opportunities to acquisition reps
  6. Pushes them into a CRM

That may be one of the most practical uses of an API like this.

A Possible Architecture

If I were building a foreclosure intelligence application around the
API, a simple architecture might look like this:

              Foreclosure Data Hub API
                        |
                        v
                 Scheduled Worker
                        |
                        v
                 Normalization Layer
                        |
                        v
                     Queue
                        |
             +----------+----------+
             |                     |
             v                     v
       PostgreSQL             Enrichment Jobs
             |                     |
             +----------+----------+
                        |
                        v
                   Application
                        |
          +-------------+-------------+
          |             |             |
          v             v             v
       Search         Alerts       Analytics
Enter fullscreen mode Exit fullscreen mode

For a small application, you may not even need the separate
normalization layer because unified search already provides normalized
fields.

Internal Use vs. Commercial Products

One implementation detail worth checking before launching is licensing.

Foreclosure Data Hub's API documentation says standard plans are for
internal use. If you're building a product that displays the records to
your own customers, the service offers commercial data licensing.

That distinction matters if you're building a public SaaS rather than an
internal analysis tool.

Final Thoughts

Real estate data APIs are interesting because the difficult part usually
isn't the REST interface.

The difficult part is everything behind it:

  • discovering fragmented sources
  • maintaining collectors
  • handling changing schemas
  • deduplicating records
  • normalizing fields
  • refreshing data
  • enriching incomplete records

Once that work is abstracted behind a consistent API, developers can
focus on the application layer.

The most interesting feature of the Foreclosure Data Hub
API
is therefore not any
single endpoint. It's the combination of nationwide source aggregation,
source-aware queries, normalized unified search, enrichment data,
filtering, pagination, and predictable JSON responses.

That creates a useful foundation for foreclosure alerts, investor
dashboards, property intelligence tools, CRMs, internal acquisition
systems, and AI-assisted real estate research.

If you're experimenting with a real estate data product, the API
documentation is available at Foreclosure Data
Hub
.

Top comments (0)