# PFAS Product Disclosure Radar (PRISM / Minnesota) (`jamshid_data/pfas-product-disclosure-radar`) Actor

Search, export and monitor PFAS-in-products disclosures filed under Minnesota's PFAS law and published in PRISM (IC2). Filter by brand, manufacturer, component, CAS number, function and date. Get only new or withdrawn disclosures since the last run.

- **URL**: https://apify.com/jamshid_data/pfas-product-disclosure-radar.md
- **Developed by:** [Jamshid Data](https://apify.com/jamshid_data) (community)
- **Categories:** Business, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 pfas records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## PFAS Product Disclosure Radar

**Search, export and monitor PFAS-in-products disclosures filed by manufacturers under Minnesota's PFAS law (Amara's Law) and published in PRISM, the public reporting system of the Interstate Chemicals Clearinghouse (IC2).**

The PRISM website is built for looking up one report at a time. This Actor turns the full public dataset (about 285,000 product × component × chemical records from 270+ disclosures and 230+ manufacturers, as of October 2026) into a clean table you can filter, schedule and export to CSV, Excel, JSON, Google Sheets or your own system.

**Just want to look something up?** The same data is browsable for free, one page per manufacturer and per chemical, at [pfasradar.com](https://pfasradar.com/), which also has a free weekly email digest of newly published reports. Use this Actor when you need filtered exports, scheduled monitoring or API/integration access.

> **Source and disclaimer.** Data source: [PRISM](https://prism.theic2.org/), public data published by the Interstate Chemicals Clearinghouse (IC2). This Actor is independent and is **not affiliated with or endorsed by IC2** or any state agency. Records are reproduced as reported by manufacturers. They are **not** a safety, legal or regulatory-compliance determination. Always verify critical findings against the original disclosure in PRISM.

### What you can do

- **Find every disclosed product** of a brand or manufacturer, with component, PFAS name, CAS number, function and concentration range.
- **Search by chemical**: for example, all products reporting PTFE (CAS 9002-84-0) or PVDF (CAS 24937-79-9).
- **Search by component**, such as gaskets, seals, cables, coatings or membranes. PRISM has no product-category field, so component and product-model keywords are the practical substitute.
- **Monitor**: in `new` mode, each scheduled run returns only records published since the previous run. It also reports which disclosures were **added, withdrawn or changed** for your watchlist.

### Who uses it

- **Retailers, distributors and procurement teams** check supplier SKUs against PFAS restrictions. Minnesota's broad ban on intentionally added PFAS starts in 2032; Maine, New Mexico and other states have their own rules.
- **Law firms and litigation support** track new filings by named manufacturers or chemicals.
- **Compliance and product-stewardship consultants** benchmark how peers report components, functions and concentrations, and pre-fill supplier questionnaires.
- **Journalists, researchers and NGOs** get a weekly feed of newly published and withdrawn disclosures.

### Input examples

All gasket components that report PTFE:

```json
{ "mode": "all", "componentKeywords": ["gasket"], "casNumbers": ["9002-84-0"] }
```

Weekly monitoring of two suppliers (schedule this run):

```json
{ "mode": "new", "manufacturers": ["Krohne", "Rogers"], "stateKey": "my-suppliers" }
```

| Field | Meaning |
|---|---|
| `mode` | `all`: everything that matches. `new`: only records published since the previous run of the same watchlist. |
| `brands`, `manufacturers`, `componentKeywords`, `productKeywords` | Case-insensitive "contains" match. A record matches if any value matches. |
| `casNumbers`, `chemicalNameKeywords`, `pfasFunctions` | Chemical filters, e.g. `9002-84-0`, `fluoro`, `Sealant`. |
| `minConcentrationRangeId` | 1 (detection limit to <100 ppm) … 8 (90–100 %). |
| `publishedSince` | Only records published on or after this date. In `new` mode it applies to the first run only. |
| `firstRunBehavior` | `outputAll` (default) or `baselineOnly`: remember the current state without returning records, and alert from the next run. |
| `stateKey` | Name of the watchlist cursor (optional; by default derived from the filters). |
| `maxItems` | Safety cap, default 1,000. Set 0 for unlimited. |

Different filters combine with AND; values within one filter combine with OR.

### Output

One row per product × component × PFAS:

```json
{
  "publishedOn": "2026-04-15T14:19:39.813Z",
  "manufacturer": "Krohne Inc",
  "brand": "KROHNE",
  "productModel": "BFS 5000, DN2.5-40",
  "productCode": "VN40",
  "component": "Gaskets, Sealings",
  "pfasName": "poly(tetrafluoroethylene) (PTFE)",
  "casNumber": "9002-84-0",
  "pfasFunction": "Sealant",
  "concentrationRange": "90 to 100%",
  "disclosureId": "MN-6AVN78N",
  "changeType": "all",
  "source": "PRISM — Interstate Chemicals Clearinghouse (IC2), public data",
  "sourceUrl": "https://prism.theic2.org/"
}
```

The run's key-value store also contains `RUN_STATS`. In `new` mode it additionally contains `REPORT_CHANGES`, the list of added, withdrawn and changed disclosures.

**Alerts:** schedule the Actor (daily or weekly) and connect it to email, Slack, Google Sheets, Make or Zapier through Apify integrations.

### Pricing

Pay per event:

- **$1.00 per 1,000 records** returned (`pfas-record`).
- **$0.02 per detected report change** (`report-change`, `new` mode only).

A monitoring run with nothing new costs only the small Actor-start fee. Use `maxItems` or a run spending limit to cap the cost. Exporting the entire database costs about $285.

### Notes and limitations

- Only information that manufacturers filed and IC2 published is available. Confidential business information and reports still under review are not public.
- Concentrations are reported as ranges, not exact values.
- The Actor uses the public PRISM API with polite rate limits and retries. It does **not** collect contact names, e-mails, phone numbers or addresses.
- Questions or feature requests (other states, extra fields)? Open an issue on the Actor's Issues tab.

# Actor input Schema

## `mode` (type: `string`):

In 'new' mode the Actor stores a cursor in the named key-value store 'pfas-radar-state' and returns only records published after the previous run with the same filters.

## `brands` (type: `array`):

Case-insensitive substring match on BrandName, e.g. 3M, Gore.

## `manufacturers` (type: `array`):

Case-insensitive substring match on the accountable company name.

## `componentKeywords` (type: `array`):

PRISM has no product-category field; use component keywords such as gasket, coating, cable, membrane, o-ring.

## `productKeywords` (type: `array`):

Case-insensitive substring match on the product model name.

## `casNumbers` (type: `array`):

e.g. 9002-84-0 (PTFE), 24937-79-9 (PVDF).

## `chemicalNameKeywords` (type: `array`):

Substring match on the PFAS chemical name, e.g. fluoroethylene.

## `pfasFunctions` (type: `array`):

e.g. Sealant, Barrier, Lubricant, Insulator.

## `minConcentrationRangeId` (type: `integer`):

PRISM range id: 1 = detection limit to <100 ppm ... 8 = 90-100%. Range 9 ('present, concentration unknown') is excluded when this is set.

## `publishedSince` (type: `string`):

Only records published on/after this date. In 'new' mode it applies to the first run only.

## `firstRunBehavior` (type: `string`):

outputAll = return everything that matches now; baselineOnly = just remember the current state (no charge for records) and alert from the next run.

## `trackReportChanges` (type: `boolean`):

In 'new' mode, also detect added, withdrawn and changed disclosures (saved as REPORT_CHANGES in the run key-value store).

## `stateKey` (type: `string`):

Name of the monitoring cursor. Default: derived from the filters.

## `maxItems` (type: `integer`):

0 = unlimited (full database is ~285k records).

## `pageSize` (type: `integer`):

Records per API request (keyset pagination).

## `requestDelayMs` (type: `integer`):

Polite pause between requests to the public PRISM API.

## Actor input object example

```json
{
  "mode": "all",
  "componentKeywords": [
    "gasket"
  ],
  "casNumbers": [
    "9002-84-0"
  ],
  "firstRunBehavior": "outputAll",
  "trackReportChanges": true,
  "maxItems": 100,
  "pageSize": 2000,
  "requestDelayMs": 800
}
```

# Actor output Schema

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

One item per product × component × PFAS chemical: manufacturer, brand, product model, component, PFAS name, CAS number, function, concentration range, disclosure ID and publication date.

## `runStats` (type: `string`):

JSON with the applied filter, number of records scanned and saved, monitoring cursor and report-change counts.

# 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 = {
    "componentKeywords": [
        "gasket"
    ],
    "casNumbers": [
        "9002-84-0"
    ],
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("jamshid_data/pfas-product-disclosure-radar").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 = {
    "componentKeywords": ["gasket"],
    "casNumbers": ["9002-84-0"],
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("jamshid_data/pfas-product-disclosure-radar").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 '{
  "componentKeywords": [
    "gasket"
  ],
  "casNumbers": [
    "9002-84-0"
  ],
  "maxItems": 100
}' |
apify call jamshid_data/pfas-product-disclosure-radar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jamshid_data/pfas-product-disclosure-radar"
        }
    }
}
```

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/eYbUf6wKaWh0LWnbN/builds/vS5qlTnjhCOX9ouGy/openapi.json
