← back to Nationalrealestate
parcels: add Klamath County OR (41035) free priced-deed feed
180998ff9618905751cf178db2be41fcbee6d948 · 2026-07-27 20:52:46 -0700 · Steve Abrams
New ArcGIS priced-deed source in arcgis_sales.ts + engine.ts adapter +
hourly-loop job (deeds-klam). KC_ParcelSales FeatureServer, 38,796 priced
sales with owner/situs/sqft/beds/baths/yrblt/total-appraised/doc. Verified
end-to-end against local usre DB (1k parcels + 1k sale events + links +
source registration). SOURCES.md documents the feed + the arcgis_sales
config family. TK-16.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M SOURCES.mdM src/ingest/parcels/arcgis_sales.tsM src/ingest/parcels/engine.tsM src/jobs/hourly_loop.ts
Diff
commit 180998ff9618905751cf178db2be41fcbee6d948
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Mon Jul 27 20:52:46 2026 -0700
parcels: add Klamath County OR (41035) free priced-deed feed
New ArcGIS priced-deed source in arcgis_sales.ts + engine.ts adapter +
hourly-loop job (deeds-klam). KC_ParcelSales FeatureServer, 38,796 priced
sales with owner/situs/sqft/beds/baths/yrblt/total-appraised/doc. Verified
end-to-end against local usre DB (1k parcels + 1k sale events + links +
source registration). SOURCES.md documents the feed + the arcgis_sales
config family. TK-16.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
SOURCES.md | 6 ++++++
src/ingest/parcels/arcgis_sales.ts | 12 ++++++++++++
src/ingest/parcels/engine.ts | 1 +
src/jobs/hourly_loop.ts | 1 +
4 files changed, 20 insertions(+)
diff --git a/SOURCES.md b/SOURCES.md
index 3880904..e940e1b 100644
--- a/SOURCES.md
+++ b/SOURCES.md
@@ -105,3 +105,9 @@ incl. 8 gated/blocked states → `BROKER-COVERAGE.md`. Adapters: `src/ingest/bro
- Read IN PLACE from the CRCP read-only SQLite (`~/Projects/commercialrealestate/data/assessor.sqlite`, 2,427,010 rows, 2025 secured roll) — never copied into PG. Registered in `parcel_source`.
- Columns actually present: ain (PK), situs_house_no, situs_street, property_location, year_built, effective_year_built, sqft_main, bedrooms, bathrooms, units, use_desc1, use_desc2, roll_total_value, roll_land_value, roll_imp_value, roll_year (single year: 2025), recording_date. **NOT present**: owner names, mailing address, zoning, sale prices, lat/lng, situs_city as its own column (city is inside property_location).
+
+## Free priced-DEED feeds — config-driven ArcGIS (`src/ingest/parcels/arcgis_sales.ts`)
+
+Each entry is a keyless ArcGIS REST layer that publishes real recorded SALE PRICE; one `SOURCES` config maps a page of features → parcel row + `parcel_event(event_type='sale')` with grantor/grantee/doc + a `source_url` deep-link. Registered in `parcel_source`, paginated over time by the hourly loop (`src/jobs/hourly_loop.ts`, `runSources` = the config's `cursorKey`). Live configs: `oregon-rlis` (41051/67/05), `spokane` (53063), `alameda` (06001), `deschutes` (41017), `crook` (41013), `sonoma` (06097), `colorado` (statewide composite `08*`), `maricopa` (04013), `thurston` (53067), `palm-beach` (12099), `klamath` (41035).
+
+- **Klamath County OR (41035)** — added 2026-07-27 (TK-16). ArcGIS Online FeatureServer `https://services.arcgis.com/H6Mh1bySxR4oHx6x/arcgis/rest/services/KC_ParcelSales/FeatureServer/0` (item `f6314b12b8cc4c35899157172601bf59`, "KC_ParcelSales" = Klamath County Parcel Sales). `where=SALE_PRICE>1000` → **38,796** priced sales. Rich fields: `SALE_PRICE` (int), `SALE_DATE` (epoch-ms), `OWNER_NAME` (→ grantee), `MIN_SITUS_ADDRESS`+`FIRST_CITY_NAME`, `SUM_FINSQFT`/`SUM_BEDRMS`/`SUM_BATH`, `MIN_YRBLT`, `SUM_Tot_Appr` (total appraised → `total_value`), `SALEBK` (→ doc_number, internal double-spaces collapsed by `clean()`), `FIRST_PROP_ID` (→ apn/source_id), `FIRST_PCLCD` (→ use_desc). Server caps pages at 1000. Verified end-to-end against the local `usre` DB (1,000 parcels + 1,000 sale events + links + source registration on first batch).
diff --git a/src/ingest/parcels/arcgis_sales.ts b/src/ingest/parcels/arcgis_sales.ts
index e0da018..2744d57 100644
--- a/src/ingest/parcels/arcgis_sales.ts
+++ b/src/ingest/parcels/arcgis_sales.ts
@@ -191,6 +191,18 @@ const SOURCES: Record<string, Source> = {
return { fips: '12099', apn, price: anyPrice(a.PRICE), saleDate: anyDate(a.SALE_DATE),
address: clean(a.SITE_ADDR), city: clean(a.CITY), grantee: clean(a.OWNER_NAME1) } as Rec; }).filter(Boolean) as Rec[],
},
+ klamath: {
+ key: 'klamath', label: 'Klamath County OR (Klamath Falls)', cursorKey: 'klamath', geometry: false, orderBy: 'OBJECTID', pageSize: 2000,
+ layer: 'https://services.arcgis.com/H6Mh1bySxR4oHx6x/arcgis/rest/services/KC_ParcelSales/FeatureServer/0',
+ where: 'SALE_PRICE>1000', // rich Klamath assessor sales layer: SALE_PRICE(int)+SALE_DATE(epoch-ms)+owner+situs+sqft/beds/baths/yrblt+total appraised
+ outFields: 'FIRST_PROP_ID,SALE_PRICE,SALE_DATE,SALEBK,OWNER_NAME,MIN_SITUS_ADDRESS,FIRST_CITY_NAME,SUM_FINSQFT,SUM_BEDRMS,SUM_BATH,MIN_YRBLT,SUM_Tot_Appr,FIRST_PCLCD',
+ toRecords: (fs) => fs.map(f => { const a = f.attributes; const apn = s(a.FIRST_PROP_ID); if (!apn) return null;
+ return { fips: '41035', apn, price: anyPrice(a.SALE_PRICE), saleDate: anyDate(a.SALE_DATE),
+ address: clean(a.MIN_SITUS_ADDRESS), city: clean(a.FIRST_CITY_NAME),
+ sqft: num(a.SUM_FINSQFT), beds: num(a.SUM_BEDRMS), baths: num(a.SUM_BATH), year: num(a.MIN_YRBLT),
+ totalValue: num(a.SUM_Tot_Appr), use: clean(a.FIRST_PCLCD),
+ grantee: clean(a.OWNER_NAME), docNum: clean(a.SALEBK) } as Rec; }).filter(Boolean) as Rec[],
+ },
};
async function fetchPage(src: Source, offset: number): Promise<any[]> {
diff --git a/src/ingest/parcels/engine.ts b/src/ingest/parcels/engine.ts
index 9d77b8b..d5c2400 100644
--- a/src/ingest/parcels/engine.ts
+++ b/src/ingest/parcels/engine.ts
@@ -27,6 +27,7 @@ const ADAPTERS: Record<string, () => Promise<{ run: () => Promise<{ upserted: nu
maricopa: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('maricopa') }; },
thurston: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('thurston') }; },
'palm-beach': async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('palm-beach') }; },
+ klamath: async () => { const m = await import('./arcgis_sales.ts'); return { run: m.ingestArcgisSales('klamath') }; },
};
async function main() {
diff --git a/src/jobs/hourly_loop.ts b/src/jobs/hourly_loop.ts
index e011d74..0d58f59 100644
--- a/src/jobs/hourly_loop.ts
+++ b/src/jobs/hourly_loop.ts
@@ -62,6 +62,7 @@ const JOBS: Job[] = [
{ name: 'deeds-maricopa',script:'src/ingest/parcels/engine.ts', args: ['maricopa'], minIntervalHours: 2, runSources: ['maricopa'] },
{ name: 'deeds-thur', script: 'src/ingest/parcels/engine.ts', args: ['thurston'], minIntervalHours: 4, runSources: ['thurston'] },
{ name: 'deeds-pb', script: 'src/ingest/parcels/engine.ts', args: ['palm-beach'], minIntervalHours: 4, runSources: ['palm_beach'] },
+ { name: 'deeds-klam', script: 'src/ingest/parcels/engine.ts', args: ['klamath'], minIntervalHours: 4, runSources: ['klamath'] },
];
/** hours since this job's freshest OK run across its runSources (∞ if never). */
← 1499f0f USRE Map: export matching counties to CSV (parity w/ grid) +
·
back to Nationalrealestate
·
parcels: add Marion County OR / Salem (41047) free priced-de de29c39 →