# USGS Bedrock Geology & Lithology Risk Screener (`malonestar/usgs-bedrock-geology-lithology-screener`) Actor

Point-in-polygon screening against the USGS State Geologic Map Compilation. Returns geologic unit, formation names, age hierarchy and full lithology, plus 8 hazard flags: asbestos, karst, acid rock drainage, expansive soil, radon, loess, soft ground, landslide parent, and rippability.

- **URL**: https://apify.com/malonestar/usgs-bedrock-geology-lithology-screener.md
- **Developed by:** [Kyle Maloney](https://apify.com/malonestar) (community)
- **Categories:** Business, Developer tools, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## USGS Bedrock Geology & Lithology Screener

Point-in-polygon screening of any US coordinate against the **USGS State Geologic Map
Compilation (SGMC)** — a seamless compilation of the 48 conterminous state geologic maps,
313,732 polygons, published scales 1:50,000 to 1:1,000,000
([doi:10.5066/F7WH2N65](https://doi.org/10.5066/F7WH2N65)).

You get the mapped bedrock unit, its formal stratigraphy, its chronostratigraphic age, its
full lithologic composition, and **eight derived engineering and environmental hazard
flags** — each with the exact keywords that triggered it, so every call is auditable.

Batch a whole portfolio in one run. No API key. No scraping.

***

### Who this is for

**Geotechnical engineers scoping an investigation.** Before you site a single boring you
want to know whether you are on carbonate (grout takes, voids), on smectitic shale
(shrink-swell), on loess (hydrocompaction on wetting), on a mapped landslide deposit, or on
hard crystalline rock that will need blasting rather than ripping. `rippability_class`,
`major_lithology_percent` and `unit_comment` — which frequently carries the published unit
thickness — turn a coordinate into a scoping memo.

**Phase I ESA and environmental due diligence.** ASTM E1527-21 asks you to describe the
geologic setting. `reference_citation` is the full bibliographic citation of the state
geologic map the answer came from, `dataset_doi` cites the compilation itself, and
`source_scale` / `positional_uncertainty_m` state honestly how precise the answer is. Drop
them straight into the report. `acid_rock_drainage_risk` and `radon_parent_rock` flag the
two geologic conditions that most often become a finding.

**Solar, BESS and data-center siting.** Pile-driving feasibility is a lithology question.
Karst wrecks a fixed-tilt racking budget; hard rock forces pre-drilling; soft compressible
ground forces deep foundations. Screen a thousand candidate parcels in one run and rank them
before anyone drives out.

**Naturally-occurring asbestos compliance.** California's CARB Asbestos ATCM, and equivalent
rules in North Carolina and Virginia, are triggered by ultramafic and serpentinite rock. This
actor scans the union of every lithology field *and* the SGMC lithology hierarchy — the token
`Ultramafic` appears in the hierarchy on 153 units and **never** in the primary-lithology
column, so a screen that reads only the obvious field misses them.

**AI agents.** See "Use as an MCP tool" below.

***

### Why the flags read more than the obvious column

SGMC has a `GENERALIZED_LITH` column that looks like the natural thing to key a hazard flag
on. It is not sufficient. **11,790 polygons carry `MAJOR1 = 'Limestone'` while
`GENERALIZED_LITH` says only `'Sedimentary, undifferentiated'`** — 35% of every limestone
polygon in the country, invisible to a generalized-lithology-only karst screen. Mammoth Cave,
Kentucky is one of them.

So every flag scans the **union** of `GENERALIZED_LITH`, `MAJOR1-3`, `MINOR1-5`,
`INCIDENTAL`, `INDETERMINATE`, and the SGMC Lithology table's full classification hierarchy
(`Igneous - Plutonic - Ultramafic - Peridotite`) plus its lowest-level rock name. Matching is
word-boundary based on normalized text, so `sand` never matches `sandstone` and `clay` never
matches `claystone`.

The depositional-form column (`LITH_FORM`) is scanned **separately**, because its controlled
vocabulary mixes real depositional settings (`Alluvial`, `Playa`, `Eolian-loess`,
`Landslide`) with metamorphic *facies* labels (`Greenschist`,
`Amphibolite epidote-amphibolite`) that describe pressure and temperature grade rather than
rock type. Merging them would flag every greenschist-facies terrane in the country as
asbestos-bearing.

***

### Example input

```json
{
  "assets": [
    { "lat": 37.187, "lon": -86.1,   "label": "Mammoth Cave, KY" },
    { "lat": 36.38,  "lon": -120.75, "label": "Clear Creek, CA" },
    { "lat": 39.9,   "lon": -102.5,  "label": "Eastern Colorado plains" },
    { "lat": 61.2,   "lon": -149.9,  "label": "Anchorage, AK" }
  ],
  "bufferMeters": 500,
  "maxResults": 1000
}
```

| Input | Required | Default | Notes |
|---|---|---|---|
| `assets` | **yes** | — | Array of `{lat, lon, label}`. `latitude` / `longitude` / `lng` aliases accepted. Omitting it is an HTTP 400 before the run starts, so nothing is billed. |
| `bufferMeters` | no | `500` | Radius for the nearby-unit search, 0–50,000 m. The query is paginated, so a large radius returns every polygon rather than silently stopping at 2,000. Set `0` to disable. |
| `maxResults` | no | `1000` | Row cap. One row per asset. |

***

### Output fields

#### The site and the mapped unit

| Field | Description |
|---|---|
| `asset_label`, `lat`, `lon` | Echoed from your input. |
| `state` | Two-letter code of the state compilation the unit belongs to. |
| `unit_name` | Name of the bedrock map unit at the coordinate. |
| `sgmc_label`, `unit_link` | SGMC harmonised label, and the key joining the polygon to the lookup tables. |
| `orig_map_label` | The label as printed on the published state sheet — often different from `sgmc_label`. |
| `unit_description` | Full descriptive text for the unit. |
| `stratigraphic_units` | **Formal formation and member names** the unit contains. Populated on 612 units. |
| `unit_comment` | Compiler note; frequently carries unit **thickness** ("thickness ranges from 97-282 m"). |
| `province` | Physiographic / geologic province. Populated on 1,754 of 6,627 units, in PA NH MD SC NY NJ VT AL GA TN NC UT. |

#### Age

| Field | Description |
|---|---|
| `age_min`, `age_max` | Chronostratigraphic paths from the polygon attributes. |
| `age_min_ma`, `age_max_ma` | Numeric bounds in millions of years. |
| `age_min_era` / `_period` / `_epoch` and `age_max_era` / `_period` / `_epoch` | The full hierarchy, split for filtering. |
| `unit_age_text` | The age in the state survey's own words, e.g. "Upper Mississippian". |
| `age_dating_type` | `Absolute` (isotopic) or `Relative` (stratigraphic correlation). |
| `age_note` | Compiler note, including isotopic dates where cited. Populated on 1,807 units. |

#### Lithology

| Field | Description |
|---|---|
| `generalized_lith` | SGMC generalized class. Coarse by design — see above. |
| `major_lith_1/2/3`, `minor_liths`, `incidental_lith`, `indeterminate_lith` | The polygon's own lithology attributes. `indeterminate_lith` is sparse (2,709 of 313,732 polygons, 19 states); a recorded input that populates it is `{"lat":33.85734,"lon":-111.97056}`. |
| `lithology_hierarchy` | `Metamorphic - Metaigneous - Serpentinite (Major) \| Igneous - Plutonic - Ultramafic - Peridotite (Minor)`. |
| `lithology_detail` | Structured array, one entry per lithology row: rank, the five classification levels, form, comment, `percent_of_unit`. |
| `lithology_forms` | Distinct depositional forms and metamorphic facies (`Landslide; Colluvial`, `Alluvial; Eolian; Playa`). |
| `lithology_notes` | Compiler notes from the lithology table. Populated on 7,568 of 18,418 rows. |
| `major_lithology_percent` | **Composition estimate**: `Limestone 40%; Sandstone 40%; Siltstone 15%; Shale 5%`. Only unambiguous single-percentage notes are parsed, so an absent value means "not stated", never zero. |

#### Hazard flags

Every flag is `true`, `false` or **`null`**. `null` means *not checked* — the source backing
it did not answer. It never means "no hazard".

| Field | Fires on |
|---|---|
| `noa_risk` | Serpentinite, ultramafic, peridotite, dunite, pyroxenite, amphibolite, talc and soapstone, tremolite / actinolite / anthophyllite, greenstone, ophiolite. |
| `karst_bedrock` | Limestone, dolostone, dolomite, marble, chalk, coquina, travertine, marl — plus the far more soluble gypsum, anhydrite, halite and other evaporites. |
| `acid_rock_drainage_risk` | Black, oil and alum shale, pyrite, sulfides, marcasite, gossan, coal, lignite, anthracite, graphite. |
| `expansive_soil_parent` | Smectite, montmorillonite, bentonite, claystone, clay, mudstone, shale, marl, argillite, saprolite. |
| `radon_parent_rock` | Uranium-bearing black / alum / oil shale, marine phosphorite, and felsic plutonic rock (granite, alkali granite, syenite, pegmatite). Screening only — not a substitute for a measured test. |
| `collapsible_loess_risk` | Loess recorded as the depositional form: hydrocompaction on wetting. This signal exists **only** in the lithology table. |
| `soft_compressible_ground` | Peat, muck and organic-rich lithologies, or playa / lacustrine / estuarine / deltaic / swamp deposition. |
| `landslide_colluvium_parent` | The map unit is itself a landslide, mass-wasting, colluvial, talus or melange deposit. |
| `hazard_flag_count` | How many fired. `null` when nothing could be checked; `0` means checked and clean. |
| `risk_basis` | **The exact keywords that triggered each flag**: `karst: limestone \| expansive: shale`. Audit every call. |
| `rippability_class`, `rippability_note` | `unconsolidated_rippable`, `weak_rock_rippable`, `intermediate_marginal`, `hard_rock_blasting_likely`, `not_applicable`, `unknown` — plus prose. |

#### Nearby units, because the point is not the whole answer

| Field | Description |
|---|---|
| `units_within_buffer` | Distinct units inside the buffer, **each with its own hazard flags**, computed through the same union. |
| `units_within_buffer_count`, `multi_unit_ambiguity`, `buffer_meters` | More than one unit means the site sits near a mapped contact. |
| `nearby_noa_risk`, `nearby_karst_bedrock`, `nearby_acid_rock_drainage_risk`, `nearby_expansive_soil_parent` | True if **any** nearby unit is; false only when every nearby unit was checked and negative. |
| `nearby_hazard_summary` | Which hazards are nearby, and exactly which unit links carry them. |
| `nearby_flags_status` | `ok`, `partial` or `not_applicable`. |

The point answer is only as good as the map. At 1:500,000 a drafted contact is worth ±250 m
on the ground, so a site reading "granite, no asbestos" with a serpentinite body 300 m away
has not been cleared.

#### Provenance and precision

| Field | Description |
|---|---|
| `source_scale`, `source_scale_denominator` | Publication scale of the source sheet — the coarsest, when the citation lists several. |
| `positional_uncertainty_m` | Ground uncertainty from the 0.5 mm drafted-line convention: denominator × 0.0005 m. 250 m at 1:500,000. |
| `map_polygon_area_km2` | Approximate area of the specific polygon, de-scaled from Web Mercator by cos²(latitude). |
| `map_precision_class` | `site_scale`, `reconnaissance` or `regional_generalization`. |
| `point_features_returned` | Polygons intersecting the coordinate. Normally 1. |
| `reference_citation` | Full bibliographic citation of the source state geologic map. |
| `ngmdb_url`, `digital_data_url` | NGMDB product page, and the publisher's GIS download. |
| `dataset_name`, `dataset_doi` | The SGMC data release itself, for a references section. |

#### Per-source status — read this before you trust a `false`

| Field | Description |
|---|---|
| `geology_layer_status` | `ok`, `no_coverage`, `unavailable`. |
| `units_lookup_status`, `age_lookup_status`, `lithology_lookup_status` | `ok`, `no_match`, `unavailable`, `not_applicable`. |
| `buffer_status`, `buffer_truncated` | Whether the nearby-unit list is complete. |
| `flags_complete` | `true` when the lithology hierarchy was actually read, so a `false` flag genuinely means checked-and-negative. |
| `sources_unavailable`, `data_completeness` | Which sources did not answer, and `complete` / `partial`. |
| `out_of_coverage`, `coverage_note` | See below. |
| `error`, `source_url`, `retrieved_at` | Per-asset error, the exact reproducible query, and the fetch timestamp. |

***

### Coverage and failure behaviour

**SGMC maps the conterminous 48 states only.** Alaska, Hawaii, Puerto Rico and the
territories are not in it. A coordinate there gets an explicit `out_of_coverage: true` row
with an explanatory `coverage_note` **and every hazard flag set to `null`** — never `false`.
An unmapped coordinate is *not checked*, and a screener that reported "no asbestos" for
Anchorage would be lying to a buyer about to break ground. The same applies offshore and in
gaps between state compilations.

The actor fails **loudly** rather than returning a plausible empty answer:

- Omitting `assets` is an HTTP 400 at run creation. The run never starts and nothing is billed.
- Four **live drift assertions** run before any screening: the geology layer's polygon count
  and the lithology table's row count must fall within their calibrated bands, the token
  `Ultramafic` must still exist in the lithology hierarchy, and the
  limestone-behind-a-generic-generalized-lithology population must still be non-zero. If the
  upstream has been silently truncated or reshaped, the run fails and nothing is billed —
  because the flags would no longer mean what they say.
- If every in-coverage asset fails against the service, the run fails rather than billing you
  for a page of error rows.
- If all three lookup tables are down at once, the run fails, because every hazard flag would
  have been `null`.
- If *some* sources answered, you get your rows, and each one states on its face which
  sources did not answer and which flags are therefore unverified.

***

### Use as an MCP tool

Available to AI agents through `mcp.apify.com`. Every input and output field carries a
description, so an agent can call it unassisted and reason about the result. It chains
cleanly: resolve an address to a coordinate, screen the geology, then hand `karst_bedrock`,
`noa_risk` and `rippability_class` to a downstream siting or cost model. `risk_basis` gives
the agent evidence to cite, and `flags_complete` tells it when not to.

***

### Pricing

Pay per result: one event per row, one row per asset. A 500-site portfolio screen is 500
results. Graduated discounts apply on paid Apify plans. Failed runs emit no rows and are
never billed.

***

### Related actors

Bedrock lithology is one layer of a site screen. These cover the rest:

- **[Karst & Sinkhole Risk Screener](https://apify.com/malonestar/karst-sinkhole-risk-screener)** —
  the USGS karst-susceptibility polygons. Complementary rather than duplicative: this actor
  reports the *mapped surface unit's* lithology, while the karst screener includes **buried**
  carbonate and evaporite units at depth. Denver reads `Gravels and alluviums` (`COQg;0`, no
  karst) here and is a genuine buried-evaporite hit there. Both are correct; they answer
  different questions. Run both.
- **[USGS Landslide Proximity Screener](https://apify.com/malonestar/usgs-landslide-proximity-screener)** —
  the mapped landslide inventory. `landslide_colluvium_parent` here tells you the bedrock map
  unit *is* a slide deposit; that actor tells you which inventoried slides are nearby.
- **[USGS Seismic Design Screener](https://apify.com/malonestar/usgs-seismic-design-screener)** —
  ASCE 7 design values. Site class is a function of the material this actor identifies.
- **[Site Due Diligence Bundle](https://apify.com/malonestar/site-due-diligence-bundle)** —
  20 layers for one coordinate in one call, with a composite score and a go / caution / no-go
  verdict.

***

### FAQ

**How current is the data?**
SGMC is a compilation of published state geologic maps, so its currency is the currency of
each state's sheet — anywhere from the 1980s to the 2010s. That is the nature of bedrock
geology: the rocks have not moved. What changes is mapping detail, which is why every row
carries `source_scale`, `reference_citation` and `positional_uncertainty_m`.

**Is this a substitute for a site investigation?**
No, and nothing costing cents per site is. It is a *screening* tool: it tells you where to
spend investigation budget and what to expect, at a scale of 1:50,000 to 1:1,000,000. Read
`map_precision_class` before leaning on any single answer.

**Why is a flag `null` instead of `false`?**
Because the source backing it did not answer. `null` means not checked; `false` means checked
and negative. Look at `flags_complete`, `lithology_lookup_status` and `sources_unavailable` on
the row.

**The point says no karst but a nearby unit is limestone. Which do I believe?**
Both. `karst_bedrock` describes the polygon your coordinate fell in; `nearby_karst_bedrock`
describes the buffer. Compare the distance you care about against `positional_uncertainty_m`
— inside that distance the map genuinely cannot distinguish them.

**Why does my coordinate return `out_of_coverage` inside the US?**
Either it is offshore or in a large water body, or it falls in a gap between state
compilations. `coverage_note` says which.

**Can I get Alaska or Hawaii?**
Not from SGMC — they are not in the compilation. Those rows come back honestly flagged rather
than silently blank.

**How many requests does a large run make?**
The lookup tables are fetched **once for the whole run**, batched by the distinct set of units
across every asset — three requests total for a typical multi-state portfolio, never one per
asset. Spatial queries are two per in-coverage asset: the point, plus a paginated buffer.

***

*Data source: U.S. Geological Survey, State Geologic Map Compilation (SGMC), conterminous
United States, [doi:10.5066/F7WH2N65](https://doi.org/10.5066/F7WH2N65). Public domain. This
actor is not affiliated with or endorsed by the USGS.*

# Actor input Schema

## `assets` (type: `array`):

REQUIRED. Array of sites to screen, each an object with numeric "lat" and "lon" (WGS84 decimal degrees) and an optional "label". Example: \[{"lat":37.187,"lon":-86.1,"label":"Mammoth Cave, KY"}]. Coverage is the conterminous US only; Alaska, Hawaii and Puerto Rico return an explicit out\_of\_coverage row whose hazard flags are null (not checked) rather than false.

## `bufferMeters` (type: `integer`):

Radius around each coordinate used to list every distinct geologic unit nearby, each with its own hazard flags. SGMC source scales run from 1:50,000 to 1:1,000,000, so a point near a mapped contact can land in the wrong unit; the buffer exposes that ambiguity instead of implying false precision. The query is paginated, so large radii are complete rather than silently truncated at 2,000 polygons. Default 500. Set 0 to disable.

## `maxResults` (type: `integer`):

Maximum number of result rows (one row per asset) to emit. Useful for capping cost on very large asset lists. Default 1000.

## Actor input object example

```json
{
  "assets": [
    {
      "lat": 37.187,
      "lon": -86.1,
      "label": "Mammoth Cave, KY - Mississippian limestone (karst hidden behind a generic generalized lithology)"
    },
    {
      "lat": 36.38,
      "lon": -120.75,
      "label": "Clear Creek, CA - serpentinite (naturally-occurring asbestos)"
    },
    {
      "lat": 42.15,
      "lon": -123.7,
      "label": "Josephine Ophiolite, OR - peridotite (ultramafic, hierarchy-only signal)"
    },
    {
      "lat": 27.85,
      "lon": -81.95,
      "label": "Bone Valley, FL - phosphorite (radon parent rock)"
    },
    {
      "lat": 39.9,
      "lon": -102.5,
      "label": "Eastern Colorado plains - Peoria loess (collapsible soil)"
    },
    {
      "lat": 39.05,
      "lon": -108.3,
      "label": "Grand Mesa, CO - mapped landslide and colluvial deposits"
    },
    {
      "lat": 32.4,
      "lon": -87.3,
      "label": "Alabama Black Belt - Mooreville Chalk, Coastal Plain Province"
    },
    {
      "lat": 33.3,
      "lon": -113.6,
      "label": "La Posa Plain, AZ - playa and alluvial fines (soft compressible ground)"
    },
    {
      "lat": 61.2,
      "lon": -149.9,
      "label": "Anchorage, AK - outside SGMC coverage (demonstrates the null-not-false contract)"
    }
  ],
  "bufferMeters": 500,
  "maxResults": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "assets": [
        {
            "lat": 37.187,
            "lon": -86.1,
            "label": "Mammoth Cave, KY - Mississippian limestone (karst hidden behind a generic generalized lithology)"
        },
        {
            "lat": 36.38,
            "lon": -120.75,
            "label": "Clear Creek, CA - serpentinite (naturally-occurring asbestos)"
        },
        {
            "lat": 42.15,
            "lon": -123.7,
            "label": "Josephine Ophiolite, OR - peridotite (ultramafic, hierarchy-only signal)"
        },
        {
            "lat": 27.85,
            "lon": -81.95,
            "label": "Bone Valley, FL - phosphorite (radon parent rock)"
        },
        {
            "lat": 39.9,
            "lon": -102.5,
            "label": "Eastern Colorado plains - Peoria loess (collapsible soil)"
        },
        {
            "lat": 39.05,
            "lon": -108.3,
            "label": "Grand Mesa, CO - mapped landslide and colluvial deposits"
        },
        {
            "lat": 32.4,
            "lon": -87.3,
            "label": "Alabama Black Belt - Mooreville Chalk, Coastal Plain Province"
        },
        {
            "lat": 33.3,
            "lon": -113.6,
            "label": "La Posa Plain, AZ - playa and alluvial fines (soft compressible ground)"
        },
        {
            "lat": 61.2,
            "lon": -149.9,
            "label": "Anchorage, AK - outside SGMC coverage (demonstrates the null-not-false contract)"
        }
    ],
    "bufferMeters": 500,
    "maxResults": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("malonestar/usgs-bedrock-geology-lithology-screener").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "assets": [
        {
            "lat": 37.187,
            "lon": -86.1,
            "label": "Mammoth Cave, KY - Mississippian limestone (karst hidden behind a generic generalized lithology)",
        },
        {
            "lat": 36.38,
            "lon": -120.75,
            "label": "Clear Creek, CA - serpentinite (naturally-occurring asbestos)",
        },
        {
            "lat": 42.15,
            "lon": -123.7,
            "label": "Josephine Ophiolite, OR - peridotite (ultramafic, hierarchy-only signal)",
        },
        {
            "lat": 27.85,
            "lon": -81.95,
            "label": "Bone Valley, FL - phosphorite (radon parent rock)",
        },
        {
            "lat": 39.9,
            "lon": -102.5,
            "label": "Eastern Colorado plains - Peoria loess (collapsible soil)",
        },
        {
            "lat": 39.05,
            "lon": -108.3,
            "label": "Grand Mesa, CO - mapped landslide and colluvial deposits",
        },
        {
            "lat": 32.4,
            "lon": -87.3,
            "label": "Alabama Black Belt - Mooreville Chalk, Coastal Plain Province",
        },
        {
            "lat": 33.3,
            "lon": -113.6,
            "label": "La Posa Plain, AZ - playa and alluvial fines (soft compressible ground)",
        },
        {
            "lat": 61.2,
            "lon": -149.9,
            "label": "Anchorage, AK - outside SGMC coverage (demonstrates the null-not-false contract)",
        },
    ],
    "bufferMeters": 500,
    "maxResults": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("malonestar/usgs-bedrock-geology-lithology-screener").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "assets": [
    {
      "lat": 37.187,
      "lon": -86.1,
      "label": "Mammoth Cave, KY - Mississippian limestone (karst hidden behind a generic generalized lithology)"
    },
    {
      "lat": 36.38,
      "lon": -120.75,
      "label": "Clear Creek, CA - serpentinite (naturally-occurring asbestos)"
    },
    {
      "lat": 42.15,
      "lon": -123.7,
      "label": "Josephine Ophiolite, OR - peridotite (ultramafic, hierarchy-only signal)"
    },
    {
      "lat": 27.85,
      "lon": -81.95,
      "label": "Bone Valley, FL - phosphorite (radon parent rock)"
    },
    {
      "lat": 39.9,
      "lon": -102.5,
      "label": "Eastern Colorado plains - Peoria loess (collapsible soil)"
    },
    {
      "lat": 39.05,
      "lon": -108.3,
      "label": "Grand Mesa, CO - mapped landslide and colluvial deposits"
    },
    {
      "lat": 32.4,
      "lon": -87.3,
      "label": "Alabama Black Belt - Mooreville Chalk, Coastal Plain Province"
    },
    {
      "lat": 33.3,
      "lon": -113.6,
      "label": "La Posa Plain, AZ - playa and alluvial fines (soft compressible ground)"
    },
    {
      "lat": 61.2,
      "lon": -149.9,
      "label": "Anchorage, AK - outside SGMC coverage (demonstrates the null-not-false contract)"
    }
  ],
  "bufferMeters": 500,
  "maxResults": 1000
}' |
apify call malonestar/usgs-bedrock-geology-lithology-screener --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=malonestar/usgs-bedrock-geology-lithology-screener",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/zNUQJ75F2crUCxtGp/builds/hAjaXHpbGYdalSePA/openapi.json
