# EPA Drinking Water Quality Screener - Violations, Lead & PFAS (`malonestar/epa-drinking-water-quality-screener`) Actor

Screen any US coordinate for the public water system serving it: SDWA health-based violations, Lead & Copper Rule 90th-percentile results and UCMR5 PFAS detections. Built for Phase I ESA and real-estate due diligence. Never reports a clear result from a source that did not answer.

- **URL**: https://apify.com/malonestar/epa-drinking-water-quality-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 $6.60 / 1,000 drinking water screening 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

## EPA Drinking Water Quality Screener - Violations, Lead & PFAS

Give it a coordinate. It tells you **which public water system serves that
address**, what the **Safe Drinking Water Act violation record** looks like, what
the **lead and copper 90th-percentile tap results** are, and whether **PFAS was
detected** there under EPA's UCMR5 monitoring programme.

Built for Phase I ESA consultants, environmental due-diligence teams, real-estate
underwriters and water-utility analysts who need a defensible drinking-water
screen per property, in bulk, from authoritative federal sources.

**The design rule that matters most:** this actor will not tell you a system is
clean on a source it never successfully read. `null` means *not checked*.
`false` means *checked, and the answer is negative*. The two are never mixed, and
the overall verdict is gated so it can never read `LOW` while any contributing
EPA source was unavailable.

***

### Who it is for

| Persona | What they get |
|---|---|
| **Phase I ESA consultant** | A per-property drinking-water screen with the serving PWSID, health-based violation history, lead action-level exceedances and PFAS results - plus an explicit `NO_SERVICE_AREA` answer when the site is probably on a private well. |
| **Real-estate / lender due diligence** | Bulk screening of a portfolio in one run, with a `water_quality_screen_level` and a plain-English `screen_reason` per address. |
| **Environmental / water engineer** | Lead and copper 90th percentiles dated to their actual monitoring period, treatment-technique violations, formal enforcement history and per-analyte PFAS concentrations. |
| **PFAS litigation and remediation** | UCMR5 detections per system with maximum concentrations, the analytes involved, a Hazard Index screen, and honest non-detect accounting. |
| **AI agents / MCP** | A clean, chainable tool: coordinates in, one fully-typed row per location out, with a per-source status on every row so an agent can tell "no finding" from "no data". |

***

### Data sources

| Leg | Source | What it provides |
|---|---|---|
| **Service area** | EPA ORD Community Water System Service Area Boundaries (ArcGIS, ~44,600 polygons) | Point-in-polygon lookup of the serving PWSID |
| **Water system** | EPA Envirofacts SDWIS `WATER_SYSTEM` + `GEOGRAPHIC_AREA` | System name, type, population served, source water, owner, counties served, utility contact |
| **Violations** | EPA Envirofacts SDWIS `VIOLATION` + `ENFORCEMENT_ACTION` | Full SDWA violation history, health-based rollup, formal enforcement |
| **Lead and copper** | EPA Envirofacts SDWIS `LCR_SAMPLE_RESULT` joined to `LCR_SAMPLE` | 90th-percentile lead and copper results, dated to their monitoring period |
| **PFAS** | EPA UCMR5 occurrence dataset (1,928,117 results, 10,299 systems, 29 PFAS analytes plus lithium) | Detections, maximum concentrations, non-detect counts, Hazard Index screen |
| **Code decoding** | EPA Envirofacts SDWIS `REF_CODE_VALUE` | EPA's own 2,171-row code table, fetched every run so labels cannot go stale |

No API key. Every source is public and keyless.

***

### Example input

```json
{
  "assets": [
    { "lat": 43.0125, "lon": -83.6875, "label": "Flint MI - lead action level exceedance" },
    { "lat": 40.9793, "lon": -74.1165, "label": "Ridgewood NJ - PFAS detections" },
    { "lat": 39.7392, "lon": -104.9903, "label": "Denver CO - control" }
  ],
  "includeViolations": true,
  "includeLead": true,
  "includePfas": true,
  "violationYears": 10
}
```

You can also screen systems directly by PWSID, with or without coordinates:

```json
{ "pwsids": ["MI0002310", "NJ0251001"] }
```

#### What that example actually returns (verified live 2026-08-04)

| Location | System | Verdict | Findings |
|---|---|---|---|
| Flint MI | `MI0002310` FLINT, CITY OF | `MODERATE` | 1 health-based violation (Lead and Copper treatment technique), lead 90th 0.0060 mg/L in the period ending 2025-12-31, 0.020 mg/L historically - above the 0.015 action level - PFAS tested and none detected |
| Ridgewood NJ | `NJ0251001` RIDGEWOOD WATER | `HIGH` | 249 PFAS detections, PFOA 0.0314 ug/L and PFOS both above the 2024 NPDWR MCL screen, Hazard Index 0.494, 1 health-based violation |
| Denver CO | `CO0116001` DENVER WATER BOARD | `LOW` | 128 violations, none health-based, lead 0.0031 mg/L, PFAS tested and none detected, lithium 10.8 ug/L (lithium is not a PFAS) |

***

### Three things that are easy to get wrong, and how this actor handles them

#### 1. A non-detect is not zero, and neither is "not tested"

97.1% of UCMR5 results (1,872,227 of 1,928,117) are non-detects. EPA writes them
as `AnalyticalResultsSign = '<'` with an **empty** value: the analyte was looked
for and not found *above the minimum reporting level*. Publishing that as `0`
would be a fabricated clean measurement.

All four states are distinguishable on the row:

| Situation | `pfas_system_tested` | `pfas_detected` | `pfas_nondetect_count` |
|---|---|---|---|
| Tested, PFAS found | `true` | `true` | count of non-detects |
| Tested, nothing above the reporting level | `true` | `false` | count of non-detects |
| Not a UCMR5 sampling system | `false` | `null` | `0` |
| The PFAS source failed | `null` | `null` | `null` |

`pfas_min_reporting_level_ugl` tells you what a non-detect actually rules out.

#### 2. Lithium is a UCMR5 analyte and is NOT a PFAS

UCMR5 monitors 30 analytes: 29 PFAS **and lithium**. Denver detected lithium at
10.8 ug/L and no PFAS at all. Counting lithium as a PFAS detection would report
Denver as a PFAS-affected system. Lithium has its own fields
(`lithium_max_ugl`, `lithium_detected`) and can never enter `pfas_detected`,
`pfas_detection_count`, the MCL screen or the Hazard Index. A live drift
assertion re-checks exactly this against Denver on every run.

#### 3. A lead 90th percentile with no date is worse than no number

`LCR_SAMPLE_RESULT` has **no date column**. The monitoring period lives in a
separate table, `LCR_SAMPLE`, joined on `sample_id`. Without that join you can
publish a 2016 result as a system's current lead level. This actor performs the
join, reports `lead_90th_period_start` and `lead_90th_period_end`, and states the
join outcome in `lead_period_join_status` (`complete`, `partial`, `failed`).

`lead_90th_mg_l` is the **most recent** monitoring period.
`lead_90th_max_ever_mg_l` and `lead_periods_exceeding_action_level` carry the
history - Flint's latest period is 0.0060 mg/L while its worst on record is
0.020 mg/L, and both matter to a buyer.

A reported `0` is a real EPA value meaning "at or below the laboratory detection
limit at the sampled taps" (26-37% of state LCR rows carry it). It is preserved,
never nulled, and flagged with `lead_90th_reported_zero` so nobody reads it as
proof that no lead is present.

***

### What each screening level means

| Level | Meaning |
|---|---|
| `HIGH` | An unresolved health-based violation, a current lead action-level exceedance, a PFAS result above the 2024 NPDWR MCL screen, or a Hazard Index above 1. |
| `MODERATE` | A health-based violation on record, a historical lead exceedance, lead at or above the 0.010 mg/L trigger level, a copper exceedance, a Tier 1 public notification, or a PFAS detection below the MCL screen. |
| `LOW` | Every requested EPA source answered and none reported any of the above. |
| `NO_SERVICE_AREA` | No EPA-mapped community water system service area covers the location. The site is likely served by a private well, or the boundary is not mapped. This is an **answer**, not a clear: private wells are not regulated under SDWA and warrant their own investigation. |
| `INCONCLUSIVE` | At least one requested EPA source did not answer. Real findings are still reported; absence of a finding on a failed source is **not** evidence of absence. |

**This is a screening tool, not a regulatory determination.** Verify anything
material against the primacy agency and the system's Consumer Confidence Report.

#### About the PFAS MCL comparison

`pfas_mcl_screen_exceeded` compares the highest UCMR5 detection against the MCL
values published in EPA's 2024 PFAS National Primary Drinking Water Regulation
(89 FR 32532): PFOA 0.004, PFOS 0.004, PFHxS 0.010, PFNA 0.010, HFPO-DA 0.010
ug/L, plus a Hazard Index over PFHxS, PFNA, HFPO-DA and PFBS.

It is a **screening comparison only**. UCMR5 reports single entry-point samples;
NPDWR compliance is determined by the primacy agency on a running annual average.
This actor never states that a system is in violation of a PFAS MCL. The basis is
restated on every row in `pfas_mcl_screen_basis`.

***

### Output fields

One row per screened location. **Every field below is emitted on every row**;
an unavailable source yields `null`, never an absent key and never `false`.

#### Location and screening verdict

| Field | Type | Description |
|---|---|---|
| `asset_label` | string | Your label for this location, echoed back so results can be joined to your own records. |
| `asset_lat` | number | Latitude (WGS84) that was screened. Null for a direct PWSID lookup. |
| `asset_lon` | number | Longitude (WGS84) that was screened. Null for a direct PWSID lookup. |
| `asset_index` | number | Zero-based position of this location in your input array. |
| `lookup_mode` | string | How the water system was identified: 'coordinate' (point-in-polygon against EPA service-area boundaries) or 'pwsid' (you supplied the PWSID directly). |
| `water_quality_screen_level` | string | Overall screening level: HIGH, MODERATE, LOW, NO\_SERVICE\_AREA or INCONCLUSIVE. INCONCLUSIVE whenever any requested EPA source failed - the verdict can never read LOW on data that was never checked. A screening indicator, not a regulatory determination. |
| `screen_flags` | array | Every screening flag raised, for example UNRESOLVED\_HEALTH\_BASED\_VIOLATION, LEAD\_ACTION\_LEVEL\_EXCEEDED, PFAS\_ABOVE\_2024\_NPDWR\_MCL\_SCREEN. |
| `screen_reason` | string | Plain-English explanation of the screening level, naming the failed sources when the result is INCONCLUSIVE. |
| `sources_ok` | number | How many of the requested EPA sources answered successfully for this location. |
| `sources_requested` | number | How many EPA sources were requested for this location (boundary, water system, violations, lead, PFAS). |
| `sources_failed` | array | Names of the EPA sources that did not answer. An empty array means every requested source answered. |
| `sources_not_attempted` | array | EPA sources that were never attempted because an upstream lookup failed - for example the violation, lead and PFAS legs when the service-area lookup itself went down. Distinct from sources\_failed and from a source that genuinely had nothing to look up. |
| `data_complete` | boolean | True only when every requested EPA source answered and none was skipped by an upstream failure. False means a finding may be missing. |

#### Serving water system (service-area boundary)

| Field | Type | Description |
|---|---|---|
| `pwsid` | string | EPA Public Water System Identification number of the system serving this location (2-letter primacy agency code plus 7 characters). |
| `service_area_pws_name` | string | Water system name as published on the EPA service-area boundary layer. |
| `service_area_primacy_agency` | string | Primacy agency (usually the state) on the boundary record. |
| `service_area_population_served` | number | Population served, as published on the boundary record. |
| `service_area_service_connections` | number | Service connection count, as published on the boundary record. |
| `service_area_type` | string | Type of service area polygon, for example Residential Area or Municipality. |
| `service_area_feature_type` | string | How EPA describes the polygon, for example 'Service Area Boundary'. |
| `service_area_data_provider` | string | Who supplied the boundary to EPA. |
| `service_area_data_provider_type` | string | Category of the boundary data provider, for example Private Company or State Agency. |
| `service_area_data_source_url` | string | Source URL EPA cites for this boundary. |
| `service_area_model_method` | string | Modelling method used to derive the boundary, when EPA records one. |
| `service_area_modification_method` | string | How EPA modified the supplied boundary, when applicable. |
| `service_area_method_details` | string | Free-text detail on the boundary derivation method. |
| `service_area_verification_status` | string | EPA's verification status for the boundary, when recorded. |
| `service_area_confirmed` | string | Whether the boundary has been confirmed, as recorded by EPA. |
| `service_area_km2` | number | Area of the service-area polygon in square kilometres. Useful for judging boundary precision. |
| `service_area_vintage` | string | Date the boundary was originally created. Boundaries vary widely in age - some date to 2004. |
| `echo_detailed_facility_report_url` | string | Link to EPA ECHO's Detailed Facility Report for this system. |
| `boundary_error` | string | Error message if the service-area lookup failed. Null on success. |
| `service_area_found` | boolean | True if a mapped EPA service area covers this location, false if none does, null if the boundary lookup failed. False and null are different answers. |
| `service_areas_matched` | number | How many mapped service areas cover this location. More than one is legitimate (a wholesaler plus its purchaser, or overlapping vintages). |
| `all_pwsids` | array | Every PWSID whose mapped service area covers this location, primary first. |
| `all_pws_names` | array | Names of every matching water system, in the same order as all\_pwsids. |
| `boundary_status` | string | Outcome of the service-area lookup: 'ok' or 'unavailable'. |
| `boundary_source` | string | Attribution for the service-area boundary layer. |
| `boundary_layer_national_count` | number | Total service-area records in EPA's national layer at run time, measured live as a truncation and drift guard. |

#### Water system record (SDWIS)

| Field | Type | Description |
|---|---|---|
| `pws_name` | string | Water system name from EPA SDWIS. |
| `pws_type_code` | string | SDWIS water system type code (CWS, NTNCWS, TNCWS, NP, U). |
| `pws_type` | string | Decoded water system type, for example 'Community water system'. |
| `pws_activity_code` | string | SDWIS activity code (A active, I inactive, and others). |
| `pws_activity` | string | Decoded activity status, for example 'Active'. |
| `pws_is_active` | boolean | True if SDWIS marks the system active, false if not, null if the water system record was not retrieved. |
| `pws_deactivation_date` | string | Date the system was deactivated in SDWIS, if applicable. |
| `primacy_agency_code` | string | Two-character primacy agency code (usually the state). |
| `primacy_agency` | string | Decoded primacy agency name. |
| `primacy_type` | string | Whether primacy is held by the State, EPA or a Tribe. |
| `epa_region` | string | EPA region number for the system. |
| `state_code` | string | State code recorded on the SDWIS water system record. |
| `population_served_count` | number | Population served, from SDWIS. May differ from the boundary layer's figure. |
| `service_connections_count` | number | Number of service connections, from SDWIS. |
| `owner_type_code` | string | SDWIS owner type code (F, L, M, N, P, S). |
| `owner_type` | string | Decoded owner type, for example 'Local government' or 'Private'. |
| `primary_source_code` | string | SDWIS primary water source code (GW, GWP, SW, SWP, GU, GUP). |
| `primary_source` | string | Decoded primary water source, for example 'Surface water purchased'. |
| `gw_sw_code` | string | Ground water / surface water code. |
| `gw_sw` | string | Decoded ground water or surface water designation. |
| `is_wholesaler` | boolean | True if the system sells water to other systems, false if not, null if not recorded. |
| `is_school_or_daycare` | boolean | True if the system serves a school or daycare, false if not, null if not recorded. |
| `is_grant_eligible` | boolean | True if EPA records the system as grant eligible. |
| `source_water_protection` | boolean | Whether a source-water protection programme is recorded for the system. |
| `outstanding_performer` | string | EPA 'outstanding performer' designation, when recorded. |
| `pws_address` | string | Mailing address of the water system's administrative office. |
| `pws_city` | string | City of the water system's administrative office. |
| `pws_zip` | string | ZIP code of the water system's administrative office. |
| `pws_admin_name` | string | Administrative contact recorded in SDWIS for the utility. |
| `pws_org_name` | string | Organisation contact name recorded in SDWIS for the utility. |
| `pws_phone` | string | Utility contact phone number published in SDWIS. |
| `pws_email` | string | Utility contact email published in SDWIS. |
| `season_begin_date` | string | Start of the operating season for seasonal systems. |
| `season_end_date` | string | End of the operating season for seasonal systems. |
| `counties_served` | array | Counties the system serves, from SDWIS GEOGRAPHIC\_AREA. |
| `cities_served` | array | Cities the system serves, from SDWIS GEOGRAPHIC\_AREA. |
| `zip_codes_served` | array | ZIP codes the system serves, from SDWIS GEOGRAPHIC\_AREA. |
| `geographic_area_types` | array | Kinds of geographic area recorded for the system (County, City, ZIP Code, Tribal, Indian Reservation). |
| `geographic_area_rows` | number | Number of GEOGRAPHIC\_AREA rows retrieved for the system. |
| `water_system_record_found` | boolean | True if SDWIS holds a WATER\_SYSTEM record for this PWSID, false if the lookup succeeded and returned none, null if the lookup failed. |
| `water_system_rows_expected` | number | Row count EPA's own COUNT endpoint reported for the WATER\_SYSTEM query, used as an exact truncation guard. |
| `geographic_area_status` | string | Outcome of the GEOGRAPHIC\_AREA lookup: 'ok' or 'unavailable'. |
| `system_error` | string | Error message if the water system lookup failed. Null on success. |
| `system_status` | string | Outcome of the water system leg: 'ok', 'unavailable', 'skipped' or 'not\_applicable'. |

#### Safe Drinking Water Act violations

| Field | Type | Description |
|---|---|---|
| `violations_total` | number | Total Safe Drinking Water Act violations on record for this system, all years and all categories. |
| `violations_health_based` | number | Violations EPA itself flags as health-based (is\_health\_based\_ind = Y): MCL, MRDL and treatment-technique violations. Not derived here. |
| `violations_health_based_in_window` | number | Health-based violations whose compliance period falls inside your violationYears window. Null when the window is disabled. |
| `violations_health_based_unresolved` | number | Health-based violations SDWIS still marks Open. This is the flag most Phase I reviewers care about. |
| `violations_health_based_known_unreturned` | number | Health-based violations with SDWIS compliance status 'Known' - recorded but not returned to compliance. Reported separately from Open rather than lumped in, because EPA distinguishes them. |
| `violations_health_based_returned_to_compliance` | number | Health-based violations SDWIS marks Returned to Compliance. |
| `violations_unresolved_total` | number | All violations, health-based or not, SDWIS still marks Open. |
| `violations_by_category` | object | Violation counts keyed by SDWIS violation\_category\_code (MCL, MRDL, TT, MR, MON, RPT, Other). |
| `violations_by_compliance_status` | object | Violation counts keyed by SDWIS compliance\_status\_code (O Open, K Known, R Returned to Compliance, I System Inactive). |
| `violations_mcl` | number | Maximum Contaminant Level violations. |
| `violations_mrdl` | number | Maximum Residual Disinfectant Level violations. |
| `violations_treatment_technique` | number | Treatment technique violations. |
| `violations_monitoring_reporting` | number | Monitoring and reporting violations (categories MR, MON and RPT combined). |
| `violations_lead_copper_rule` | number | Violations under the Lead and Copper Rule family (rule family 350). |
| `violations_public_notification_tier1` | number | Violations that carried a Tier 1 public notification - the most urgent tier, requiring notice within 24 hours. |
| `violations_earliest_date` | string | Earliest violation compliance-period date on record. |
| `violations_latest_date` | string | Most recent violation compliance-period date on record. |
| `health_based_contaminants` | array | Distinct contaminants named on the system's health-based violations, decoded using EPA's own REF\_CODE\_VALUE table. Null when EPA publishes no description for the codes involved - see health\_based\_contaminant\_codes, which is always populated. |
| `health_based_contaminant_codes` | array | Raw SDWIS contaminant codes on the system's health-based violations. Always populated when health-based violations exist. EPA's reference table omits several modern codes (5200, the Revised Lead and Copper Rule contaminant, is one), so the raw code is authoritative and the decoded name may be null. |
| `health_based_contaminants_undecoded` | number | How many of the health-based contaminant codes EPA publishes no description for. Non-zero is normal and reflects a gap in EPA's own reference table, not a gap in the violation record. |
| `most_recent_health_based_violation` | object | The most recent health-based violation as a full object (type, category, contaminant, rule, compliance status, dates, public notification tier). |
| `most_recent_health_based_violation_date` | string | Compliance-period date of the most recent health-based violation. |
| `health_based_violation_details` | array | Up to maxViolationDetails individual health-based violation records, newest first, each fully decoded. |
| `health_based_violation_details_truncated` | boolean | True when more health-based violations exist than were included in the details array. Counts above are never truncated. |
| `enforcement_actions_total` | number | Number of formal SDWIS enforcement actions on record for this system. |
| `most_recent_enforcement_date` | string | Date of the most recent formal enforcement action. |
| `most_recent_enforcement_type` | string | Decoded type of the most recent formal enforcement action. |
| `most_recent_enforcement_type_code` | string | Raw SDWIS enforcement action type code for the most recent action. |
| `violations_rows_expected` | number | Row count EPA's own COUNT endpoint reported for the violation query, used as an exact truncation guard. |
| `violations_rows_retrieved` | number | Violation rows actually retrieved. A shortfall against violations\_rows\_expected fails the leg rather than publishing a rollup over a subset. |
| `enforcement_status` | string | Outcome of the enforcement lookup: 'ok', 'unavailable' or 'skipped'. |
| `violations_error` | string | Error message if the violation lookup failed. Null on success. |
| `violations_status` | string | Outcome of the violations leg: 'ok', 'unavailable', 'skipped' or 'not\_applicable'. |

#### Lead and copper (LCR 90th percentile)

| Field | Type | Description |
|---|---|---|
| `lead_90th_mg_l` | number | Lead and Copper Rule 90th-percentile tap result. Value for the MOST RECENT monitoring period, in mg/L. Reported by the water system under 40 CFR 141 Subpart I. |
| `lead_90th_period_start` | string | Start of the monitoring period the reported lead 90th percentile belongs to. EPA publishes the result and the period in separate tables; this actor joins them, because an undated 90th percentile can present a decade-old result as current. |
| `lead_90th_period_end` | string | End of the monitoring period the reported lead 90th percentile belongs to. |
| `lead_90th_result_sign_code` | string | EPA result sign code on the lead result. 'L' means the value is an upper bound (below minimum detection limits), 'E' means exactly equal to the value reported. Null means EPA published no sign, which is the case on every row observed to date. |
| `lead_90th_below_detection` | boolean | True when the lead result sign code is 'L' and the reported number is therefore an upper bound rather than a measurement. Null when EPA published no sign code. |
| `lead_90th_reported_zero` | boolean | True when EPA published the lead 90th percentile as exactly 0. That is EPA's encoding of 'at or below the laboratory detection limit at the sampled taps' - it is a reported value, not a missing one, and it is not proof that no lead is present. Between 26% and 37% of state LCR rows carry it. |
| `lead_action_level_mg_l` | number | The federal lead action level, 0.015 mg/L. Constant, included so a row is self-describing. |
| `lead_action_level_exceeded` | boolean | True if the most recent lead 90th percentile exceeds 0.015 mg/L, false if it does not, null if the lead leg did not answer or the system has no reported lead result. |
| `lead_90th_max_ever_mg_l` | number | Highest lead 90th percentile on record for this system across all monitoring periods. |
| `lead_90th_max_ever_period_end` | string | End of the monitoring period in which the highest lead 90th percentile was reported. |
| `lead_periods_exceeding_action_level` | number | How many distinct monitoring periods exceeded the lead action level. A system can be compliant today and have exceeded repeatedly in the past. |
| `lead_monitoring_periods` | number | Number of distinct lead monitoring periods on record. |
| `lead_results_reported` | number | Number of lead 90th-percentile results retrieved for this system. |
| `copper_90th_mg_l` | number | Copper 90th-percentile tap result for the most recent monitoring period, in mg/L. |
| `copper_90th_period_start` | string | Start of the monitoring period the reported copper 90th percentile belongs to. |
| `copper_90th_period_end` | string | End of the monitoring period the reported copper 90th percentile belongs to. |
| `copper_90th_result_sign_code` | string | EPA result sign code on the copper result ('L' below detection, 'E' exactly equal). Null when EPA published no sign. |
| `copper_90th_below_detection` | boolean | True when the copper result is an upper bound rather than a measurement. Null when EPA published no sign code. |
| `copper_90th_reported_zero` | boolean | True when EPA published the copper 90th percentile as exactly 0 - a reported value meaning at or below detection, not a missing one. |
| `copper_action_level_mg_l` | number | The federal copper action level, 1.3 mg/L. Constant, included so a row is self-describing. |
| `copper_action_level_exceeded` | boolean | True if the most recent copper 90th percentile exceeds 1.3 mg/L, false if it does not, null if the leg did not answer or no result exists. |
| `copper_90th_max_ever_mg_l` | number | Highest copper 90th percentile on record for this system. |
| `copper_90th_max_ever_period_end` | string | End of the monitoring period in which the highest copper 90th percentile was reported. |
| `copper_periods_exceeding_action_level` | number | How many distinct monitoring periods exceeded the copper action level. |
| `copper_monitoring_periods` | number | Number of distinct copper monitoring periods on record. |
| `copper_results_reported` | number | Number of copper 90th-percentile results retrieved for this system. |
| `lcr_results_total` | number | Total Lead and Copper Rule sample-result rows retrieved for this system (lead and copper combined). |
| `lead_period_join_status` | string | How well the lead and copper results joined to their monitoring periods: 'complete', 'partial', 'failed', 'no\_results' or 'not\_attempted'. Anything but 'complete' means some reported values are undated. |
| `lead_period_join_matched` | number | How many result rows were successfully matched to a monitoring period. |
| `lcr_rows_expected` | number | Row count EPA's own COUNT endpoint reported for the lead and copper query, used as an exact truncation guard. |
| `lcr_sample_period_error` | string | Error message if the monitoring-period lookup failed while the results themselves succeeded. |
| `lead_error` | string | Error message if the lead and copper leg failed. Null on success. |
| `lead_status` | string | Outcome of the lead and copper leg: 'ok', 'unavailable', 'skipped' or 'not\_applicable'. |

#### PFAS (UCMR5)

| Field | Type | Description |
|---|---|---|
| `pfas_ucmr5_vintage` | string | Publication timestamp of the UCMR5 occurrence file actually used, read from its Last-Modified header. The download URL contains '2023-08' but EPA replaces the file in place, so the path is NOT the vintage. |
| `pfas_ucmr5_source_url` | string | URL of the EPA UCMR5 occurrence dataset used for the PFAS screen. |
| `pfas_ucmr5_national_rows` | number | Total UCMR5 result rows indexed on this run, measured live as a truncation guard. |
| `pfas_ucmr5_national_systems` | number | Total public water systems present in UCMR5 on this run. |
| `pfas_mcl_screen_basis` | string | Plain statement of what the PFAS MCL comparison is and is not: a screening comparison against EPA's 2024 PFAS NPDWR values, not a compliance determination, because UCMR5 reports single entry-point samples rather than the running annual average used for compliance. |
| `pfas_system_tested` | boolean | True if this system appears in UCMR5 at all, false if it does not (most small systems were not in the UCMR5 sample), null if the PFAS leg failed. False and null are different answers. |
| `pfas_results_count` | number | Number of UCMR5 result rows for this system, detections and non-detects combined. |
| `pfas_analytes_tested` | number | Number of distinct UCMR5 analytes this system was tested for (up to 30: 29 PFAS plus lithium). |
| `pfas_sample_points` | number | Number of distinct entry-point sample locations UCMR5 holds for this system. |
| `pfas_nondetect_count` | number | Number of UCMR5 results reported as non-detect - the analyte was looked for and not found above the minimum reporting level. A non-detect is NOT zero and NOT untested. |
| `pfas_min_reporting_level_ugl` | number | Lowest minimum reporting level applied to this system's UCMR5 samples, in micrograms per litre. A non-detect only rules out concentrations above this level. |
| `pfas_first_collection_date` | string | Earliest UCMR5 sample collection date for this system. |
| `pfas_last_collection_date` | string | Most recent UCMR5 sample collection date for this system. |
| `pfas_detected` | boolean | True if any PFAS analyte was detected, false if the system was tested and no PFAS was detected, null if the PFAS leg did not answer. Lithium is a UCMR5 analyte but is NOT a PFAS and never sets this true. |
| `pfas_detection_count` | number | Number of individual PFAS detections (excluding lithium) across all of this system's UCMR5 samples. |
| `pfas_analytes_detected` | array | Names of the PFAS analytes detected at this system, alphabetically. Lithium is deliberately excluded. |
| `pfas_max_analyte` | string | PFAS analyte with the highest detected concentration at this system. |
| `pfas_max_ugl` | number | Highest single PFAS concentration detected at this system, in micrograms per litre. |
| `pfoa_max_ugl` | number | Highest detected PFOA concentration, in micrograms per litre. The 2024 NPDWR MCL is 0.004 ug/L. |
| `pfos_max_ugl` | number | Highest detected PFOS concentration, in micrograms per litre. The 2024 NPDWR MCL is 0.004 ug/L. |
| `pfhxs_max_ugl` | number | Highest detected PFHxS concentration, in micrograms per litre. The 2024 NPDWR MCL is 0.010 ug/L. |
| `pfna_max_ugl` | number | Highest detected PFNA concentration, in micrograms per litre. The 2024 NPDWR MCL is 0.010 ug/L. |
| `hfpo_da_max_ugl` | number | Highest detected HFPO-DA (GenX chemicals) concentration, in micrograms per litre. The 2024 NPDWR MCL is 0.010 ug/L. |
| `pfbs_max_ugl` | number | Highest detected PFBS concentration, in micrograms per litre. PFBS has no individual MCL; it is one of the four Hazard Index analytes. |
| `pfas_hazard_index_screen` | number | Unitless Hazard Index computed over PFHxS, PFNA, HFPO-DA and PFBS against their published health-based water concentrations. Null when the system was not tested for any Hazard Index analyte. |
| `pfas_hazard_index_screen_exceeded` | boolean | True if the Hazard Index screen exceeds 1.0, false if it does not, null if it could not be computed. |
| `pfas_mcl_screen_exceedances` | array | PFAS analytes whose highest detected concentration exceeds the corresponding 2024 NPDWR MCL. A screening comparison only - see pfas\_mcl\_screen\_basis. |
| `pfas_mcl_screen_exceeded` | boolean | True if any detected PFAS exceeds its 2024 NPDWR MCL on this screening comparison, false if none does, null if the PFAS leg did not answer. |
| `lithium_max_ugl` | number | Highest detected lithium concentration, in micrograms per litre. Lithium is a UCMR5 analyte and is NOT a PFAS; it is reported separately so it can never inflate a PFAS count. |
| `lithium_detected` | boolean | True if lithium was detected, false if the system was tested for lithium and none was detected, null if lithium was not among the analytes tested or the leg did not answer. |
| `pfas_error` | string | Error message if the PFAS leg failed. Null on success. |
| `pfas_status` | string | Outcome of the PFAS leg: 'ok', 'unavailable', 'skipped' or 'not\_applicable'. |

#### Provenance and source integrity

| Field | Type | Description |
|---|---|---|
| `retrieved_at` | string | UTC timestamp when this run queried EPA. |
| `sdwis_source` | string | Attribution for the tabular data (EPA Envirofacts SDWIS). |
| `actor_version` | string | Version of this actor that produced the row. |
| `drift_status` | string | Result of this run's live source-integrity checks: 'ok' or 'degraded'. A 'failed' status fails the run before any row is emitted. |
| `drift_measurements` | string | JSON string of every value measured by the live drift checks on this run (national record counts, canary results, UCMR5 vintage and vocabulary), so source health is auditable. |

Total: **186 declared fields**, every one of them documented above.

***

### Fields that are legitimately null on a healthy run

Some fields are null because the answer is genuinely absent, not because
something failed. Each has a recorded input that populates it.

| Field(s) | Why null, and what populates it |
|---|---|
| `boundary_error`, `system_error`, `violations_error`, `lead_error`, `pfas_error`, `lcr_sample_period_error` | Null is **good news** - the source answered. Populate with `{"simulateOutage": "lead"}` or any other leg name. |
| `copper_90th_*`, `copper_action_level_exceeded`, `copper_periods_exceeding_action_level` | Most systems report lead only. Populate with `{"pwsids": ["RI1583829"]}` - 8 copper results to 2 lead. |
| `health_based_contaminants` | EPA's own `REF_CODE_VALUE` table omits several modern codes, so the decoded name can be null while `health_based_contaminant_codes` is populated. See below. |
| `lead_90th_result_sign_code`, `lead_90th_below_detection`, and the copper equivalents | EPA publishes no result sign on any LCR row observed to date. The vocabulary (`E` equal, `L` below detection) is asserted live, so the day it starts appearing the value is carried through rather than ignored. |
| `pws_deactivation_date`, `season_begin_date`, `season_end_date`, `outstanding_performer` | Only populated for deactivated, seasonal or EPA-designated systems. |
| `hfpo_da_max_ugl`, `pfna_max_ugl` and the other per-analyte maxima | Null when that analyte was never detected at the system. `pfas_analytes_tested` confirms it was looked for. |
| `sources_failed`, `sources_not_attempted` | Empty arrays on a healthy run. |
| `zip_codes_served`, `cities_served` | Many states report only the county in SDWIS `GEOGRAPHIC_AREA`. |

#### A known gap in EPA's own reference table

`REF_CODE_VALUE` is EPA's authoritative code decoder and this actor fetches it on
every run - but it is materially incomplete for newer SDWIS codes. Measured live
on 2026-08-04 across Michigan's 63,401 violations: **18 alphanumeric violation
codes are absent from it** (`3A` alone appears 22,955 times), along with 8
contaminant codes including `5200` and rule code `351`, the Revised Lead and
Copper Rule codes.

This actor never invents a label. The **raw code is always emitted** next to the
decoded name, `health_based_contaminants_undecoded` counts how many labels EPA
does not publish, and every undecoded code is listed in the run log. The one
documented exception is `violation_category_code` `MON` and `RPT`, which live
data carries and EPA's table omits; those two are supplied locally and the
substitution is stated in the source.

***

### Live source-integrity checks

Offline tests cannot see a silently degraded upstream, because the fixtures were
shaped from the degraded data. Every run therefore performs **23 live drift
assertions before a single billable row is emitted**, and logs every measured
value. A critical failure fails the run and bills nothing.

Among them:

- The boundary layer resolves, still exposes all 20 fields this actor requests,
  holds a national record count in band (44,615 measured), and answers in WGS84.
- **Positive canary:** the point 43.0125, -83.6875 must resolve to `MI0002310`.
- **Negative control:** a point in the open Pacific must match **no** service
  area. This is what catches a query that silently matches nothing.
- The legacy SDWIS table names must still answer, with national counts in band
  (`WATER_SYSTEM` 434,040, `VIOLATION` 2,098,792, `LCR_SAMPLE_RESULT` 279,257).
- `MI0002310` must still show a health-based violation and a lead result at or
  above the action level. `NC0392373` must still show PFHxS at or above
  0.05 ug/L.
- **The lithium trap:** `CO0116001` must still show lithium detected and **zero**
  PFAS detections.
- UCMR5 must hold 30 analytes, all classified, with a closed sign vocabulary and
  units that decode to the micro sign rather than U+FFFD.
- The UCMR5 vintage must come from the file's `Last-Modified` header. The
  download URL contains `2023-08`, but EPA **replaces the file in place** - the
  copy served on 2026-08-04 was last modified 2026-02-12. The real vintage is
  published on every row in `pfas_ucmr5_vintage`.

***

### Failure behaviour

| Situation | What happens |
|---|---|
| No usable `assets` or `pwsids` | The run **FAILS** with a message naming the field and an example value. Nothing emitted, nothing billed. |
| A coordinate is out of range | That location is rejected, named in the log, and **no row is emitted for it** - you are not billed for an unusable input. Other locations still run. |
| One EPA source is down | The row is still emitted with that leg's fields `null`, `<leg>_status` set to `unavailable`, and the verdict forced to `INCONCLUSIVE`. |
| **Every** source is down for **every** location | Buffered rows are **discarded before any push** and the run **FAILS**. Zero rows, zero billable events. |
| A live drift assertion fails critically | The run fails before the first push. Zero rows, zero billable events. |
| Upstream answered and there is genuinely nothing | `SUCCEEDED` with an honest row - for example `NO_SERVICE_AREA`, or a system with zero violations. |

You can prove any of this yourself with the `simulateOutage` input.

***

### Performance and the PFAS cache

`UCMR5_All.txt` is 308,819,534 bytes uncompressed. It is streamed and filtered
rather than materialised, and the per-system index is cached in a **named**
key-value store keyed to the file's `Last-Modified` vintage. The first run in a
new vintage rebuilds the index in about 40 seconds; later runs reuse it. EPA
republishing the file invalidates the cache automatically - no manual refresh is
needed, though `refreshPfasCache: true` forces one.

Set `includePfas: false` to skip that leg entirely when PFAS is out of scope.

***

### Use as an MCP tool

This actor is callable by AI agents through `mcp.apify.com`. Every output field
carries a description, and the per-source status fields let an agent distinguish
**"EPA reports no health-based violations"** from **"the violation source did not
answer"** - a distinction most tools collapse, and one that matters a great deal
in an environmental screen.

***

### Pricing

Pay per result: **$12 per 1,000 rows**, one row per screened location. Graduated
paid-plan discounts apply (Bronze 20%, Silver 30%, Gold 45%, Platinum 60%,
Diamond 70%).

A run that fails loudly emits zero rows and bills zero result events.

***

### Related actors

Same buyer, same due-diligence workflow:

- **EPA Contaminated Site Screener** - Superfund, RCRA, USTs, spills and ECHO
  enforcement within a radius of the same coordinate.
- **Site Due Diligence Bundle** - a 20-layer federation for one coordinate in one
  call, covering contamination, wetlands, flood, seismic and habitat.
- **EPA Impaired Waters 303(d) Screener** - surface-water impairments and TMDLs
  near the site; the surface-water counterpart to this actor's drinking-water view.

***

### FAQ

**How do I find out which water utility serves an address?**
Pass the address coordinates in `assets`. The actor returns `pwsid`, `pws_name`,
`population_served_count`, the counties served, and the utility's published
contact details.

**How do I check a water system for lead?**
`lead_90th_mg_l` is the most recent 90th-percentile tap result with its
monitoring period. `lead_action_level_exceeded` compares it to the 0.015 mg/L
federal action level. `lead_90th_max_ever_mg_l` and
`lead_periods_exceeding_action_level` give the history, which is what a system
like Flint makes clear: currently compliant, historically not.

**How do I check whether a water system has PFAS?**
`pfas_detected`, `pfas_analytes_detected` and `pfas_max_ugl` come from EPA's
UCMR5 monitoring. `pfas_mcl_screen_exceeded` compares detections against the 2024
NPDWR MCL values as a screen. If `pfas_system_tested` is `false`, the system was
simply not in the UCMR5 sample - that is not a clean result.

**What if my site is on a private well?**
You get a `NO_SERVICE_AREA` row saying so explicitly. SDWA does not regulate
private wells, so a drinking-water screen from SDWIS cannot cover the site.

**Does this cover every US water system?**
SDWIS covers all regulated public water systems. The **service-area boundary**
layer maps roughly 44,600 of them, so a coordinate lookup can miss a system whose
boundary EPA has not published. Use `pwsids` to screen a specific system directly
when you already know it.

**Is a lead result of 0 mg/L proof there is no lead?**
No. EPA uses `0` to mean "at or below the laboratory detection limit at the
sampled taps". The row flags it with `lead_90th_reported_zero`.

**Why does a row say INCONCLUSIVE when most of it looks fine?**
Because at least one requested EPA source did not answer. The findings you can
see are real; what you cannot see was never checked. `sources_failed` names the
legs, and `data_complete` is `false`.

**Can I use this for a Phase I ESA?**
It is designed for that screening step and reports its own data completeness on
every row. It is a screening tool, not a determination - verify material findings
with the primacy agency and the system's Consumer Confidence Report.

**Is an API key needed?**
No. Every source is a public, keyless EPA endpoint.

# Actor input Schema

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

Sites to screen, each {"lat": <number>, "lon": <number>, "label": "<your name for the site>"}. Each location is matched against EPA's mapped community water system service areas to identify the serving public water system. A location with no mapped service area returns an explicit NO\_SERVICE\_AREA row (likely a private well), never a false clear.

## `pwsids` (type: `array`):

Optional. Screen specific public water systems by 9-character EPA PWSID (for example \["MI0002310"]) without a coordinate lookup. Combined with any locations supplied above.

## `includeViolations` (type: `boolean`):

Fetch the system's full Safe Drinking Water Act violation history from EPA SDWIS and roll it up (health-based, monitoring/reporting, treatment technique, Lead & Copper Rule, public-notification tier).

## `includeLead` (type: `boolean`):

Fetch Lead and Copper Rule 90th-percentile tap results and join them to their monitoring periods, so the reported value is dated rather than undated.

## `includePfas` (type: `boolean`):

Screen the system against EPA's UCMR5 occurrence dataset (1.9 million results, 29 PFAS analytes plus lithium). Turn off for a faster run when PFAS is out of scope.

## `includeEnforcement` (type: `boolean`):

Fetch the system's SDWIS formal enforcement action history and report the count and most recent action.

## `violationYears` (type: `integer`):

How many years back counts as a recent health-based violation for the screening flags. The full violation history is still summarised regardless. Set 0 to disable the window.

## `maxViolationDetails` (type: `integer`):

How many individual health-based violation records to include in the health\_based\_violation\_details array on each row, newest first. Counts are never truncated.

## `maxAssets` (type: `integer`):

Safety cap on how many locations are screened in one run. Locations beyond the cap are reported in the log and not billed.

## `runBudgetSeconds` (type: `integer`):

Total time budget for all upstream requests including retries. Requests stop rather than retry past this budget, so a long EPA outage fails loudly instead of hanging.

## `refreshPfasCache` (type: `boolean`):

Re-download and re-index the UCMR5 occurrence file even if the cached index already matches EPA's current published vintage. Normally unnecessary: the cache is keyed to the file's Last-Modified header and rebuilds itself whenever EPA republishes.

## `simulateOutage` (type: `string`):

Diagnostic seam for verifying failure behaviour. Forces one or all EPA sources to fail so you can confirm the actor reports the source as unavailable and never publishes a false clear. Leave as none for normal use.

## Actor input object example

```json
{
  "assets": [
    {
      "lat": 43.0125,
      "lon": -83.6875,
      "label": "Flint MI - lead action level exceedance"
    },
    {
      "lat": 40.9793,
      "lon": -74.1165,
      "label": "Ridgewood NJ - PFAS detections"
    },
    {
      "lat": 39.7392,
      "lon": -104.9903,
      "label": "Denver CO - control"
    }
  ],
  "pwsids": [],
  "includeViolations": true,
  "includeLead": true,
  "includePfas": true,
  "includeEnforcement": true,
  "violationYears": 10,
  "maxViolationDetails": 25,
  "maxAssets": 250,
  "runBudgetSeconds": 900,
  "simulateOutage": "none"
}
```

# Actor output Schema

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

The default dataset.

# 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": 43.0125,
            "lon": -83.6875,
            "label": "Flint MI - lead action level exceedance"
        },
        {
            "lat": 40.9793,
            "lon": -74.1165,
            "label": "Ridgewood NJ - PFAS detections"
        },
        {
            "lat": 39.7392,
            "lon": -104.9903,
            "label": "Denver CO - control"
        }
    ],
    "pwsids": [],
    "includeViolations": true,
    "includeLead": true,
    "includePfas": true,
    "includeEnforcement": true,
    "violationYears": 10,
    "maxViolationDetails": 25,
    "maxAssets": 250,
    "runBudgetSeconds": 900,
    "refreshPfasCache": false,
    "simulateOutage": "none"
};

// Run the Actor and wait for it to finish
const run = await client.actor("malonestar/epa-drinking-water-quality-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": 43.0125,
            "lon": -83.6875,
            "label": "Flint MI - lead action level exceedance",
        },
        {
            "lat": 40.9793,
            "lon": -74.1165,
            "label": "Ridgewood NJ - PFAS detections",
        },
        {
            "lat": 39.7392,
            "lon": -104.9903,
            "label": "Denver CO - control",
        },
    ],
    "pwsids": [],
    "includeViolations": True,
    "includeLead": True,
    "includePfas": True,
    "includeEnforcement": True,
    "violationYears": 10,
    "maxViolationDetails": 25,
    "maxAssets": 250,
    "runBudgetSeconds": 900,
    "refreshPfasCache": False,
    "simulateOutage": "none",
}

# Run the Actor and wait for it to finish
run = client.actor("malonestar/epa-drinking-water-quality-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": 43.0125,
      "lon": -83.6875,
      "label": "Flint MI - lead action level exceedance"
    },
    {
      "lat": 40.9793,
      "lon": -74.1165,
      "label": "Ridgewood NJ - PFAS detections"
    },
    {
      "lat": 39.7392,
      "lon": -104.9903,
      "label": "Denver CO - control"
    }
  ],
  "pwsids": [],
  "includeViolations": true,
  "includeLead": true,
  "includePfas": true,
  "includeEnforcement": true,
  "violationYears": 10,
  "maxViolationDetails": 25,
  "maxAssets": 250,
  "runBudgetSeconds": 900,
  "refreshPfasCache": false,
  "simulateOutage": "none"
}' |
apify call malonestar/epa-drinking-water-quality-screener --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ncQILpCP40uqy7hyT/builds/4b166zmbZpPMX0I4E/openapi.json
