US Property Assessment Scraper — Values, Owners & Sale Price
Pricing
from $4.80 / 1,000 property record scrapeds
US Property Assessment Scraper — Values, Owners & Sale Price
County assessor data from 13 states and 45.5M parcels: assessed value, market value, land and improvement value, tax year, last sale date and price, owner, acreage, year built, mailing address. Search by address, parcel or owner; each owner search returns a free portfolio row with absentee count.
Pricing
from $4.80 / 1,000 property record scrapeds
Rating
0.0
(0)
Developer
Vladimir Chernykh
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 hours ago
Last modified
Categories
Share
US Property Assessment Data Scraper — Assessed Value, Sale Price & Owner
Scrape US property assessment and sales data from the official statewide parcel layers that
county assessors and state GIS offices publish themselves. No proxy, no API key, no login, no
CAPTCHA. Thirteen states are measured and served, covering 45 542 174 parcels. Every number on
this page comes from querying the layer's own returnCountOnly endpoint before the state was added —
not from a vendor datasheet.
You pay for valuation, tax and sale depth, not for a name-and-address list. Of the 13 states, 10 return a valuation (land value, improvement value, total or assessed or market value), 5 return a last sale date, 4 a last sale price and 4 the tax year the value applies to — and where a source does not publish one of these, the row says so instead of leaving an unexplained blank.
Every state it serves, and the format each one returns
The point of this table is that you can see before you spend a cent whether your state and your
fields are covered. Full means the layer carries that group for the whole state. — means the
source does not publish the column at all, so no row from that state will ever contain it — and each
such row says so explicitly in its omitted array.
| State | Jurisdictions covered | Parcels | Returns owner | Returns situs address | Returns mailing address | Returns valuation | Returns county FIPS | Lookups that work |
|---|---|---|---|---|---|---|---|---|
| North Carolina (NC) | 100 / 100 counties | 5 938 804 | yes | yes | yes | yes | yes | owner, address, parcel |
| New York (NY) | 62 / 62 counties | 5 510 061 | yes (+ co-owner, owner type) | yes | yes | yes | yes | owner, address, parcel |
| California (CA) | 58 / 58 counties | 13 138 000 | — | yes | — | — | yes | address, parcel |
| Colorado (CO) | 44 / 64 counties | 2 599 937 | yes (+ co-owner) | yes | yes | assessed value | yes | owner, address, parcel |
| Arkansas (AR) | 75 / 75 counties | 2 149 448 | yes | yes | — | yes | yes | owner, parcel |
| Connecticut (CT) | 8 / 8 counties | 1 282 833 | yes (+ co-owner) | yes | yes | yes, plus tax year | yes | owner, parcel |
| Maryland (MD) | 24 / 24 jurisdictions | 2 395 737 | — | yes | yes | yes | yes | address, parcel |
| Massachusetts (MA) | 351 / 351 municipalities | 2 559 749 | yes | yes | yes | yes, plus tax year | — | owner, address, parcel |
| Utah (UT) | 29 / 29 counties | 1 600 062 | — | yes | — | — | — | address, parcel |
| Virginia (VA) | county column absent | 76 957 | yes | — | yes | yes | — | owner, parcel |
| Washington (WA) | 39 / 39 counties | 3 321 859 | — | yes | — | yes | 38 of 39 counties | address, parcel |
| West Virginia (WV) | 55 / 55 counties | 1 394 081 | yes (+ co-owner) | street line | street line | — | — | owner, address, parcel |
| Wisconsin (WI) | 72 / 72 counties | 3 574 646 | yes (+ co-owner) | yes | yes | yes, plus tax year | yes | owner, parcel |
The same table as rows and columns per state
| State | Fields the layer actually fills | Fields the source lacks (declared per row) |
|---|---|---|
| NC | parcel, county name, FIPS, jurisdiction, owner, co-owner, owner type, land value, improvement value, total value, acreage, land use code, land use, year built, last sale date, situs, mailing | market value, assessed value, tax year, building sq ft, last sale price |
| NY | parcel, county, FIPS, jurisdiction, owner, co-owner, owner type, land value, improvement value, total value, market value, tax year, acreage, land use code, year built, building sq ft, situs, mailing | assessed value, land use text, sale date, sale price |
| CA | parcel, county, FIPS, situs address | owner (all owner fields), mailing address, every valuation field, acreage, year built, building sq ft, land use, sale date, sale price |
| CO | parcel, county, FIPS, owner, co-owner, total value, assessed value, acreage, land use code, land use, sale date, sale price, situs, mailing | jurisdiction, owner type, land value, improvement value, market value, tax year, year built, building sq ft |
| AR | parcel, county, FIPS, owner, land value, improvement value, total value, assessed value, land use code, situs | jurisdiction, co-owner, owner type, mailing address, market value, tax year, acreage, year built, sale date, sale price |
| CT | parcel, FIPS, jurisdiction, owner, co-owner, land value, improvement value, total value, assessed value, tax year, acreage, land use code, land use, year built, building sq ft, sale date, sale price, situs, mailing | county name, owner type, market value |
| MD | parcel, FIPS, land value, improvement value, total value, acreage, land use code, land use, year built, building sq ft, sale date, sale price, situs, mailing | county name, jurisdiction, owner (all owner fields), market value, tax year |
| MA | parcel, municipality, owner, land value, improvement value, assessed value, tax year, acreage, land use code, land use, year built, building sq ft, sale date, sale price, situs, mailing | county name, county FIPS, co-owner, owner type, market value |
| UT | parcel, county, owner type, situs address | FIPS, jurisdiction, owner name, co-owner, mailing address, every valuation field, acreage, land use, year built, building sq ft, sale date, sale price |
| VA | parcel, owner, land value, improvement value, total value, land use code, land use, mailing address | county name, FIPS, jurisdiction, co-owner, owner type, situs address, market value, assessed value, tax year, acreage, year built, building sq ft, sale date, sale price |
| WA | parcel, FIPS, land value, improvement value, land use code, situs address | jurisdiction, owner (all owner fields), mailing address, market value, assessed value, tax year, acreage, year built, building sq ft, sale date, sale price |
| WV | parcel, owner, co-owner, acreage, situs street line, mailing street line | county name, FIPS, jurisdiction, owner type, every valuation field, land use, year built, building sq ft, sale date, sale price |
| WI | parcel, county, FIPS, owner, co-owner, land value, improvement value, assessed value, market value, tax year, acreage, land use code, situs, mailing street line | jurisdiction, owner type, land use text, year built, building sq ft, sale date, sale price |
California is the largest layer here (13.1 M parcels) and the sparsest in columns: it publishes geometry-linked parcel identity and address, and nothing about the owner. That is a property of the source, not a mapping gap — and the run summary reports it as such.
Which states actually return value and sale prices
This is the part most property datasets obfuscate, so it is on one screen.
| State | Value fields returned | Tax year | Last sale | Physical |
|---|---|---|---|---|
| NC | land, improvement, total | — | date only | acreage, year built, land use |
| NY | land, improvement, total, market | yes | — | acreage, year built, sq ft, land use |
| CA | none | — | — | — |
| CO | total, assessed | — | date + price | acreage, land use |
| AR | land, improvement, total, assessed | — | — | land use |
| CT | land, improvement, total, assessed | yes | date + price | acreage, year built, sq ft, land use |
| MD | land, improvement, total | — | date + price | acreage, year built, sq ft, land use |
| MA | land, improvement, assessed | yes | date + price | acreage, year built, sq ft, land use |
| UT | none | — | — | — |
| VA | land, improvement, total | — | — | land use |
| WA | land, improvement | — | — | — |
| WV | none | — | — | acreage |
| WI | land, improvement, assessed, market | yes | — | acreage, land use |
A dash is a fact about the source, and the same fact is repeated in the omitted array of every row
from that state. Nothing here is inferred to fill a column.
The omitted array is the reason to trust a blank cell
Every canonical field exists on every record. When one is null, it is never silent — the row
carries omitted, an array naming the field and the reason:
source-lacks-field— the layer has no such column. No record from this state will ever have it.not-published— the column exists, but this row's value was blank.derived— the number was computed rather than read, and it says so (New York's improvement value; North Carolina's glued addresses).not-covered— the jurisdiction is outside the layer.lookup-miss— you searched, and nothing matched.filtered— your own input excluded it.
So lastSaleDate: null with { "field": "lastSaleDate", "reason": "source-lacks-field" } means
"this county does not publish sale dates", not "this house never sold". Those are different
statements and only one of them is true. A property data scraper that quietly leaves cells empty
forces you to guess which. This one does not.
Input parameters
| Parameter | Type | Default | What it does |
|---|---|---|---|
ownerNames | string list | — | Owner-name search, one name per row, minimum 3 characters. Partial match: SILVER PINES finds SILVER PINES PROPERTIES LLC. |
addresses | string list | — | Situs address search, one per row, minimum 4 characters, with a street-only fallback. 609 MAIN ST works better than 609 Main Street, Raleigh, NC 27601. |
parcelIds | string list | — | Parcel number as the county writes it. 1234-56-789, 123456789 and 1234 56 789 are all tried. New York wants the PRINT_KEY value. |
states | multi-select | all | Which of the 13 states to query. A state measured as broken is an error naming the measurement, not a silent empty dataset. |
bulk | boolean | false | Ignore lookup lists and sample rows straight from the layer, to inspect a source before paying for lookups. |
bulkCount | integer | 50 | Rows per state in bulk mode (max 1000). The layer's own maximum is respected and truncation is reported. |
maxRecords | integer | 50 | Hard cap for the whole run across all states — this is also your cost cap (max 1000). |
maxRecordsPerLookup | integer | 10 | How many parcels one owner name or one address may return. Stops a surname like SMITH from eating the budget. |
ownerPortfolio | boolean | true | After every owner search, push one free owner_portfolio row: parcels returned, counties, value totals with the count of records behind each total, acreage, absentee count. Never billed. |
includeRaw | boolean | false | Attach the untouched source attributes to each record under raw, for columns outside the mapped set. |
maxConcurrency | integer | 2 | Parallel lookups. The layers are public and unauthenticated; 2 is polite and fast enough. |
requestTimeoutSecs | integer | 45 | Per-request timeout. New York answers in 6–8 seconds from the platform, so do not go below 20. |
chargePerRecord | boolean | true | Emits one billing event per distinct record pushed. Missed lookups are never charged. |
Example — lookups across two states:
{"ownerNames": ["SILVER PINES PROPERTIES LLC"],"addresses": ["105 E MAIN ST"],"parcelIds": ["010100000100001000100000"],"states": ["NC", "NY"],"maxRecords": 200}
Example — sample a state without spending on a lookup list:
{ "bulk": true, "bulkCount": 100, "states": ["NC"] }
Output
Two row shapes share the dataset. Parcel rows are one per parcel, identical across all 13 states; the
free owner_portfolio row described below is the only other rowType. Filter on rowType if you feed
the dataset straight into a pipeline.
| Group | Fields |
|---|---|
| Identity | state, countyName, countyFips, jurisdiction, parcelId, parcelIdType |
| Owner | ownerName, ownerName2, ownerType |
| Property address | situsAddress (street1, street2, city, state, zip) and ownerMailingAddress |
| Valuation | landValue, improvementValue, totalValue, assessedValue, marketValue, valuationType, taxYear |
| Physical | acreage, buildingSqFt, yearBuilt, landUseCode, landUse |
| Sale | lastSaleDate, lastSalePrice |
| Provenance | source, sourceUrl, lookupType, scrapedAt, raw |
| Honesty | completeness, omitted |
The free owner_portfolio row
A list of parcels does not tell you whether you found a landlord or a resident. So every owner search
also emits one summary row of rowType: "owner_portfolio", and that row is never charged:
{"rowType": "owner_portfolio","ownerQuery": "GLOVER FARMS OF CAROLINA LLC","state": "NC","parcelCountReturned": 10,"totalMatches": 16,"truncated": true,"counties": { "Northampton": 10 },"countiesCount": 1,"ownerNames": ["GLOVER FARMS OF CAROLINA LLC"],"valueTotal": 505779,"valueRecords": 10,"valueBasis": ["totalValue"],"lastSalePriceTotal": null,"lastSalePriceRecords": 0,"acreageTotal": 1170.55,"acreageRecords": 10,"absenteeCount": 0,"absenteeComparableRecords": 10,"totalsScope": "all_returned_records","note": null}
Three things make it honest rather than decorative. Every total carries the number of records that
actually contributed to it, and totalsScope drops to records_that_publish_the_field the moment the
state does not fill that field on every row — so a portfolio total is never silently divided by the
wrong denominator. totalMatches comes from the layer's own returnCountOnly count on the same
where clause, so you can see how much of the portfolio you were truncated out of. And absenteeCount
only counts a parcel when the record publishes both the mailing state and the situs state; if it does
not, the count is null with a note explaining why, because "0 absentee owners" and "I cannot tell"
are different answers.
valueTotal follows the state, not a single field: it sums the best valuation each record publishes —
assessedValue first, then marketValue, then totalValue — and valueBasis names which one it used.
That is why North Carolina, which publishes only total value, still returns a portfolio figure instead
of null.
States are inferred from the addresses you give
Leave states empty and the actor reads the state out of each address, so a Florida address queries
Florida instead of sweeping all 13 states. It understands Lakeland, FL 33813, WI 546428226 with a
glued ZIP+4, and the spelled-out Ohio. When every address resolves, the run narrows to those states
and says so in the log; when only some do, it warns and queries everything rather than silently
dropping the addresses it could not read.
A SUMMARY record lands in the key-value store with a per-state breakdown: the coverage statement,
the layer's live row count and drift since it was probed, lookup hits and misses, bulk-slice stats,
fieldAudit (which mapped columns the layer actually replied with and which were missing) and
omissions (for each null field, how many records lacked it and why). If a source changes its schema
under you, fieldAudit is where you see it, in the run where it happened.
How matching behaves
- Owner —
LIKE '%value%'on the owner column. The column holds the name as the county recorded it, so try the surname first, then the full entity name. - Address —
LIKEon the situs street line with a street-only fallback, because layers store the county's own formatting and a full address with city and ZIP often fails to match it. - Parcel — exact match, tried three times: verbatim, compact, compact without dashes.
- Deduplication happens before billing, so overlapping lookups never charge twice for the same parcel. A lookup that matches nothing costs nothing.
What it is not
- Not a nationwide scraper. Thirteen measured states out of fifty. The registry is data, so adding a state means adding an entry — but each entry needs a real probe first, and ten candidates were probed and rejected because their layers refuse queries or lack owner and address columns.
- Not a deeds or liens database. This is the assessor's roll: ownership, value, physical description. Transfers appear only where the source publishes them — you get the last sale, not a sale history, because the layers carry a current snapshot rather than a transaction ledger.
- Not a uniform field set. Four states publish the tax year, five publish a sale date, two publish
market value. The table above is the contract; a field absent from it is absent from every row of
that state, with the reason recorded in
omitted. - Not a tax-bill calculator.
taxYeartells you which assessment year the value belongs to. The millage rate is set by each jurisdiction separately and is not in these layers. - Not a guarantee of a situs address in every county. Address completeness is county-dependent and it was measured, not assumed: in North Carolina only 25 of 100 counties publish a situs city and 90 of 100 publish a situs street.
- Not a source of exact coordinates. Geometry is not returned; the parcel number and county FIPS join to any public parcel geometry you already have.
- Not free of the source's own lag. These are annual assessment rolls. A sale recorded last month is not in them yet.
Cost and speed
$5 per 1 000 records — $0.005 per record, and the Store adds its 20 % margin, so you pay
$6 per 1 000. Plus one apify-actor-start event per run at $0.00005. You are billed per parcel
record pushed to the dataset, not per request and not per lookup, and maxRecords is therefore a
real spend cap. The owner_portfolio summary row is free, and so is every lookup that matches
nothing — a run that finds no parcels costs only the start event. chargePerRecord: false disables
billing entirely.
Most layers answer a query in about 2 seconds. New York takes 6–8 seconds, which is why the timeout defaults to 45. Concurrency defaults to 2 because the services are public and unauthenticated, and hammering them is how you get throttled.
Keywords this actor is built for
property assessment data scraper · property tax records by owner name · county assessor assessed value lookup · US parcel data with sale price · land and improvement value data · property owner mailing address list · absentee owner list · acreage and year built data · real estate lead generation by owner · situs address and parcel number search.
Frequently asked
Does it need a proxy? No. These are public ArcGIS and REST services, and the actor talks to them directly — which is also why it is fast and why no proxy cost is baked into the price.
What happens to states whose layer is broken? They are rejected at probe time and recorded with the exact error. Asking for one is a run error that names the measurement, so you never mistake "the source is dead" for "there is no such owner".
Can I get the raw columns? Yes — set includeRaw: true and each record carries the untouched
source attributes under raw, alongside the normalised fields.
Do I get a tax history or a sale history? No, and neither does a scraper that claims to: these
layers publish the current roll — the latest assessed value, the latest sale — not a yearly
ledger. What you get instead is the year the value applies to (taxYear, where the source publishes
it), so you can tell a 2023 assessment from a 2025 one, and omitted tells you when a state does not
say.
How do I find absentee owners? Search the owner name across a state and read absenteeCount on
the free portfolio row: it counts parcels whose recorded mailing state differs from the parcel's own
state. It is null — not 0 — where the source publishes no mailing state, because a missing column
is not evidence of an owner who lives on site.