# Absentee Owner & Land Owner Lists · US County Parcel Data (`thequietstack/us-parcel-owner-lists`) Actor

Extracts of official US county and state parcel registers for market research and land acquisition: absentee and out-of-state owners, vacant land, acreage, value and sale-date filters for whole counties. Companies, trusts and public bodies by default; no phone numbers, no emails.

- **URL**: https://apify.com/thequietstack/us-parcel-owner-lists.md
- **Developed by:** [TheQuietStack](https://apify.com/thequietstack) (community)
- **Categories:** Real estate
- **Stats:** 3 total users, 2 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Absentee Owner & Land Owner Lists · US County Parcel Data

**Absentee owner and land owner lists from official county parcel registers:** out-of-state owners, vacant land, acreage and value for whole counties.

Structured extracts of **official public parcel registers** that counties and states publish themselves: absentee owners, out-of-state owners, vacant land, lot size, value, land-use code, long-held parcels - for a whole county at once. Built for **market research and land acquisition**. No address list needed, no login, no data broker, no enrichment.

The Actor reads the **public ArcGIS parcel services that counties and states publish themselves**, normalizes them into one schema, applies your filters (on the county server where possible) and writes one clean row per parcel - or one row per owner with their whole portfolio.

### What it is for

- **Land acquisition**: vacant land between X and Y acres in a county, parcels whose owner is registered in another state - with the owner and address of record from the public register.
- **Real estate market research**: absentee and out-of-state ownership shares, long-held parcels, portfolio owners per county.
- **Public-records research**: who owns how much of a county (owners mode) - companies, trusts and public bodies by default.

Before you use the output, read [Personal data & legal use](#personal-data--legal-use).

### Why this one

| | This Actor | Typical property lookup Actors |
|---|---|---|
| Input | A county + filters | One address / parcel ID per row |
| Output | Every matching parcel in the county | The record you asked for |
| Absentee / out-of-state / vacant flags | Computed on every row | Usually not |
| One row per owner with parcel count | Yes (`outputMode: owners`) | No |
| Any other open county layer | Paste its ArcGIS URL, columns are mapped automatically | No |
| Completeness proof | SUMMARY compares rows scanned with the server's own count | No |
| Free preview | `countOnly` - how many parcels match, before you pay | No |

### Coverage (verified directory)

Every source below is a public, unauthenticated government ArcGIS service. It is re-checked live before each release.

| Area input | Publisher | Value published | Vacant filter | Notes |
|---|---|---|---|---|
| `FL/<any of the 67 counties>` e.g. `FL/Brevard`, `FL/Miami-Dade`, `FL/St. Lucie` | Florida Dept. of Revenue statewide cadastral | just value | yes (DOR codes 000/010/040/070) | Last two recorded sales only |
| `FL/Lee` | Lee County GIS | just value | yes | More sale history, zoning, property card link |
| `CT/<any of the 169 towns>` e.g. `CT/Andover` | Connecticut statewide CAMA + parcels | assessed (70% of appraised) | yes | Mailing ZIP is not published by the state |
| `MT/<any of the 56 counties>` e.g. `MT/Gallatin` | Montana Cadastral Framework | total appraised | yes | |
| `GA/Fulton` (Atlanta) | Fulton County | - | no | No value or sale columns in this layer |
| `TX/Williamson` | Williamson County (WCAD) | assessed, prior certified year | no | Acreage published for few parcels |
| `SC/York` | York County | appraised total | yes | |
| `OK/Canadian` | Canadian County assessor | total market value | yes | |
| `IN/Marion` (Indianapolis) | City of Indianapolis / Marion County | total assessed value | yes | |
| `OR/Marion` (Salem) | Marion County | real market value | yes | |
| `NY/Oswego` | Oswego County | full market value | yes (class 300-399) | |
| `AK/Fairbanks North Star` | Fairbanks North Star Borough | total assessed | yes | No property address - absentee flag stays empty, out-of-state works |
| `NC/Carteret` | Carteret County | estimated market value | yes | |

Every run writes the full directory to the `DIRECTORY` record.

**Any other county:** if your county publishes its parcels as a public ArcGIS layer, paste the layer URL into `customLayers`. Owner and mailing columns are detected automatically; you can also pass an explicit `fieldMap` (keys: this Actor's normalized field names only; columns that look like phone, email, SSN or birth date are rejected). Layers that require a token or login are skipped with a reason - never worked around.

### Filters

- `absenteeOnly` - mailing address differs from the property address (street number and street words compared after USPS normalization: `COUNTY ROAD 5` = `CR 5`, directionals and unit numbers ignored). Rows where it cannot be determined are left out, not guessed.
- `outOfStateOnly` - owner mails from another US state or from abroad (foreign owners carry `mailCountry`).
- `vacantLandOnly` - by the county's own land-use code or zero building value.
- `minAcres` / `maxAcres`, `minValue` / `maxValue`
- `ownerTypes` - individual, company, trust, government (a heuristic, see below); `excludeGovernment` is on by default. `individual` only works together with `includeIndividuals`.
- `includeIndividuals` - off by default: only companies, trusts and public bodies are written. Switching it on requires `acknowledgeLegalResponsibility`. See [Personal data & legal use](#personal-data--legal-use).
- `suppressOwners` - owner names that are never written (your own opt-out list).
- `landUseCodes`, `ownerNameContains`, `situsZipCodes` (prefixes work), `lastSaleBefore` (parcels without any recorded sale are kept).
- `whereClause` - raw ArcGIS SQL for power users.

Filters that a county supports are sent to its server, so only matching parcels are downloaded. If a server rejects a filter, the Actor retries once and then filters locally - the result is the same.

### Output

One row per parcel (`outputMode: parcels`):

`parcelId, state, area, situsAddress, situsCity, situsZip, ownerName, ownerName2, careOf, ownerType (heuristic), mailAddress1, mailAddress2, mailCity, mailState, mailZip, mailCountry, mailingAddressFull, landUseCode, landUseDesc, acres, totalValue, valueType, landValue, buildingValue, yearBuilt, lastSaleDate, lastSalePrice, yearsSinceLastSale, zoning, lat, lon, absenteeOwner, outOfStateOwner, vacantLand, sourceUrl, sourceId, sourceLayer`

Fields a county does not publish are `null`, never invented. For private persons (only with `includeIndividuals`) `lat`, `lon`, `ownerName2`, `careOf` and `rawAttributes` are always `null`.

Or one row per owner (`outputMode: owners`): owner name, type and mailing address, `parcelCount`, `absenteeParcelCount`, `vacantParcelCount`, `totalAcres`, `totalValue`, `areas`, `parcelIds`, `situsAddresses`. Use `minParcelsPerOwner: 3` to get portfolio owners only - they are usually the active buyers and landlords in a county. For private persons `parcelIds` and `situsAddresses` are `null`; only the count is written.

Example (Lee County, FL, owners mode, all owner types, 30,000 parcels scanned): 24,385 distinct owners, 672 with three or more parcels.

### Completeness

The `SUMMARY` record lists per area: parcels matching on the server, parcels scanned, rows written, and `complete: true` only if every matching parcel was read. Example: Brevard County, FL, out-of-state owners of vacant land >= 0.25 acres: 6,681 matching on the server, 6,681 scanned, 6,663 written (18 government-owned excluded; measured with all owner types), complete, in about 3.5 minutes. `countOnly` counts every owner type - private persons and redacted records are removed only when rows are read. Per area SUMMARY also counts `skippedIndividuals` and `skippedRedacted`. SUMMARY and the log hold counts only, never names.

### Cost control

- You pay per row written - never for parcels scanned or filtered out.
- `countOnly: true` asks each server how many parcels match and writes nothing: a free preview.
- `maxResults`, `maxResultsPerArea` and `maxCostUsd` (computed from the live event price) stop the run cleanly. The Apify "Max cost per run" limit is honoured as well.

### Being a good citizen

These are public government services. The Actor sends one request at a time per server with a pause between requests (`requestGapMs`, minimum 200 ms), identifies itself with an honest user agent, pages by object ID instead of deep offsets, backs off on 429/5xx and honours `Retry-After`. No proxies, no bot-protection bypass: services behind a login, token or bot protection are simply not in the directory.

### Data notes and limits

- Data is as current as the county's published roll - usually updated yearly, some counties more often.
- Value types differ by state (just, assessed, market) and are named in every row as `valueType`.
- Owner names are as recorded by the assessor.
- **`ownerType` is a heuristic**: a text rule on the owner name (keywords such as LLC, INC, TRUST, COUNTY OF). It is not a legal classification. A private person can be read as a company or trust, and the other way round - check before you rely on it.
- Public records only. This is not a consumer report - see the next section.

### Personal data & legal use

Parcel registers are public, but owner names and mailing addresses of private persons are still personal data.

- **You are the controller.** Under the Apify Standard Actor Contract (section 5.2.1) the user who runs this Actor is the controller of the personal data it processes; the Actor's creator acts as processor. You need your **own legal basis** for your purpose and you must give the people concerned the **information (transparency) the law requires** - for example when you contact them.
- **Acknowledgement required for personal data.** With `includeIndividuals` (or `includeRawAttributes`) on, a run only starts when `acknowledgeLegalResponsibility` is `true`; otherwise it stops at once with a message and fetches nothing. The default run - companies, trusts and public bodies only - needs no acknowledgement, because it writes no row whose owner the `ownerType` heuristic reads as a private person, and drops a second owner or c/o line that reads as a person (the heuristic can err - see Data notes). Note: trust and estate names often contain a person's name (e.g. "DOE JANE REVOCABLE TRUST", "ROE JOHN TRUSTEE") and are written in the default scope - for those you are the controller as well.
- **Not allowed:** any purpose covered by the **FCRA** (decisions about credit, employment, insurance, housing or other eligibility - this is not a consumer report), **stalking**, **locating, tracing or tracking people (identity or skip tracing)**, and **harassment** of any kind.
- **Contacting owners:** phone and text outreach is governed by the **TCPA**, the national and state **Do-Not-Call** lists and, for Florida, the **Florida Telephone Solicitation Act (s. 501.059, F.S.)**. This Actor delivers no phone numbers, but if you add them elsewhere, those rules are yours to follow.
- **No enrichment.** The output contains only what the public register publishes. The Actor adds **no phone numbers, no email addresses**, no social profiles and no data from other sources. Layer columns that look like phone, email, SSN or birth date are rejected in `fieldMap` and never requested as raw attributes.
- **Private persons are off by default.** Without `includeIndividuals` only companies, trusts and public bodies are written (by the `ownerType` heuristic), and a second owner or c/o line on such a row is kept only when it is itself a company, trust or public body - otherwise it is `null`. With it, private persons are minimized: no coordinates, no second owner, no c/o line, no raw columns, and in owners mode only the parcel count.
- **Redacted records are never written.** Rows whose name or address carries a marker such as CONFIDENTIAL, EXEMPT, REDACTED, ADDRESS PROTECTED or PROTECTED ADDRESS (for example Florida s. 119.071 exemptions or address confidentiality programs) are dropped.
- **Opt-out.** Names on the built-in opt-out list and in your `suppressOwners` input are never written, in any mode.
- **Nothing is kept between runs.** Each run reads the public source fresh; the Actor stores no owner data of its own.
- **Users in the EU/EEA** (or processing data of people there) are themselves subject to the **GDPR**, including Art. 6 (legal basis), Art. 14 (information when data is not collected from the person) and Art. 21 (right to object).

**Opt-out and erasure requests:** open an issue in this Actor's Issues tab on Apify (mark it 'Opt-out'); we add the name to the built-in suppression list within 30 days. From then on the name is removed from all future runs of this Actor.

### Input example

Default scope (companies, trusts, public bodies) - no acknowledgement needed:

```json
{
  "areas": ["FL/Brevard", "FL/Lee"],
  "outputMode": "parcels",
  "absenteeOnly": true,
  "vacantLandOnly": true,
  "minAcres": "0.25",
  "maxResults": 5000,
  "maxCostUsd": "20"
}
```

With private persons (the acknowledgement is required, otherwise the run stops before fetching anything):

```json
{
  "acknowledgeLegalResponsibility": true,
  "includeIndividuals": true,
  "areas": ["MT/Gallatin"],
  "outOfStateOnly": true,
  "maxResults": 500
}
```

# Actor input Schema

## `acknowledgeLegalResponsibility` (type: `boolean`):

Required only when "Include private persons" or "Include raw county attributes" is on - the default run (companies, trusts and public bodies, no person's name in any column) does not need it. Tick to confirm: you are the controller of any personal data in the output (Apify Standard Actor Contract 5.2.1), you have your own legal basis and give the people concerned the information the law requires; you will not use the output for FCRA purposes (credit, employment, insurance, housing decisions), stalking, locating or tracking people, or harassment; you follow TCPA, Do-Not-Call rules and the Florida Telephone Solicitation Act (s. 501.059). Users in the EU/EEA are themselves subject to the GDPR. With private persons or raw attributes on, the run stops at once when this is not ticked.

## `areas` (type: `array`):

Areas from the verified directory, written STATE/Name. Florida: all 67 counties (e.g. "FL/Brevard", "FL/Miami-Dade", "FL/St. Lucie"). Montana: any county ("MT/Gallatin"). Connecticut: any town ("CT/Andover"). Single counties: GA/Fulton, TX/Williamson, SC/York, OK/Canadian, IN/Marion, OR/Marion, NY/Oswego, AK/Fairbanks North Star, NC/Carteret. The full list is written to the DIRECTORY record of every run.

## `customLayers` (type: `array`):

Paste the URL of any public ArcGIS FeatureServer/MapServer parcel layer (…/FeatureServer/0). Owner and mailing columns are detected automatically. For full control pass objects: {"url": "…", "state": "FL", "label": "My County", "where": "CITY='X'", "fieldMap": {"ownerName": "OWNER", "mailAddress1": "MAIL\_ADDR", …}}. Allowed object keys: url, state, label, where, fieldMap, valueType. fieldMap keys must be normalized field names of this Actor; columns that look like phone, email, SSN or birth date are rejected. Layers that require a token or login are skipped, never worked around.

## `outputMode` (type: `string`):

"parcels" = one row per parcel. "owners" = one row per owner (same name + mailing address) with parcel count, parcel IDs, total acres and value - owners of several parcels are usually active buyers or landlords.

## `absenteeOnly` (type: `boolean`):

Owner's mailing address differs from the property address (or the owner mails from another state). Parcels where this cannot be determined are left out, not guessed.

## `outOfStateOnly` (type: `boolean`):

Owner's mailing state differs from the property's state.

## `vacantLandOnly` (type: `boolean`):

Vacant land by the county's own land-use code (e.g. Florida DOR 000/010/040/070) or zero building value. Areas that publish neither are skipped for this filter - see DIRECTORY.

## `minAcres` (type: `string`):

Minimum lot size in acres, e.g. 0.25

## `maxAcres` (type: `string`):

Maximum lot size in acres.

## `minValue` (type: `string`):

Minimum assessor value. Which value a county publishes (just, market, assessed) is named in every row as valueType.

## `maxValue` (type: `string`):

Maximum assessor value.

## `ownerTypes` (type: `array`):

Keep only these owner types: individual, company, trust, government. ownerType is a HEURISTIC text rule on the owner name, not a legal classification. "individual" requires includeIndividuals. Empty = all allowed types.

## `excludeGovernment` (type: `boolean`):

Drop parcels owned by counties, cities, states, the federal government, school and water districts. Recommended for land acquisition research.

## `includeIndividuals` (type: `boolean`):

Off (default): only rows whose owner looks like a company, trust or government body are written, and a second owner or c/o line is kept only when it is itself a company, trust or public body. On: requires "I am responsible for the legal use of this data". On: private persons are included, reduced to what the register purpose needs - no lat/lon, no second owner, no c/o line, no raw columns; in owners mode no parcel list, only the count. ownerType is a heuristic on the name text, not a legal classification.

## `suppressOwners` (type: `array`):

Owner names that must never be written, e.g. people who objected to you. Matching ignores case, punctuation and word order and checks owner, second owner and c/o. Applied on top of the Actor's built-in opt-out list.

## `landUseCodes` (type: `array`):

Keep only these raw county land-use codes (e.g. Florida DOR "000" vacant residential, "099" acreage). Codes differ per county - check the landUseCode column of a small test run.

## `ownerNameContains` (type: `string`):

Case-insensitive text match on the owner name, e.g. LLC or a company name.

## `situsZipCodes` (type: `array`):

Keep only properties in these ZIP codes (prefixes work: 329 = 329xx).

## `lastSaleBefore` (type: `string`):

Keep parcels whose last recorded sale is before this date (2015 or 2015-06-30). Parcels without any recorded sale are kept - for long-held lists that is the strongest signal.

## `minParcelsPerOwner` (type: `integer`):

In owners mode, keep only owners with at least this many matching parcels.

## `maxResults` (type: `integer`):

Stop after this many rows in total. You pay per row written - never for scanned or filtered-out parcels.

## `maxResultsPerArea` (type: `integer`):

Optional cap per county/area (parcels mode).

## `maxCostUsd` (type: `string`):

The run stops cleanly before this amount is reached, calculated from the live price. Leave empty for no cap.

## `countOnly` (type: `boolean`):

Only ask each server how many parcels match (filters that the county supports server-side are included). Writes no rows, charges no rows.

## `maxScanPerArea` (type: `integer`):

Safety limit for very large areas with strict filters. SUMMARY says whether an area was scanned completely (compared with the server's own count).

## `whereClause` (type: `string`):

Raw SQL appended with AND for power users, using the layer's own column names, e.g. PHY\_CITY='MIMS' for Florida.

## `pushdownFilters` (type: `boolean`):

Filters verified per county are sent to the GIS server so fewer parcels are downloaded. If a server rejects one, the Actor falls back to local filtering automatically.

## `includeRawAttributes` (type: `boolean`):

Add the original columns of the county layer as rawAttributes (bigger rows). Columns that look like phone, email, SSN or birth date are never requested. Not written for private persons. Requires "I am responsible for the legal use of this data" (raw columns can hold co-owner names).

## `requestGapMs` (type: `integer`):

Minimum pause between two requests to the same government server. These are public services - be polite.

## Actor input object example

```json
{
  "acknowledgeLegalResponsibility": false,
  "areas": [
    "FL/Brevard",
    "FL/Lee",
    "MT/Gallatin"
  ],
  "customLayers": [],
  "outputMode": "parcels",
  "absenteeOnly": false,
  "outOfStateOnly": false,
  "vacantLandOnly": false,
  "excludeGovernment": true,
  "includeIndividuals": false,
  "minParcelsPerOwner": 1,
  "maxResults": 20,
  "countOnly": false,
  "maxScanPerArea": 250000,
  "pushdownFilters": true,
  "includeRawAttributes": false,
  "requestGapMs": 350
}
```

# Actor output Schema

## `rows` (type: `string`):

One row per parcel (or per owner in owners mode).

## `summary` (type: `string`):

Per area: server match count, parcels scanned, rows written, complete yes/no, stop reason, field notes; amount charged.

## `directory` (type: `string`):

All verified county/state parcel layers with their publisher and notes.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "areas": [
        "NY/Oswego"
    ],
    "customLayers": [],
    "maxResults": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("thequietstack/us-parcel-owner-lists").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "areas": ["NY/Oswego"],
    "customLayers": [],
    "maxResults": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("thequietstack/us-parcel-owner-lists").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "areas": [
    "NY/Oswego"
  ],
  "customLayers": [],
  "maxResults": 20
}' |
apify call thequietstack/us-parcel-owner-lists --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thequietstack/us-parcel-owner-lists"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/vX7tam9NUw0t87W44/builds/aaZUft43p2cSNSeXy/openapi.json
