# NY Lobbying Search Scraper (`crawlerbros/ny-lobbying-search-scraper`) Actor

Search New York State's official Lobbying Search (reports.ethics.ny.gov) - lobbyist/client relationships, subjects lobbied, parties lobbied, source-of-funding, disbursement-of-public-monies, reportable-business-relationship, and coalition-contribution filings.

- **URL**: https://apify.com/crawlerbros/ny-lobbying-search-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Automation, Agents, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

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

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

## NY Lobbying Search Scraper

Scrape New York State's official **Lobbying Search** application (`reports.ethics.ny.gov`), run by the NYS Commission on Ethics and Lobbying in Government. Search lobbyist/client relationships, subjects and parties lobbied, and every disclosure filing type — source of funding, disbursement of public monies, reportable business relationships, and coalition contributions. No login, no API key, no proxy required.

### What this actor does

- **7 search modes**, matching every tab of the official public search tool:
  - `globalSearch` — lobbyist / client / public corporation / coalition relationships
  - `subjectsLobbied` — filings by subject-matter category (health, tax, energy, ...)
  - `partiesLobbied` — filings by government body lobbied (agencies, legislature, municipalities, ...)
  - `sourceOfFunding` — source-of-funding disclosure statements
  - `disbursementOfPublicMonies` — disbursement-of-public-monies disclosures
  - `reportableBusinessRelationship` — reportable business relationship disclosures
  - `coalitionContribution` — coalition contribution disclosures
- **Rich nested detail** — principal lobbyists, contractual/beneficial clients, and individual lobbyists with profile links, addresses, and entity types
- **Dollar amounts parsed to numbers** — compensation, expenses, and contribution fields are emitted as plain numeric USD values, not currency strings
- **Direct filing links** — every record includes a link to its official filing detail page on the Commission's site
- **Empty fields are always omitted** — every record only contains data that was actually reported

### Output per record

Every record shares this core (present regardless of mode):

- `formSubmissionId`, `filingYear`, `filingType`, `filingPeriod`, `filingConfirmationNumber`, `filingStatus`
- `isPublicCorporation`
- `principalLobbyists[]`, `contractualClients[]`, `beneficialClients[]` — each with `id`, `name`, `filedAsName` (if amended), `entityType`, `address`
- `individualLobbyists[]` — `firstName`/`lastName` or `organizationName`, `role`, `profileUrl`
- `subjectsLobbied[]` — subject-matter categories reported on the filing
- `associatedFilingUrl` — link to the official filing detail page
- `sourceUrl` — canonical record URL (same as `associatedFilingUrl` when available)
- `recordType` — the search mode that produced the record
- `scrapedAt` — UTC timestamp

Mode-specific fields layer on top:

| Mode | Extra fields |
|---|---|
| `subjectsLobbied` | `totalCompensationExpensesUsd`, `totalExpensesUsd` |
| `partiesLobbied` | `activityType`, `communicationType`, `governmentBody`, `partyLobbiedName`, `lobbyingFocus`, `lobbyingFocusNumber` |
| `sourceOfFunding` | `sourceType`, `sourceName`, `dateOfContribution`, `contributionAmountUsd`, `contractualClientName`, `contractualClientAddress`, `sofReportingRequired`, `sofReasonNotRequired`, `sourceOfFundingClients[]` |
| `disbursementOfPublicMonies` | `descriptionsOfActivities[]`, `compensationUsd`, `reimbursedExpensesUsd`, `noExpensesReported` |
| `reportableBusinessRelationship` | `filerName`, `filerId`, `relationshipType`, `relationshipWith`, `statePersonInvolved`, `employedBy`, `paymentMade`, `servicesProvided`, `compensationAmountUsd`, `reimbursedExpenseAmountUsd` |
| `coalitionContribution` | `coalitionName`, `coalitionMember`, `contributionAmountUsd`, `expenseIncurredOnBehalf`, `totalExpenseAmountUsd`, `pooledFundsUsed`, `pooledFundsMemberPortionUsd`, `totalContributionAmountUsd`, `expensePurpose` |

### Input

| Field | Type | Applies to | Description |
|---|---|---|---|
| `mode` | select | all | Search mode (see above) |
| `searchQuery` | string | all | Individual/organization name or address to search for |
| `year` | select | all | Filing year, or `ALL` |
| `filerType` | select | globalSearch | Lobbyist / Client / Public Corporation / Coalition / ALL |
| `levelOfGovernment` | select | globalSearch, disbursementOfPublicMonies | State / Municipal / Both / ALL |
| `filerCategory` | select | subjectsLobbied, partiesLobbied | Lobbyist / Client / Public Corporation / Coalition / ALL |
| `subject` | select | subjectsLobbied | Fine-grained subject-matter category (93 categories sourced live from the site's own taxonomy — e.g. Cannabis/Marijuana, Cryptocurrency, Health – Pharmaceuticals, or ALL) |
| `period` | select | subjectsLobbied, disbursementOfPublicMonies | Bi-monthly filing period, or ALL |
| `filingTypeFilter` | select | subjectsLobbied, partiesLobbied | Registration / Bi-Monthlies / Client Semi-Annuals / ALL |
| `partyType` | select | partiesLobbied | Government body category (18 options, or ALL) |
| `specificAgency` | select | partiesLobbied, partyType=AGCY | Narrow to one specific state agency/authority (110 options, or ALL) — only applied when `partyType` is `AGCY` |
| `communicationType` | select | partiesLobbied | Direct / Grassroots / Direct+Grassroots / Monitoring Only / ALL |
| `sourceType` | select | sourceOfFunding, coalitionContribution | Single / Multiple / Not Required to Report / ALL |
| `relationshipType` | select | reportableBusinessRelationship | Entity / State Person / ALL |
| `employedBy` | select | reportableBusinessRelationship | Assembly / Executive Chamber / Senate / State Agency / ALL |
| `maxItems` | integer | all | Hard cap on emitted records (1–2000) |

#### Example: search Global Search for a company name

```json
{
  "mode": "globalSearch",
  "searchQuery": "Google",
  "year": "ALL",
  "maxItems": 50
}
```

#### Example: browse Health-subject lobbying filings

```json
{
  "mode": "subjectsLobbied",
  "subject": "37",
  "year": "2024",
  "maxItems": 100
}
```

#### Example: filings lobbying a state agency

```json
{
  "mode": "partiesLobbied",
  "partyType": "AGCY",
  "year": "2024",
  "maxItems": 100
}
```

#### Example: coalition contribution disclosures for a year

```json
{
  "mode": "coalitionContribution",
  "year": "2024",
  "maxItems": 100
}
```

### Use cases

- **Investigative journalism** — trace which lobbyists represent which clients, and which state agencies or legislative bodies they target
- **Government transparency / policy research** — analyze lobbying spend by subject matter (health, energy, gaming, ...) over time
- **Compliance & due diligence** — check a company's or law firm's registered lobbying relationships and disclosures
- **Academic research** — bulk-export New York's lobbying disclosure corpus for quantitative analysis
- **Competitive intelligence** — monitor which organizations are actively lobbying on issues relevant to your industry

### FAQ

**Do I need a login or API key?** No. This scrapes the public, no-auth search endpoints that power `reports.ethics.ny.gov/publicquery`.

**Why do some records for the same filing repeat?** A single filing can report multiple distinct facts — e.g. lobbying two different state agencies, or making two separate coalition contributions in the same period. Each is emitted as its own record; `formSubmissionId` links records that share a filing.

**What does `filingYear` like `2025 - 2026` mean?** Lobbyist/client registrations run on a two-year legislative session; the value reflects the session the registration covers. Use the `year` input filter to match either year in the range.

**Are dollar amounts accurate?** They're parsed directly from the Commission's own reported figures — the actor doesn't recompute or estimate.

**How far back does the data go?** The public search covers filings from 2019 onward.

**What if my filter combination returns 0 results?** The actor reports a status message and exits cleanly — try widening `year` to `ALL` or removing other filters.

**Can I filter Parties Lobbied by State vs. Municipal activity level?** No — the Commission's own public search tool exposes a "State/Municipal activity" dropdown, but it's broken on their end: selecting anything other than the default returns zero results, confirmed directly against their live search API independent of this actor. Rather than expose a filter that can never return data, the actor always queries unfiltered on this axis (equivalent to the "ALL" state).

**Can I narrow Parties Lobbied to a specific senator, assembly member, or municipality (county/city/town/village)?** Not currently. The official site's own drill-down selectors for a specific senator/assembly-member/executive-office and for municipal entities (counties, cities, towns, villages, school districts, etc.) either don't reliably filter server-side when queried directly (confirmed by testing — the "specific senator" filter silently returns the unfiltered result set) or cover thousands of unstable entity names (e.g. 900+ towns, 7,000+ special taxing districts) that can't be maintained as a reliable dropdown. The one drill-down that *does* filter reliably — narrowing to a specific **state agency** — is exposed via `specificAgency` (only applies when `partyType` is `AGCY`).

**Why does `coalitionContribution` not have an `associatedFilingUrl` per record?** The upstream Coalition Contribution endpoint doesn't expose a per-row filing-detail link — `sourceUrl` falls back to the main search application URL for this mode only. Every other mode links directly to the filing.

**A very broad `partiesLobbied` query with `partyType: ALL` combined with another filter (like `communicationType`) is slow or returns nothing — why?** Some very broad filter combinations trigger a genuinely slow server-side query on the state's own site (independently confirmed to take 90s+ regardless of how few rows are requested). The actor fails soft with a status message rather than hanging — narrow the query by picking a specific `partyType` (or `subject`, for `subjectsLobbied`) instead of `ALL`.

# Actor input Schema

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

Which NYS Lobbying Search tab to query.

## `searchQuery` (type: `string`):

Individual or organization name (or address) to search for. Leave blank to browse a mode's filters without a name search (all modes).

## `year` (type: `string`):

Restrict results to a filing year (all modes).

## `filerType` (type: `string`):

Restrict Global Search to a specific filer category.

## `levelOfGovernment` (type: `string`):

Restrict to State, Municipal, or Both levels of government.

## `filerCategory` (type: `string`):

Restrict Subjects/Parties Lobbied search to a specific filer category.

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

Fine-grained subject-matter category to search within (mode=subjectsLobbied). Sourced live from the site's own 93-value subject taxonomy.

## `period` (type: `string`):

Restrict to a bi-monthly filing period.

## `filingTypeFilter` (type: `string`):

Restrict to a specific filing type.

## `partyType` (type: `string`):

Government body/entity category to search within (mode=partiesLobbied).

## `specificAgency` (type: `string`):

Narrow Parties Lobbied search to lobbying activity directed at one specific state agency/authority. Only applied when Party lobbied type = State Agency; ignored otherwise.

## `communicationType` (type: `string`):

Restrict to a specific type of lobbying communication.

## `sourceType` (type: `string`):

Restrict to funding sources reported as Single, Multiple, or Not Required to Report.

## `relationshipType` (type: `string`):

Restrict Reportable Business Relationship search to Entity or State Person relationships.

## `employedBy` (type: `string`):

Restrict to state persons employed by a specific government body.

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

Hard cap on emitted records.

## Actor input object example

```json
{
  "mode": "globalSearch",
  "searchQuery": "Google",
  "year": "ALL",
  "filerType": "ALL",
  "levelOfGovernment": "ALL",
  "filerCategory": "ALL",
  "subject": "37",
  "period": "ALL",
  "filingTypeFilter": "ALL",
  "partyType": "ALL",
  "specificAgency": "ALL",
  "communicationType": "ALL",
  "sourceType": "ALL",
  "relationshipType": "ALL",
  "employedBy": "ALL",
  "maxItems": 20
}
```

# Actor output Schema

## `filings` (type: `string`):

Dataset containing all scraped NY lobbying search records.

# 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 = {
    "mode": "globalSearch",
    "searchQuery": "Google",
    "year": "ALL",
    "filerType": "ALL",
    "levelOfGovernment": "ALL",
    "filerCategory": "ALL",
    "subject": "37",
    "period": "ALL",
    "filingTypeFilter": "ALL",
    "partyType": "ALL",
    "specificAgency": "ALL",
    "communicationType": "ALL",
    "sourceType": "ALL",
    "relationshipType": "ALL",
    "employedBy": "ALL",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/ny-lobbying-search-scraper").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 = {
    "mode": "globalSearch",
    "searchQuery": "Google",
    "year": "ALL",
    "filerType": "ALL",
    "levelOfGovernment": "ALL",
    "filerCategory": "ALL",
    "subject": "37",
    "period": "ALL",
    "filingTypeFilter": "ALL",
    "partyType": "ALL",
    "specificAgency": "ALL",
    "communicationType": "ALL",
    "sourceType": "ALL",
    "relationshipType": "ALL",
    "employedBy": "ALL",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/ny-lobbying-search-scraper").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 '{
  "mode": "globalSearch",
  "searchQuery": "Google",
  "year": "ALL",
  "filerType": "ALL",
  "levelOfGovernment": "ALL",
  "filerCategory": "ALL",
  "subject": "37",
  "period": "ALL",
  "filingTypeFilter": "ALL",
  "partyType": "ALL",
  "specificAgency": "ALL",
  "communicationType": "ALL",
  "sourceType": "ALL",
  "relationshipType": "ALL",
  "employedBy": "ALL",
  "maxItems": 20
}' |
apify call crawlerbros/ny-lobbying-search-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/71hITVxEKUMe6YZV8/builds/QS4X5JIUs1KL230hm/openapi.json
