# Environmental Records Report - ASTM E1527 Records Screen PDF (`malonestar/environmental-records-report`) Actor

One HTML + PDF Environmental Records Report per US property: ASTM E1527-21 Sec. 8.2 federal records at standard search distances, Sec. 8.3 prior uses, historical topo coverage, tank/spill registries, 20-layer site screen, live drift-gate page, explicit not-included page. $2.50/report + child rows.

- **URL**: https://apify.com/malonestar/environmental-records-report.md
- **Developed by:** [Kyle Maloney](https://apify.com/malonestar) (community)
- **Categories:** Real estate, Business, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1,375.00 / 1,000 environmental records report generateds

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Environmental Records Report - ASTM E1527-21 records-search appendix, one PDF per property

**One address or coordinate in, one Environmental Records Report out - as HTML, as PDF and as a machine-readable JSON model - for $2.50 per report (list price) plus the child screeners' own per-row charges (measured $0.98-1.32 per property, never more than $2.40) - so one report fits inside the Apify free plan's $5 monthly credit.** The report is the records layer a Phase I Environmental Site Assessment consultant attaches as an appendix or runs as a desktop pre-screen before ordering a full commercial database package: federal records at the ASTM E1527-21 Sec. 8.2.1 standard search distances, Sec. 8.3 prior industrial uses, Sec. 8.3.4 historical topographic map coverage, underground storage tank and spill registries, and a 20-layer site screen - with a radius map, per-layer data vintages, a **live source-verification (drift gate) page** and an explicit **"what this report does NOT include"** page.

It is composed by Actor-to-Actor calls to five published `malonestar` screeners on their `latest` builds, so every table in the report is exactly what those actors return today, and every one of them verifies its government upstream before it emits a row.

### Who it is for

- **Environmental consultants** preparing Phase I ESAs (ASTM E1527-21 / 40 CFR Part 312) who want the federal and state records tables in a citable, dated, per-property document rather than as CSV rows.
- **CRE lenders, brokers and acquirers** doing a desktop pre-screen before paying for a full commercial environmental database report (published price lists put those at $250-415 - see the price section).
- **Portfolio owners** who need one honest one-page-per-layer document per site, including an explicit list of the record classes that were *not* searched.

### What you get per property

| Artefact | Where | Notes |
|---|---|---|
| `report-NN-<label>.pdf` | run key-value store, URL in `report_pdf_url` | Letter, ~15 pages, pure-JS render (no browser) |
| `report-NN-<label>.html` | run key-value store, URL in `report_html_url` | self-contained, inline SVG radius map, print-ready |
| `report-NN-<label>.json` | run key-value store, URL in `report_json_url` | the full report model every table is rendered from |
| one dataset row | default dataset | status, URLs, headline counts, per-layer status, child run ids, stacked cost |

The run key-value store is private to your account: open the `report_*_url` links with your API token appended (`?token=...`), or click through `report_console_url` while signed in to the Console. A token-less request returns HTTP 403 - the report is never world-readable by URL.

#### Report pages

1. **Cover** - property, coordinates and how they were resolved, state and how it was resolved, radii, timestamp, run id, report status, headline findings, a layers-and-vintages table and the **radius map** (ASTM rings at 0.25 / 0.5 / 1 mi; every record the agency published a coordinate for is plotted; records without a coordinate are counted, not invented).
2. **ASTM E1527-21 Sec. 8.2 federal records** - the eight ASTM databases (NPL, delisted NPL / SEMS-CERCLIS, RCRA CORRACTS, RCRA TSD, RCRA generators, LUST, UST, Brownfields) each at its own standard search distance with count, nearest distance and result; whether the property sits **inside a published Superfund site boundary or institutional-control boundary**; the nearest-first records table (10 nearest per program, ECHO enforcement and penalty detail where EPA publishes it).
3. **Sec. 8.3 prior uses** - EPA FRS facilities within the adjoining-property radius carrying a contaminating SIC/NAICS classification (dry cleaners, wood preserving, plating, petroleum bulk storage, ...), the contaminants the cited authorities associate with each use, how many in-radius facilities carry **no** classification at all (never counted as clean), and the live inventory of **state and tribal equivalent record systems** EPA normalises for the property's state - including the twelve jurisdictions where that inventory is empty.
4. **Sec. 8.3.4 historical topographic coverage** - every USGS map year covering the property (1880s-present), the five-year interval strip for the review window, data gaps, longest uncovered span, and a chronology with a GeoPDF link per year.
5. **Tank and spill registries** - EPA UST Finder nationally plus NY DEC, CA GeoTracker, TX TCEQ and FL DEP, nearest first, open/closed with the basis for that status, and a plain statement of whether the property's state has a state-registry leg at all.
6. **20-layer site screen** - the `site-due-diligence-bundle` verdict, score and flags, with each layer's status and data vintage.
7. **Live source verification (drift gate)** - the differentiator: per layer, the child's gate status, how many live checks ran and failed, which probes passed (positive canaries, negative controls, row-count floors, vocabulary checks), and what exactly was verified. A layer whose gate did not pass is shown as unavailable, never rendered as a clean result.
8. **What this report does NOT include** - historical aerials, Sanborn maps, city directories, state records beyond EPA FRS and the four state tank registries, coordinate-less records, site reconnaissance, a professional's interpretation, a signed E\&O deliverable, AAI / 40 CFR Part 312 compliance.
9. **Appendix** - every child run id and build, rows returned per layer, and the estimated child charges for this property.

### Honesty contract - three-valued everywhere

- Each layer is `complete` (the child answered and its own completeness flags say every source answered), `partial` (the child answered but disclosed a failed, truncated or deadline-cut source - its "none found" statements are unverified for those sources), `unavailable` (the child did not answer for this property - **the layer was NOT screened** and the report says so on a red page), or `not_requested`.
- A report is **`complete` only when every requested layer is complete**; `partial` when at least one layer answered; `failed` when no layer answered - then nothing is rendered and **nothing is charged**.
- Every headline count is `null` when its layer was not screened - never `0`.
- If no report at all could be generated for any property, the run **FAILS** with a plain status message and no charge.
- The run checks its own charge limit **before** calling any child: the limit must cover the report fee **plus** the children's worst-case charges for each property ($2.50 + $2.40 = $4.90 for one property on the free plan). If it cannot, the run fails immediately and calls no child, instead of spending your budget on children for a report it cannot then bill. Each child call also carries its own charge cap, set just above the most that child can bill, so the stacked bill can never exceed what the pre-flight checked.

### Pricing - read this first

| Event | List price (FREE plan) | Bronze / Silver / Gold and above |
|---|---|---|
| `report-generated` - one per property with a complete or partial report whose HTML/PDF were stored | **$2.50** | $2.00 / $1.75 / $1.375 (Platinum and Diamond are billed at the Gold price) |
| dataset row | none - the row is the report's index, not a second charge | - |

**The bill is stacked, and this is stated plainly:** the five child screeners run on *your* account and bill their own per-result prices in addition to the report fee. Measured on the prefill property (Denver, 1 mi, all five layers, 2026-09-26):

| Child (latest build) | Rows | List price | Cost |
|---|---|---|---|
| `malonestar/epa-contaminated-site-screener` | 68 | $0.010/row | $0.68 |
| `malonestar/historic-land-use-sic-contaminant-screener` | 4 | $0.012/row | $0.05 |
| `malonestar/usgs-historical-topo-records-review` | 1 | $0.010/row | $0.01 |
| `malonestar/state-tank-spill-registry-screener` | 20 | $0.010/row | $0.20 |
| `malonestar/site-due-diligence-bundle` | 1 | $0.100/row | $0.10 |
| **Children total** | | | **~$1.04** |
| **Report fee** | | | **$2.50** |
| **All-in, one property, list prices** | | | **~$3.54** |

Measured again on 2026-10-06 across four dense industrial parcels (Denver, Newark NJ, Vernon CA, Houston ship channel): $0.98-1.32 in child rows per property. A rural parcel returns a handful of rows and costs about $0.30. The hard ceiling is $2.40 per property (every child at its own row cap, plus a 15% margin) - that is the figure the pre-flight budgets, so **one property costs at most $4.90 all-in at list prices**. Each dataset row carries `child_rows_usd_estimate` and `total_usd_list_estimate` for the property it describes. Paid Apify plans pay the tiered price on both the report fee and the children.

#### How this compares with a commercial environmental database report

A3 Environmental Consultants publishes a dated price list for the equivalent commercial packages (a3e.com, "What does an EDR report cost?", updated 2026-05-29): about **$250 for a desktop environmental screen and $375-415 for a database report package**, delivered in 48-72 hours. Those packages include things this report does not - historical aerial photographs, Sanborn fire-insurance maps, city directories, full state and tribal coverage and an analyst's review - and this report includes things they typically do not: the live source-verification page, per-layer data vintages measured at run time, the ASTM per-database table computed from EPA's own coordinate-bearing records, and a machine-readable model. It runs in about a minute. Read the not-included page before relying on it for anything the standard requires.

### Input

```json
{
  "properties": [
    { "lat": 39.8037, "lon": -104.9986, "state": "CO", "label": "Denver industrial parcel (prefill)" },
    { "address": "5980 Lipan St, Denver, CO 80221", "label": "Same parcel by address" }
  ],
  "layers": ["federal_records", "prior_uses", "historical_topo", "tank_spill", "site_screen"],
  "radiusMiles": 1,
  "priorUseRadiusMiles": 0.25,
  "topoReviewStartYear": 1940,
  "includePdf": true
}
```

- `properties` (required) - address (geocoded with the free US Census geocoder) or lat/lon, optional `label` and `state` hint. A property that cannot be resolved gets a `not_screened` row and is not charged.
- `layers` - default all five. Dropping a layer drops its child call and its page.
- `radiusMiles` - 0.25-5, default 1 (the widest ASTM Sec. 8.2.1 distance; the ASTM table always uses each database's own distance).
- `priorUseRadiusMiles` - 0.02-1, default 0.25 (subject and adjoining properties).
- `topoReviewStartYear` - 1880-2020, default 1940.
- `includePdf` - default true.
- `maxProperties` - optional cap; properties beyond it are `not_screened` and not charged.

The prefill runs one Denver property through all five layers in roughly 60-90 seconds and costs one report fee plus about $1 of child rows.

### Output fields (one row per property)

| Field | Type | Meaning |
|---|---|---|
| `property_label` | string | Your label for the property, echoed back (or the geocoded address when no label was supplied). |
| `property_address` | string | The address you supplied, or null when the property was given as lat/lon. |
| `property_lat` | number | Latitude actually screened (WGS84), after geocoding if an address was supplied. Null when the property could not be resolved. |
| `property_lon` | number | Longitude actually screened (WGS84). Null when the property could not be resolved. |
| `property_state` | string | Two-letter state the property resolved to (supplied hint, Census geocoder, or FCC block API). Null when unresolved - the tank/spill state-registry coverage is then unknown and says so. |
| `property_resolution` | string | "lat_lon_supplied" or "census_geocoded". Null when the property could not be resolved. |
| `radius_miles` | number | Radius used for the federal records, tank/spill and site-screen layers. |
| `prior_use_radius_miles` | number | Radius used for the ASTM Sec. 8.3 prior-uses layer. |
| `generated_at` | string | UTC timestamp (ISO 8601) the report was generated. |
| `run_id` | string | This Apify run id, printed on the report cover. |
| `report_status` | string | "complete" = every requested layer answered in full; "partial" = at least one layer answered but one or more layers are unavailable or partial (read layers_unavailable / layers_partial); "failed" = no requested layer answered, no report was rendered and NOTHING was charged; "not_screened" = the property could not be resolved or was beyond the cap, no report, no charge. |
| `not_screened_reason` | string | Why no report exists for this property (report_status failed or not_screened). Null when a report was generated. |
| `report_html_url` | string | API URL of the HTML report in this run's key-value store. The store is private to your account: open the URL with your API token appended as ?token=... or use report_console_url. Null when no report was generated. |
| `report_pdf_url` | string | API URL of the PDF report (same access rule as report_html_url). Null when includePdf was false or no report was generated. |
| `report_json_url` | string | API URL of the JSON report model the HTML and PDF were rendered from - every table in the report, machine-readable (same access rule). |
| `report_console_url` | string | Apify Console page of this run's key-value store, where the HTML, PDF and JSON records can be opened and downloaded while signed in. |
| `report_urls_require_token` | boolean | Always true: the run key-value store is private to the account that ran the report, so the report\_\*\_url links need ?token=<your Apify API token> (or the Console) to open. Measured 2026-09-26: a token-less GET returns HTTP 403. |
| `report_html_key` | string | Key-value store record key of the HTML report. |
| `report_pdf_key` | string | Key-value store record key of the PDF report. |
| `report_json_key` | string | Key-value store record key of the JSON model. |
| `artefact_error` | string | Set when the report could be composed but storing HTML/PDF failed. The report is then NOT charged. |
| `layers_requested` | array | Layer keys requested for this run. |
| `layers_complete` | array | Layers whose child answered in full for this property. |
| `layers_partial` | array | Layers whose child answered but disclosed a failed, truncated or deadline-cut source. Their "none found" statements are unverified for the sources named. |
| `layers_unavailable` | array | Layers whose child did NOT answer for this property. They were NOT screened; the report says so on a red page. |
| `layer_status_federal_records` | string | "complete" / "partial" / "unavailable" / "not_requested" for the ASTM Sec. 8.2 federal-records layer (malonestar/epa-contaminated-site-screener). |
| `layer_status_prior_uses` | string | Same vocabulary, for the ASTM Sec. 8.3 prior-uses layer (malonestar/historic-land-use-sic-contaminant-screener). |
| `layer_status_historical_topo` | string | Same vocabulary, for the historical topographic coverage layer (malonestar/usgs-historical-topo-records-review). |
| `layer_status_tank_spill` | string | Same vocabulary, for the tank/spill registry layer (malonestar/state-tank-spill-registry-screener). |
| `layer_status_site_screen` | string | Same vocabulary, for the 20-layer site screen (malonestar/site-due-diligence-bundle). |
| `astm_databases_flagged` | number | How many of the ASTM E1527-21 Sec. 8.2.1 databases have at least one record within their standard search distance. Null when the federal layer was not screened - never 0 in that case. |
| `astm_databases_measured` | number | How many ASTM databases the federal layer actually measured (8 when complete). Null when not screened. |
| `federal_listings_within_radius` | number | EPA program records within radius_miles, capped at 10 nearest per program. Null when not screened. |
| `on_superfund_site` | boolean | True when the property coordinate falls inside a published EPA NPL Superfund site boundary polygon; false when checked and outside; null when not checked. |
| `superfund_site_name` | string | Name of the containing Superfund site when on_superfund_site is true. |
| `prior_use_verdict` | string | The Sec. 8.3 verdict from the prior-uses child: "contaminating_use_identified" / "no_classified_contaminating_use_found" / "inconclusive" / "not_screened" ... Null when the layer was not screened. |
| `prior_use_facilities_counted` | number | Contaminating-use facilities with a site-specific coordinate that counted toward the Sec. 8.3 verdict. Null when not screened. |
| `topo_coverage_pct` | number | Share of the ASTM Sec. 8.3.4 review-window intervals covered by at least one USGS topographic map. Null when not screened or when a USGS collection did not answer. |
| `topo_map_years` | number | Distinct map years covering the property across the USGS collections. Null when not screened. |
| `topo_data_gap_present` | boolean | True when at least one review-window interval has no covering map; null when not determined. |
| `tank_spill_records` | number | Tank/spill records within radius (up to 20 nearest). Null when not screened. |
| `tank_spill_open` | number | Of those, how many the registry reports as open. Null when not screened. |
| `tank_state_registry_covered` | boolean | True when the property's state has a state-registry leg in the tank/spill child (NY, CA, TX, FL); false when only the national EPA UST Finder baseline was searched for it; null when the state is unknown. |
| `site_verdict` | string | The 20-layer bundle verdict: "proceed" / "caution" / "no-go". Null when not screened. |
| `site_score` | number | The bundle's composite 0-100 site score. Null when not screened. |
| `child_run_ids` | object | Apify run id of each child screener call, keyed by layer. Null for a layer that was not called. |
| `child_builds` | object | Build number each child ran on (always its latest build at run time), keyed by layer. |
| `child_rows` | object | How many child rows this property received from each layer - the basis of the child cost estimate. |
| `drift_gate_summary` | string | One line per layer summarising the live source verification each child reported (the drift-gate page of the report). |
| `report_charged` | boolean | True when one report-generated event was charged for this property. False when the report was not generated, artefacts could not be stored, or the charge did not go through (see report_charge_note). |
| `report_charge_event` | string | Always "report-generated" - the name of the pay-per-event event this actor charges. |
| `report_charge_note` | string | Why the report was not charged, when it was not. Null when charged. |
| `report_fee_usd_list` | number | The report fee at the FREE-tier list price when charged ($2.50), else 0. Paid Apify plans pay the tiered price. |
| `child_rows_usd_estimate` | number | Estimated charges the five child screeners billed to your account for this property: their rows x their FREE-tier list prices. |
| `total_usd_list_estimate` | number | report_fee_usd_list + child_rows_usd_estimate. |
| `run_properties_requested` | number | How many properties were supplied to this run. |
| `run_reports_generated` | number | How many reports (complete or partial) this run generated. |
| `run_complete` | boolean | True only when every supplied property produced a complete report. |
| `disclaimer` | string | Scope statement: records appendix / desktop pre-screen, not a Phase I ESA, not AAI. |

### How it is built

- `geocode.js`, `children.js`, `compose.js`, `render.js`, `pdf.js`, `billing.js` are pure modules; `main.js` is wiring only and is asserted as text.
- Fixtures are the five children's live datasets captured verbatim (run ids inside the fixture files); the offline suite renders the fixture report to HTML and PDF and exercises every degraded path (a child down, a child answering other properties but not this one, every child down, layers not requested).
- A mutation harness re-injects the defects this actor is built to prevent (charging a failed report, rendering an unavailable layer as clean, defaulting a null count to 0, skipping the budget pre-flight, pushing before the gate) and requires the suite to go red on each.

### Use as an MCP tool

Published Apify Actors are callable by AI agents through `https://mcp.apify.com` (Claude Desktop, Claude Code, Cursor and any MCP client). An agent can pass a property and receive the report URLs plus the headline counts in one call. The report fee and the children's charges apply exactly as above, and a run that cannot answer fails without billing.

### FAQ

**Is this a Phase I ESA?** No. It is a records-search appendix / desktop pre-screen. It does not perform AAI under 40 CFR Part 312, carries no professional interpretation and confers no CERCLA landowner liability protection. The not-included page lists what a full Phase I adds.

**Why did my report come back `partial`?** One of the five child screeners did not answer for that property - usually a government service outage. The report names the layer on a red page and in `layers_unavailable`, and the drift-gate page shows what the other children verified. You are charged the report fee for a partial report (the other layers are real work); you are never charged for a `failed` report.

**Why is the state tank registry "NOT searched" for my property?** The tank/spill child has state legs for New York, California, Texas and Florida only; elsewhere it searches the national EPA UST Finder baseline and the report says so rather than implying state coverage.

**Can I get the tables as data?** Yes - `report_json_url` is the full model every table is rendered from, and the five children's own datasets are linked by run id in the appendix.

**Does the free plan cover a report?** Yes - one property. The $2.50 report fee plus the children's $2.40 worst case is $4.90, inside the free plan's $5 monthly credit (typical all-in is about $3.50). A run whose remaining limit cannot cover that fails before calling any child and bills nothing.

# Actor input Schema

## `properties` (type: `array`):

One report is generated per property. Each item is EITHER {"address": "5980 Lipan St, Denver, CO 80221", "label": "..."} (geocoded with the free US Census geocoder) OR {"lat": 39.8037, "lon": -104.9986, "label": "...", "state": "CO" (optional 2-letter hint)}. A property that cannot be resolved to coordinates gets a dataset row with report_status=not_screened and is NOT charged. Each generated report is one $2.50 report-generated event (list price; paid Apify plans pay less) PLUS the five child screeners' own per-result charges on your account (measured $0.98-1.32 per property at 1 mile; capped at $2.40). Before calling any child the run checks that its charge limit covers the report fee plus that $2.40 worst case per property, so one property fits a free plan's $5 monthly credit.

## `layers` (type: `array`):

Which record layers the report is composed from. Each layer is one Actor-to-Actor call to a published malonestar screener on its latest build. Leave all five selected for the full appendix. A layer whose child screener does not answer is rendered as an explicit 'UNAVAILABLE - NOT SCREENED' page and the report status becomes 'partial'; a report is 'complete' only when every requested layer answered in full.

## `radiusMiles` (type: `number`):

Radius for the federal records table, the tank/spill table and the site screen. 1 mile is the largest ASTM E1527-21 Sec. 8.2.1 standard search distance and the working default; the ASTM summary always evaluates each database at its own standard distance regardless. Accepts fractional miles, range 0.25-5.

## `priorUseRadiusMiles` (type: `number`):

Radius for the ASTM Sec. 8.3 prior-uses layer. The standard concerns the subject and adjoining properties, so 0.25 mile is the working default; 1 mile is the maximum. Accepts fractional miles, range 0.02-1.

## `topoReviewStartYear` (type: `integer`):

First year of the ASTM Sec. 8.3.4 historical-map review window passed to the topographic layer. 1940 is the standard baseline; set it earlier when the property has an obvious first developed use before 1940. Range 1880-2020.

## `includePdf` (type: `boolean`):

When true (recommended) each report is stored both as HTML and as a PDF in the run's key-value store, and the dataset row carries report_pdf_url. When false only the HTML (and the JSON model) are stored. Does not change billing.

## `maxProperties` (type: `integer`):

Safety cap on how many of the supplied properties are screened and billed in this run. Leave empty to screen every property supplied. Properties beyond the cap get a dataset row with report_status=not_screened and are not charged. The run also caps itself at what the run's charge limit can pay for.

## Actor input object example

```json
{
  "properties": [
    {
      "lat": 39.8037,
      "lon": -104.9986,
      "state": "CO",
      "label": "Denver industrial parcel (prefill)"
    }
  ],
  "layers": [
    "federal_records",
    "prior_uses",
    "historical_topo",
    "tank_spill",
    "site_screen"
  ],
  "radiusMiles": 1,
  "priorUseRadiusMiles": 0.25,
  "topoReviewStartYear": 1940,
  "includePdf": true
}
```

# 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 = {
    "properties": [
        {
            "lat": 39.8037,
            "lon": -104.9986,
            "state": "CO",
            "label": "Denver industrial parcel (prefill)"
        }
    ],
    "layers": [
        "federal_records",
        "prior_uses",
        "historical_topo",
        "tank_spill",
        "site_screen"
    ],
    "radiusMiles": 1,
    "priorUseRadiusMiles": 0.25,
    "topoReviewStartYear": 1940,
    "includePdf": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("malonestar/environmental-records-report").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 = {
    "properties": [{
            "lat": 39.8037,
            "lon": -104.9986,
            "state": "CO",
            "label": "Denver industrial parcel (prefill)",
        }],
    "layers": [
        "federal_records",
        "prior_uses",
        "historical_topo",
        "tank_spill",
        "site_screen",
    ],
    "radiusMiles": 1,
    "priorUseRadiusMiles": 0.25,
    "topoReviewStartYear": 1940,
    "includePdf": True,
}

# Run the Actor and wait for it to finish
run = client.actor("malonestar/environmental-records-report").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "properties": [
    {
      "lat": 39.8037,
      "lon": -104.9986,
      "state": "CO",
      "label": "Denver industrial parcel (prefill)"
    }
  ],
  "layers": [
    "federal_records",
    "prior_uses",
    "historical_topo",
    "tank_spill",
    "site_screen"
  ],
  "radiusMiles": 1,
  "priorUseRadiusMiles": 0.25,
  "topoReviewStartYear": 1940,
  "includePdf": true
}' |
apify call malonestar/environmental-records-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,malonestar/environmental-records-report"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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