US Parcel & Property Assessment Scraper (2 cities)
Pricing
from $3.20 / 1,000 parcel delivereds
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 hours ago
Last modified
Categories
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
parcelIdsand abboxfilter 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-checkevent (0.10 USD per 1,000 checks). - Paginates with SoQL
$limit/$offsetand respects each portal'sCrawl-delay: 1(at least 1 second between requests).
Sources and compliance
| City | Dataset id | Public endpoint | Licence |
|---|---|---|---|
| Los Angeles, CA | qyra-qm2s | https://data.lacity.org/resource/qyra-qm2s.json | CC0 1.0 Universal (Public Domain Dedication). |
| Denver, CO | tsdg-z9uy | https://data.colorado.gov/resource/tsdg-z9uy.json | Public 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
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
city | string | Yes | denver | los-angeles or denver. |
parcelIds | array | No | [] | Optional parcel filter (pind in Los Angeles, schednum in Denver). Required in monitor mode: it is the watchlist. |
bbox | string | No | empty | "west,south,east,north" in decimal degrees. Both sources publish geometry. |
mode | string | No | extract | extract returns every parcel in scope; monitor emits only new or changed watchlist parcels. |
maxItems | integer | No | 1000 | Maximum parcels read (extract) or checked (monitor), 1-5000. |
strictSchema | boolean | No | true | Fail 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
| Field | Type | Description |
|---|---|---|
url | string | Public JSON row permalink used as the source URL. |
title | string | Parcel identifier plus situs address. |
scrapedAt | date-time | ISO 8601 UTC timestamp of the run. |
city | string | los-angeles or denver. |
sourceDataset | string | Socrata dataset id. |
parcelId | object | primary plus the city-specific identifiers the source publishes (mod is populated for Los Angeles). |
address | object | Situs address (full, city, state, zip); null parts are never invented. |
tract, block, lot | string or null | Legal parcel parts when published. Los Angeles also reports parcelId.mod. |
landUse | object | Property/land-use code and description as published. |
yearBuilt | number or null | Year built when published. |
buildingAreaSqft, landAreaSqft | number or null | Building and land area when published. |
valuations | object | USD 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). |
lastSale | object | Last sale date, year and price when published. |
rollYear | string or null | Assessment/roll year when published. |
districts | object | Council, engineering, zone and municipality when published. |
collectedAt | date-time | Timestamp of the normalized record. |
changeType, changedFields | string / array | Monitor 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.