US WARN Layoff Notice Aggregator & Delta Monitor (OR/TX API) avatar

US WARN Layoff Notice Aggregator & Delta Monitor (OR/TX API)

Pricing

from $4.40 / 1,000 results

Go to Apify Store
US WARN Layoff Notice Aggregator & Delta Monitor (OR/TX API)

US WARN Layoff Notice Aggregator & Delta Monitor (OR/TX API)

Aggregate US state WARN Act layoff & closure notices into one normalized schema and track new / updated / removed deltas. Oregon & Texas live (keyless Socrata); CA/NY/WA/WI/IL/NJ scaffolded. For RevOps, recruiting, econ research and CRE. No API key.

Pricing

from $4.40 / 1,000 results

Rating

0.0

(0)

Developer

Kyle Maloney

Kyle Maloney

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

3 days ago

Last modified

Share

US WARN Layoff Notice Aggregator & Delta Monitor

Aggregate US state WARN Act layoff & plant-closure notices into one normalized schema, and get a delta feed of exactly what changed since your last run: new notices, updated notices (employee count / effective date / type revised), and removed notices.

Every state publishes WARN filings in a different shape (Socrata, CSV, HTML, Excel) with different column names and layoff-type wording. This actor unifies them so you can monitor layoffs across states from a single, stable dataset — no logins, no API keys.

What v1.1 changed (2026-08-01 validation pass)

Every source is now checked live, before a single row is billed, and every row carries the outcome of every requested state. Concretely:

  • A dead state is loud. If Texas fails and Oregon succeeds, every emitted row carries run_complete = false, run_states_failed = "TX" and the error text. Previously the run emitted Oregon rows and nothing else, indistinguishable from "Texas had no layoffs". If every requested state fails, the run fails and nothing is billed.
  • The delta engine no longer invents changes. Oregon's WARN number is not one-per-row — 397 live rows carry only 239 distinct WARN numbers, and WARN 9434 alone covers 19 separate Kroger store closures. Keying on it made a re-run against byte-identical upstream data report 146 "updated" notices, complete with invented headcount changes. A re-run now reports zero.
  • maxResults is split evenly across states. maxResults: 100 over ["OR","TX"] used to return 100 Oregon rows and zero Texas rows with no error. Rows now also carry source_truncated when a state was cut short.
  • Source freshness is on every row. source_last_notice_date and source_stale_days. Oregon's dataset measured 80 days since its newest notice on 2026-08-01 — a fact a buyer needs, and one no amount of offline testing could surface.
  • Nine fields that were fetched and thrown away are now emitted — see the table below.
  • An unrecognised layoff-type value fails the run instead of being silently bucketed to null.
  • Nothing was removed or renamed. Every 1.0 field still means exactly what it meant.

Who it's for

  • RevOps & recruiting / staffing — catch fresh layoffs the day they're filed to source candidates or reach affected employers before competitors.
  • Economic & labor-market researchers — build a clean cross-state layoff time series without hand-scraping each agency portal.
  • Commercial real estate (CRE) & site selection — flag closures that free up facilities and shifts in regional employment.
  • Investors & risk / supply-chain teams — track distress signals by company, county and sector.

Coverage

StateSourceStatus (verified live 2026-08-01)
OR OregonSocrata data.oregon.gov (ijbz-jpx8)Live — 397 rows, newest notice 2026-05-13
TX TexasSocrata data.texas.gov (8w53-c4f6)Live — 2,368 rows, newest notice 2026-06-23
CA CaliforniaEDD WARN report (HTML/Excel)Scaffolded — requesting it fails loudly
NY New YorkNY DOL WARN (HTML)Scaffolded — requesting it fails loudly
WA WashingtonESD WARN (Excel)Scaffolded — requesting it fails loudly
WI WisconsinDWD WARN (HTML)Scaffolded — requesting it fails loudly
IL IllinoisDCEO WARN (HTML/PDF)Scaffolded — requesting it fails loudly
NJ New JerseyNJ DOL WARN (HTML)Scaffolded — requesting it fails loudly

Adding a state is a single config block (

{ state, format, domain, datasetId, map, requiredColumns, expectedMinRows, expectedMaxRows }
) in source.js. States marked "scaffolded" publish only HTML/Excel/PDF today. Requesting only scaffolded states now returns HTTP-400-style failure before the run starts rather than a zero-row success, so a buyer never mistakes "not implemented" for "no layoffs".

Example input — snapshot

{
"states": ["OR", "TX"],
"mode": "snapshot",
"sinceDate": "2026-01-01",
"maxResults": 100000
}

Example input — delta (scheduled monitoring)

{
"states": ["OR", "TX"],
"mode": "delta",
"sinceDate": "2026-01-01",
"priorKvKey": "warn_last_snapshot",
"deltaStoreName": "warn-layoff-delta"
}

In delta mode with priorKvKey, the actor diffs against the snapshot stored under that key in a named, cross-run key-value store and saves the current snapshot back to it — so a daily schedule emits only what changed. (The platform's default key-value store is per-run, so a delta built on it would find an empty baseline every run and re-report the whole registry as "new". This actor uses a named store for exactly that reason.) The stored key is scoped to the states and window of the run, so two schedules with different filters cannot overwrite each other's baseline. Alternatively pass the prior records directly as priorItems.

Output fields — all 38 declared fields

The notice

FieldMeaning
stateTwo-letter code of the state registry that issued the notice (the jurisdiction).
state_nameFull name of that state.
companyEmployer or job-site name named in the notice.
cityCity where the layoff or closure occurs.
countyCounty, where the state publishes it. Texas only — Oregon publishes none.
site_stateTwo-letter state of the actual job site. Oregon publishes this and it is not always OR: 26 of 397 live rows are sites in GA, CA, IL, WI, VA and elsewhere (e.g. WARN 9178, UPS, Atlanta, GA). Texas publishes only Texas sites.
site_state_matches_jurisdictiontrue in-state, false out-of-state, null when the source publishes no site state.
notice_dateDate the notice was filed (YYYY-MM-DD).
state_received_dateDate the state agency received the notice. Texas publishes this separately and the two differ on 1,249 of 2,368 rows (52.7%). Oregon publishes one date, so the two agree there.
effective_dateDate the layoff or closure takes effect.
employees_affectedWorkers affected. null, never 0, when the state published no number (4 Oregon rows, 4 Texas rows).
layoff_typeNormalized bucket: layoff, closure or relocation.
layoff_type_rawThe state's exact reason string. layoff_type null + layoff_type_raw null = the state does not publish a reason (all of Texas). layoff_type null + layoff_type_raw non-null = the state published a value outside the three buckets (Oregon "Other", 16 live rows).
industryIndustry / sector. Neither Oregon nor Texas publishes it, so it is null on every row from these two sources. Retained because removing a published field would break existing pipelines; it will populate when a state that publishes industry is wired.
regionWorkforce development area. Texas only.
notice_idState-assigned WARN number. Oregon only — and it is NOT unique: one WARN number can cover 19 store closures. Use notice_key, not this, as a key.
notice_keyStable per-row cross-run key: state + notice id + company + city + effective date. Unique on 2,746 of 2,765 live rows; the residual pairs are byte-identical duplicate rows in the sources themselves.
identity_keyKey for the notice-site independent of every changeable field. Two rows sharing it are the same site across runs even if the effective date moved.
source_urlThe official state open-data endpoint the row was pulled from.
source_dataset_idSocrata dataset identifier.
retrieved_atISO 8601 timestamp of this run.

The per-source outcome contract

null means not checked. false means checked and negative. These four fields exist so a buyer can never mistake an outage for an absence of layoffs.

FieldMeaning
source_status"ok" for the state that produced this row.
source_row_countExact upstream row count (count(*)) measured on this run — the free truncation guard. null if not measured.
source_last_notice_dateNewest notice date present in the source dataset. If this is far in the past, the registry has stopped publishing — not the employers.
source_stale_daysWhole days between source_last_notice_date and this run. Oregon measured 80, Texas 39, on 2026-08-01.
source_truncatedtrue when maxResults cut this state short. null when undetermined.
run_states_requestedEvery state this run attempted.
run_states_okEvery state that answered.
run_states_failedRequested states that did not answer. null on a healthy run. A state listed here has no rows here for reasons of availability.
run_states_failed_reasonPer-state error text. null on a healthy run.
run_completetrue only when every requested state answered.

Delta mode only

change_type (new / updated / removed), plus old_employees_affected, new_employees_affected, old_effective_date, new_effective_date, old_layoff_type, new_layoff_type. All seven are null in snapshot mode by design.

Inputs that populate the conditionally-null fields (each verified on a live run): county / region — any run including "TX". notice_id / layoff_type / layoff_type_raw — any run including "OR". site_state_matches_jurisdiction = false{"states":["OR"]} (26 rows). layoff_type null + raw non-null{"states":["OR"]} (16 rows). The seven delta columns — {"states":["OR"],"mode":"delta","sinceDate":"2026-04-01","priorItems":[...]}. run_states_failed / run_states_failed_reason — populate only during a genuine partial upstream outage; observed live on run JkmtVBtuTh8EgXBUI's successor when data.oregon.gov transiently refused a connection, and pinned by offline fixtures. industry is the one field with no populating input from the two live sources.

Live drift assertions

An offline fixture cannot see a silently degraded upstream, because the fixture was shaped from the degraded data. Before any row is fetched or billed, each live state is checked against the running service and every measured value is written to the log (DRIFT PROBE OR: {...}):

  1. Every column the mapper reads is named in a $select. Socrata returns HTTP 400 on a renamed column, so the drift that would otherwise emit a full dataset of billable all-null rows fails the run instead. 8 columns asserted per state.
  2. Exact row count via count(*), checked against a measured band (Oregon 150–20,000 against a live 397; Texas 800–60,000 against a live 2,368). Bands are deliberately wide — a false-positive drift failure on a live actor costs real money.
  3. A negative control: <date field> >= '2999-01-01' must return exactly 0. If the $where clause ever stops being applied, sinceDate is silently ignored, and this is what catches it.
  4. A positive canary: the newest row must map to a non-null company and notice date.
  5. Freshness: the source's own max(<date field>), reported on every row.
  6. Closed vocabulary: any Oregon layoff_type value outside the six live values fails the run rather than being bucketed to null.

Use as an MCP tool

This actor is callable by AI agents (Claude, Cursor, etc.) via mcp.apify.com. The clean, field-level output schema makes it a good chainable tool: an agent can pull a state's WARN notices, filter by company, county or headcount, and hand rows to an outreach, enrichment or analysis step. The run_complete / run_states_failed fields let an agent tell a genuine "no layoffs" from an unavailable registry without reading logs.

Pricing

Pay per result — one WARN notice (or one delta change row) = one dataset item. Graduated discounts apply on paid Apify plans. A run that fails because every source was unavailable emits nothing and bills no result events.

FAQ

How do I monitor for new layoff notices? Run in delta mode on a schedule with a priorKvKey; each run emits only new / updated / removed rows. The first run establishes the baseline and reports everything as new — the log says so explicitly.

Which states are live today? Oregon and Texas, via their keyless Socrata open-data APIs. California, New York, Washington, Wisconsin, Illinois and New Jersey are scaffolded config blocks; requesting only those fails the run with a message naming the live states, rather than returning an empty dataset.

What counts as an "updated" notice? The employee count, effective date, notice date, or layoff type changed versus the prior snapshot — for the same job site. A revision to a region label or the run timestamp is not a change.

Why does an Oregon row sometimes show a city outside Oregon? Because Oregon's registry contains them. state is the issuing registry; site_state is where the job site actually is, and site_state_matches_jurisdiction flags the 26 live rows where they differ.

Oregon's newest notice is months old — is the actor broken? No: source_last_notice_date and source_stale_days report the state of the source dataset. Oregon's Socrata dataset had not been refreshed for 80 days as of 2026-08-01. Every row tells you that.

Do I need an API key? No. All sources are public and keyless.

How is it billed? Pay per result — one WARN notice (or one delta change row) = one dataset item.

  • sos-registry-monitor — new business registrations across state Secretary-of-State registries; the growth-side counterpart to this actor's distress signal.
  • fdic-ncua-health-rollup — bank and credit-union financial health, for the same regional-distress question from the balance-sheet side.
  • city-business-license-leads — municipal licence filings for local market-entry signal.