US Parcel & Property Assessment Scraper (2 cities) avatar

US Parcel & Property Assessment Scraper (2 cities)

Pricing

from $3.20 / 1,000 parcel delivereds

Go to Apify Store
US Parcel & Property Assessment Scraper (2 cities)

US Parcel & Property Assessment Scraper (2 cities)

Public parcel & property-assessment data from Los Angeles & Denver in one normalized schema: parcel IDs, legal parts, land use, values, last sale and districts, plus a parcel change monitor. For real estate research, valuation analytics and market monitoring. Open data, no login, no owner names.

Pricing

from $3.20 / 1,000 parcel delivereds

Rating

0.0

(0)

Developer

Steadfetch

Steadfetch

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Share

Public parcel and property-assessment records from Los Angeles and Denver in one normalized property-side schema. One row per parcel with parcel identifiers, legal parcel parts, situs address, land use, building and land values, last sale and districts, plus an optional change monitor for a parcel watchlist.

What it does

  • Queries two official US open-data JSON endpoints (Socrata) and returns one unified schema regardless of portal.
  • Normalizes Los Angeles (qyra-qm2s) and Denver (tsdg-z9uy) into the same fields, so downstream code does not need two parsers.
  • Requests only an explicit property-side column allow-list with SoQL $select. Owner, taxpayer and mailing-address columns are never downloaded, even when the source publishes them.
  • Supports optional parcelIds and a bbox filter for both cities (both publish geometry).
  • Optional monitor mode: keeps a property-side snapshot per parcel in the Actor key-value store and emits only parcels that are new or whose fields changed. A quiet day delivers no rows and bills 0 results; each watched check bills the cheap monitor-check event (0.10 USD per 1,000 checks).
  • Paginates with SoQL $limit/$offset and respects each portal's Crawl-delay: 1 (at least 1 second between requests).

Sources and compliance

CityDataset idPublic endpointLicence
Los Angeles, CAqyra-qm2shttps://data.lacity.org/resource/qyra-qm2s.jsonCC0 1.0 Universal (Public Domain Dedication).
Denver, COtsdg-z9uyhttps://data.colorado.gov/resource/tsdg-z9uy.jsonPublic Domain (State of Colorado open data).

Both portals allow /resource/* in robots.txt and declare Crawl-delay: 1. This Actor only calls those JSON endpoints, with a descriptive User-Agent that identifies Steadfetch: no login, no token, no CAPTCHA bypass, no browser and no proxies. The HTML front ends and proprietary assessor search portals are never requested.

A third source, Ramsey County MN (4fwy-py9e), was evaluated and discarded: its robots.txt declares Disallow: / for every user-agent, so it is not a permitted source under Steadfetch rule 3. It is not queried by this Actor.

No personal data (binding rule). Owner names, taxpayer names and mailing addresses are excluded by construction: the queries select property-side columns only. The Denver dataset publishes owner_* and mailing columns and the Actor never requests them. Output contains property facts only and complies with the RGPD.

Attribution

  • Contains information from the City of Los Angeles Open Data Portal (dataset qyra-qm2s, Bureau of Engineering), made available under CC0 1.0.
  • Data provided by the State of Colorado Open Data Portal (dataset tsdg-z9uy).

Input

FieldTypeRequiredDefaultDescription
citystringYesdenverlos-angeles or denver.
parcelIdsarrayNo[]Optional parcel filter (pind in Los Angeles, schednum in Denver). Required in monitor mode: it is the watchlist.
bboxstringNoempty"west,south,east,north" in decimal degrees. Both sources publish geometry.
modestringNoextractextract returns every parcel in scope; monitor emits only new or changed watchlist parcels.
maxItemsintegerNo1000Maximum parcels read (extract) or checked (monitor), 1-5000.
strictSchemabooleanNotrueFail the run when a row does not match the output schema. Keep enabled.

Example input

Matches the declared exampleRunInput:

{
"city": "denver",
"maxItems": 25,
"mode": "extract"
}

Monitor mode

{
"city": "denver",
"parcelIds": ["1100001000", "2100002000"],
"mode": "monitor",
"maxItems": 100
}

The first monitor run emits every watchlist parcel as changeType: "new". Later runs compare against the stored snapshot and emit only parcels whose property-side fields changed, with changeType: "updated" and the list of changed fields. State is kept under us-parcel-assessment-extractor-state, keyed by city, parcel id and roll year when the source publishes one.

Output

Example output

{
"url": "https://data.colorado.gov/resource/tsdg-z9uy.json?$where=schednum%3D'1100001000'",
"title": "1100001000 - 26100 E 88TH AVE",
"scrapedAt": "2026-10-25T00:00:00.000Z",
"city": "denver",
"sourceDataset": "tsdg-z9uy",
"parcelId": {"primary": "1100001000", "scheduleNumber": "1100001000", "appendage": "0", "map": "11", "block": "0", "lot": "1"},
"address": {"full": "26100 E 88TH AVE", "city": "DENVER", "state": "CO", "zip": null},
"tract": null,
"block": "0",
"lot": "1",
"landUse": {"code": "9139", "description": "VACANT LAND"},
"yearBuilt": null,
"buildingAreaSqft": null,
"landAreaSqft": 7974751,
"valuations": {"currency": "USD", "land": 45800, "building": 0, "total": 45800, "marketTotal": 45800, "assessedTotal": 11910, "taxable": 0},
"lastSale": {"date": null, "year": null, "price": null},
"rollYear": null,
"districts": {"council": null, "engineering": null, "engineeringName": null, "zone": "DIA", "municipality": "DENVER"},
"collectedAt": "2026-10-25T00:00:00.000Z"
}

Output fields

FieldTypeDescription
urlstringPublic JSON row permalink used as the source URL.
titlestringParcel identifier plus situs address.
scrapedAtdate-timeISO 8601 UTC timestamp of the run.
citystringlos-angeles or denver.
sourceDatasetstringSocrata dataset id.
parcelIdobjectprimary plus the city-specific identifiers the source publishes (mod is populated for Los Angeles).
addressobjectSitus address (full, city, state, zip); null parts are never invented.
tract, block, lotstring or nullLegal parcel parts when published. Los Angeles also reports parcelId.mod.
landUseobjectProperty/land-use code and description as published.
yearBuiltnumber or nullYear built when published.
buildingAreaSqft, landAreaSqftnumber or nullBuilding and land area when published.
valuationsobjectUSD land/building/total, market value, assessed value and taxable amount; null when the source does not publish it (the Los Angeles parcel layer has no values).
lastSaleobjectLast sale date, year and price when published.
rollYearstring or nullAssessment/roll year when published.
districtsobjectCouncil, engineering, zone and municipality when published.
collectedAtdate-timeTimestamp of the normalized record.
changeType, changedFieldsstring / arrayMonitor mode only: new or updated plus the changed property-side fields.

New fields are additive and required fields never change, so downstream code can rely on the documented contract.

Pricing

Pay-per-event with the two synthetic platform events plus the reserved per-check event for the monitor:

  • apify-actor-start: 0.00005 USD per run (Apify-recommended default, includes the first 5 seconds of compute).
  • apify-default-dataset-item: 0.004 USD per parcel = 4.00 USD per 1,000 results.
  • monitor-check: 0.0001 USD per watched parcel checked = 0.10 USD per 1,000 checks, charged once per monitor run for every watchlist parcel actually checked, including checks where nothing changed (STE-389 contract). Extract runs (no watchlist) never charge this event.

Users are never billed twice: rows rejected by the schema are never pushed and never charged; unchanged checks bill only the check event, and new or changed parcels bill the per-result event on top of their check. A 1,000-parcel watchlist with a quiet day (nothing changed) costs about 0.10 USD in checks plus the run start.

Measured cost is about 0.001 USD per 1,000 parcels (JSON endpoints, no browser, no proxies). The result price is inside the Steadfetch 1-10 USD per 1,000 results band and about 10x below the closest proprietary owner-lookup competitor, which this Actor intentionally does not replicate; the product is official, cross-city normalized property data. The check price sits inside the 0.01-1.00 USD per 1,000 checks monitor band with a wide margin over the measured compute cost per check.

Works on the Apify free plan: with the 5 USD monthly credit, about 1,249 parcels can be delivered per month (N = floor((5.00 - 0.00005) / 0.004)).

Usage with the API

curl -X POST "https://api.apify.com/v2/acts/steadfetch~us-parcel-assessment-extractor/runs?token=<YOUR_API_TOKEN>" \
-H 'Content-Type: application/json' \
-d '{"city":"denver","maxItems":100,"mode":"extract"}'

Then read the default dataset of the run.

FAQ

Do I need an API key for the portals? No. Both are anonymous public Socrata endpoints. The Actor sends only a descriptive User-Agent and respects each portal's crawl delay.

Are both cities really the same schema? Yes. Parcel identifiers, legal parts, address, land use, areas, valuations, last sale and districts are normalized. Fields a city does not publish are null, never invented. The Los Angeles parcel layer, for example, publishes no valuation or address; it is delivered as a parcel-identifier, legal-part and district layer.

Does the Actor return owner names? No, never. Owner, taxpayer and mailing-address columns are excluded by construction and are not even downloaded. Steadfetch does not sell personal data.

Which legal parcel parts are filled? Los Angeles publishes tract, block, mod and lot, so all of them are delivered. Denver publishes block and lot; its tract stays null.

What does monitor mode bill? The check itself plus the new result: every watchlist parcel actually checked charges monitor-check (0.10 USD per 1,000 checks, including checks where nothing changed), and only new or changed parcels additionally charge the per-result event (4.00 USD per 1,000 results). The first run emits the watchlist as new; later runs emit only drift. Extract runs never charge the check event.

Does the Actor use a browser? No. Both sources are JSON APIs, so HTTP is roughly 10x cheaper than a browser.

Is the output schema stable? Yes. New fields are added additively and required fields never change.

Maintenance

The Actor is tested daily through the Steadfetch catalogue QA and the monorepo CI (npm test and npm run publish:check on every push). Repairs take priority over new features. Schema changes are announced through repository releases.

Support

Report bugs or request features through the Apify Store page (Issues tab) of this Actor, or through the Steadfetch actors repository issues. Include the run ID and the input used.