US Property Owner & Parcel Records Scraper
Find who owns a US property from the public assessment roll. Search 7.6M parcels by address, owner name, city, postal code or parcel id.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
jurisdictions,address,ownerName(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.0007 per parcel record = $0.7 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Parcel record | One property parcel with its owner of record. Jurisdictions that cannot answer a filter are skipped and never charged. | $0.0007 |
Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-09-20, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
jurisdictions | The places this Actor covers. Pick one or more. Every extra place you tick is another lookup, and the row budget below is shared between them - so for a single address, tick only the place it is in. | array |
address | A street address, written the way you would write it: "2125 Bruckner Blvd". The house number has to start the address, and after that the words are matched however the local roll happens to spell them - Blvd finds BOULEVARD, Ave finds AV. Leave off apartment and unit numbers; most rolls keep those in a separate column. A street name on its own, with no number, returns the whole street. | string |
ownerName | Part of an owner name. Word order does not matter - "John Smith" finds a roll that writes "SMITH JOHN". Every word you type has to appear, so fewer words finds more. Useful for tracking one landlord or LLC across a whole city. | string |
city | A city or town name, for the places that cover more than one. In New York City this is the borough - Brooklyn, Queens, Manhattan, Bronx, Staten Island. A place that cannot honour it is skipped with a note rather than quietly handing you a different city's parcels. | string |
zipCode | A five-digit postal code of the PROPERTY, not of the owner's mailing address. Connecticut, Vermont and Cambridge publish no property postal code at all - only the owner's - so those three are skipped with a note when you use this rather than answering with the wrong one. | string |
parcelIds | Look up parcels directly by their identifier. Every place uses its own and calls it its own thing: a New York BBL, a Cook County PIN, a Philadelphia OPA account number, a Vermont SPAN, a Montana geocode, a Washington DC square-suffix-lot, a Texas property id. Up to 200 per run. Type a DC SSL with single spaces - "1077 0130" finds the record however the roll pads it. Ids that do not look like they belong to a place you ticked are skipped there with a note. | array |
maxItems | How many parcels to return in total, across every place you ticked. The budget is shared between them. Keep it low while you are trying things out - you pay per row. Hard ceiling 5,000. | integer |
proxyUrls | Leave this empty. The run brings its own egress and it costs you nothing per gigabyte. Fill it in only if you specifically want the traffic to leave through servers you already pay for, as http://user:pass@host:port. | array |
What you get
A structured dataset — each result includes fields like:
jurisdictionNameownerNamepropertyAddresspropertyCitypropertyStatepropertyZipparcelIdpropertyUseyearBuiltassessedTotalUsdmarketValueUsdlastSaleDatelastSalePriceUsdrecordUrlExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
Related tools in Developer & Research Tools
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
GitHub Scraper
Search GitHub repos and users: stars, forks, language, topics, licence, plus user bio, company and followers. No token needed. $0.90 per 1,000 rows.
Stack Overflow / Stack Exchange Scraper
Search Stack Overflow and Stack Exchange by keyword or tag. Score, answer count, views, reputation and body text. $2 per 1,000 questions.
Package Registry Scraper (npm + PyPI)
Get npm and PyPI package metadata as JSON. Version, license, author, repo, keywords and npm monthly downloads. $2 per 1,000 packages.
arXiv Scraper
Search arXiv papers by title, author, abstract or category. Get full abstracts, authors, categories, DOI, dates and PDF links. $2 per 1,000 papers.
OpenAlex Scholarly Works Scraper
Search 250M+ OpenAlex papers with no API key. Get titles, authors, venue, year, citations, DOI, OA links and full abstracts. $2.00 per 1,000 papers.
Crossref Scholarly Works Scraper
Search 150M+ papers on Crossref: DOI, title, authors, journal, publisher, date, citations and abstract. No API key. $1.00 per 1,000 works.
Where this tool sits
- Categories
- Developer & Research Tools
US Property Owner Lookup
Ask who owns a property and get the answer off the public assessment roll: the owner of record, the property address, what the place is, what it is assessed at, and where the record came from. Thirteen jurisdictions, about 7.6 million parcels, read straight from the government open-data host each one publishes on. No account, no key, no cookies, no browser.
- Search by street address, owner name, city or town, postal code, or parcel id.
- Address matching survives however the local roll spells things - type "Blvd" and it finds BOULEVARD, type "Ave" and it finds AV.
- Owner search ignores word order, so "John Smith" finds a roll that writes "SMITH JOHN".
- Every row carries a
recordUrlpointing straight back at the public record it came from, so anything here can be checked at the source. - A place that cannot answer one of your filters is skipped with a written reason, not quietly handed back as somebody else's parcels.
- Empty input returns one labelled sample row, free.
Price
$0.70 per 1,000 parcels, plus a $0.0015 start fee per run.
This is a flat rate on every plan, free or paid. There are no volume tiers, no minimum spend, no subscription and no add-on fees. What you read here is what you pay on day one and on day four hundred.
| Parcels | Total cost |
|---|---|
| 10 | $0.0085 |
| 100 | $0.0715 |
| 1,000 | $0.7015 |
| 5,000 | $3.5015 |
A run returns at most 5,000 parcels, so each line above is a single run and a single start fee.
What is actually charged
- One
parcel-recordevent per parcel row written to the dataset. Nothing else is metered per row. - Free: the sample row an empty run returns, and every diagnostic row — a blocked target, a dead URL, a search that matched nothing. Those rows all carry
"charged": false. - Records that came back from a roll but did not match what you asked for are dropped before they are charged, and the run tells you how many.
- A parcel that turns up twice in one run is charged once.
- A jurisdiction that cannot honour one of your filters costs nothing - it is skipped and explained.
- A run that finds nothing costs the start fee and nothing more.
- Rows never leave the dataset without a charge, and are never charged without a row. The billed event is a named one, so there is no price quietly attached to
apify-default-dataset-item— the trick that makes some scrapers bill you for their own error messages.
Input
{
"jurisdictions": [
"nyc"
],
"address": "2125 Bruckner Blvd",
"maxItems": 25
}
| Field | What it does |
|---|---|
jurisdictions | Which places to search. One or more of nyc, connecticut, cook-county-il, philadelphia, collin-county-tx, williamson-county-tx, norfolk-va, cambridge-ma, montana, wake-county-nc, vermont, nashville-tn, washington-dc. Every extra one is another lookup and they share the row budget, so for a single address tick only the place it is in. |
address | A street address as you would write it. The house number has to come first. Leave apartment and unit numbers off - most rolls keep those in their own column. A street name with no number returns the whole street. |
ownerName | Part of an owner name. Every word you type has to appear somewhere in the name, in any order. |
city | A city or town, for the places that cover more than one. In New York City this is the borough. |
zipCode | A five-digit postal code of the property. Connecticut and Cambridge publish no property postal code, so both are skipped with a note when you use it. |
parcelIds | Look parcels up directly by identifier - a BBL, a PIN, an OPA account number, a Texas property id. Up to 200 per run. |
maxItems | Total rows across every place ticked. Default 25, ceiling 5,000. The budget is shared, so thirteen places and 25 rows is about two each. |
proxyUrls | Leave empty. Only for callers who want the traffic to leave through servers they already pay for. |
Run it with empty input and you get one clearly labelled sample row, free, so you can see the output shape before you spend anything.
Output
One row per parcel. A real row from a real run:
{
"ok": true,
"charged": true,
"recordType": "parcel",
"jurisdiction": "nyc",
"jurisdictionName": "New York City, NY",
"state": "NY",
"ownerNameSource": "assessment roll",
"parcelId": "2038060070",
"parcelIdType": "BBL (borough-block-lot)",
"ownerName": "LAURA IRIS VALENTIN REVOCABLE TRUST",
"coOwnerName": null,
"ownerMailingAddress": null,
"propertyAddress": "2125 BRUCKNER BOULEVARD",
"propertyCity": "Bronx",
"propertyState": "NY",
"propertyZip": "10472",
"unit": null,
"propertyUse": "Mixed residential and commercial buildings",
"buildingDescription": "Building class S4",
"landAreaSqFt": 2627,
"buildingAreaSqFt": 5003,
"unitsTotal": 5,
"unitsResidential": 4,
"buildingCount": 1,
"stories": 2,
"yearBuilt": 1929,
"assessedLandUsd": 182700,
"assessedTotalUsd": 359550,
"zoning": "R5",
"latitude": 40.8275484,
"longitude": -73.8521013,
"rollLabel": "PLUTO 26v2",
"dataPublisher": "NYC Department of City Planning (PLUTO)",
"recordUrl": "https://data.cityofnewyork.us/resource/64uk-42ks.json?bbl=2038060070",
"scrapedAt": "2026-09-20T08:31:04.013Z"
}
Field notes
ownerName— the name on the roll, exactly as the roll writes it. Rolls are inconsistent about this: "SMITH JOHN A & MARY B" and "Smith, John" are both normal.ownerNameSource— what kind of name it is. Most sayassessment rollorappraisal roll, and Vermont saysgrand list, which is Vermont's name for the same thing. Cook County saystaxpayer of record, because that is what the Assessor publishes there and it is not the same thing as a deeded owner.parcelId— the local identifier, andparcelIdTypesays which kind it is. Stable, so it is the right key to re-run against.recordUrl— the public record this row was read from. Open it and you see the same parcel.rollLabel— which roll the row came from - "PLUTO 26v2", "Grand list 2025", "Tax year 2026", "Assessed 2025-01-01". Four of the thirteen sources keep every year in one table, and the run asks each one which year is newest rather than assuming. Vermont is the awkward one and its rows say so: every town is on the extract from the year it last filed, which is 2026 in some towns and 2018 in others.assessedTotalUsd— the assessed figure, which in most places is not the market price. Philadelphia has no single assessed total, so it is land plus building.lastSaleDate— the last transfer the roll records. It is not a deed search and there is no chain of title.propertyCity— in New York City this is the borough, because PLUTO has no city column and the borough is the unit that means something there.
Every real row carries "charged": true. Sample rows carry "_sample": true and diagnostic rows carry "_diagnostic": true with an errorCode you can filter on, and neither is ever billed.
How it works
- Each jurisdiction publishes its own assessment or appraisal roll on a government open-data host. The run reads those directly, over plain HTTP, and asks for only the columns that end up in a row. On the mapping hosts it also leaves the parcel boundary behind, which on a rural county is most of the payload and none of the answer.
- Your filters are sent to the host and applied there, and then every row is checked again on the way out against what you asked for. Anything that does not match is dropped and not charged.
- The four rolls that keep several years in one table are asked which year is their newest, every run, so a county publishing next year's roll does not leave this quietly serving last year's owners.
- Rate limits on the source are handled automatically, so a throttle does not stop the run.
- Nothing is joined to anything else. A row is the public record, and only the public record.
What people use it for
- Finding out who actually owns a building when the listing, the letterbox and the management company all say something different.
- Tracking one landlord or one LLC across a whole city - search the owner name and get every parcel on the roll under it.
- Building an absentee-owner list: search a city or postal code and compare the property address against the owner mailing address, which the roll publishes side by side in ten of the thirteen places here.
- Checking a portfolio you already have against the record - feed in the parcel ids and diff on
ownerNameafter each roll is published. - Filling in what a listing site leaves out: land area, year built, assessed value and the last recorded sale, for parcels that are not on the market and so are not on any listing site.
- Research and journalism, where the point is that every row links back to the public record it came from.
What is covered
Thirteen jurisdictions across eleven states and the District of Columbia, about 7.6 million parcels. Every figure below was counted on the live roll, not read off a documentation page.
| Where | Parcels | Published by | The owner name is |
|---|---|---|---|
| New York City, NY | 858,284 | NYC Department of City Planning (PLUTO) | the assessment roll |
| Connecticut (statewide) | 1,347,910 | State of Connecticut Office of Policy and Management | the assessment roll |
| Cook County, IL | 1,863,562 | Cook County Assessor | the taxpayer of record |
| Philadelphia, PA | 583,779 | City of Philadelphia Office of Property Assessment | the assessment roll |
| Collin County, TX | 479,364 | Collin Central Appraisal District | the appraisal roll |
| Williamson County, TX | 291,076 | Williamson Central Appraisal District | the appraisal roll |
| Norfolk, VA | 74,329 | City of Norfolk Office of the Real Estate Assessor | the assessment roll |
| Cambridge, MA | 30,156 | City of Cambridge Assessing Department | the assessment roll |
| Montana (statewide) | 921,301 | Montana State Library, from Department of Revenue assessment data | the appraisal roll |
| Wake County, NC | 438,403 | Wake County Department of Tax Administration | the assessment roll |
| Vermont (statewide) | 344,019 | Vermont Center for Geographic Information | the grand list |
| Nashville and Davidson County, TN | 287,112 | Metro Nashville Assessor of Property | the assessment roll |
| Washington, DC | 137,400 | DC Office of Tax and Revenue, via DC GIS | the assessment roll |
- New York City, NY — All five boroughs: Manhattan, Bronx, Brooklyn, Queens, Staten Island.
- Connecticut (statewide) — Every town in the state, on the state-published parcel and CAMA extract.
- Cook County, IL — Chicago and the rest of Cook County. Owner name, property address and mailing address only. This roll publishes no valuation or building detail.
- Philadelphia, PA — The whole city, on the Office of Property Assessment roll.
- Collin County, TX — Plano, Frisco, McKinney, Allen, Wylie and the rest of the county, on the appraisal district roll.
- Williamson County, TX — Round Rock, Georgetown, Cedar Park, Leander and the rest of the county, on the appraisal district roll.
- Norfolk, VA — The whole city, on the real estate assessment roll.
- Cambridge, MA — The whole city, on the property database. This roll publishes building detail but no assessed value.
- Montana (statewide) — Every county. Owner, valuation and acreage are on 99% of parcels, but only about half carry a street address - Montana has a lot of land with nothing on it - so owner and town searches reach the whole state while an address search reaches the half that has one.
- Wake County, NC — Raleigh, Cary, Apex, Wake Forest, Holly Springs and the rest of the county. The fullest roll here: owner, address and valuation on essentially every parcel, year built and last sale on most.
- Vermont (statewide) — Every town, on the standardized parcel extract. Each town appears at the year it last filed and that is not the same year everywhere: Burlington is on its 2025 list, Rutland City is still on 2018. Every row says which year it is. About one parcel in eight has no grand list entry matched to it yet; those carry no owner, and they are dropped and not charged rather than handed to you blank.
- Nashville and Davidson County, TN — The whole consolidated city and county. Owner, address, appraised value, zoning and acreage on effectively every parcel.
- Washington, DC — The whole District, on the common ownership lot layer. Owner, assessment and land area on 97% of lots. The other 3% are public space and rail beds, which have an owner but no street address.
That is the whole list. This is not every county in the United States and it does not pretend to be - most US counties publish nothing machine-readable, and the ones that do are added here only after their roll has been read and checked. If the place you need is not on the list above, this Actor has nothing for it and will say so rather than guessing.
What each roll actually publishes
Rolls differ, and a column one city publishes another simply does not have. Rather than inventing a value, the field is null and this table says where to expect that.
| Where | Owner mailing address | Assessed or market value | Year built | Last sale | Coordinates |
|---|---|---|---|---|---|
| New York City, NY | not published | assessed | yes | not published | yes |
| Connecticut | yes | both | yes | date and price | not published |
| Cook County, IL | yes | not published | not published | not published | not published |
| Philadelphia, PA | yes | both | yes | date and price | not published |
| Collin County, TX | yes | both | yes | date only | not published |
| Williamson County, TX | yes | assessed | yes | not published | not published |
| Norfolk, VA | not published | assessed | yes | date and price | not published |
| Cambridge, MA | not published | not published | yes | not published | yes |
| Montana | yes | assessed | not published | not published | not published |
| Wake County, NC | yes | assessed | yes | date and price | not published |
| Vermont | yes | assessed | not published | not published | not published |
| Nashville, TN | yes | both | not published | date and price | not published |
| Washington, DC | yes | assessed | not published | date and price | not published |
Cook County is the thin one: the Assessor publishes owner name, property address and mailing address there and no valuation or building detail in the same table, so those columns are null on every Cook County row. It is on the list anyway because 1.86 million Chicago-area ownership records is the thing most people came for.
Reading the output
Every run writes three kinds of row and they are easy to tell apart:
- Real rows carry
"charged": trueand"recordType": "parcel". One billed event each. - The sample row carries
"_sample": trueand"charged": false. There is exactly one, it only appears when the input had no jurisdiction or nothing to search on, and it is there so you can see the shape before spending anything. - Diagnostic rows carry
"_diagnostic": true,"charged": falseand anerrorCodeyou can switch on:NO_RESULTSwhen a roll matched nothing,FILTER_UNSUPPORTEDwhen a place cannot answer one of your filters and was skipped rather than answering a different question,ROWS_DROPPEDwith a count when records came back and did not match,QUERY_REFUSEDwhen a host rejected the query outright,SERVER_ERRORandNETWORKwhen a host was unreachable,TIME_BUDGETwhen the run ran out of time before reaching a place,BAD_INPUTfor a jurisdiction name that is not on the list.
If you only want the data, filter on charged == true. That count always equals the number of events you were billed for, so the dataset is its own invoice.
About the personal information in these records
The owner name on a land record is published by the government, on purpose, and it is the point of the product. So that is what is here: the name and the mailing address exactly as the roll prints them, and nothing else.
Nothing is joined to anything. No email addresses, no telephone numbers, no dates of birth, no household members, no lookups against any other source. If a roll ever started publishing an email or a telephone number in one of these columns it would be stripped before the row was written, and the field would read [removed]. None of the thirteen sources does today.
Use of these records is regulated in some places and for some purposes, and that is your call to make, not this Actor's. Every row carries recordUrl so you can always go and read the original.
Limitations
- Thirteen jurisdictions, listed above. Nowhere else. A parcel outside them is not in here and no amount of searching will find it.
- It reads assessment and appraisal rolls, not deeds. There is no chain of title, no mortgage, no lien and no document image.
lastSaleDateis the last transfer the roll happens to record, and seven of the thirteen rolls do not record a sale price at all. - The owner name is whatever the roll says. Rolls lag reality - a sale from last month usually is not on them yet, and a few are a full cycle behind.
rollLabelon every row says which roll it came from so you can see how old it is. - Cook County publishes the taxpayer of record rather than the deeded owner, and publishes no valuation or building detail in that table. Both are stated on the row itself, in
ownerNameSourceand as nulls. - Condominiums are a mess everywhere. Cambridge publishes a building record whose owner reads "Condominium Building - See Individual Unit Records"; other rolls repeat the building address once per unit. You get what the roll has.
- Address search matches text, so it returns candidates rather than one authoritative hit - a multi-tenant commercial address returns every parcel at it. Every row is checked against your search before it is charged, but "2300 W Plano Pkwy" is genuinely five parcels.
- Connecticut, Vermont and Cambridge publish no property postal code, so all three are skipped with a note when you search by postal code. Connecticut and Vermont publish the owner's mailing postal code, which is a different question.
- Montana is half a street-address dataset. Owner and valuation are on 99% of its parcels but only about half have an address on the roll, so an address search there will miss land the owner search finds.
- Vermont's towns are on different years, from 2026 down to 2018, and about one parcel in eight has no grand list entry matched to it.
rollLabelsays the year on every row. - Cambridge publishes no assessed or market value. Cook County publishes neither value nor building detail. Montana, Vermont, Nashville and Washington DC publish no year built. The table above says which columns are null where.
- Coordinates are only on New York City and Cambridge rows. The others publish none in these tables.
- A run returns at most 5,000 parcels and accepts at most 200 parcel ids. For more than that, split the work across runs.
- The row budget is shared evenly between the places you tick. Ticking all thirteen and asking for 25 rows gives you about two from each, not 25 from each.
- These are public sector hosts. They go down for maintenance, and when one does the run says so in a diagnostic row and charges nothing for it, rather than pretending the parcels do not exist.
Questions
Does this cover the whole United States?
No, and the name is broader than the coverage. It covers thirteen jurisdictions across eleven states and the District of Columbia, about 7.6 million parcels: three of them are whole states (Connecticut, Vermont, Montana), the rest are single cities and counties. The exact list, with parcel counts, is in "What is covered" above. Most US counties publish nothing machine-readable, and of the ones that do, plenty publish a parcel map with the owner column blanked out - New Jersey publishes 3.5 million parcels that way and it is no use to anyone asking who owns one. So there is no honest way to claim more than the list.
Is this the deed, or the tax roll?
The tax roll. Assessment and appraisal rolls are what these jurisdictions publish as open data, and they carry the owner of record, the property, and usually a value. They are not deeds: no chain of title, no mortgage, no lien, no document image. If you need the recorded instrument, this will tell you who to look up and not much more.
How current is the data?
Each row carries rollLabel saying which roll it came from, and for the four sources that hold several years the run asks the host which year is newest every time rather than assuming. Rolls are published on a cycle, so a sale from last month is usually not on one yet. Vermont is the one to watch: its towns file separately and the oldest on the extract is 2018, so read the year on the row before acting on a Vermont owner.
What happens if I search a postal code in a place that has none?
That place is skipped and you get one free FILTER_UNSUPPORTED row saying so. It does not fall back to returning parcels that might be in the right postal code, because that would be answering a different question and billing you for it.
Why did I get five rows for one address?
Because there are five parcels at it. A multi-tenant commercial building, a condominium, or a subdivided lot all have more than one record on the roll. Every row returned was checked against what you typed before it was charged.
Do I need an API key or an account for any of this?
No. Every source is a public government open-data host and the run reads them without a key, a login or a cookie. You need nothing beyond this Actor.
Can I run it on a schedule?
Yes. Nothing is held between runs, so the same input is safe to repeat. Use parcelId to work out what has changed since last time - it is stable, which the owner name is not.
Will the run fail if a source is down?
No. A source that is unreachable, refuses the query, or matches nothing produces an uncharged diagnostic row explaining what happened, and the run carries on to the others and finishes as succeeded. A failed run would still bill you the start fee, which would mean paying to be told something went wrong.
How do I get exactly the rows I paid for?
Filter the dataset on "charged": true. Sample and diagnostic rows are always false, and the number of charged rows always equals the number of billed events.