EPA Toxic Releases — What a ZIP Code's Industry Emits
Pricing
from $0.50 / 1,000 results
EPA Toxic Releases — What a ZIP Code's Industry Emits
Look up US facilities by ZIP code and report what each one released: chemical, CAS number, year, total pounds and the split across air, water, land and underground. Source: the EPA Toxic Release Inventory.
Pricing
from $0.50 / 1,000 results
Rating
0.0
(0)
Developer
Alauddin burki
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
18 hours ago
Last modified
Categories
Share
Give it a US ZIP code and get back what the facilities there released: chemical, CAS number, reporting year, total pounds, and the split across air, water, land and underground.
Source: the EPA Toxic Release Inventory through Envirofacts — public, keyless, official.
Why this needs an Actor rather than a query
The data is four tables that cannot be joined through the API:
tri_facility (name, address, ZIP)└── tri_reporting_form one chemical, ONE YEAR, per doc_ctrl_num├── tri_release_qty one row PER MEDIUM (AIR FUG, AIR STACK, WATER, LAND TREA …)└── tri_chem_info the chemical name and CAS number
The Actor walks the chain for you: ZIP → facilities → forms → the chosen year → quantities → chemical names.
Two traps that make naive numbers wrong
1. total_release is often null, and null is not zero. The API also sets release_na when a facility reports
"not applicable". Summing null as zero understates a facility — and printing "0 lb" when the truth is "not reported"
is worse than printing nothing. So an unreported chemical keeps totalPounds: null and carries a note saying so.
2. A facility has decades of forms. Without picking one year deliberately you would add 1987 to 2023. The Actor uses the year you ask for, or the newest the facility filed, and never mixes years in one row.
What you get
| Field | Example |
|---|---|
facilityName / facilityId | GOLDEN BELT MANUFACTURING CO · 27701GLDNB807EA |
chemical / casNumber | Toluene · 108-88-3 |
year | 1996 |
totalPounds | 2,895 |
airPounds / waterPounds / landPounds / undergroundPounds | 2,000 · — · 895 · — |
city / state / zip | RALEIGH · NC · 27701 |
Two views: Releases (who released what) and By medium (air vs water vs land).
Use cases
- Site due diligence — what has been released near a property or a school.
- ESG and supply-chain screening — a supplier's reported releases by chemical.
- Local journalism — the numbers behind a neighbourhood story, row by row.
Limitations — read these
- Coverage is US facilities that must report to TRI. Not every business does.
- Reporting is annual and often years behind. The example above is 1996 because that is the newest report that
facility filed; a ZIP with no recent filer returns old years, and the
yearcolumn says which. - Quantities are self-reported estimates by the facility, not measurements.
nullmeans "not reported", never "zero" — filter ontotalPounds !== nullwhen you need numbers.- Several API calls per facility, so
maxFacilitiesbounds the run.
Why this is different
The TRI tables are public and free, so the usual answer is "write a script". The script is where the
work is: four tables that share no single join key, one row per medium that has to be summed without
turning "not reported" into zero, and decades of forms per facility that have to be narrowed to one
year before anything adds up. This returns that finished join as flat rows — facility, chemical, CAS
number, year and the medium split — with null kept honest and a note explaining every null. It is
standalone: no key, no ETL, no warehouse, no per-lookup form.
FAQ
Do I need an EPA API key? No. Envirofacts is public.
Why is totalPounds null instead of 0? The facility reported that release as not applicable or
left it blank. Treating that as zero would understate the plant, so it stays null with a note.
Which year am I looking at? The year you ask for, or the newest year that facility filed. The
year field on every row says which.
Why is the newest year old? TRI reporting is annual and published with a lag; a plant that closed in 2005 has no later reports.
Does a missing facility mean nothing was released? No. It means the facility does not report to TRI, or the ZIP has no TRI filer.
Pricing
Pay per result: $0.0005 per release row. Each stored dataset row is billed, including any diagnostic row returned instead of results.
An Actor-start event is also charged at $0.0001 per GB of allocated memory (minimum one event), even if no rows are returned. At 1 GB or less, 1,000 result rows cost $0.5001 before any applicable Store discount.
Demand — stated honestly
Zero competing Actors in the Store for this data. That is a fact about supply, not proof of demand: the independent signals are modest (30–70 GitHub repositories around TRI data, low Hacker News volume). This is a compliance/ESG niche, not a mass market — the trade-off that comes with a zero-competition lane.
Verified
28 unit tests (buckets, the null-is-not-zero rule, ZIP validation, year selection, row shape) + 9 live checks against the real Envirofacts service (facility → form → release → chemical).
Built for the second account (alauddinburki), Actor 1000, per plan/OPERATIONS.md.