# PBGC Trusteed Pension Plan Monitor — Failed DB Plan Tracker (`malonestar/pbgc-pension-failure-monitor`) Actor

PBGC trusteed pension plan tracker: every defined-benefit plan taken over by PBGC, with sponsor, state, trusteeship date, participants and case number. Delta mode surfaces newly failed plans each run — a hard corporate-distress signal for credit, vendor-risk and distressed-debt teams.

- **URL**: https://apify.com/malonestar/pbgc-pension-failure-monitor.md
- **Developed by:** [Kyle Maloney](https://apify.com/malonestar) (community)
- **Categories:** Lead generation, Developer tools, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.85 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## PBGC Trusteed Pension Plan Monitor — Failed DB Plan Tracker

Tracks every defined-benefit (DB) pension plan the **Pension Benefit Guaranty
Corporation (PBGC)** has taken over — "trusteed" — because the sponsoring
employer could no longer fund it. A PBGC trusteeship is a hard, publicly
documented corporate-distress event: it usually accompanies or precedes
bankruptcy, liquidation, or a major restructuring, and it names the sponsor
company directly. This actor turns PBGC's open trusteed-plans file into a
clean, filterable, delta-trackable dataset — **5,176 trusteed plans covering
1975 to 2026** as of the 2026-07-01 file vintage.

### Who this is for

- **Credit / vendor-risk analysts** screening counterparties for early distress signals.
- **Distressed-debt and special-situations funds** hunting for newly-trusteed sponsors before the news cycle catches up.
- **ERISA counsel and benefits consultants** tracking trusteeship trends by state, sponsor, or plan size.
- **M\&A / diligence teams** checking whether a target or its affiliates has ever had a plan trusteed.
- **Journalists and researchers** covering pension-fund failures and corporate bankruptcies.

### What it does

1. **Resolves the current PBGC trusteed-plans data file.** PBGC republishes this
   list as an XLSX (sometimes CSV) whose exact filename drifts over time, so the
   actor tries several open-data page scrapes and then four known-filename
   fallback constants. The step that actually worked is reported on every row in
   `source_resolution_method`, and the file's HTTP `Last-Modified` — its data
   vintage — in `source_file_last_modified`.
2. **Verifies the payload is the file it asked for.** An HTML error page served
   at HTTP 200 is rejected rather than parsed into an empty answer.
3. **Resolves every column by name**, spelling-insensitively (handles
   "Plan Name" vs `plan_name`, "Sponsor Name" vs "Employer", "Date of PBGC
   Trusteeship" vs "DOT", and PBGC's own long-standing "Paricipants" typo),
   converting Excel serial dates.
4. **Runs a live drift gate before emitting a single billable row** — row-count
   floor, per-column population floors, oldest/newest date bands, case-number
   uniqueness, a positive canary (PBGC case 20357000, the US Airways IAM plan,
   must still read 11,410 participants trusteed 2005-02-01) and a negative
   control. If PBGC renames a column, truncates the file, or changes its date
   convention, the run **fails loudly and bills nothing** instead of publishing a
   confident wrong answer.
5. **Filters** by since-date, state, sponsor-name substring and minimum
   participant count. An unparseable `sinceDate` fails the run rather than
   silently returning a wrong subset.
6. **Computes a real cross-run delta.** Every row carries
   `is_new_since_last_run` against a baseline held in the **named** key-value
   store `pbgc-trusteed-baseline`, so it works across scheduled runs. The
   baseline covers the whole PBGC universe, not just the rows your filters
   matched, so changing a filter never fabricates "new" trusteeships. When there
   is no baseline to compare against, `is_new_since_last_run` is **null (not
   checked)** — never `true`.

### Example input

```json
{
  "sinceDate": "2023-01-01",
  "states": ["PA", "OH", "TX"],
  "sponsorQuery": "",
  "minParticipants": 100,
  "maxResults": 500,
  "deltaOnly": false
}
```

Search the **full history** for a sponsor by leaving `sinceDate` out entirely:

```json
{ "sponsorQuery": "airways", "maxResults": 100 }
```

### Output fields

Every field the actor declares, and what it means. `null` always means **not
published / not checked** — it is never a substitute for a real `0` or `false`.

| Field | Description |
|---|---|
| `plan_name` | Name of the trusteed DB pension plan |
| `sponsor` | Employer/sponsor company that maintained the plan — the distress-signal target |
| `city` | Sponsor city as published by PBGC |
| `state` | Sponsor state as published by PBGC (mostly 2-letter codes; PBGC also publishes a handful of non-US values) |
| `trusteeship_date` | Date PBGC formally became trustee (YYYY-MM-DD) |
| `participants` | Participant count as published by PBGC. Null on the 10 rows PBGC publishes no count for; one plan has a genuine published `0`, and the two are distinguishable |
| `participants_measured_at` | `"plan_termination"` when a count is published, else null. PBGC measures participants at plan **termination**, not at trusteeship |
| `ein` | Sponsor Employer Identification Number, zero-padded to the full 9 digits (PBGC publishes it as a number, so leading zeros are lost in the source file) |
| `ein_formatted` | The same EIN in IRS display form `NN-NNNNNNN` |
| `plan_number` | ERISA plan number identifying which of the sponsor's plans this is |
| `ein_plan_key` | Canonical `EIN-PPP` join key for Form 5500 / EFAST2 / DOL filings, e.g. `530218143-002`. Null when either part is missing |
| `plan_termination_date` | Date the plan formally terminated (YYYY-MM-DD) — a distinct, usually earlier event than trusteeship |
| `days_termination_to_trusteeship` | Whole days from termination to trusteeship. Median 447 across the live file; **can be negative** (22 rows are trusteed before the recorded termination date) |
| `case_number` | PBGC case identifier — the plan's stable identity for delta tracking |
| `is_new_since_last_run` | `true` = absent from your stored baseline; `false` = present in it; **`null` = not checked** (first run, or the baseline could not be read) |
| `delta_baseline_status` | `ok` / `initialized` / `unavailable` — how the delta comparison went |
| `source_url` | The resolved PBGC data file used this run |
| `source_resolution_method` | Which resolution step produced it: `page_scrape:<url>` or `fallback_constant` |
| `source_file_last_modified` | HTTP `Last-Modified` of the PBGC file — the data vintage |
| `source_row_count` | Total trusteed plans in the file before any filter (the universe behind a filtered answer) |
| `filter_since_date` | The normalized since-date actually applied, or null when no date filter was applied |
| `matched_rows_total` | How many rows matched your filters in total, before `maxResults` capping |
| `results_truncated` | True when more rows matched than `maxResults` allowed |
| `monitored_at` | UTC timestamp of this run |

### Use as an MCP tool

This actor is Pay-Per-Event priced and discoverable via `mcp.apify.com` —
Claude, Cursor, and other MCP-aware agents can call it directly as a tool to
screen a sponsor name or state for pension-failure history without any setup.
Billing is unchanged when called as a tool, and a run that cannot answer fails
without billing.

Ask an agent: *"Has PBGC ever taken over a pension plan for a company with
'airways' in its name? Give me the sponsor, plan, trusteeship date and
participant count."* — the agent should call this actor with
`{"sponsorQuery": "airways"}` and no `sinceDate`, which searches the full
1975-2026 history.

### Pricing

Pay-per-result: you are billed only for dataset rows returned. A run that fails
a gate — unresolvable source file, HTML instead of data, a renamed PBGC column,
a drifted source, or an unparseable `sinceDate` — emits nothing and bills
nothing.

### FAQ

**Which pension plans did PBGC take over?**
Every result row is a plan PBGC has trusteed — this actor is the searchable,
filterable, delta-aware version of PBGC's own trusteed-plans list.

**How do I search the whole history instead of recent years?**
Leave `sinceDate` blank or omit it entirely — that applies no date filter and
searches back to 1975. The Console form pre-fills `2023-01-01` as a convenient
starting point; clear it for a full-history sponsor lookup.

**What date formats does `sinceDate` accept?**
`YYYY-MM-DD`, `YYYY-MM`, `YYYY` and `MM/DD/YYYY`. Anything else fails the run
with an explanatory message rather than silently returning a wrong subset.

**Is there a company pension failure signal I can monitor automatically?**
Yes — set `deltaOnly: true` and schedule this actor daily or weekly. The first
scheduled run stores a baseline and stops with a message (there is nothing to
compare against yet); every run after that returns only genuinely new
trusteeships.

**Why did my first `deltaOnly` run fail?**
Because "new since your last run" has no answer before there is a last run.
Rather than bill you for the entire list labelled "new", the actor stores the
baseline and tells you to re-run.

**What does "trusteed" mean?**
PBGC trusteeship means the plan's sponsor could not or did not continue to
fund it, and PBGC has taken over paying (guaranteed, capped) benefits to
participants. It is one of the most concrete, dated, named corporate-distress
signals available in open federal data.

**Can I join this to Form 5500 filings?**
Yes — use `ein_plan_key` (`EIN-PPP`), or `ein` plus `plan_number`. The EIN is
zero-padded back to 9 digits, which a raw read of the PBGC file does not give
you.

### Related actors

- **FDIC Structure Change Delta Monitor** — bank charter M\&A and failure events.
- **DOL Enforcement Rollup** — wage-and-hour enforcement against the same employers.
- **WARN Layoff Aggregator** — state WARN mass-layoff notices, an earlier distress signal.

### Notes

- Source: PBGC (pbgc.gov) open-data trusteed-plans file. Keyless, no API key required.
- This is a screening tool, not a determination. Verify any finding against
  PBGC's own record before acting on it.
- Column names in the published file vary over time; header resolution is
  spelling/format-insensitive across known variants, and a required column that
  cannot be matched **fails the run** listing the columns PBGC actually
  published.
- If PBGC renames or relocates the data file beyond the built-in fallback
  candidates, the actor **fails loudly with an explanatory message and bills
  nothing**. (Version 1.0 exited with zero results here, which was
  indistinguishable from "PBGC has trusteed no plans".)

# Actor input Schema

## `sinceDate` (type: `string`):

Only include plans trusteed on or after this date. Accepts YYYY-MM-DD, YYYY-MM, YYYY or MM/DD/YYYY. Leave blank (or omit the field) to search the full trusteed-plans history back to 1975 — omitting it applies NO date filter. An unparseable value fails the run loudly rather than silently returning a wrong subset.

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

Optional list of US states (2-letter code or full name) to filter plan sponsors by. Leave empty for all states.

## `sponsorQuery` (type: `string`):

Optional case-insensitive substring match against the plan sponsor/employer name (e.g. "Steel" or "Airlines").

## `minParticipants` (type: `integer`):

Optional minimum plan-participant count. Plans with an unknown/missing participant count are excluded when this is set.

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

Maximum number of trusteed-plan rows to return in this run.

## `deltaOnly` (type: `boolean`):

When true, only emit plans that appeared in the PBGC file since your last run (tracked in the named key-value store 'pbgc-trusteed-baseline', so it works across scheduled runs). The FIRST run has no baseline to compare against: it stores one and fails with an explanatory message rather than billing you for the whole list labelled 'new'. When false (default), emit every plan matching the filters, each flagged with is\_new\_since\_last\_run.

## Actor input object example

```json
{
  "sinceDate": "2023-01-01",
  "states": [],
  "maxResults": 500,
  "deltaOnly": false
}
```

# Actor output Schema

## `results` (type: `string`):

The default dataset.

# 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 = {
    "sinceDate": "2023-01-01",
    "maxResults": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("malonestar/pbgc-pension-failure-monitor").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 = {
    "sinceDate": "2023-01-01",
    "maxResults": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("malonestar/pbgc-pension-failure-monitor").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 '{
  "sinceDate": "2023-01-01",
  "maxResults": 500
}' |
apify call malonestar/pbgc-pension-failure-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,malonestar/pbgc-pension-failure-monitor"
        }
    }
}

```

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/l7Ykz51T49bylXKo6/builds/a2vhyowA3Vmsk1R8D/openapi.json
