APProjects's picture
site refresh (1420 changed)
cbe3565 verified
|
Raw
History Blame Contribute Delete
7.54 kB

A free WARN Act API β€” 61,431 layoff notices, 48 states, one GET request

No key, no signup, no rate limit, CORS open. Every US state publishes the mass-layoff notices employers file under the WARN Act, and every state publishes them differently. We scrape all 48 of them every morning, normalize them into one 11-field schema, resolve the employer names, and serve the result as plain JSON and CSV over HTTPS. Rebuilt 2026-09-25; newest notice in this build is dated 2026-09-25. CC BY 4.0 β€” credit "WARN Feed".

Full docs, examples and a per-state list: https://approjects-warn-act-notices.static.hf.space/api.html

Quickstart

# the whole archive as JSON
curl -sL https://approjects-warn-act-notices.static.hf.space/data/warn_notices.json | jq '.[0]'
# just what is new β€” poll this one daily
curl -sL https://approjects-warn-act-notices.static.hf.space/data/latest.json | jq '.count, .generated_at'
# poll politely: every file carries an ETag; send it back and an unchanged file is a 304 with no body
curl -sL -o latest.json -D - -H 'If-None-Match: "<etag from last run>"' https://approjects-warn-act-notices.static.hf.space/data/latest.json
# streaming: one notice per line (NDJSON), no 20 MB buffer
curl -sL https://approjects-warn-act-notices.static.hf.space/data/warn_notices.ndjson | head -n 3 | jq -c '{company_canonical, state, notice_date}'
# one state, as CSV
curl -sL https://approjects-warn-act-notices.static.hf.space/data/by-state/ca.csv | head -3

Files over ~10 MB (the JSON and NDJSON archives) answer 302 to a CDN copy that sends the same CORS header β€” keep -L (every HTTP library follows by default).

import pandas as pd
df = pd.read_csv("https://approjects-warn-act-notices.static.hf.space/data/latest.csv")
print(len(df), df.columns.tolist())

From an LLM or an agent: the MCP server

warn-mcp wraps these endpoints in six read-only Model Context Protocol tools, so an agent asks a question instead of pulling a 9 MB file into a context window: employer + state + date-range search, the rolling new-notice feed, one employer's whole history back to 1988, monthly state totals, the revision log (which rows changed or vanished between daily builds, tagged by what is mechanically distinguishable β€” never a guess at why), and a freshness call. Standard library only, no key, disk cache with ETag revalidation.

claude mcp add warn -- uvx --from git+https://github.com/APVentureEngine/warn-mcp warn-mcp

Any client that reads an mcpServers block (Claude Desktop, Cursor, Continue):

{"mcpServers": {"warn": {"command": "uvx",
  "args": ["--from", "git+https://github.com/APVentureEngine/warn-mcp", "warn-mcp"]}}}

Prefer a URL to a subprocess β€” ChatGPT and Claude.ai connectors, n8n, anything that only speaks remote MCP? The same six tools are hosted over Streamable HTTP at https://mQpACuIiQcnwK93JY.apify.actor/mcp. One honest caveat: the host meters compute to whoever calls it, so that endpoint needs YOUR own free Apify API token in an Authorization: Bearer header. We charge nothing for it and keep nothing. The install-free bundle above needs no token of any kind, so use it instead if your client can.

Both routes are listed as io.github.APProj/warn-mcp in the official MCP registry.

Source, tool reference and issues: https://github.com/APVentureEngine/warn-mcp

Endpoints

Endpoint What Records Size
/data/warn_notices.json Whole archive, JSON 61,431 notices 20.1 MB
/data/warn_notices.ndjson Whole archive, NDJSON 61,431 notices 18.7 MB
/data/latest.csv Recent notices, CSV 88 notices 16 kB
/data/latest.json Recent notices, JSON 88 notices 36 kB
/datapackage.json Schema (Frictionless Table Schema) 11 fields 3 kB
/data/coverage.json Per-state coverage + freshness 48 states 11 kB
/data/stale.json Sources behind their usual cadence 10 late sources 2 kB
/data/trends.json Monthly series 24 months 56 kB
/data/search-index.json Employer search index 29,971 employers 2.7 MB
/data/badge.json Shields.io endpoint badge β€” 153 B
/feed.xml RSS of new notices 50 items 29 kB

Per-state CSVs for 48 states: https://approjects-warn-act-notices.static.hf.space/data/by-state/<two-letter-code-lowercase>.csv (AK, AL, AZ, CA, CO, CT, DC, DE, FL, GA, HI, IA, ID, IL, IN, KS, KY, LA, MA, MD, ME, MI, MN, MO, MS, MT, NC, ND, NE, NJ, NM, NV, NY, OH, OK, OR, PA, RI, SC, SD, TN, TX, UT, VA, VT, WA, WI, WV).

Schema

Field Type Meaning
id string Stable dedupe id (source record number where available, else content hash)
state string 2-letter US postal code
company string Employer name exactly as published by the state
company_canonical string Cleaned employer name; groups the same employer across states, renotices and store numbers
company_dba string Trade name when the state published a dba/aka alias
location string City/county/address, best effort
employees_affected integer Workers affected; empty if the state omitted it
notice_date date ISO date the notice was received/posted (NJ: month precision, day pinned to 01)
effective_date date ISO date the layoff/closure takes effect
notice_type string Layoff/closure label as published
first_seen datetime UTC timestamp the pipeline first saw this notice

What this API does not do

  • It does not push. A snapshot cannot tell you that your employer just filed; you would poll and diff it yourself. warn-layoff-alert-bot is a 120-line, dependency-free example that does exactly that from a daily GitHub Actions cron and posts to Slack or Discord (MIT; fork it).
  • It does not filter. Static files have no query parameters.
  • It is a once-a-morning rebuild, not a stream.

If what you wanted was an alert rather than a file, WARN Watch runs your employer list (up to 500 names, or whole states) against every daily refresh for a year and pushes hits to a private page, RSS, a calendar and your Slack/Discord/Teams webhook β€” $49/year, one payment, or a free 30-day trial.

Need an endpoint we do not publish? Open an issue and say which field, state or shape β€” the pipeline runs every day anyway.