# Nonprofit Finder: IRS Exempt Organizations by State (`ledgerstar/nonprofit-finder`) Actor

Find U.S. tax-exempt organizations from the IRS Exempt Organizations Business Master File. Filter by state, city, 501(c) type, NTEE cause code, revenue and assets. Records include nonprofit name, address, EIN and financial data. Ready for accountants, fundraisers and market researchers.

- **URL**: https://apify.com/ledgerstar/nonprofit-finder.md
- **Developed by:** [Ledger Star](https://apify.com/ledgerstar) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$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

## Nonprofit Finder: IRS Exempt Organizations by State

Every month the IRS recognizes thousands of new tax-exempt organizations. This Actor turns the official list into ready-to-use prospects: nonprofit name, address, 501(c) type, cause, size and ruling date, filtered to your state and cause.

### What you get

- Fresh volume: the IRS Exempt Organizations Business Master File contains 1,964,958 tax-exempt organizations as of September 8, 2026. Colorado alone has 36,344.
- Each record has nonprofit name, legal street address, city, ZIP, 501(c) type, NTEE cause code and name, ruling date (month the IRS recognized exemption), latest tax period, revenue and assets. All 50 states, DC and Puerto Rico included.
- Filters for 501(c) type, NTEE cause code, city, ZIP, revenue and assets, plus an alert mode that returns only nonprofits you have not seen yet.

### Quick start

1. Choose a state or multiple states.
2. Add filters if you want them: 501(c) types, NTEE cause codes, cities, ZIP prefixes, revenue and assets, ruling year.
3. Click Start, then export the results.

**Worked example:** Colorado, 501(c)(3), cause code B (education), minimum revenue $100,000, maximum results 20. You get the first 20 matching organizations for $0.04. Colorado has 36,344 exempt organizations in the IRS file, and the file is refreshed monthly, so the matches change month to month.

### Who uses it

- **Accountants and CPAs:** find and filter 501(c)(3)s by revenue and size, export prospect lists for outreach.

- **Fundraisers and consultants:** build foundation or youth organization lists, see size, link to Form 990s.

- **Vendors and researchers:** size markets by cause and revenue band, build benchmarks.

### Sample output

Example rows showing the format:

| Organization | EIN | City | State | Type | Cause | Revenue |
|---|---|---|---|---|---|---|
| VERMONT YOUTH DEVELOPMENT ASSOCIATION | 22-1234567 | MONTPELIER | VT | 501(c)(3) | Youth Development | $2.4M |
| COLORADO EDUCATION FOUNDATION | 84-0987654 | DENVER | CO | 501(c)(3) | Education | $5.2M |
| HEALTH FIRST NONPROFIT CORP | 59-1555555 | AURORA | CO | 501(c)(3) | Health Care | $1.8M |

<details><summary>Full JSON example</summary>

```json
{
  "ein": "22-1234567",
  "name": "VERMONT YOUTH DEVELOPMENT ASSOCIATION",
  "street": "42 CHURCH ST",
  "city": "MONTPELIER",
  "state": "VT",
  "zip": "05602",
  "subsection": "501(c)(3)",
  "nteeCode": "O20",
  "nteeCategory": "Youth Development",
  "rulingDate": "2015-03",
  "taxPeriod": "2023-12",
  "foundationCode": "16",
  "filingRequirementCode": "01",
  "assets": 3647873,
  "income": 2520000,
  "revenue": 2400000,
  "revenueBand": "$1M–$5M",
  "nonprofitExplorerUrl": "https://projects.propublica.org/nonprofits/organizations/221234567",
  "source": "IRS — Exempt Organizations Business Master File Extract (EO BMF)",
  "sourceUrl": "https://www.irs.gov/pub/irs-soi/eo_vt.csv",
  "scrapedAt": "2026-09-25T14:00:00.000Z"
}
```

</details>

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| States | array | VT | One per state, all 50 plus DC and PR. |
| 501(c) types (optional) | array | none | e.g. 3 for 501(c)(3)s, 4 for social welfare. |
| Cause codes (NTEE prefixes, optional) | array | none | e.g. B = education, E = health care. |
| Cities (optional) | array | none | Exact city names, case-insensitive. |
| ZIP codes or prefixes (optional) | array | none | Full ZIP or prefix (054) for regions. |
| Name contains (optional) | array | none | Words in org names: FOUNDATION, SCHOOL. |
| Minimum annual revenue (optional) | integer | none | Latest return on file. Excludes unreported. |
| Maximum annual revenue (optional) | integer | none | Upper bound on latest reported revenue. |
| Minimum total assets (optional) | integer | none | From latest return on file. |
| Recognized in or after year (optional) | integer | none | Find organizations by ruling year. |
| Sort | string | File order | File order or by revenue or assets. |
| Maximum results | integer | 20 | Stop after this many. Charged per result. |

<details><summary>Advanced options</summary>

- **Alert mode: only organizations new since (string, optional)** Enter a date in YYYY-MM-DD format or the word lastRun to receive only newly recognized nonprofits or those with new returns. Leave empty to turn alert mode off.
- **Alert mode: lookback safety window in days (integer, default 7, max 30)** Only used with lastRun above. Checks this many days before your last run for organizations the IRS posted late. You are never charged twice for the same organization.
- **Alert mode: also include new returns from existing organizations (boolean, default false)** By default alert mode only returns newly recognized organizations (new ruling date). Turn this on to also include organizations with a new return, even if their ruling is old. Each new return for the same organization is delivered once.
- **Alert mode: stable state name (string, optional)** Only used with alert mode. Give this a fixed name such as "co nonprofits nightly" so this schedule always uses the same saved last run date, even if you change other filters. Letters, numbers, and hyphens only, up to 30 characters.

**How alert mode decides what is new:** A nonprofit is new if its ruling date (month recognized by IRS) is on or after the previous run date. With alertIncludeNewFilings on, organizations with new returns also count. The Actor looks back alertLookbackDays days (default 7, max 30) to catch late filings and stores delivered ids in alert-nonprofit-finder-{code} so you are never charged twice.

</details>

### Alert mode: only new records

Run the Actor on a schedule to get only nonprofits recognized since your last run. The first run returns normal results; later runs return only new organizations. A run with nothing new costs nothing.

Set it up in three steps:

1. Create a Task in Apify Console with your filters.
2. In Task input, set "Alert mode: only organizations new since" to lastRun.
3. Go to Schedule tab, click Add Schedule, and choose daily or weekly.

### Pricing

$2.00 per 1,000 results ($0.002 per organization).

Worked examples: 100 results cost $0.20, 1,000 results cost $2.00, and 10,000 results cost $20.00. Set a maximum cost per run and the Actor stops cleanly at your budget.

### Integrations

- **Google Sheets:** send every run's results to a sheet automatically.
- **Zapier and Make:** trigger a workflow for each new nonprofit, for example add it to your CRM.
- **Slack:** post a message when a run finds new organizations.
- **Apify API:** download results as CSV, Excel or JSON from your own code.
- **Export:** CSV, Excel and JSON downloads straight from the dataset view.

### Data source and compliance

The data is official open data from the IRS Exempt Organizations Business Master File, read without login. The Actor never returns personal names or in-care-of details. Financial figures may be several years old, so verify them before relying on them.

### FAQ

**How current is the data?**
Each run queries the live IRS dataset.

**Why do some organizations have no revenue?**
Small organizations and churches often don't report. Set a revenue filter to exclude them.

**Can I get officer or contact names?**
No, organization-level data only. Officer names are in public Form 990s via nonprofitExplorerUrl.

**Is sorting by revenue slower?**
Yes, slightly. File order stops when enough results are found.

**Can I use this for outreach?**
Yes, within compliance rules. This is public nonprofit data, not a mailing list.

### More from Ledgerstar

- **Texas New Business Leads:** Sales tax permit holders by week: https://apify.com/ledgerstar/texas-sales-tax-permits

- **New Business Filings:** Colorado and New York business formation data: https://apify.com/ledgerstar/state-business-filings

- **Chamber of Commerce Directory Scraper:** Local Chamber of Commerce business lists: https://apify.com/ledgerstar/chamber-directory-scraper

- **Building Permits Leads:** new construction and contractor permits across several cities (arriving on the Store soon)

### Support

Support: open an issue on this Actor's Issues tab in Apify Console.

# Actor input Schema

## `newSince` (type: `string`):

Turns on alert mode: only return newly recognized organizations, those whose ruling date (the month the IRS recognized their exemption, taken as the first day of that month) is on or after this date. Turn on alertIncludeNewFilings below to also include organizations with a new return. Use an exact date (YYYY-MM-DD) or the word lastRun to return only organizations new since the previous successful run. Leave empty to turn alert mode off.

## `alertLookbackDays` (type: `integer`):

Only used with the word lastRun above. Also checks this many days before your last run for organizations the IRS posted late. You are never charged twice for the same organization or return, so a larger number is always safe.

## `alertIncludeNewFilings` (type: `boolean`):

By default alert mode only returns newly recognized organizations (a new ruling date). Turn this on to also include organizations that are not newly recognized but whose latest return or tax period is new since your date. Each new return for the same organization is delivered once.

## `alertStateKey` (type: `string`):

Only used with alert mode (the field above). Give this a fixed name such as vt nightly so this schedule always uses the same saved last run date, even if you change other filters. Letters, numbers and hyphens only, up to 30 characters. Leave empty to have one chosen automatically based on your filters.

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

One IRS file is downloaded per state.

## `subsections` (type: `array`):

e.g. 3 for 501(c)(3) charities, 4 for social-welfare groups, 6 for trade associations. Leave empty for all.

## `nteePrefixes` (type: `array`):

e.g. B = education, E = health care, P = human services, X = religion-related, B82 = scholarships. Leave empty for all.

## `cities` (type: `array`):

Exact city name, case-insensitive.

## `zipPrefixes` (type: `array`):

e.g. 05401 or 054.

## `nameKeywords` (type: `array`):

Keep organizations whose name contains any of these words, e.g. FOUNDATION, SCHOOL, CLINIC.

## `minRevenue` (type: `integer`):

From the organization's latest return on file with the IRS. Organizations without reported revenue are excluded when set.

## `maxRevenue` (type: `integer`):

Upper bound on latest reported revenue.

## `minAssets` (type: `integer`):

From the latest return on file.

## `rulingYearFrom` (type: `integer`):

Find newer organizations, e.g. 2022.

## `sortBy` (type: `string`):

'File order' is fastest and stops as soon as enough results are found. Sorting reads the whole state file first.

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

Stop after this many results. You are charged per result.

## Actor input object example

```json
{
  "alertLookbackDays": 7,
  "alertIncludeNewFilings": false,
  "states": [
    "VT"
  ],
  "sortBy": "none",
  "maxItems": 20
}
```

# Actor output Schema

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

No description

## `runSummary` (type: `string`):

No description

## `output` (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 = {
    "alertLookbackDays": 7,
    "states": [
        "VT"
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("ledgerstar/nonprofit-finder").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 = {
    "alertLookbackDays": 7,
    "states": ["VT"],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("ledgerstar/nonprofit-finder").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 '{
  "alertLookbackDays": 7,
  "states": [
    "VT"
  ],
  "maxItems": 20
}' |
apify call ledgerstar/nonprofit-finder --silent --output-dataset

```

## MCP server setup

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

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/A5cFu4Dc8cTKJEja5/builds/WbLVfUeUhoQA9FYtR/openapi.json
