# WARN Layoff Notices Feed (CA, TX, WA, VA, OR, CO in one schema) (`moment-data/warn-layoff-notices-feed`) Actor

Multi-state WARN Act layoff and plant-closure notices from official state workforce agencies, normalized: company, city, county, employees affected, notice and effective dates, layoff vs closure, permanent vs temporary, source links. Filters and 'new since last run' alerts.

- **URL**: https://apify.com/moment-data/warn-layoff-notices-feed.md
- **Developed by:** [Luke Miller](https://apify.com/moment-data) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 notice records

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

## WARN Layoff Notices Feed: Multi-State WARN Act Layoffs & Plant Closures in One Schema

Get **WARN Act layoff and plant-closure notices** from official state workforce agencies in **one clean, normalized dataset**: **California (EDD), Texas (TWC), Washington (ESD), Virginia (Virginia Works), Oregon (HECC) and Colorado (CDLE)**. Each record has the company, city, county, number of employees affected, notice date, effective (layoff) date, layoff vs closure, permanent vs temporary, industry where published, and a link to the official source or notice PDF. Filter by company, city or county and minimum headcount, then schedule it daily in *new since last run* mode for a **layoff alert feed** that only bills you for notices you have not seen.

WARN (Worker Adjustment and Retraining Notification) notices are usually filed **60 days before** a mass layoff or closure, which makes them one of the earliest public signals of company distress, restructuring and talent becoming available.

### Who it is for

- **B2B sales and revenue teams**: layoffs and site closures are buying triggers for outplacement, staffing, HR tech, benefits, legal, relocation, liquidation, commercial real estate and IT asset recovery. Filter by `minEmployees` to focus on big events.
- **Recruiters and talent teams**: know which companies are releasing engineers, nurses, warehouse or manufacturing workers in your city 60 days ahead, and reach the talent pool first.
- **Commercial real-estate, landlords and economic developers**: closures and relocations signal upcoming vacancies; watch by county or city.
- **Journalists, newsletters and researchers**: a daily, multi-state layoff tracker with links to the official state records for verification.
- **Investors and analysts**: company-level distress signals, headcount affected and timing, per state.
- **Workforce boards and nonprofits**: a single feed of notices across states for rapid-response planning.

### Why this WARN Actor

- **Six official state sources, one schema**: `CA`, `CO`, `OR`, `TX`, `VA`, `WA`, merged newest-first.
- **Normalized fields, not raw columns**: `employeesAffected` as a number, ISO dates, `noticeType` (`layoff` / `closure` / `relocation`), `permanence` (`permanent` / `temporary`), `isAmendment` flag, `city`, `county`, `workforceArea`, `industry`, `unionized` (VA), plus the state's original type text in `layoffTypeRaw`.
- **Stable `noticeId`** per notice for dedupe in your CRM or warehouse.
- **Filters**: states, days back, company keyword, city/county keyword, minimum employees, include/skip amendments.
- **New since last run** mode with saved history per *State key* (named key-value store), for daily alerts without duplicates.
- **Resilient**: if one state's site is down, the run continues with the others and reports it in `failedStates`.
- **Polite and compliant**: declared User-Agent, spaced requests, robots.txt crawl-delays honored, official public lists only.
- **Privacy by design**: company-level data only. Personal contact names (e.g. Virginia's "Contact Person") and union contact details are dropped.
- **Fast and cheap**: a default run takes about 10-15 seconds at 512 MB.

### Quick start

1. Click **Start** with the default input. You get the **40 newest WARN notices across all six states from the last 30 days**.
2. Narrow it down: choose `states`, set `minEmployees` (e.g. 100), a `companyKeyword` (e.g. `Amazon`) or a `locationKeyword` (e.g. `Seattle`, `Harris`, `Los Angeles`), and raise `maxItems` for bigger pulls.
3. **Daily layoff alerts (schedule tip):** create an Apify **Schedule** (e.g. every weekday at 7:00) with:

```json
{ "mode": "sinceLastRun", "stateKey": "daily-all", "daysBack": 14, "maxItems": 500 }
```

Each run delivers only notices not delivered before for that `stateKey`. Add a webhook or the Slack / Google Sheets / email / HubSpot integration to route them to your team. Use one `stateKey` per schedule (e.g. `tx-100plus`, `seattle-tech`).

Example: big layoffs in Texas and Washington in the last 60 days

```json
{ "states": ["TX", "WA"], "daysBack": 60, "minEmployees": 100, "maxItems": 200 }
```

### Input

| Field | Default | Meaning |
|---|---|---|
| `states` | all six | `CA`, `CO`, `OR`, `TX`, `VA`, `WA` |
| `daysBack` | 30 | Notices dated in the last N days (1-730) |
| `companyKeyword` | none | Company name contains this text (case-insensitive) |
| `locationKeyword` | none | City, county, location or workforce area contains this text |
| `minEmployees` | 0 | Minimum employees affected (0 = no minimum) |
| `includeAmendments` | true | Set false to skip notices flagged as amended/updated |
| `maxItems` | 40 | Cap per run (also caps your spend), newest first |
| `mode` | `window` | `window` = everything in the window; `sinceLastRun` = only new notices (**use for schedules**) |
| `stateKey` | `default` | Saved history name for `sinceLastRun` |

### Output (real records, Oct 2026)

```json
{
  "noticeId": "CA-b790a0c688b5f21d",
  "state": "CA",
  "stateName": "California",
  "company": "Dropbox, Inc.",
  "noticeDate": "2026-10-28",
  "receivedDate": "2026-10-28",
  "effectiveDate": "2026-11-18",
  "effectiveEndDate": null,
  "employeesAffected": 57,
  "noticeType": "layoff",
  "permanence": "permanent",
  "layoffTypeRaw": "Layoff Permanent",
  "isAmendment": false,
  "city": "San Francisco",
  "county": "San Francisco",
  "location": "50 Hawthorne Street San Francisco CA 94105",
  "address": "50 Hawthorne Street San Francisco CA 94105",
  "locationState": "CA",
  "workforceArea": null,
  "industry": "54 Professional Scientific and Technical Services",
  "reason": null,
  "unionized": null,
  "totalNotifiedAllStates": null,
  "sourceRecordId": null,
  "sourceAgency": "California Employment Development Department (EDD)",
  "sourceUrl": "https://edd.ca.gov/en/jobs_and_training/Layoff_Services_WARN/",
  "noticeUrl": null,
  "firstSeenAt": "2026-10-31T05:01:53.178Z"
}
```

```json
{
  "noticeId": "WA-c08c69c753bb4cd1",
  "state": "WA",
  "company": "Comcast",
  "noticeDate": "2026-10-29",
  "effectiveDate": "2026-12-31",
  "employeesAffected": 159,
  "noticeType": "layoff",
  "permanence": "permanent",
  "location": "Statewide",
  "sourceAgency": "Washington Employment Security Department (ESD)",
  "noticeUrl": "https://fortress.wa.gov/esd/file/WARN/Public/DownloadFile.aspx?file=3b33f7df-fb60-454e-9761-9137ca511101.pdf"
}
```

One example per state: `sample-output.json`. Every run also writes a summary (window, per-state counts, failed states, source update cadence) to the `OUTPUT` record. Export as JSON, CSV, Excel or via the API.

### Field notes

- `noticeDate`: date on the notice (CA, CO, TX, VA) or date received by the state (WA, OR). `receivedDate`: processed/received date where published.
- `effectiveDate`: first layoff/closure date; `effectiveEndDate`: end of the layoff period (CO).
- `employeesAffected`: workers affected in that state (CO also gives `totalNotifiedAllStates`).
- `address`: worksite business address (CA only). `locationState`: Oregon lists some employers by headquarters city in another state.
- `industry`: NAICS sector where published (CA, CO). `workforceArea`: TX workforce development area, CO workforce area.
- Fields a state does not publish are `null`. Records are as published by each state; companies sometimes file multiple notices (one per site) or amendments.

### Data sources, update timing and fair use

| State | Official source | Coverage / cadence |
|---|---|---|
| CA | EDD WARN report (.xlsx) | Current program year (from July 1), updated twice a week |
| CO | CDLE "Real-Time WARNs" list (public sheet linked from cdle.colorado.gov) | Current calendar year |
| OR | HECC Rapid Response WARN listings | As received |
| TX | TWC WARN Act listings (.xlsx, current + previous year) | Weekly |
| VA | Virginia Works WARN notices (CSV export) | As received, multi-year history |
| WA | ESD WARN layoff and closure database | As received |

These are public records published by state agencies for public use. This Actor reads only the official public listings, identifies itself with a User-Agent, spaces requests per host and honors robots.txt crawl-delays. Not affiliated with or endorsed by any state agency or the U.S. Department of Labor. Always confirm critical decisions against the official record linked in `sourceUrl` / `noticeUrl`. Not legal advice.

### FAQ

**Which states are next?** More states are planned (e.g. NY, NJ, IL, MD, IN, MI). Tell us in the Issues tab which ones you need.
**Why fewer notices for small states?** Volume follows the economy: California files ~60 notices a month, Colorado a handful.
**Can I get history?** Yes, raise `daysBack` (up to 730) and `maxItems`. Depth depends on each state's published list (see table).

### Pricing

Pay per event (Apify takes care of billing; you only pay for what is delivered):

| Event | Price | Charged |
|---|---|---|
| `apify-actor-start` | $0.005 | once per run |
| `notice-record` | $0.004 | per WARN notice delivered |

A default test run (40 notices) costs about $0.165. A daily all-state `sinceLastRun` alert (~3 new notices/day) costs about $0.017/day. `maxItems` and Apify's *max cost per run* cap your spend; the Actor stops delivering when your budget is reached, so you are never charged for more than you set. No separate platform-usage charges: compute is included in the event prices.

# Actor input Schema

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

Which states' official WARN lists to include. Default: all supported states.

## `daysBack` (type: `integer`):

Only notices dated in the last N days (notice date, or received date when a state publishes no notice date).

## `companyKeyword` (type: `string`):

Optional. Only notices whose company name contains this text (case-insensitive), e.g. 'Amazon', 'hospital', 'Inc'.

## `locationKeyword` (type: `string`):

Optional. Only notices whose city, county, location or workforce area contains this text, e.g. 'Seattle', 'Harris', 'Los Angeles'.

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

Only notices affecting at least this many workers. 0 = no minimum (notices without a count are then included too).

## `includeAmendments` (type: `boolean`):

Uncheck to skip notices flagged as amendments or updates (isAmendment = true).

## `maxItems` (type: `integer`):

Hard cap on delivered notices (also caps your spend). Newest first, mixed across states.

## `mode` (type: `string`):

window (default): every matching notice in the window, no saved state. sinceLastRun: only notices not delivered before for this State key (saved in a named key-value store); use this for daily schedules and alerts.

## `stateKey` (type: `string`):

Name of the saved history for sinceLastRun mode. Use one key per schedule.

## Actor input object example

```json
{
  "states": [
    "CA",
    "CO",
    "OR",
    "TX",
    "VA",
    "WA"
  ],
  "daysBack": 30,
  "minEmployees": 0,
  "includeAmendments": true,
  "maxItems": 40,
  "mode": "window",
  "stateKey": "default"
}
```

# Actor output Schema

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

One normalized record per WARN notice.

## `summary` (type: `string`):

Window, per-state counts, failed states.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("moment-data/warn-layoff-notices-feed").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("moment-data/warn-layoff-notices-feed").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 '{}' |
apify call moment-data/warn-layoff-notices-feed --silent --output-dataset

```

## MCP server setup

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

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/wt4X4M6fi2Osv5dgM/builds/hKTVPzF0kj9gv2dHY/openapi.json
