# WA Certified Public Accountant Register (`j0401/wa-cpa-licenses`) Actor

Washington credentialed CPAs (public open data, 51k records, daily): name, the board's own status vocabulary - active/lapsed/retired/deceased + ~184 under board order - with issue/expiry dates and city/state/country. Filter by name/state/status or pull the active list.

- **URL**: https://apify.com/j0401/wa-cpa-licenses.md
- **Developed by:** [Wenhao Yang](https://apify.com/j0401) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.10 / 1,000 wa cpa credential 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?

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

## WA Certified Public Accountant Register - Every CPA the Board Has Credentialed

The Washington State Board of Accountancy publishes its **register of credentialed CPAs** - every individual the board has ever licensed, active and historical, refreshed daily - as open data. This actor turns that register into a **charged-per-record lookup and filter tool**: find a CPA by name or credential number, pull the **currently licensed** list, or see the board's status vocabulary at a glance.

**Built for:** background screening and hire diligence (is this CPA currently licensed? lapsed? retired? under a board order?), CPA firm / staffing verification, and compliance checks on out-of-state or international CPAs credentialed to do Washington work.

### What it covers

**51,435 credentialed individuals** - one row per person (credential number is unique), covering the board's **full status vocabulary**:

| Status (the board's own words) | People |
|---|---|
| **Licensed to practice public accounting** | 26,108 |
| Lapsed Licensee | 12,271 |
| Retired Licensee | 5,077 |
| Lapsed Certificateholder | 4,564 |
| Retired Certificate holder | 1,926 |
| Holds a CPA License in an Inactive status | 911 |
| **Suspended per Board Order** | 154 |
| **Licensed to practice Revoked per Board Order** | 30 |
| Lapsed Registration / ConvertedToCPA / Deceased / non-CPA firm owner | ~400 |

The **~184 people currently under a board order** (suspended 154 + revoked 30) are the headline screening signal, and it's read straight off the status word the board assigns - no parsing documents, no guessing.

Each record carries:

- **name** (first / middle / last / suffix) and the unique **credential number**
- **original-issue and expiration dates** - the register is current to this week (newest credentials issue daily), and the expiration cliff is aggregable by year
- the holder's **city, state and country** as the board reports them

### One honest caveat

This is the board's **credential register, not a Washington practice directory**. The holder's reported state is WA on about half of the currently-licensed rows - the board credentials CPAs living and working elsewhere (Japan is the second-largest country in the file after the United States), so holding a Washington credential does **not** mean the person is located in Washington. If you need "CPAs physically in Seattle," filter by state + city; if you need "everyone the board currently considers licensed," that's the `active` mode.

### Typical questions

- "Is this person a **currently licensed** Washington CPA, or lapsed / retired?"
- "Who is currently **under a board order** - suspended or revoked?"
- "Every active CPA reporting a **Seattle** / **Spokane** address."
- "How many active credentials are **expiring in the next renewal year**?"
- "Look up credential **#60831**."
- "Aggregate the register by **status** or **country**."

### Inputs

| Input | What it does |
|---|---|
| `mode` | `active` (default, currently licensed) / `rows` / `aggregate` |
| `name` / `credentialNumber` | find a person |
| `status` | source value or a short word: active / licensed / suspended / revoked / retired / deceased... |
| `city` / `state` / `country` | where the holder reports living |
| `originalIssueFrom/To` / `expiresFrom/To` | date-range filters |
| `activeOnly` | only currently licensed (the active mode does this automatically) |
| `groupBy` | aggregate over status / state / country / city / expiration year |
| `maxResults` | cap records (default 200) |

**Default run = the 200 most recently issued, currently-licensed CPAs** - fast for the daily auto-test. For a targeted query add a filter; for a broad view use `aggregate` (a handful of summary rows, not a 51k-row dump).

### Low cost

**From $0.0001 per record** - billed only for the rows you use, at the platform floor. Cost scales with what you pull, not with the size of the register - and because each record is metered individually there's no per-run charge cap to hit on a big pull.

Washington's register is a "just download the CSV" dataset that hides real traps: **the status column is one long human phrase per person** ("Licensed to practice public accounting" vs "A non-CPA who is registered as an owner in a Washington CPA firm; may not use the title CPA"), so a naive substring search for "revoked" misses half the discipline rows and drags in lapsed/retired look-alikes; **the discipline signal lives in the status word**, not in the near-empty board-order column; and the **credential is not a Washington-residency claim** - half the licensed holders live out of state or abroad, which a casual read of "WA CPAs" gets wrong. Normalizing that into a register where an `active` / `suspended` / `state=WA` query returns exactly the people you mean is the actual product. Every pull is integrity-checked against the feed's known shape, so a degraded source fails loudly instead of returning bad rows.

### Source

- [Washington State Board of Accountancy: Certified Public Accountants](https://data.wa.gov/accountability-oversight/Certified-Public-Accountants/6du3-3h9e) - the board's credential register. Reflects the board's record as of each pull; not an endorsement of any individual.

# Actor input Schema

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

active = currently licensed CPAs (default). rows = credentialed individuals matching your filters (blank filters = the whole register). aggregate = one count row per group (see groupBy).

## `name` (type: `string`):

Last or first name (fuzzy), e.g. 'SMITH' or 'Katherine'.

## `credentialNumber` (type: `string`):

The board's credential number (unique per person), e.g. '60831'. Exact.

## `status` (type: `string`):

Status as the board words it. Use a source value: Licensed to practice public accounting, Lapsed Licensee, Retired Licensee, Suspended per Board Order, Deceased, ... or a short word (active / licensed / suspended / revoked / retired / deceased). Blank = any.

## `city` (type: `string`):

Holder's reported city (fuzzy), e.g. 'Seattle' or 'Spokane'. Note: holders live out of state / abroad too.

## `state` (type: `string`):

Holder's reported US state abbreviation (exact), e.g. WA, CA, OR. Roughly half of active holders report WA.

## `country` (type: `string`):

Holder's reported country (fuzzy). The board credentials CPAs abroad — Japan is the second-largest country in the file.

## `originalIssueFrom` (type: `string`):

Only credentials originally issued on/after this date (YYYY-MM-DD).

## `originalIssueTo` (type: `string`):

Only credentials originally issued before this date.

## `expiresFrom` (type: `string`):

Only credentials that expire on/after this date.

## `expiresTo` (type: `string`):

Only credentials that expire before this date.

## `activeOnly` (type: `boolean`):

When on, returns only individuals whose status is 'Licensed to practice public accounting'. The active mode does this automatically.

## `groupBy` (type: `string`):

Which dimension to aggregate over. status -> the live vs lapsed/retired/discipline mix; state / country -> where holders report living; expirationYear -> the renewal cliff.

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

Cap the number of records pushed (0 = up to ~10k per run). An aggregate has at most a few hundred groups.

## Actor input object example

```json
{
  "mode": "active",
  "name": "",
  "credentialNumber": "",
  "status": "",
  "city": "",
  "state": "",
  "country": "",
  "originalIssueFrom": "",
  "originalIssueTo": "",
  "expiresFrom": "",
  "expiresTo": "",
  "activeOnly": false,
  "groupBy": "status",
  "maxResults": 50
}
```

# Actor output Schema

## `recordsUrl` (type: `string`):

Washington CPA credential records or aggregates - as JSON

## `datasetUrl` (type: `string`):

No description

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

// Run the Actor and wait for it to finish
const run = await client.actor("j0401/wa-cpa-licenses").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("j0401/wa-cpa-licenses").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 j0401/wa-cpa-licenses --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,j0401/wa-cpa-licenses"
        }
    }
}
```

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/ar4zRQ6rkcdDlJNBh/builds/cMf87KkKlkI6QNGLJ/openapi.json
