BLM Mining Claims Search & Monitor API — Lode/Placer (MLRS)
Pricing
from $4.40 / 1,000 results
BLM Mining Claims Search & Monitor API — Lode/Placer (MLRS)
Search and monitor US federal mining claims from the official BLM MLRS national dataset. Filter by state, claim type (lode / placer / mill site) and status, and track newly recorded or modified claims. Mineral-rights and land data. Keyless, official source.
Pricing
from $4.40 / 1,000 results
Rating
0.0
(0)
Developer
Kyle Maloney
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
0
Monthly active users
4 days ago
Last modified
Share
BLM Mining Claims Search & Monitor (MLRS)
Search and monitor US federal unpatented mining claims from the official BLM Mineral & Land Records System (MLRS) national dataset — lode claims, placer claims, mill sites and tunnel sites — with PLSS legal locations, case serials, status, acreage and change dates. Keyless, official, public-domain source.
This is a screening tool, not a title determination. The BLM spatial layers do not carry claimant or owner names; those live only in separate MLRS case reports.
Scope and cost — read this first
states is required. There is no default and no hidden nationwide mode,
so a run always answers about the states you actually named.
{ "states": ["NV"] }
A call with no states is rejected before the run starts — HTTP 400, no
compute, no rows, nothing billed. That is deliberate: this field used to
carry a schema default, and because Apify injects defaults server-side, anyone
who omitted it was quietly answered about one arbitrary state and charged for
it on a run that reported SUCCESS. A rejected call is cheaper than a wrong answer.
What a run costs. Billing is pay-per-result at $8.00 per 1,000 rows
(about $0.80 per 100 rows), and paid Apify plans get a graduated discount
of 20-70% off that. Only rows actually written to the dataset are billed — a run
that fails a pre-flight check emits nothing and bills nothing. Set maxResults
to put a hard ceiling on any single run.
How many rows to expect. Scope drives the bill, so size it deliberately: Nevada is the largest claim state by a wide margin - cap it with maxResults. Run one state per run and combine the datasets rather than guessing at a wide scope.
What v1.1 fixes (read this if you used v1.0)
Every change is append-only — no field was removed or renamed. Five defects meant v1.0 could bill you for a confident wrong answer while the run reported SUCCESS:
states: ["AR"]returned zero rows while 18 Arkansas claims existed. The state filter matched only the case-serial prefix, but BLM's Eastern States office files everything east of the Mississippi under anESserial, with the real state appearing only in the PLSS legal description. v1.0 also emittedstate: "ES"— not a US state. The filter now matches the serial prefix or the PLSS state, andstateresolves correctly.- A disposition that cannot exist returned an empty dataset on a green run. v1.0's own input schema advertised
ClosedandVoid.Closedexists only in the Closed layer (so it matched nothing unlessincludeClosedwas set) andVoiddoes not exist in either layer. Both now fail the run with the valid values listed, before anything is billed. - A failed BLM layer was swallowed. v1.0 logged a warning and continued, so a dead Not Closed layer produced a green run holding only closed claims — or nothing. A partial answer is now a loud failure.
- Delta mode never worked.
monitor: trueused Apify's default key-value store, which is created fresh for every run, so the "already seen" baseline was always empty and every run re-emitted — and re-billed — the entire result set while reporting it as "only new since last run". It now uses a named, filter-scoped store. - Truncation was invisible. A default Nevada query matches over 275,000 claims and returns
maxResultsof them with no indication. Every row now carrieslayer_total_matchingandresult_truncated.
"Not Closed" is not "Active"
Measured live 2026-08-01, the Not Closed layer holds 578,019 records:
| Disposition | Records | Share |
|---|---|---|
| Active | 417,489 | 72.2% |
| Filed | 153,348 | 26.5% |
| Under Review | 6,076 | 1.1% |
| Submitted | 1,097 | 0.2% |
| On Appeal | 5 | — |
| Appeal - Stay Granted | 2 | — |
| Pending | 2 | — |
27.8% of "not closed" records are applications, not adjudicated active claims. Use is_active and claim_status_group rather than assuming the layer means active. The Closed layer (80,095 records) carries exactly one disposition: Closed.
Who it's for
- Title & land professionals — screen a section or township for unpatented claims before acquisition.
- Mineral exploration & staking — find open ground, track competitor staking activity by state and claim type.
- Mining companies & royalty holders — monitor claims adjacent to a position.
- Environmental & permitting consultants — surface federal mining claims in a project footprint.
- Data teams & AI agents — clean, flat, keyless claim records with structured status and data-quality flags.
Example input
{"states": ["NV"],"claimType": "Lode","disposition": "Active","maxResults": 200}
New and updated claims since a date, across two states, including closed cases:
{ "states": ["AZ", "NM"], "sinceModified": "2026-01-01", "includeClosed": true, "maxResults": 500 }
Recurring new-claim alert (named cross-run baseline, first run establishes it):
{ "states": ["NV"], "claimType": "Placer", "monitor": true, "maxResults": 1000 }
Date format: sinceModified must be YYYY-MM-DD
sinceModified is the only date input, and it is spliced into BLM's own SQL
where clause as Modified > DATE '<value>'. Only YYYY-MM-DD is accepted
(for example 2026-06-01). 2026-6-1 is accepted and padded. An empty value
means no lower bound. Anything else fails the run before any request is made,
and bills nothing - it is not guessed at.
That is deliberate, because BLM's ArcGIS date parser does not reject a bad
format, it silently reinterprets it. Measured live against the Not Closed layer
on 2026-08-20 (returnCountOnly, so these are exact match counts, not samples):
| You send | What BLM actually does | Matched claims |
|---|---|---|
2026-01-15 (correct form) | parsed as written | 201,542 |
05/06/2026 | silently read as US May 6. The European June 5 reading returns 126,065 - a difference of 8,094 claims (6.0%), with nothing in the response saying a format was guessed | 134,159 |
15/01/2026 | silently swaps day and month rather than rejecting the impossible month 15, returning the same answer as 2026-01-15 | 201,542 |
01/15/2026 | silently accepted as US month/day/year | 201,542 |
2026/01/15 | silently accepted | 201,542 |
Jan 2026 | silently reinterpreted as the 1st of the month - a wider window than most callers mean | 201,793 |
2026-13-45, 2026-02-30, last tuesday, 2026 | rejected by BLM, but only as an error envelope inside an HTTP 200 | run fails |
The first six rows all return HTTP 200 on a run that reports SUCCESS and bills normally, so a wrong-format date produces a plausible, confidently-labelled, wrong answer rather than a visible error. Rejecting every ambiguous form up front trades that for a loud, free, fixable failure. This matters most for AI agents calling the actor as an MCP tool, since a date is exactly the value an agent formats however it likes.
Output fields
Every field the actor declares.
| Field | Description |
|---|---|
claim_name | Name of the mining claim |
claim_type | Claim/product type exactly as BLM publishes it (casing is inconsistent upstream) |
claim_type_normalized | Normalized: Lode Claim, Placer Claim, Mill Site, Tunnel Site |
is_national_park_claim | True when BLM tags the claim as within a National Park unit |
disposition | Case disposition exactly as BLM publishes it |
claim_status_group | active / pending / appeal / closed; null when BLM returned a disposition outside the known vocabulary |
is_active | True only for Active. null when the disposition is unrecognised |
disposition_known | Whether the disposition is in the known BLM vocabulary |
case_serial | BLM case serial number |
legacy_serial | Legacy (LR2000-era) case serial, when present |
case_type_number | BLM case type number |
state | Two-letter US state code |
state_from_case_serial | State implied by the serial prefix, when that prefix is a state |
state_from_plss | State at the front of the PLSS legal description |
state_source | Which field state came from: case_serial or plss_meta |
admin_office_code | The two-character serial prefix — a state, or a BLM office |
admin_office_name | Office name when the prefix is an office (ES = Eastern States) |
plss_state_codes | Every distinct state across the claim's PLSS descriptions |
acres | Recorded acreage of the claim |
plss_location | First PLSS legal land description |
plss_descriptions | All PLSS aliquot descriptions |
parcel_count | Number of PLSS parcels |
data_quality_score | BLM geocoding quality score parsed from QLTY |
data_quality_notes | The free-text remainder of BLM's geocoding diagnostic |
data_quality_flags | TOWNSHIP_NOT_FOUND, PM_ANGLE_MISMATCH, OVERLAY, UNCLEAN_TOWNSHIP, UNNUMBERED_LOT, FIRST_DIVISION_ONLY, MAPPED_TO_WHOLE_DIVISION |
data_source | BLM source code for the record |
blm_case_id | BLM internal record identifier |
stage_case_id | BLM staging system case identifier |
salesforce_id | BLM MLRS Salesforce record identifier |
objectid | ArcGIS feature object id within the layer |
created / modified | Record create and last-modified dates (YYYY-MM-DD) |
status_layer | Which BLM layer the claim came from: not_closed or closed |
layer_total_matching | How many records in that layer match your query in total |
result_truncated | True when the layer held more matches than maxResults returned |
source_status | Per-layer outcome: ok when the BLM layer answered |
source_error | Why the layer did not answer, when it did not |
source_system / source_url | BLM MLRS and a link to the MLRS system |
Fields that are legitimately null on a healthy run, with an input that populates them: legacy_serial, data_source, stage_case_id and salesforce_id are sparsely populated by BLM; admin_office_name and state_from_plss populate on Eastern States records (states: ["AR"]); state_from_case_serial populates on every other record; data_quality_notes / data_quality_flags populate where BLM recorded a geocoding caveat; source_error populates only when a layer fails, in which case the run fails and emits nothing.
Reliability: what makes this fail loudly instead of answering wrongly
Every run checks the live service before any billable row is written:
- Layer resolves and still carries every field a row depends on. A retired ArcGIS service returns HTTP 200 with an embedded error, not a 404 — that is caught.
- Truncation guard read from the service's own
maxRecordCount, never a code constant, and paging is sized from it. Records repeated across page boundaries are de-duplicated and counted. - Row-count bands — each layer's total must sit in a measured band (Not Closed 578,019; Closed 80,095, both 2026-08-01), so a re-scoped or emptied layer fails instead of quietly returning a different dataset.
- Disposition vocabulary —
Activemust still return rows in Not Closed andClosedin Closed. If BLM changes the vocabulary, every status classification would be silently wrong, so the run fails. - Positive canary — case serial
NV105216280("WR 195") must resolve to exactly one record, and to that record. - Negative control — the impossible serial
ZZ000000000must match zero records. If it ever matches rows, BLM is ignoring thewhereclause and every filtered answer would be a full-layer dump wearing your filter's label. The run fails immediately. - No silent zero — a query matching nothing fails with the counts that explain it. An impossible
dispositionfails before any request. - All-or-nothing layers — if any selected layer fails, the run fails rather than presenting a partial answer as a complete one.
Every measured value is logged on every run, so the bands can be tightened on evidence.
Use as an MCP tool
Callable by AI agents (Claude, Cursor, etc.) via mcp.apify.com. "Are there active lode claims in Nevada modified since January?" maps directly to states + claimType + disposition + sinceModified. Agents should read is_active (null means not classified, never not active) and result_truncated before treating a result set as complete.
Pricing
Pay per result: $8 per 1,000 claim records. Graduated discounts apply on paid Apify plans. A run that fails a reliability gate emits nothing and bills nothing.
FAQ
Where does the data come from? The BLM National MLRS mining-claim FeatureServers (gis.blm.gov), public domain, no API key. Not Closed and Closed are separate layers.
Does it include the claimant / owner name? No. The BLM spatial layers do not publish claimant names; they exist only in MLRS case reports. Use case_serial to look a claim up at mlrs.blm.gov.
Which states have claims? AK, AZ, CA, CO, ID, MT, NM, NV, OR, UT and WY, plus a small number administered by BLM Eastern States (currently Arkansas). Nevada alone holds 275,828 not-closed claims.
Why did my run fail with "not a BLM MLRS case disposition"? You asked for a status BLM does not use — most often Void. The message lists the valid values. This is deliberate: returning an empty dataset would read as "there are no such claims".
Did I get all the claims? Check result_truncated and layer_total_matching on any row. Rows come back most-recently-modified first, so raise maxResults or narrow the filter.
What does a data_quality_flags value mean? BLM records how confidently it mapped the claim's PLSS description. TOWNSHIP_NOT_FOUND or PM_ANGLE_MISMATCH means the mapped location is less reliable — worth verifying against the case file.
Related actors
- PAD-US Protected Lands Screener — federal land manager and protection status for a coordinate.
- BLM Sage Grouse Siting Screener — habitat-management overlays on BLM ground.
- Energy Corridor Section 368 Screener — designated federal energy corridors.
- USGS Bedrock Geology & Lithology Screener — mapped bedrock units and mineral-relevant lithology.