# IRS 990 Pro - Nonprofit Search & Filing History (`red.cars/irs-990-pro`) Actor

Search 1.8M+ IRS-registered nonprofits by keyword or EIN. Get full Form 990 filing history with revenue, expenses, assets and direct PDF/XML links. Donor prospecting, grant research, charity KYB. No API key needed.

- **URL**: https://apify.com/red.cars/irs-990-pro.md
- **Developed by:** [AutomateLab](https://apify.com/red.cars) (community)
- **Categories:** Automation, Developer tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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.

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

## IRS 990 Pro - Nonprofit Search & Filing History

Search **1.8M+ IRS-registered nonprofits** by name keyword, or pull one organization's full **Form 990 filing history** with revenue, expenses, assets and direct filing PDF/XML links. One actor for donor prospecting, grant research and charity KYB.

Built on [ProPublica's mirror of IRS 990 data](https://projects.propublica.org/nonprofits/). No API key, no login, no browser.

### Why this one

| | |
|---|---|
| Data source | ProPublica Nonprofit Explorer API (public mirror of IRS filings) |
| Coverage | 1.8M+ tax-exempt organizations, full 990 e-filing history |
| Auth | None. No key, no anti-bot fights |
| Modes | Keyword/state/city search + per-EIN filing history with financials |
| Pricing | $0.005 per run + $2.00 per 1,000 results |

### How it compares

| Actor | Users | What you get |
|---|---|---|
| **irs-990-pro** (this actor) | - | Search + filing history + per-filing financials + PDF/XML links, zero config |
| [pink_comic/irs-990-nonprofit-search](https://apify.com/pink_comic/irs-990-nonprofit-search) | 28 | Nonprofit search via ProPublica, lookup-style |
| [maximedupre/irs-nonprofit-search](https://apify.com/maximedupre/irs-nonprofit-search) | 2 | Basic nonprofit search |

The difference: this actor returns **clean rows** (EIN, formatted EIN, name, DBA sub-name, city, state, NTEE code, 501(c) subsection) and in organization mode returns **one row per filing year** with revenue, expenses, assets, liabilities, contributions, program revenue and the direct filing PDF and XML URLs. A grant writer or prospect researcher gets a years-long giving picture in one run.

### Input

**Search mode (default)**

- `query`: keywords matched against nonprofit names (`food bank`, `veterans`, `stem education`)
- `page`: start page (25 results per page), `maxResults`: 1-1000 rows

Search matches organization names (that is what the IRS e-file index exposes), so use words you would find in a name; EIN lookups are exact in organization mode.

**Organization mode**

- `ein`: 9-digit EIN, dashes optional (`530196605` = American Red Cross)
- returns every filing year, newest first, with financials; paper-only filings are marked `reasonNoData` so you know to open the PDF

### Output

Search rows: `ein`, `einFormatted`, `name`, `subName`, `city`, `state`, `nteeCode`, `subsection`, `hasFilings`, `hasPdfFilings`, `url` (ProPublica org page).

Filing rows: everything above plus `taxPeriod`, `taxYear`, `formType`, `revenue`, `expenses`, `assetsEnd`, `liabilitiesEnd`, `netAssetsEnd`, `contributions`, `programRevenue`, `filingPdfUrl`, `filingXmlUrl`.

Zero-match runs return one `ZERO_RESULTS` hint row instead of an empty dataset, so you always know what happened.

### Pricing

$0.005 per run + $2.00 per 1,000 results. No API key, no login walls. Typical 10-result search costs **$0.025**.

### FAQ

**Do I need a ProPublica API key?** No. The actor uses the public endpoints directly.

**Is this real IRS data?** Yes, as mirrored by ProPublica's Nonprofit Explorer from IRS 990 e-file records. Financials are the amounts as reported on each filing.

**Can I page deeply?** Yes, `page` up to 400 (the API caps at 10,000 matches per query). Use `page` + `maxResults` to walk long lists.

**Where do the filing PDFs come from?** ProPublica's own hosted copies of the IRS filing PDFs, linked directly per row.

**Pair it with** [Grants.gov Pro](https://apify.com/red.cars/grants-gov-pro) (find the federal money, check the charity's financials before you pitch) or [Academic Research MCP](https://apify.com/red.cars/academic-research-mcp).

# Actor input Schema

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

search: find nonprofits by keyword, state and city. organization: pull one EIN's full 990 filing history with financials and filing PDF/XML links.

## `query` (type: `string`):

Search words matched against nonprofit names, e.g. 'food bank', 'veterans', 'stem education'. Required for search mode.

## `page` (type: `integer`):

Search result page to start from (1-based, 25 results per page). Use with maxResults to page through long result lists. Search mode only.

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

Maximum rows to return, 1 to 1000. In search mode this is nonprofit rows; in organization mode it caps filing-history rows (newest first).

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

Employer Identification Number for organization mode, digits only or dashed, e.g. 530196605 or 53-0196605 (American Red Cross).

## Actor input object example

```json
{
  "mode": "search",
  "query": "food bank",
  "page": 1,
  "maxResults": 10
}
```

# Actor output Schema

## `results` (type: `string`):

Default dataset of nonprofit rows: EIN, name, city/state, NTEE code, 501(c) subsection, plus filing-history rows with revenue, expenses, assets and filing PDF/XML links.

# 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": "search",
    "query": "food bank",
    "page": 1,
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("red.cars/irs-990-pro").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": "search",
    "query": "food bank",
    "page": 1,
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("red.cars/irs-990-pro").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": "search",
  "query": "food bank",
  "page": 1,
  "maxResults": 10
}' |
apify call red.cars/irs-990-pro --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,red.cars/irs-990-pro"
        }
    }
}
```

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/XL54LBx0NLY40MzGo/builds/FSXX8TibKO2hYSjLe/openapi.json
