# Nonprofit 990 Scraper — EIN, Financials & Execs (ProPublica) (`haketa/propublica-nonprofit-scraper`) Actor

Scrape US nonprofits from ProPublica Nonprofit Explorer: name, EIN, address, NTEE, 501(c) type, IRS ruling, plus 990 financials (revenue, expenses, assets, liabilities, executive compensation) by year with filing PDFs. Search by name, state or category. For KYC, grants and research.

- **URL**: https://apify.com/haketa/propublica-nonprofit-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Business, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.75 / 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/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

## Nonprofit 990 Scraper — EIN, Financials & Execs (ProPublica)

> **Search and scrape US nonprofits: name, EIN, address, NTEE category, 501(c) type, IRS ruling date — plus 990 financials (revenue, expenses, assets, liabilities, executive compensation) across years, with links to the filing PDFs.** Search by name, state, category or 501(c) type, or look up EINs. Clean JSON/CSV/Excel in seconds. Built for KYC, grant research, due diligence and sector analysis.

[![Nonprofit Explorer](https://img.shields.io/badge/Nonprofit-990%20Filings-0b5394)]()
[![Financials + EIN](https://img.shields.io/badge/EIN%20%2B%20990%20Financials-2da44e)]()
[![KYC / Grants](https://img.shields.io/badge/KYC%20%2F%20Grant%20Research-8250df)]()
[![Export](https://img.shields.io/badge/Export-JSON%20%2F%20CSV%20%2F%20Excel-fb8500)]()

***

### What This Actor Does

Search the US nonprofit universe and get a clean record per organization:

- **Identity** — name, **EIN**, full address, NTEE category, **501(c) subsection** (type), IRS ruling date, profile URL
- **990 financials** — total **revenue, expenses, assets, liabilities** and **executive compensation** from the latest Form 990, plus the IRS BMF revenue/asset/income figures
- **Filing history** — how many years of 990 data are available, which years, and a link to the latest 990 **PDF**

Search by **name, state, NTEE category or 501(c) type**, or look up specific **EINs**.

***

### Why Use This

- **Financial KYC in one call.** Revenue, assets, liabilities and executive pay for any US nonprofit — straight from its 990s.
- **Grant & prospect research.** Find and size nonprofits by cause (NTEE), state and budget.
- **Due diligence.** Verify an organization's EIN, 501(c) status, IRS ruling and financial trajectory across years.
- **Official & free.** Reads public IRS/990 data via Nonprofit Explorer — no key, no login, no anti-bot.

***

### Quick Start

#### Run it in the console (no code)

1. Add **search terms** and/or filters (**states**, **NTEE categories**, **501(c) subsection**), or specific **EINs**.
2. Keep **Include 990 financials** on for revenue/assets/exec pay.
3. Set **Max organizations**, click **Start**, export as **JSON, CSV, Excel or HTML**.

#### Size nonprofits in a sector (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {"searchTerms": ["food bank"], "states": ["CA"], "maxItems": 1000}

run = client.actor("YOUR_USERNAME/propublica-nonprofit-scraper").call(run_input=run_input)

for o in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(o["name"], "·", o["state"], "· revenue", o["latestRevenue"], "· assets", o["latestAssets"])
```

#### Look up specific organizations (Python)

```python
run = client.actor("YOUR_USERNAME/propublica-nonprofit-scraper").call(run_input={
    "einList": ["53-0196605", "131624102"],
})
```

***

### Input Parameters

| Field | Type | Description |
|---|---|---|
| `searchTerms` | array | Nonprofit names or keywords. Each runs as a separate search. |
| `states` | array | Two-letter US state codes. |
| `nteeCategories` | array | Major NTEE category IDs (1 Arts … 10 Unclassified). |
| `cCode` | string | 501(c) subsection number (e.g. `3` for 501(c)(3)). |
| `einList` | array | Specific EINs to look up (with or without dash). |
| `includeFilings` | boolean | Fetch 990 financials + filing history (default on). |
| `maxItems` | integer | Max organizations across all searches. `0` = no limit. |
| `maxPagesPerSearch` | integer | Pagination cap per search (25 per page). |
| `proxyConfiguration` | object | Apify Proxy. Datacenter is enough (public API). |

***

### Output

Each organization is one record:

```json
{
  "ein": "530196605", "einFormatted": "53-0196605",
  "name": "American National Red Cross",
  "address": "431 18TH ST NW", "city": "Washington", "state": "DC", "zipcode": "20006",
  "nteeCode": "P210", "subsectionCode": 3, "subsectionLabel": "501(c)(3) Charitable",
  "rulingDate": "1938-12-01",
  "latestFilingYear": 2023, "latestFormType": "990",
  "latestRevenue": 3217077611, "latestExpenses": 3100000000,
  "latestAssets": 4028321133, "latestLiabilities": 1200000000,
  "latestExecCompensation": 5947262,
  "latestFilingPdfUrl": "https://projects.propublica.org/nonprofits/.../pdf",
  "filingsCount": 13, "filingYears": [2023, 2022, 2021],
  "profileUrl": "https://projects.propublica.org/nonprofits/organizations/530196605"
}
```

**About coverage:** identity fields (name, EIN, address, ruling date) are present for essentially every organization. Financials come from filed 990s — most active nonprofits have them, but very small orgs (that file 990-N postcards) and brand-new ones may have limited or no financial data. Executive compensation appears where the organization reports officer pay.

***

### Use Cases

#### 1. KYC & due diligence

Verify a nonprofit's EIN, 501(c) status, IRS ruling and multi-year financials before partnering, granting or donating.

#### 2. Grant & prospect research

Build lists of nonprofits by cause, state and budget — with revenue and assets to size each prospect.

#### 3. Sector & market analysis

Analyse nonprofit counts, revenue and assets across categories and geographies.

#### 4. Journalism & watchdog research

Track executive compensation, revenue and assets of organizations over time.

***

### Tips

- **`cCode: "3"`** limits to 501(c)(3) charities; other subsections (4, 6, 7…) cover social-welfare, business leagues, clubs and more.
- **`nteeCategories`** filters by cause area (Arts, Education, Health, Human Services, …).
- **`latestRevenue` / `latestAssets` / `latestExecCompensation`** make it easy to rank and size organizations.
- **`filingYears`** shows how much history is available; **`latestFilingPdfUrl`** links the source 990.
- **Schedule it** with Apify Schedules to track new filings.

***

### Frequently Asked Questions

**Do I need an account or key?**
No. The Nonprofit Explorer API is public and free — no login, key or anti-bot.

**What is an EIN?**
The Employer Identification Number — the IRS's unique identifier for an organization (e.g. `53-0196605`).

**Where do the financials come from?**
From organizations' filed IRS Form 990 returns. The latest year is summarized on each record; `filingYears` lists all available years.

**Why do some small nonprofits have no financials?**
Organizations that file the 990-N "postcard" (very small nonprofits) report no detailed financials, so those fields are empty.

**What export formats are supported?**
JSON, CSV, Excel, HTML, or via API — plus Google Sheets, webhooks, Make and Zapier.

***

### Legal & Responsible Use

This Actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by ProPublica or the IRS.** It reads only public 990 and IRS data. Use the data responsibly and in line with applicable terms and laws.

# Actor input Schema

## `searchTerms` (type: `array`):

Nonprofit names or keywords (e.g. "food bank", "red cross"). Each runs as a separate search.

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

Two-letter US state codes to filter by (e.g. CA, NY).

## `nteeCategories` (type: `array`):

Major NTEE category IDs: 1 Arts, 2 Education, 3 Environment/Animals, 4 Health, 5 Human Services, 6 International, 7 Public/Societal, 8 Religion, 9 Mutual benefit, 10 Unclassified.

## `cCode` (type: `string`):

501(c) subsection number to filter by (e.g. 3 for 501(c)(3) charities, 4, 6).

## `einList` (type: `array`):

Specific EINs to look up (e.g. 530196605 or 53-0196605).

## `includeFilings` (type: `boolean`):

Fetch each organization's 990 financials (revenue, expenses, assets, exec compensation) and filing history.

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

Maximum organizations across all searches. 0 = no limit.

## `maxPagesPerSearch` (type: `integer`):

Pagination cap per search (25 per page).

## `proxyConfiguration` (type: `object`):

Apify Proxy. The API is public — datacenter is enough and enabled by default.

## Actor input object example

```json
{
  "searchTerms": [
    "food bank"
  ],
  "includeFilings": true,
  "maxItems": 150,
  "maxPagesPerSearch": 40,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `ein` (type: `string`):

Employer ID Number

## `einFormatted` (type: `string`):

EIN with dash

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

Organization name

## `address` (type: `string`):

Street address

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

City

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

State

## `zipcode` (type: `string`):

ZIP code

## `nteeCode` (type: `string`):

NTEE classification

## `subsectionCode` (type: `string`):

501(c) subsection

## `subsectionLabel` (type: `string`):

501(c) type label

## `rulingDate` (type: `string`):

IRS ruling date

## `assetAmount` (type: `string`):

IRS BMF assets

## `incomeAmount` (type: `string`):

IRS BMF income

## `revenueAmount` (type: `string`):

IRS BMF revenue

## `latestFilingYear` (type: `string`):

Latest 990 year

## `latestFormType` (type: `string`):

990 form type

## `latestRevenue` (type: `string`):

Latest total revenue

## `latestExpenses` (type: `string`):

Latest total expenses

## `latestAssets` (type: `string`):

Latest total assets

## `latestLiabilities` (type: `string`):

Latest liabilities

## `latestExecCompensation` (type: `string`):

Officer compensation

## `latestFilingPdfUrl` (type: `string`):

Latest 990 PDF URL

## `filingsCount` (type: `string`):

Years with data

## `filingYears` (type: `string`):

Years available

## `profileUrl` (type: `string`):

Nonprofit Explorer URL

## `scrapedAt` (type: `string`):

ISO timestamp

# 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 = {
    "searchTerms": [
        "food bank"
    ],
    "maxItems": 150,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/propublica-nonprofit-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 = {
    "searchTerms": ["food bank"],
    "maxItems": 150,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/propublica-nonprofit-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 '{
  "searchTerms": [
    "food bank"
  ],
  "maxItems": 150,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/propublica-nonprofit-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/propublica-nonprofit-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/GAsoqZf9W2Qb4e8Yn/builds/anhFayN0AmsQJ5ewl/openapi.json
