# US WARN Layoff Notices: 12 States Daily Feed (`offerastudio/us-warn-layoff-notices`) Actor

Layoff and plant closure notices filed under the US WARN Act, read from 12 official state labor department sites and normalised: company, location, employees affected, notice and layoff dates, type, source link, a dedupe hash and the company's notice count in the past 12 months.

- **URL**: https://apify.com/offerastudio/us-warn-layoff-notices.md
- **Developed by:** [Offera Studio](https://apify.com/offerastudio) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 notice returneds

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

### What does US WARN Layoff Notices do?

**US WARN Layoff Notices** collects the **layoff and plant closure notices** that US employers must file under the **WARN Act** (Worker Adjustment and Retraining Notification), straight from the **official state labor department websites**, and turns 12 different formats (XLSX, CSV, Google Sheets, HTML tables) into **one clean, normalised list**. For every notice you get:

- 🏢 **company** as published, plus a **normalised company name** for matching
- 📍 **address, city, county or workforce region** when the state publishes them
- 👥 **employees affected**
- 📅 **notice date** and **layoff / effective date**
- 🏷️ **type**: closure, layoff or relocation (when the state publishes it), plus permanent or temporary
- 🔗 the **source URL** of the official list, and a **`sourceRowHash`** to de-duplicate across runs
- 🔁 **`previousNotices12m`**: how many other notices the same company filed in the 12 months before, in any of the states read, with the latest five listed

Schedule it every morning with the default date filter and you have a **daily feed of new WARN notices** in Google Sheets, Slack, your CRM or a webhook.

### Who uses WARN notices?

- **Recruiters and staffing agencies**: reach experienced people weeks before a layoff takes effect, and the employers hiring them.
- **Outplacement and career-transition firms**: offer services to the employer while the notice period is still running.
- **B2B sales teams**: spot companies that are shrinking, closing sites or moving work (and their suppliers and landlords).
- **Journalists and researchers**: track layoffs by state, sector, size or company, and repeat filers.
- **Investors and analysts**: an early, official signal of restructuring at a company or in a region.

### Supported states (12)

| State | Official source | Format | "Notice date" means | History available |
| --- | --- | --- | --- | --- |
| California (CA) | Employment Development Department (EDD) | XLSX | notice date | current fiscal year (from 1 July); earlier years are PDF only |
| Colorado (CO) | Dept. of Labor and Employment (CDLE) | public Google Sheet per year | WARN date | from 2015 |
| Florida (FL) | FloridaCommerce (REACT) | HTML table per year | state notification date | several years |
| Indiana (IN) | Dept. of Workforce Development (DWD) | HTML table | notice date | from 2008 |
| Iowa (IA) | Iowa Workforce Development | XLSX event log | notice date | from June 2021 |
| Maryland (MD) | Maryland Department of Labor | HTML table per year | notice date | from 2010 |
| Oregon (OR) | Higher Education Coordinating Commission (HECC) | HTML table | notification date | six years |
| South Dakota (SD) | Dept. of Labor and Regulation (DLR) | HTML table | date received | from 2007 |
| Texas (TX) | Texas Workforce Commission (TWC) | XLSX per year; fallback: TWC's dataset on data.texas.gov | notice date | from 2020 |
| Utah (UT) | Dept. of Workforce Services (DWS) | HTML table per year | date of notice | from 2009 |
| Virginia (VA) | Virginia Works | CSV export | notice date | from 2010 |
| Washington (WA) | Employment Security Department (ESD) | HTML search table | received date | many years |

The Actor reads each list exactly as the state publishes it, a few requests per state, one at a time per website, with a pause in between.

**States not included yet, and why:** New York (dashboard only, no file), New Jersey (yearly PDF), Pennsylvania, Ohio, Illinois and Michigan (no stable machine-readable list found). PDF-only states are left out until they can be read reliably. Missing a state you need? Open an issue.

### How to use it

1. Leave **States** as is (all 12) or pick the ones you need.
2. Leave **Notice date from / to** empty for the **last 30 days**, or enter dates (`2026-09-01`) or relative dates (`7 days`).
3. Optional filters: **Company name contains**, **City or county contains** (also matches the address and workforce region), **Minimum employees affected**, **Maximum notices**.
4. Click **Start**. The **Notices** tab shows one row per notice, newest first; **All fields** and **Repeat filers** show the rest.

#### A daily WARN feed with schedules

1. Save your input as a **task** with **Notice date from** set to `3 days` (states publish with a few days' delay, so a short overlap catches late entries).
2. Add a **schedule** in Apify Console, for example every morning at 8:00.
3. Connect the dataset to **Google Sheets, Slack, email, Zapier, Make or a webhook** (Integrations tab), and de-duplicate on **`sourceRowHash`**: the same published row always gets the same hash, so overlapping runs never create duplicates in your sheet or CRM.

### Input example

```json
{
    "states": ["CA", "TX", "WA", "FL"],
    "noticeDateFrom": "7 days",
    "companyNameContains": "",
    "locationContains": "Los Angeles",
    "minEmployees": 50,
    "maxResults": 500
}
```

### Output example

Real rows from a run on 1 October 2026 (default input):

```json
{
    "state": "CA",
    "stateName": "California",
    "company": "Covenant Aviation Security, LLC",
    "companyNormalized": "covenant aviation security",
    "address": "Highway 101 San Francisco CA 94128",
    "city": "San Francisco",
    "county": "San Francisco County",
    "region": null,
    "locationText": "Highway 101 San Francisco CA 94128, San Francisco County",
    "employeesAffected": 1279,
    "noticeDate": "2026-09-28",
    "effectiveDate": "2026-11-30",
    "effectiveDateText": null,
    "noticeType": "layoff",
    "permanent": true,
    "noticeTypeText": "Layoff Permanent",
    "industry": "56 Administrative and Support and Waste Management and Remediation",
    "sourceName": "California Employment Development Department (EDD)",
    "sourceUrl": "https://edd.ca.gov/siteassets/files/jobs_and_training/warn/warn_report1.xlsx",
    "sourceRowHash": "0967121476adc1e0270b31ab22ff7663",
    "previousNotices12m": 0,
    "previousNotices": [],
    "retrievedAt": "2026-10-01T08:50:30.308Z",
    "error": null,
    "errorMessage": null
}
```

A company that filed before (Maryland):

```json
{
    "state": "MD",
    "company": "LifeBridge Suburban Staffing, LLC (LBSS)",
    "address": "2021-B Emmorton Road, Suite 110 Bel Air, MD 21015",
    "county": "Susquehanna",
    "employeesAffected": 12,
    "noticeDate": "2026-09-28",
    "effectiveDate": "2026-09-30",
    "noticeType": "closure",
    "noticeTypeText": "Plant Closure",
    "industry": "NAICS 561320",
    "previousNotices12m": 1,
    "previousNotices": [{ "state": "MD", "company": "LifeBridge Suburban Staffing, LLC", "noticeDate": "2026-02-06", "employeesAffected": 23 }]
}
```

Fields a state doesn't publish are `null` (for example, Texas has no notice type and Oregon has no layoff date).

#### Free info rows

If a state's website is down, blocks the request or has changed its layout, that state gets **one free row** with `error` and a plain-English `errorMessage`, and **every other state still runs**:

| `error` | Meaning |
| --- | --- |
| `source-unavailable` | The website did not answer, answered with an error, or refused the request. |
| `format-changed` | The page or file was read, but no longer has the expected table or columns. |
| `partial-data` | The state was read with a limitation, e.g. Texas from the data.texas.gov copy, or a slow site whose oldest history was skipped. |
| `no-results` | Nothing matched your filters. |
| `invalid-input` | An input value can't be used; the message says which. |

### How much does it cost?

This Actor uses **pay per event**:

| Event | Price |
| --- | --- |
| Notice returned | **$0.002** per notice |
| Info rows (state could not be read, partial data, no results, invalid input) | **free** |

- 100 notices cost **$0.20**; a typical 30-day run over all 12 states returns 100 to 200 notices.
- A daily feed with a 3-day window usually returns 10 to 40 notices a day (**about $0.02 to $0.08 per day**); pass `sourceRowHash` to your integration to skip rows you already have, or narrow the states.
- Apify also charges a tiny standard start fee per run.
- Set **Maximum cost per run** in the run options and the Actor stops when it is reached.

### Data and your responsibility

- WARN notices are **public records** published by the states. The Actor returns **company-level data only**: employer, site address, numbers and dates. Virginia's export also names a contact person and union contacts; those columns are **never read or returned**.
- The data is as accurate as each state's list. States correct and amend notices; amendments can appear as separate rows (Iowa marks them as `Amendment`, type `other`).
- This is not legal advice, and a WARN notice is not proof that a layoff happened or will happen as described.

### Limitations

- **Notice date vs received date.** Some states only publish the date they received the notice (see the table). Filters use that date.
- **Locations differ by state.** California, Florida, Iowa and Maryland publish an address; most others a city, county or region. Oregon lists the employer's city as entered on the notice, which can be a head office in another state.
- **`previousNotices12m` only counts what was read**: the 12 states, back to one year before your start date, and only as far back as each state publishes (California: current fiscal year only). Company names are matched after normalisation (`Genentech, Inc.` = `GENENTECH INC`; `Maverick Washington LLC / Chips Casino` = `Maverick Washington`), so different legal entities with very different names are not linked.
- **Texas:** TWC's own website protects itself with a bot challenge that may refuse automated requests. The Actor then uses TWC's dataset on the Texas Open Data Portal (data.texas.gov), which TWC updates less often, and adds a free `partial-data` row saying how current it is.
- **Speed:** most states take seconds; Florida's site is slow (about 15 seconds per page), so a full run takes 1 to 2 minutes. At most 2 years per run, 10,000 notices.
- States publish with a delay of a few days to a few weeks after the employer files.

### FAQ

#### Is this data official?

Yes. Every row comes from the state labor department's own website (Colorado's are the department's own public Google Sheets; Texas may come from TWC's dataset on the official Texas Open Data Portal). Each row links its source.

#### How do I avoid duplicates when I run it every day?

Use a short overlapping window (e.g. `3 days`) and de-duplicate on `sourceRowHash` in your sheet, database or integration.

#### Why is a state missing from my results?

Either it had no notices in your date range, or its row in the dataset has an `error` explaining what went wrong (free). Other states are not affected.

#### Can I get every notice for a company?

Set a wide date range (up to 2 years), fill in **Company name contains**, and check `previousNotices` on each row.

#### Can I get the people affected?

No. WARN lists don't name employees, and this Actor only returns company-level data.

### More tools from the same developer

All pay-per-result, no proxy or login needed, built and maintained by the same developer:

**Website audits**

- [Website Accessibility Checker: WCAG 2.2 & EAA](https://apify.com/offerastudio/website-accessibility-audit): accessibility issues with fixes, SEO basics and security headers.
- [Cookie & Tracker Audit: GDPR Consent Checker](https://apify.com/offerastudio/cookie-tracker-audit): cookies and tracking tags that load before consent.
- [AI Crawler Access Checker: robots.txt & llms.txt](https://apify.com/offerastudio/ai-crawler-access-audit): which AI crawlers a site allows, plus llms.txt.
- [Website Change Monitor: Diffs, Prices & Alerts](https://apify.com/offerastudio/website-change-monitor): get a row only when a page changes, with a clean diff.

**Company data and compliance**

- [Company Contact Finder: Emails, Phones & Socials](https://apify.com/offerastudio/company-contact-finder): contact details published on company websites.
- [UK New Companies Feed: Companies House Daily](https://apify.com/offerastudio/uk-new-companies-feed): newly incorporated UK companies with sector filters.
- [EU VAT Number Validator: Bulk VIES Checker](https://apify.com/offerastudio/eu-vat-number-validator): bulk VAT checks with name, address and consultation number.
- [LEI Corporate Tree: GLEIF Parents & Subsidiaries](https://apify.com/offerastudio/gleif-lei-corporate-tree): LEI lookup with parents, subsidiaries and a KYC summary.

**Market signals**

- [US Product Recalls Monitor: FDA & CPSC Feed](https://apify.com/offerastudio/us-product-recalls-monitor): FDA and CPSC recalls in one feed, with severity.

### Feedback

Missing a state or a field? Open an issue on the **Issues** tab.

# Changelog

This Actor's version history is a separate document: https://apify.com/offerastudio/us-warn-layoff-notices/changelog.md

# Actor input Schema

## `states` (type: `array`):

States to read. All 12 supported states by default. Each state's list comes from its own labor department website (see the README for the exact sources).

## `noticeDateFrom` (type: `string`):

First notice date, e.g. 2026-09-01, or a relative date like "7 days" (7 days ago). Leave both dates empty for the last 30 days. With only this date set, the range runs to today. At most 2 years per run. Some states publish the date they received the notice instead; see the README.

## `noticeDateTo` (type: `string`):

Last notice date, inclusive. Default: today.

## `companyNameContains` (type: `string`):

Keep only notices whose company name contains this text (not case-sensitive), e.g. amazon.

## `locationContains` (type: `string`):

Keep only notices whose address, city, county or workforce region contains this text, e.g. Seattle or Los Angeles County.

## `minEmployees` (type: `integer`):

Keep only notices with at least this many affected employees. Notices that don't state a number are left out when this is above 0.

## `maxResults` (type: `integer`):

Stop after this many notices (newest notice dates first). Each notice returned costs $0.002.

## Actor input object example

```json
{
  "states": [
    "CA",
    "CO",
    "FL",
    "IN",
    "IA",
    "MD",
    "OR",
    "SD",
    "TX",
    "UT",
    "VA",
    "WA"
  ],
  "minEmployees": 0,
  "maxResults": 100
}
```

# Actor output Schema

## `notices` (type: `string`):

No description

## `history` (type: `string`):

No description

# 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 = {
    "states": [
        "CA",
        "CO",
        "FL",
        "IN",
        "IA",
        "MD",
        "OR",
        "SD",
        "TX",
        "UT",
        "VA",
        "WA"
    ],
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("offerastudio/us-warn-layoff-notices").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 = {
    "states": [
        "CA",
        "CO",
        "FL",
        "IN",
        "IA",
        "MD",
        "OR",
        "SD",
        "TX",
        "UT",
        "VA",
        "WA",
    ],
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("offerastudio/us-warn-layoff-notices").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 '{
  "states": [
    "CA",
    "CO",
    "FL",
    "IN",
    "IA",
    "MD",
    "OR",
    "SD",
    "TX",
    "UT",
    "VA",
    "WA"
  ],
  "maxResults": 100
}' |
apify call offerastudio/us-warn-layoff-notices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,offerastudio/us-warn-layoff-notices"
        }
    }
}
```

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/RRalSbUWkkSp2yGwI/builds/eRSugW2ozIE1Ospoh/openapi.json
