Spaces:
Running
Running
File size: 7,538 Bytes
f24ca1f a9286e4 cbe3565 a9286e4 7c62bf2 a9286e4 f24ca1f cbe3565 a9286e4 f24ca1f a9286e4 44db402 a9286e4 4ffdff4 a9286e4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | # 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
```bash
# 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).
```python
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](https://modelcontextprotocol.io) 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.
```bash
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):
```json
{"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](https://registry.modelcontextprotocol.io/v0/servers?search=warn-mcp).
Source, tool reference and issues: <https://github.com/APVentureEngine/warn-mcp>
## Endpoints
| Endpoint | What | Records | Size |
|---|---|---|---|
| [`/data/warn_notices.json`](https://approjects-warn-act-notices.static.hf.space/data/warn_notices.json) | Whole archive, JSON | 61,431 notices | 20.1 MB |
| [`/data/warn_notices.ndjson`](https://approjects-warn-act-notices.static.hf.space/data/warn_notices.ndjson) | Whole archive, NDJSON | 61,431 notices | 18.7 MB |
| [`/data/latest.csv`](https://approjects-warn-act-notices.static.hf.space/data/latest.csv) | Recent notices, CSV | 88 notices | 16 kB |
| [`/data/latest.json`](https://approjects-warn-act-notices.static.hf.space/data/latest.json) | Recent notices, JSON | 88 notices | 36 kB |
| [`/datapackage.json`](https://approjects-warn-act-notices.static.hf.space/datapackage.json) | Schema (Frictionless Table Schema) | 11 fields | 3 kB |
| [`/data/coverage.json`](https://approjects-warn-act-notices.static.hf.space/data/coverage.json) | Per-state coverage + freshness | 48 states | 11 kB |
| [`/data/stale.json`](https://approjects-warn-act-notices.static.hf.space/data/stale.json) | Sources behind their usual cadence | 10 late sources | 2 kB |
| [`/data/trends.json`](https://approjects-warn-act-notices.static.hf.space/data/trends.json) | Monthly series | 24 months | 56 kB |
| [`/data/search-index.json`](https://approjects-warn-act-notices.static.hf.space/data/search-index.json) | Employer search index | 29,971 employers | 2.7 MB |
| [`/data/badge.json`](https://approjects-warn-act-notices.static.hf.space/data/badge.json) | Shields.io endpoint badge | β | 153 B |
| [`/feed.xml`](https://approjects-warn-act-notices.static.hf.space/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](https://github.com/APVentureEngine/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](https://approjects-warn-act-notices.static.hf.space/watch.html)
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](https://approj.gumroad.com/l/warn-free-watch).
Need an endpoint we do not publish? [Open an issue](https://github.com/APVentureEngine/warn-act-notices/issues/new) and say which
field, state or shape β the pipeline runs every day anyway.
|