# PCAOB Registered Audit Firm Portfolio Status Monitor (`plym-actor-factory/us-pcaob-registered-firm-id-portfolio-status-monitor`) Actor

Watch named PCAOB-registered audit firms by Firm ID; get an event when registration becomes Withdrawal Pending, Withdrawn, Revoked or Disapproved, or the firm name changes, from the official PCAOB daily firm file. Pay per delivered change - not a firm-list dump.

- **URL**: https://apify.com/plym-actor-factory/us-pcaob-registered-firm-id-portfolio-status-monitor.md
- **Developed by:** [Daniel Witney](https://apify.com/plym-actor-factory) (community)
- **Categories:** Business, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 pcaob firm status event delivereds

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

## PCAOB Registered Audit Firm Portfolio Status Monitor

Watch named **PCAOB-registered public accounting firms (by PCAOB Firm ID)** against the official **PCAOB firm data file (FirmData.txt)**, which the PCAOB refreshes overnight. Get one event when a firm on your list moves to **Withdrawal Pending, Registration Withdrawn, Registration Revoked or Registration Disapproved**, or changes its name.

**Quick start:** replace the example `firmIds` with your firms' PCAOB IDs, set `sourceMode` = **live**, then save as a Task and schedule it daily or weekly. No API key needed.

**Who this is for:**

- **Broker-dealer finance and compliance teams** (SEC Rule 17a-5 annual reports must be audited by a PCAOB-registered firm)
- **Investment advisers and fund administrators** (custody-rule pooled-fund audits must use a PCAOB-registered and inspected accountant)
- **SEC issuers, SPAC sponsors and audit committees** whose auditor or component auditors must stay registered
- **Lenders, D\&O insurers, investors and KYB teams** that rely on audited financials from smaller or offshore firms

The recurring job: **tell me as soon as the PCAOB file shows that an audit firm we rely on is withdrawing, withdrawn, revoked or renamed**, for example after a merger, so the engagement can be replaced before a filing deadline.

Billable events (PPE `pcaob-firm-status-event-delivered` @ $0.02):

| Group | Event | Meaning |
|-------|-------|---------|
| `status` | `STATUS_CHANGED` | Currently Registered ↔ Withdrawal Pending / Registration Withdrawn / Registration Revoked / Registration Disapproved (`adverse=true` for the last four) |
| `name` | `NAME_CHANGED` | Firm name changed in the PCAOB file (often a merger or rebrand) |
| `directory` | `APPEARED` / `DROPPED` | Firm ID appeared in, or disappeared from, the PCAOB file |
| `location` (opt-in) | `LOCATION_CHANGED` | City / state / country changed |

Non-billable: `RUN_STATUS` (`FIXTURE_HEALTH`, `MONITOR_IDLE`, `CATCHUP_COMPLETE`, `HEALTH_OK`), first-run baselines and duplicates. A quiet watchlist costs only the platform start fee.

This is **not** a dump of the firm list billed per row. It does **not** cover Form AP engagement partners or inspection reports.

### First run vs later runs

Default `sourceMode=fixture` is a **free health check**: one non-billable `RUN_STATUS` row, not product data.

In live mode, **run 1** stores a baseline for each firm (no change events, no product charge). **Run 2 onwards** emits only the differences against that checkpoint. Keep using the same Task so the checkpoint carries over.

### What you get per $0.02 event

Each event is one unique change for a named firm. It includes the firm name, PCAOB status, an `adverse` flag, before and after values, city and country, the file date (`as_of`) and the official source URL. You are never charged for `RUN_STATUS`, baselines, quiet `MONITOR_IDLE` runs, invalid IDs, duplicates or fixture SAMPLE rows.

### Example output (SAMPLE)

SAMPLE: illustrative field shape only, not a real event.

```json
{
  "firm_id": "SAMPLE01",
  "firm_name": "EXAMPLE AUDIT FIRM A LLP (SAMPLE)",
  "event_type": "STATUS_CHANGED",
  "event_subtype": "REGISTRATION_REVOKED",
  "previous_value": "Currently Registered",
  "new_value": "Registration Revoked",
  "adverse": true,
  "as_of": "2026-10-06",
  "billable": false,
  "sample": true,
  "summary": "SAMPLE (fixture demo data with placeholder entities, not a real event)"
}
```

### Input

- `firmIds`: PCAOB Firm IDs, for example `34` or `00034` (leading zeros optional). Aliases: `pcaobFirmIds`, `firmNumbers`.
- `sourceMode`: `fixture` (free health check) or `live` (official PCAOB file)
- `signalGroups`: any of `directory`, `status`, `name`, `location` (default: directory + status + name)

### Production use

```json
{
  "firmIds": ["00034", "00042", "00185", "00688"],
  "sourceMode": "live",
  "signalGroups": ["directory", "status", "name"]
}
```

### Source and honesty notes

- Official file: `https://assets.pcaobus.org/firm-filings/FirmData.txt` (linked from `pcaobus.org/assets/PCAOBFiles/FirmData.txt`). The PCAOB publishes it for Form AP XML preparation and refreshes it overnight. One small download (~0.3 MB) per run.
- Durable key: the 5-digit PCAOB Firm ID. On 2026-10-06 the file held 4,099 firm IDs: about 1,385 Currently Registered, 20 Withdrawal Pending, 2,491 Registration Withdrawn, 145 Registration Revoked and 58 Registration Disapproved.
- Cadence: changes appear when the PCAOB refreshes the file overnight, not in real time. `as_of` is the file's Last-Modified date.
- Attribution: Source: Public Company Accounting Oversight Board (PCAOB) public firm data file. This Actor is not affiliated with or endorsed by the PCAOB.

### Pricing

| Event | USD |
|-------|-----|
| `pcaob-firm-status-event-delivered` | $0.02 |
| `apify-actor-start` | $0.00005 |

### Limitations

- Check the official PCAOB registered-firms page and the firm's PCAOB filings before relying on a status for an engagement or a regulatory filing.
- Withdrawn and revoked firms normally stay in the file with their status. `DROPPED` fires only if an ID disappears from the file entirely.
- Covers registration status, name and location only. It does not include inspection findings, Form AP engagements or enforcement order text.

# Actor input Schema

## `firmIds` (type: `array`):

PCAOB Firm IDs to watch (the numeric ID shown on pcaobus.org / AuditorSearch, e.g. 34 or 00034; leading zeros optional). Examples are Deloitte & Touche LLP (00034), Ernst & Young LLP (00042), KPMG LLP (00185) and Marcum LLP (00688).

## `pcaobFirmIds` (type: `array`):

Optional alias merged into the watchlist.

## `firmNumbers` (type: `array`):

Optional alias merged into the watchlist.

## `signalGroups` (type: `array`):

directory (APPEARED/DROPPED from the PCAOB file), status (STATUS_CHANGED: Currently Registered / Withdrawal Pending / Registration Withdrawn / Registration Revoked / Registration Disapproved), name (NAME_CHANGED), location (LOCATION_CHANGED city/state/country, opt-in). Default: directory+status+name.

## `maxRunSeconds` (type: `integer`):

Wall-clock budget.

## `maxEvents` (type: `integer`):

Stop after this many unique change events are delivered (RUN_STATUS excluded).

## `resumeFromCheckpoint` (type: `boolean`):

If true, resume firm snapshots and seen event_uids from the default Key-Value Store (keep the same Task).

## `sourceMode` (type: `string`):

fixture = free Store/CI health check (no network; one non-billable RUN_STATUS row unless emitFixtureDemoEvents=true). live = official PCAOB firm data file (no API key; refreshed overnight). Fixture demo rows use placeholder entities, are flagged sample=true / isSample=true, billable=false, and are never charged.

## `emitFixtureDemoEvents` (type: `boolean`):

When sourceMode=fixture, emit SAMPLE demo events from local fixtures (placeholder firms, never charged). Default false.

## `maxTotalChargeUsd` (type: `number`):

Optional soft budget hint.

## `asOfHint` (type: `string`):

Optional as_of label (defaults to the PCAOB file Last-Modified date).

## `firmDataUrl` (type: `string`):

Optional override for the official PCAOB FirmData.txt URL.

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

Optional label that pins this monitor's persistent baseline (named key-value store in YOUR Apify account). Leave empty to derive it automatically from the watchlist (and the saved task, if any), so different watchlists/tasks never share state. Set it (e.g. 'client-acme') if you want to edit the watchlist without re-baselining existing entries. The first live run for a new state key only stores the baseline: no change events, no product charge.

## Actor input object example

```json
{
  "firmIds": [
    "00034",
    "00042",
    "00185",
    "00688"
  ],
  "signalGroups": [
    "directory",
    "status",
    "name"
  ],
  "maxRunSeconds": 120,
  "maxEvents": 500,
  "resumeFromCheckpoint": true,
  "sourceMode": "fixture",
  "emitFixtureDemoEvents": false
}
```

# Actor output Schema

## `OUTPUT` (type: `string`):

JSON summary: delivered, charged, runStatus, checkpoint, stats, coverage, attribution

# 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 = {
    "firmIds": [
        "00034",
        "00042",
        "00185",
        "00688"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("plym-actor-factory/us-pcaob-registered-firm-id-portfolio-status-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 = { "firmIds": [
        "00034",
        "00042",
        "00185",
        "00688",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("plym-actor-factory/us-pcaob-registered-firm-id-portfolio-status-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 '{
  "firmIds": [
    "00034",
    "00042",
    "00185",
    "00688"
  ]
}' |
apify call plym-actor-factory/us-pcaob-registered-firm-id-portfolio-status-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,plym-actor-factory/us-pcaob-registered-firm-id-portfolio-status-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/anmeKqh59pyqow9mz/builds/iTbgDdsklywv7sxoS/openapi.json
