API
Read-only REST over the verified record. Base URL https://harvest.thrain.ai. All endpoints are GET; responses are JSON. Two products share one key and one quota: the farmland record below, and the impact fee schedules further down.
Two tables of transactions. Sales are auction and listing results as the seller published them: a cleared, competitive price with acreage, soil rating and crop economics attached. Transfers are recorded deeds a county publishes as open data, filtered to ground the county's own land-use code calls agricultural — the gifts, foreclosures and intra-family conveyances included, each labelled rather than hidden. Buyer and seller names are never published on either.
Authentication
Authorization: Bearer tract_live_…
Keys are issued by hand while the API is in private beta — Request access. The free tier is limited to 1,000 requests/day, sees data lagged 90 days, and omits source_url. The live tier is 10,000/day, current data, sources included. Remaining quota is returned on every response in x-ratelimit-remaining.
Endpoints
| Endpoint | Returns |
/v1/farmland/sales | Sales, filterable, paginated (limit ≤ 500, offset) |
/v1/farmland/sales/{sale_key} | One sale |
/v1/farmland/transfers | Recorded agricultural deeds, filterable, paginated |
/v1/farmland/transfers/{transfer_key} | One transfer |
/v1/farmland/counties | Per-county rollup: sales, acres, avg $/acre, date range |
/v1/farmland/stats | Dataset totals |
Filters
These apply to both /v1/farmland/sales and /v1/farmland/transfers, with the same names and the same meanings.
| Param | Meaning |
state | 2-letter code, e.g. IA |
county_fips | 5-digit FIPS, e.g. 19167 |
since / until | Sale-date bounds, YYYY-MM-DD |
min_acres / max_acres | Acreage bounds |
min_ppa / max_ppa | Price-per-acre bounds |
sort / dir | sale_date (default), price_per_acre, acres; desc/asc |
limit / offset | Page size (≤ 500, default 100) and start |
Only on /v1/farmland/sales:
| Param | Meaning |
sale_type | auction, online_auction, sealed_bid, listing |
county_source | source_stated (the page named the county) or town_lookup (resolved from a town it named). Pass source_stated when you need only counties the source stated outright. |
has_coordinates | true / false — keep only sales that carry a point, or only those that do not. Read geo_precision for how close each point is before mapping. |
Only on /v1/farmland/transfers:
| Param | Meaning |
deed_type | warranty, quit_claim, trustee, sheriff, special_warranty, personal_rep, tax, other, unknown |
arms_length | true / false — the county's own determination. A county that publishes none leaves it null, and null is not false: arms_length=false returns the deeds a county judged not arm's-length, never the ones it said nothing about. |
is_market_sale | true / false — whether the record looks like a genuine market transaction. Same null rule. |
Example
curl -H "Authorization: Bearer $TRACT_KEY" \
"https://harvest.thrain.ai/v1/farmland/sales?state=IA&min_acres=100&since=2024-01-01&limit=5"
{
"data": [ { "sale_key": "…", "sale_date": "2026-04-23", "state_code": "IN",
"county_fips": "18127", "acres": 102.0, "price_per_acre": 14588.56,
"soil_index_value": 140.5, "soil_index_system": "WAPI",
"organization": "Geswein Farm & Land Realty LLC", "source_url": "…" } ],
"total": 252, "limit": 5, "offset": 0, "tier": "live", "lag_days": 0
}
curl -H "Authorization: Bearer $TRACT_KEY" \
"https://harvest.thrain.ai/v1/farmland/transfers?state=IL&arms_length=true&min_acres=40&limit=5"
{
"data": [ { "transfer_key": "fa0a3033…", "sale_date": "2025-11-03", "state_code": "IL",
"county_fips": "17075", "county_name": "Iroquois County",
"parcel_id": "08-34-400-004", "acres": 77.0, "sale_price": 1008700.0,
"price_per_acre": 13100.0, "deed_type": "warranty", "arms_length": 1,
"is_market_sale": 1, "land_use_code": "J",
"grantor_entity_type": "individual", "grantee_entity_type": "llc",
"record_ref": "20251003820756", "source_url": "…" } ],
"total": 21027, "limit": 5, "offset": 0, "tier": "live", "lag_days": 0
}
Columns on /v1/farmland/sales
Every column the endpoint returns, and nothing else. Any of them can be null: a source that did not state a figure leaves it null rather than guessing, and a derived figure is null wherever its input is. source_url is returned on the live tier only.
The row atlas lists more columns than this, because it describes the whole dataset. What the API leaves off the row is the county-wide constants — soil shares, NCCPI, cash rent, growing-season rainfall — which are identical for every sale in a county and belong in a county rollup rather than repeated on each of thousands of rows. Everything below either describes this sale or was computed as of its year.
The sale
| Column | What it is |
sale_key | Stable id for this sale. Safe as a primary key across releases. |
auction_key | Groups tracts sold at the same auction event. |
sale_date | The date it sold. For third-party compilations this is the publication date. |
sale_type | How it sold: auction, online_auction, sealed_bid, listing (private treaty), unknown. |
sold | 1 when the source reports it sold, 0 when it did not clear. |
tract_label | The tract's label at the auction, e.g. "Tract 3". |
tract_count | How many tracts the property was offered in. |
organization | The company that published the result. |
source_url | The page the row was read from. Every figure can be checked there. |
Where
| Column | What it is |
state_code | Two-letter state code. |
county_fips | 5-digit census county FIPS, the key to join on (not the name). The county the page named; where it named only a town, the county that town resolves into — county_source says which. Null when the source named neither. |
county_name | County as the source named it. |
county_source | Where county_fips came from. source_stated: the page named the county. town_lookup: the page named no county, so this is the county the town it did name resolves into, via the Census geocoder — right about 83% of the time, measured against sales that name both. Null when the row has no county. The county-wide figures on a sale (yields, soil, cash rent, crop risk) stay joined on a stated county and are null under town_lookup: a town-derived county is good enough to find a sale by, not to hang a county average on. |
township_name | Civil township the source named, e.g. "Chalmers". |
plss_section | Survey section (1–36) from the stated legal description. |
plss_township | Survey township from the legal description, e.g. "98N". |
plss_range | Survey range from the legal description, e.g. "64W". |
legal_description | The legal description as the source wrote it. |
location_text | Directions as the source wrote them: "6 miles southwest of Amboy, IL". |
address | A road or street address, where the source states one. |
latitude / longitude | WGS84 coordinates. |
geo_source | Where the coordinates came from, best first. source_stated: the page published them. plss_section_centroid: resolved from the stated section-township-range through the federal survey polygons, county-checked. town_offset: the page gave a distance and direction from a named town ("6 miles SW of Amboy, IL") and the town's point was moved along that bearing. town_centroid: the page gave only a direction or "near", so the point is the town's. A town reference never displaces a stated point or a resolved section. |
geo_precision | How close the point is — read this before you map anything. point: the parcel's own coordinates. section: the centroid of the surveyed square mile the legal description names, within about a mile. locality: a town reference within about three miles — the town itself or a short offset. area: a town offset of ten to thirty miles, where the point may sit several miles off across the bearing. Offsets beyond thirty miles are not published: they place the reader, not the farm. |
The land and the price
| Column | What it is |
land_use | Land use as the source described it: cropland, pasture, recreational, building site, mixed. |
acres | Total acres in this tract. |
tillable_acres | Tillable or crop acres, when the source states them. |
is_dwelling | 1 when the sale carries a house or building site, so its per-acre price is partly a building price. Null when the source stated no land use — null is not 0. Exclude these before averaging. |
price_total | Total sale price, US dollars. |
price_per_acre | Price per acre. The source's figure when stated, otherwise total ÷ acres. |
price_per_tillable_acre | Price per tillable acre. Null unless tillable acres are known. |
price_per_soil_point | Price per acre ÷ the tract's soil productivity index: the standard way to compare farms of different soil quality. |
Soil under this farm
| Column | What it is |
soil_index_value | Soil productivity rating as published for this tract. |
soil_index_system | Which rating system that value uses (CSR2, PI, WAPI, CPI, NCCPI, SPI). Values are not comparable across systems. |
soil_map_unit_name | The USDA soil map unit under the sale's own coordinates: series, texture and slope phase, e.g. "Drummer silty clay loam, 0 to 2 percent slopes". |
soil_capability_class | USDA non-irrigated land capability class of that map unit, 1 (best) to 8. |
soil_drainage_class | Drainage class of that map unit. |
soil_hydrologic_group | Hydrologic soil group (A, B, C, D or dual) — how fast water leaves. |
soil_flood_frequency | None, Very rare, Rare, Occasional, Frequent, Very frequent. The sale's own flood signal. |
soil_slope_pct | Representative slope of that map unit, percent. |
soil_farmland_class | USDA farmland classification: prime, prime if drained, statewide importance, not prime. |
soil_grain | Which grain of soil this row carries. map_unit_at_point: the soil_* columns come from the sale's own coordinates. county_aggregate: only county-level soil is known for it. Null: neither. |
Crop economics
The price a bushel fetched around the sale, the county's yield, and the revenue an acre produced. Each yield carries the crop year it came from: counties report intermittently, and a figure two seasons old should say so.
| Column | What it is |
corn_price_at_sale_usd_bu | State corn price received in the calendar month this farm sold. What the market looked like when the bid was made. |
corn_price_marketing_year_usd_bu | State marketing-year average corn price as of the sale year. The figure behind revenue. |
county_corn_yield_bu_acre | County corn yield, the most recent year at or before the sale and within five crop years of it. Null rather than stale beyond that. |
county_corn_yield_year | Which crop year that yield is from. |
corn_gross_revenue_per_acre | Yield × marketing-year price: gross revenue an acre produced, before costs. |
price_to_revenue_multiple | Price per acre ÷ gross corn revenue per acre — how many years of gross crop revenue the buyer paid. The earnings multiple for farmland. Corn-based; soybean and wheat revenue sit alongside rather than blended in. |
soybean_price_at_sale_usd_bu | State soybean price received in the month it sold. |
soybean_price_marketing_year_usd_bu | State marketing-year average soybean price as of the sale year. |
county_soybean_yield_bu_acre | County soybean yield, same five-year rule as corn. |
county_soybean_yield_year | Which crop year that yield is from. |
soybean_gross_revenue_per_acre | The other half of a corn/soy rotation, before costs. |
wheat_price_at_sale_usd_bu | State all-wheat price in the month it sold. Not every state still has a monthly wheat series — Iowa's ended in 1976 — and it is null where none exists. |
wheat_price_marketing_year_usd_bu | State marketing-year average all-wheat price as of the sale year. |
county_wheat_yield_bu_acre | County all-wheat yield. From 2008 on, the harvested-acre-weighted combination of the winter, spring and durum series. |
county_wheat_yield_year | Which crop year that yield is from. Wheat is reported intermittently across much of the Corn Belt. |
wheat_gross_revenue_per_acre | Wheat yield × marketing-year price, before costs. |
Crop insurance risk
Federal crop insurance experience for this county over the ten commodity years before the sale (USDA Risk Management Agency). A county figure, but not a county constant: the same county in 2015 and in 2025 carries a different window, so it is this sale's number.
| Column | What it is |
county_corn_indemnified_policy_pct_10yr | Share of the county's corn policies paid a claim over those ten years, percent. "One year in six" reads as about 17. |
county_corn_loss_ratio_10yr | Corn indemnity per premium dollar. Above 1: the crop paid out more than it cost to insure. |
county_corn_top_loss_cause_10yr | What took the most corn indemnity — Drought, Excess Moisture, Hail, Decline in Price, and so on. |
county_soybean_indemnified_policy_pct_10yr | The same, for soybeans. |
county_soybean_loss_ratio_10yr | The same, for soybeans. |
county_soybean_top_loss_cause_10yr | The same, for soybeans. |
county_crop_risk_through_year | The last commodity year that ten-year window covers. |
Wind and solar
The energy build-out around the sale as it stood in the sale year, from the USGS turbine and large-scale solar databases. A sale in 2013 is not credited with a wind farm built in 2020.
| Column | What it is |
county_wind_turbines_at_sale | Utility-scale turbines online in the county by the end of the sale year. 0 is a real answer; null only means the county is unknown. |
county_wind_mw_at_sale | Wind capacity online in the county by then, MW. |
county_solar_mw_ac_at_sale | Large-scale (1 MW-AC and up) solar capacity online in the county by then, MW-AC. |
nearest_wind_turbine_km_at_sale | Kilometres from this sale's coordinates to the nearest turbine already online. Null when the sale has no coordinates, or nothing stands within about 100 km. |
nearest_solar_project_km_at_sale | The same, for large-scale solar. |
Audit trail
| Column | What it is |
first_seen_timestamp | When we first observed this record. |
last_seen_timestamp | When we last observed it in a source. |
conformed_timestamp | Row last-updated stamp. Use it to pull incrementals. |
Columns on /v1/farmland/transfers
One row per recorded deed on ground the county's own land-use code calls agricultural. Buyer and seller names are never published — entity type is the analytically useful half and carries no personal data. source_url is returned on the live tier only.
| Column | What it is |
transfer_key | Stable id for this transfer. Safe as a primary key across releases. |
county_fips | 5-digit census county FIPS. The key to join on. |
county_name | County name from the census list, suffix included ("Iroquois County", "Catahoula Parish"). |
state_code | Two-letter state code. |
parcel_id | The county's own parcel identifier. Join key back to that county's parcel records. |
sale_date | The date the transfer was recorded. |
sale_price | Stated consideration, US dollars. Nominal amounts ($0–$1) are real records, not errors — see deed_type and is_market_sale before treating one as a price. |
acres | Parcel acreage, where the county publishes a land area. |
price_per_acre | Price ÷ acres, where both are known and positive. |
deed_type | Normalised instrument: warranty is an ordinary sale; sheriff and tax mean distress; quit_claim is usually not a market sale; trustee, special_warranty, personal_rep, other, unknown. |
arms_length | 1/0 — the county's own arm's-length determination. Null where the county publishes none, and null is not 0. Today Indiana, Illinois and Florida publish it. |
is_market_sale | 1/0 — whether this looks like a genuine market transaction: the county's flag where there is one, otherwise inferred from price and deed type. Null when undetermined. |
sale_validity | The county's own validity or qualification note, verbatim — "24 Current Use", "10 Gift or Love and Affection Deed", "15 Forced Sale". Codes differ by county on purpose; this is what the county said, not our reading of it. |
land_use_code | The county land-use code that classified this parcel agricultural. County-specific. |
grantor_entity_type | Seller type: individual, llc, trust, corporation, government, other, unknown. |
grantee_entity_type | Buyer type, same set. The individual-to-LLC shift over time is a real ownership signal. |
record_ref | Instrument number, deed book/page or receipt number — what you would quote to the recorder. Null where the county publishes none. |
source_url | A live-tested query link to the county's own service, filtered to this record. Null where no query pattern has been verified against the live service: an untested link is not shipped. |
source_id | Which county service published it. |
fetch_timestamp | When the page or file this record came from was fetched. |
first_seen_timestamp | When we first observed this record. |
last_seen_timestamp | When we last observed it. |
conformed_timestamp | When this published row was last written. |
Coverage today: 272,749 transfers across 267 counties in ten states — Indiana and Illinois statewide, plus counties in Washington, Ohio, Florida, Iowa, Colorado, Virginia, North Carolina and Minnesota. 205,770 carry a price and 174,194 carry a price per acre.
Impact fee endpoints
Development impact fees, system development charges and impact taxes — what a local government charges new construction — one row per published fee line at the grain the jurisdiction prints it: service area × fee × land-use label × unit × amount kind × effective date. Every amount is the verbatim printed figure and every row links the .gov document and page it was read from. The same rows are free to browse at /fees/explore/; the API adds filters, stability and quota. Unlike the farmland endpoints, both tiers see current data and source_url.
| Endpoint | What it returns |
/v1/fees/schedules | Fee lines, filterable, paginated (limit ≤ 500, offset) |
/v1/fees/schedules/{schedule_key} | One fee line |
/v1/fees/jurisdictions | Per-jurisdiction rollup: lines, categories, service areas, effective range |
/v1/fees/stats | Dataset totals |
Filters on /v1/fees/schedules
| Param | Meaning |
state | 2-letter state code |
jurisdiction_geoid | Census GEOID: 5-digit county or 7-digit place |
fee_category | transportation, water, wastewater, stormwater, parks, schools, fire, police, ems, library, general_government, housing, power, other |
land_use_class | Normalised class, e.g. single_family, multifamily, retail, industrial (land_use_label on each row keeps the printed wording) |
unit | Normalised charging unit, e.g. per_dwelling_unit, per_1000_sqft, per_meter |
amount_kind | collected (what is charged) or max_assessable (a published ceiling) |
basis | flat or formula (formula lines state a rate × lookup; amount is null) |
service_area | Exact service-area name as the schedule prints it; citywide means the whole jurisdiction |
as_of | YYYY-MM-DD — only lines in force on that date, keeping the latest line where a later schedule restates one (the same rule the explorer applies). Without it, every published line is returned, superseded and future included. |
effective_since / effective_until | Bounds on effective_start |
min_amount / max_amount | Bounds on the printed amount |
source_id | One registry source |
sort, dir | jurisdiction (default), effective_start, amount, state; asc/desc |
Example
curl -H "Authorization: Bearer $KEY" \
"https://harvest.thrain.ai/v1/fees/schedules?state=FL&land_use_class=single_family&unit=per_dwelling_unit&as_of=2026-08-23&limit=5"
Each row carries the jurisdiction (GEOID, name, type, state), the fee as the jurisdiction names it plus its normalised category, the printed land-use label and its class, the unit as printed and normalised, the amount and the exact printed token, the stated effective window, any footnote or extractor note, and source_url + source_page — the .gov document and page the line was read from.
Errors
| Status | Meaning |
400 | Bad parameter; the message names it |
401 | Missing or unknown key |
403 | Key revoked |
405 | Anything but GET |
429 | Daily quota exceeded |