# WA Lobbying & PDC Enforcement - Who Pays to Lobby (`j0401/wa-lobbying`) Actor

Washington lobbying money (332k filings, current to this month): who pays whom to lobby Olympia. Search by client, lobbyist, year, min compensation; aggregate top client spenders or top lobbying firms. Plus PDC campaign-finance/lobbying enforcement cases with penalties, status and amounts.

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

## Pricing

$3.00 / 1,000 wa lobbying / enforcement 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 Lobbying & PDC Enforcement (`wa-lobbying`)

Pull **Washington's lobbying money** - **~332,000 filings, current to this month** (from the state's free public open data) - showing **who pays whom to lobby** the legislature, with compensation amounts per filing period. Plus **PDC enforcement cases** (campaign-finance / lobbying violations) with penalties.

This is the **money-flow layer of WA politics that no one else packages**: every retainer a law firm or government-affairs shop collects to lobby Olympia, attributed to the client that paid it.

Built for **government-relations teams, associations, law firms, PR agencies, lobbyists, journalists and market-intelligence users** who need the B2G angle on WA - "who's spending what to shape state policy".

### Two modes

#### `lobbying` (default) - Lobbyist Compensation

Each record is **one client paying a lobbyist/firm** for one filing period:

| Field | Meaning |
|---|---|
| `lobbyistName` | The lobbyist or lobbying firm |
| `clientName` | The organization paying (funding source / employer) |
| `period` / `year` | Filing period (monthly) and year |
| `type` | `Employer` = client-attributable row (default); `Lobbyist` = self summary |
| `compensation` / `netCompensation` | What the client paid the lobbyist that period |
| `netTotal` | Compensation + expenses for the period |
| `sourceUrl` | Link to the PDC filing |

#### `enforcement` - PDC cases

Each record is one **Public Disclosure Commission case** (alleged campaign-finance or lobbying violation):

| Field | Meaning |
|---|---|
| `case` / `opened` | Case number and opened date |
| `respondent` | The person/organization under review |
| `subject` | The alleged violation (statute cited) |
| `status` | e.g. `Assessment of Facts`, `Violation Found by Commission`, `Closed` |
| `totalPenalties` / `totalPaid` / `balanceDue` | Money outcomes |

### Typical questions it answers

- **Who spends the most lobbying Olympia?** Aggregate by `client` -> Puget Sound Energy, Amazon, Boeing, Microsoft, associations (year to date, all years).
- **What does a given company pay for lobbying?** Filter `clientName=Boeing` -> every firm it retains and the monthly amounts.
- **Which lobbying firm earns the most?** Aggregate by `lobbyist` -> Gordon Thomas Honeywell, Insight Strategic, McBride...
- **A retainer-scale search** - `clientName=Microsoft` + `minCompensation=10000`.
- **Who's been cited for campaign violations?** `mode=enforcement` + `status=Violation Found`, or `status=Assessment of Facts` for cases in review.

### Aggregate mode (lobbying only)

Turn on **`aggregate`** and it rolls up **compensation** over the **whole 332k-row corpus instantly**:

| Output field | Meaning |
|---|---|
| `key` | The client or lobbyist |
| `compensation` | Total compensation paid (all matched filings) |
| `filings` | Number of filings in that group |

Group by `client` (top spenders) or `lobbyist` (top earners). Aggregation runs on **Employer** records only, so a client's compensation is never double-counted against the lobbyist's self row.

### Inputs (all optional)

| Input | Mode | What it does |
|---|---|---|
| `clientName` | lobbying | Organization paying for lobbying - substring ("Boeing", "Microsoft", "Puget Sound Energy") |
| `lobbyistName` | lobbying | Lobbyist or firm - substring ("Gordon Thomas Honeywell", "McBride") |
| `lobbyistType` | lobbying | `Employer` (client-attributable, default) / `Lobbyist` / `both` |
| `aggregate` + `groupBy` | lobbying | Roll up by `client` / `lobbyist` -> total compensation + filings |
| `respondent` | enforcement | Person/organization cited |
| `subject` | enforcement | Text of the alleged violation |
| `status` | enforcement | Case status keyword ("Violation Found", "Closed") |
| `yearFrom` / `yearTo` | both | Filing-period / opened-date year range |
| `minCompensation` | lobbying | Only filings at or above this compensation |
| `minPenalty` | enforcement | Only cases with penalties at least this amount |
| `maxResults` | both | Cap records (default 200) |

### Low cost

**$0.003 per record** - with a per-run charge cap so even a broad query can't surprise-bill.

This couples Washington's **lobbying-disclosure corpus** (~332k filings) with the **PDC enforcement docket** (campaign-finance & lobbying penalties) behind one query surface. The money data is trickier than it reads: a single lobbying payment can be reported **twice** - once by the employer paying and once by the lobbyist self-reporting - so spend aggregates are pinned to the employer-side filings to keep a dollar from being counted two times. Client names are as-messy-as-you'd-expect in the source (`1-800 CONTACTS (Bill Clarke)`), so matching spans both the funding-source and employer fields. You query one money-flow surface - filings and penalties - where a client's spend is never double-counted; the dedup and messy-name matching stay on our side. An unfiltered run returns the newest month's filings.

### Data source & freshness

- **Sources**: [data.wa.gov](https://data.wa.gov/) - **Lobbyist Compensation by Source** (`9nnw-c693`, 332k rows) and **PDC Enforcement** (`a4ma-dq6s`, 8k rows), via the Socrata SODA API (free public, no login).
- **Update cadence**: lobbying filings are **monthly** (data runs through the latest filing month); enforcement cases open continuously.
- **Coverage**: registered lobbyist compensation in WA from 2016 to present, and PDC campaign-finance/lobbying enforcement actions.

# Actor input Schema

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

lobbying = Lobbyist Compensation filings (client pays lobbyist, with amounts). enforcement = PDC campaign-finance / lobbying violation cases (respondent, penalties). The fields below apply per mode.

## `clientName` (type: `string`):

Lobbying mode. Return filings where this organization is the client paying for lobbying (substring, case-insensitive). E.g. "Boeing", "Microsoft", "Puget Sound Energy", "Assn of WA Business".

## `lobbyistName` (type: `string`):

Lobbying mode. Return filings by this lobbyist or lobbying firm (substring). E.g. "Gordon Thomas Honeywell", "Insight Strategic", "McBride".

## `lobbyistType` (type: `string`):

Employer = one row per client paying a lobbyist (has client name + compensation) - the recommended view. Lobbyist = the lobbyist's self summary rows. both = every row.

## `aggregate` (type: `boolean`):

Lobbying mode. When on, returns one summary row per group (see groupBy) with total compensation and filing count - instead of individual records. Only meaningful for Employer records.

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

Lobbying mode (when aggregate is on). client = which organizations spend the most on lobbying; lobbyist = which firms/individuals earn the most from lobbying.

## `respondent` (type: `string`):

Enforcement mode. Return cases where this person/organization is the respondent (substring).

## `subject` (type: `string`):

Enforcement mode. Return cases whose subject (alleged violation) contains this text (substring). E.g. "late contribution report", "campaign finance registration".

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

Enforcement mode. Return cases whose status contains this text (substring). E.g. "Violation Found", "Assessment of Facts", "Closed". Use "Open" / "closed" style keywords; exact statuses are long phrases.

## `yearFrom` (type: `string`):

Lobbying: first filing period year (>=). Enforcement: first opened year (>=). E.g. "2024".

## `yearTo` (type: `string`):

Lobbying: last filing period year (<=). Enforcement: last opened year (<=).

## `minCompensation` (type: `number`):

Lobbying mode. Only return records where the compensation is at least this amount. E.g. 10000 for retainer-scale lobbying.

## `minPenalty` (type: `number`):

Enforcement mode. Only return cases with total penalties at least this amount.

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

Cap the number of records pushed (0 = up to ~10k per run; each record is metered individually, so there is no per-run charge cap). An aggregate has at most a few thousand groups.

## Actor input object example

```json
{
  "mode": "lobbying",
  "lobbyistType": "Employer",
  "aggregate": false,
  "groupBy": "client",
  "minCompensation": 0,
  "minPenalty": 0,
  "maxResults": 200
}
```

# Actor output Schema

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

Washington lobbying compensation records, aggregates, or PDC enforcement cases - 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-lobbying").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-lobbying").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-lobbying --silent --output-dataset

```

## MCP server setup

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

```

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/gXlsZqCHFcCOp5t9z/builds/b9mDaak5Ym6QXnpAL/openapi.json
