USDA Cropland Data Layer Farmland & Land-Cover Screener avatar

USDA Cropland Data Layer Farmland & Land-Cover Screener

Pricing

from $3.85 / 1,000 results

Go to Apify Store
USDA Cropland Data Layer Farmland & Land-Cover Screener

USDA Cropland Data Layer Farmland & Land-Cover Screener

Farmland & land-cover API: batch coordinates to USDA Cropland Data Layer class (Corn, Soybeans, Developed, Forest, Water), an active-cropland flag, and a prime-farmland proxy. For solar-siting, land-use diligence, and farmland-protection screening. Keyless, MCP-ready. Prime-farmland is a proxy.

Pricing

from $3.85 / 1,000 results

Rating

0.0

(0)

Developer

Kyle Maloney

Kyle Maloney

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

5 days ago

Last modified

Share

USDA Cropland Data Layer Farmland & Siting Screener

Classifies a batch of coordinates against the USDA Cropland Data Layer (CDL) and returns, per site, the land-cover class, an active-cropland flag, and a prime-farmland proxy. Aimed at solar and wind site developers, land-use diligence teams, and ag lenders who need to know whether a candidate parcel is in active crop production before they act on it.

How it works

For each site you supply (lat/lon, WGS84), the actor projects the point into the CDL's native CONUS Albers Equal Area projection (EPSG:5070) and samples it through USDA's public CropScape GetCDLValue point service (nassgeodata.gmu.edu). No API key, no login, no scraping.

Two USDA backends, with automatic failover. CropScape is the primary. If it cannot be reached or verified, the run is answered instead by USDA's CroplandCROS ArcGIS image service (pdi.scinet.usda.gov), which publishes the same annual Cropland Data Layer. A CropScape outage therefore degrades this actor rather than stopping it. See Which backend answered below — you can always tell, per row. The CDL is a ~30 m annual satellite crop-classification raster; the sampled pixel gives you the class code (1 = Corn, 5 = Soybeans, 176 = Grassland/Pasture, 121–124 = Developed, 141–143 = Forest, 111 = Open Water, 0 = No Data outside CONUS).

Coverage is the Contiguous US. A point in the ocean or outside CONUS returns a row with coverage_status "no_data" or "out_of_coverage" and NULL crop flags - an explicit non-answer, not a finding of "no farmland" - and a single bad coordinate produces an ERROR row without failing the run. Years 1997 to the newest published vintage are available. Leave year empty and the actor uses whichever vintage USDA publishes today, discovered live from the service rather than hard-coded — CDL 2025 was live as of 2026-08-01, and the same Iowa point is Corn in 2024 and Soybeans in 2025.

Example input

{
"assets": [
{ "lat": 42.45, "lon": -93.55, "label": "Iowa cornfield" },
{ "lat": 42.30, "lon": -94.20, "label": "Iowa soybean field" },
{ "lat": 40.75, "lon": -73.98, "label": "Manhattan, NY (developed)" }
],
"year": 2024
}

Output fields (one row per site)

All fields are nullable. null means not checked / not published — it is never a negative finding.

Site + vintage

FieldWhat it is
asset_label, asset_lat, asset_lonYour label and coordinates, echoed back
cdl_yearThe CDL vintage actually sampled
requested_yearThe vintage you asked for
cdl_latest_available_yearThe newest vintage USDA publishes, discovered live from the service on every run. null if it could not be measured
cdl_year_is_latestWhether cdl_year is that newest vintage. null when the newest vintage could not be verified this run — no claim is made
cdl_year_noteSet when the requested year could not be honoured and a different one was sampled
cdl_vintage_statusHow the newest vintage was established: verified (a direct year probe and/or the service year-range message agreed), conflict (they disagreed; the direct data probe was followed), unverified (neither could be measured this run)
cdl_vintage_methodThe evidence used: probe_ladder, fault_range, or both
cdl_drift_gate_statuspassed, or passed_with_warnings when a check could not be measured
cdl_drift_gate_warningsWhich checks could not be measured, spelled out. null on a clean run
checked_atRun timestamp

Land cover

FieldWhat it is
cdl_codeCDL class code (0–255)
land_cover_classClass name from the full published legend, e.g. Corn, Herbaceous Wetlands, Pomegranates
categoryCoarse bucket: cropland, pasture, forest, water, developed, no_data, other
land_cover_groupFiner group: cropland, orchard_vineyard, pasture_grassland, forest, shrubland, barren, wetland, water, developed, aquaculture, nonag_undefined, no_data
is_active_croplandWhether the pixel is in active crop production. null when the pixel was never classified
prime_farmland_flagThe active-cropland proxy for prime farmland. null when not assessed
prime_farmland_basisPlain-language statement of what that flag does and does not mean
cdl_colorLegend colour hex

Coverage + service status

FieldWhat it is
coverage_statusin_coverage · no_data (CDL never classified this pixel — ocean, Canada, Mexico, cloud) · out_of_coverage (outside CONUS entirely: Alaska, Hawaii, Puerto Rico) · service_error · invalid_input
cdl_service_statusok, or the upstream failure text
errorWhy no determination was made
albers_x, albers_yThe EPSG:5070 coordinate sent
albers_echo_x, albers_echo_yThe coordinate CropScape echoed back. Measured 2026-08-04, it echoes the request verbatim rather than snapping to a pixel centre, so this restates albers_x/albers_y; it is retained as a tripwire in case that ever changes. null on a failover row — the image service does not echo a comparable value
webmercator_x, webmercator_yThe EPSG:3857 coordinate. This is the projection the failover backend reads; emitted on every row because it is a fact about your input
source_url, citation, disclaimerProvenance. The citation and disclaimer name the backend that actually answered

Backend provenance

FieldWhat it is
cdl_backendcropscape (primary) or pdi_imageserver (failover) — which USDA service produced this row
cdl_backend_failovertrue when the primary was unreachable and the failover answered. false when the primary served or you pinned a backend. null when nothing answered
cdl_backend_selection_reasonprimary_healthy · failover_primary_unavailable · user_pinned_primary · user_pinned_secondary
cdl_backend_primary_status, cdl_backend_secondary_statusPer-backend verification outcome: ok · unavailable (could not be reached or verified — nothing was measured) · drifted (was measured, and it is wrong) · disabled · not_checked. Both backends are verified on every run
cdl_backend_primary_detail, cdl_backend_secondary_detailWhy, when a backend was not ok
cdl_cross_backend_agreementDid the two services agree on the shared canary pixel this run: agree · agree_group_differs_code (adjacent classes at a boundary — expected, see above) · disagree (different land-cover group — treat the run as lower confidence) · null (one backend was not consulted)
cdl_cross_backend_detailBoth readings, when they differ
cdl_raster_name, cdl_pixel_metersThe exact USDA raster and its ground resolution, e.g. 2025_10m_cdls / 10. CDL moved from 30 m to 10 m with the 2024 vintage. Published only by the failover backend, so null on a CropScape row — not checked, not "unknown resolution"

Area composition (set sampleRadiusMeters > 0)

A siting decision is about a parcel, not one 30 m pixel. With a radius set, each site also gets a land-cover composition over a square box of that half-width, from USDA's GetCDLStat service — same keyless source, no extra billable rows. It is off by default because that clip service is far slower than the point lookup and does not always answer; each site gets 20 seconds for it and otherwise falls back to area_status "unavailable" without affecting the land-cover result.

FieldWhat it is
area_statusok, unavailable, or unknown_class: <codes>

| area_radius_m | Half-width sampled, in metres | | area_acres | Total acreage of the sampled box | | area_distinct_classes | How many different CDL classes occur in it | | area_dominant_class, area_dominant_code, area_dominant_pct | The largest class and its share | | area_cropland_pct | Share in cropland or orchard/vineyard — the number that matters for a farmland-conversion screen | | area_pasture_pct, area_forest_pct, area_wetland_pct, area_water_pct, area_developed_pct, area_barren_shrub_pct, area_no_data_pct | The rest of the composition | | area_top_classes | Up to five largest classes, each with code, name, acres and percent | | area_source_url | The GetCDLStat request used |

Which backend answered

The same USDA Cropland Data Layer is published through two independent public services. This actor uses both.

PrimaryFailover
cdl_backendcropscapepdi_imageserver
ServiceNASS CropScape GetCDLValueUSDA CroplandCROS ArcGIS Image Service
Hostnassgeodata.gmu.edupdi.scinet.usda.gov
Projection sampled inEPSG:5070 CONUS Albers (CDL native)EPSG:3857 Web Mercator
Names its raster / resolutionno (cdl_raster_name is null)yes (e.g. 2025_10m_cdls, 10 m)

How to tell which one you got. Every row carries cdl_backend, cdl_backend_failover and cdl_backend_selection_reason, plus a status and reason for each backend (cdl_backend_primary_status, cdl_backend_secondary_status). cdl_backend_failover: true means the primary was unreachable and the secondary answered. The citation and disclaimer strings on the row name the service that actually answered, so a failover row is never presentable as a primary row.

Should you care? For the cropland and prime-farmland answer, almost never — but here is the honest measurement rather than a reassurance. Both services serve the same CDL, reprojected differently, and their pixel grids are offset by about one pixel. Measured live on 2026-08-04 across 21 point/year probes, 18 returned the identical CDL code and 3 differed — all three within one pixel of a class boundary or inside the urban mosaic (Manhattan 2024: Developed/Medium vs Developed/High). Zero differed at the land-cover group level, so is_active_cropland and prime_farmland_flag agreed on every probe. A 20 m north-south transect through a soybean/corn boundary in Webster County, Iowa agreed at every step except the one where the boundary itself sits.

So: within roughly 10-30 m of a field edge the two services can name adjacent crops. Away from edges they agree exactly. Every run compares them on a shared canary pixel and publishes the verdict in cdl_cross_backend_agreement (agree, agree_group_differs_code, disagree, or null when one backend was not consulted). A disagreement is reported, never silently resolved in favour of whichever one answered.

Pinning a backend. Set backend to cropscape or pdi_imageserver if you need every answer to come from one named service — useful when you are diffing runs over time and want the pixel grid held constant. A pinned backend is never silently substituted: if it is unhealthy the run fails loudly and bills nothing, because a silent swap would destroy the reproducibility you asked for. The default, auto, is the one you want otherwise.

Reliability: how this actor fails

CDL is published annually, so the two things that can quietly go wrong are a stale vintage and a changed legend. Both are checked live, before any billable row is emitted - against whichever backend is about to answer:

  • Vintage is discovered two independent ways, not assumed. The primary check is a direct probe: candidate years are requested in descending order and the first that returns real CDL data is the newest published vintage. The service's own out-of-range message is read as a second, corroborating measurement (and is the only thing that reveals the earliest published year). If the two disagree, the direct data probe wins and the row says so. If the service ever publishes less than the vintage this build was verified against, the run fails.
  • "Could not measure" is reported separately from "measured and wrong." An upstream outage that silences a probe is a measurement failure, not evidence the data has drifted. The run continues, every row carries cdl_drift_gate_status: passed_with_warnings plus the specific caveat, and cdl_year_is_latest reports null rather than claiming the fallback year is current. A drift that is actually measured still fails the run and bills nothing.
  • Four positive canaries and a negative control run every time. Known row-crop pixels in Iowa, Illinois and Nebraska must classify as active cropland (the crop rotates year to year — Corn in 2024, Soybeans in 2025 — so the assertion is the stable property, not the class). Checking several points across several states means one field changing use cannot take the actor down, while a broken coordinate transform — which moves every point at once — still fails the run. A known North Atlantic ocean point must come back as No Data; if it ever returns a land-cover class, the transform or the product footprint has changed.
  • Projection is checked by magnitude and by end-to-end behaviour. CropScape echoes back the coordinate it was sent, verbatim (it does not snap to a pixel centre - measured 2026-08-04), so the echo comparison is a change-detector rather than live projection coverage; the real projection guard is the canary/negative-control pair plus a CONUS envelope bound on the projected coordinate. The failover backend additionally reports the spatial reference it interpreted the request in, and the run fails if that ever stops being Web Mercator.
  • An unrecognised CDL class code fails the run. The full published legend ships with the actor. A code outside it means USDA changed the legend, which invalidates every cropland and prime-farmland flag derived from it — so nothing is emitted rather than something plausible and wrong.
  • null means not checked. A pixel USDA never classified (CDL "No Data" — ocean, Canada, Mexico, cloud) and a point outside CONUS both return null crop flags with an explicit coverage_status, never a confident "not farmland".
  • If neither backend can be verified, the run fails and bills nothing. Rows are buffered and gated before anything is written.
  • A measured drift is never "failed over" around. Failover is for availability - a timeout, a 5xx, an unreadable body, a backend that verified nothing. If a backend is reached and its answer proves something has actually changed (superseded vintage, a canary on the wrong land cover, an unknown legend code), the run fails loudly instead, even when the other backend looks healthy. Two USDA services publishing the same product disagreeing about whether the world changed is a contradiction this actor will not resolve silently in your favour.

Pricing

Pay-per-result: one billable dataset row per site screened. Setting sampleRadiusMeters adds upstream calls but no extra rows — the composition fields ride on the same row. A failed run emits nothing and bills nothing.

About the prime-farmland flag

The CDL does not carry the legal "prime farmland" soil classification — that lives in NRCS SSURGO as the farmlndcl attribute. So prime_farmland_flag is a transparent proxy: true when the point is in active crop production, which strongly indicates farmland but is not a substitute for an SSURGO determination. For an authoritative answer (for example, a Farmland Protection Policy Act / AD-1006 review), use NRCS Web Soil Survey / SSURGO.

Who uses it

  • Solar and renewable-energy developers screening candidate parcels for active cropland or farmland-conversion sensitivity before acquisition.
  • Land-use and environmental diligence teams (Phase I / ESA-adjacent) needing a fast land-cover read at many coordinates.
  • Ag lenders, appraisers, and CRE analysts checking whether collateral is productive cropland.
  • Farmland-protection and conservation planners flagging active-cropland parcels.
  • AI agents needing a coordinate-to-land-cover lookup.

Use as an MCP tool

This is a Pay-Per-Result API with field-level output descriptions, so AI agents (Claude, Cursor, and others) can call it over mcp.apify.com as a coordinate-to-land-cover tool. Empty input costs nothing beyond the actor start.

FAQ

Is this the legal prime-farmland determination? No. It is a CDL active-cropland proxy; use NRCS SSURGO for the authoritative soil class.

Does it need an API key? No. Both USDA backends are public and keyless.

What happens for an ocean or non-US point? You get a valid No Data (code 0, category no_data) row with null crop flags and an explicit coverage_status — an honest non-answer, not an error and not a finding of "no farmland".

What happens if USDA CropScape goes down? The run is answered by USDA's CroplandCROS image service instead, and every row is stamped cdl_backend: "pdi_imageserver", cdl_backend_failover: true. Both publish the same Cropland Data Layer. This is why v1.4 exists: on 2026-08-02 CropScape was down for about an hour, and for that hour this actor was simply offline.

Can a failover answer differ from a primary answer? Yes, marginally, and the row tells you so. The two services reproject the same CDL and their pixel grids sit about one pixel apart, so within roughly 10-30 m of a field boundary they can name adjacent crops. Across 21 live probes on 2026-08-04 the two agreed on the land-cover group — and therefore on is_active_cropland and prime_farmland_flag — every single time. See Which backend answered.

Can I force one backend? Yes — set backend to cropscape or pdi_imageserver. A pinned backend is never silently substituted; if it is unhealthy the run fails and bills nothing.

What is simulateOutage? A diagnostic switch that forces a backend to be treated as unreachable, so the failover path can be exercised on demand rather than only discovered during a real outage. Leave it at none.

How is billing calculated? One dataset row per site.