# Nonprofit & Foundation Prospects from IRS 990 Data (`signalloom/nonprofit-990-prospects`) Actor

US nonprofit and foundation prospect lists from official IRS data: filter by state, city, NTEE, size, ruling year, type and grant-making. Revenue trend, grants paid, top grant recipients, website, mission and role counts per organization. Monitor mode for new filings.

- **URL**: https://apify.com/signalloom/nonprofit-990-prospects.md
- **Developed by:** [Signalloom](https://apify.com/signalloom) (community)
- **Categories:** Lead generation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 organizations

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 & Foundation Prospects from IRS 990 Data

Build lists of US nonprofits and private foundations straight from **official IRS public data**. Filter by state, city, ZIP, NTEE activity code, size, ruling year, charity or foundation type, and "makes grants". Each organization comes back as one clean record:

- EIN, name, city, state and ZIP; NTEE category, 501(c) subsection, IRS foundation type and ruling year
- latest e-filed return (Form 990, 990-EZ or 990-PF): total revenue, expenses, assets, net assets, contributions received and grants paid
- a **revenue trend** over the available years (usually 3–4), with the change in %
- the **largest grants it made** to organizations (name, city, state, amount, purpose)
- for private foundations, **how to apply**: application form and materials, deadlines and restrictions as filed on Part XIV
- website and mission statement where the return states them
- leadership as **counts and role titles only**: no names and no pay
- source links to the IRS file and the exact return

Monitor mode (`onlyChanged` / `onlyNew`) reports only organizations that **filed a newer return**, are new to your search, or changed in the IRS master file since your last run.

### Use this when…

- **You're a grant seeker** and want the foundations in your state that actually pay grants, what they gave and to whom last year, and how to apply.
- **You're a fundraiser or prospect researcher** building a list of organizations of a certain size, cause and region, with growth trends.
- **You sell to nonprofits** (software, audit, insurance, consulting, fundraising services) and need a sized, segmented target list with websites.
- **You track a portfolio** of grantees or peers and want to know when a new 990 lands.

### Price

**$0.003 per organization record** (pay per event, `organization`). You pay only for organizations returned; a monitor run that finds no changes costs only the Apify platform start.

### Input

| Field | What it does |
|---|---|
| `states` (required) | 1–10 states, codes or names (`VT`, `New York`) |
| `organizationType` | `any`, `public-charity`, `private-foundation`, `private-non-operating-foundation` (grant-makers), `private-operating-foundation` |
| `makesGrants` | only organizations whose latest return reports grants paid |
| `cities`, `zipPrefixes` | location filters (city spelling as in the IRS file, e.g. `S BURLINGTON`) |
| `nteeCodes` | NTEE prefixes: `B` education, `E` health, `T` philanthropy, `P20` human services… |
| `keywords` | any word in the name or the mission statement |
| `subsections` | 501(c) subsections, default `["3"]`; empty = all |
| `minAssets`, `maxAssets`, `minRevenue`, `maxRevenue` | size, from the IRS master file |
| `rulingYearFrom`, `rulingYearTo` | year the IRS recognized the exemption |
| `filedSinceYear` | drop organizations whose latest e-filed return is older |
| `sortBy` | `assets` (default), `revenue`, `newest`, `name` |
| `maxResults` | organizations to output (default 50) |
| `maxFilingsPerOrg` | yearly returns read for the trend (default 3) |
| `includeGrantRecipients`, `maxGrantRecipients` | top grant recipients per organization (default 10) |
| `includeOrgsWithoutEfile` | also list organizations with no e-filed 990 (990-N filers, churches, paper filers), master-file figures only |
| `onlyNew`, `onlyChanged`, `monitorId` | monitor mode; memory is kept in the named key-value store `nonprofit-990-prospects-state` |

Example (the prefilled input, about 20 seconds):

```json
{ "states": ["VT"], "organizationType": "private-non-operating-foundation", "makesGrants": true, "minAssets": 1000000, "maxResults": 25 }
```

### Output example

A real record from a run on 2026-11-12 (grant recipients shortened to 3 of 10):

```json
{
  "ein": "204818866",
  "name": "NATIONAL LIFE GROUP CHARITABLE FOUNDATION INC",
  "city": "MONTPELIER",
  "state": "VT",
  "zip": "05604",
  "nteeCode": "T200",
  "nteeCategory": "Philanthropy, Voluntarism & Grantmaking Foundations",
  "subsection": "501(c)(3)",
  "organizationType": "Private non-operating foundation",
  "rulingYear": 2007,
  "latestForm": "990-PF",
  "latestTaxYear": 2024,
  "latestFiledOn": "2025-11-10",
  "totalRevenue": 3100616,
  "totalExpenses": 2672029,
  "totalAssets": 27377919,
  "contributionsReceived": 2403635,
  "grantsPaid": 2654987,
  "makesGrants": true,
  "revenueTrend": [
    { "taxYear": 2022, "form": "990-PF", "totalRevenue": 3080975, "totalExpenses": 1990721, "totalAssets": 21452764, "grantsPaid": 1990721, "source": "return" },
    { "taxYear": 2023, "form": "990-PF", "totalRevenue": 3764370, "totalExpenses": 3056772, "totalAssets": 24058202, "grantsPaid": 3045087, "source": "return" },
    { "taxYear": 2024, "form": "990-PF", "totalRevenue": 3100616, "totalExpenses": 2672029, "totalAssets": 27377919, "grantsPaid": 2654987, "source": "return" }
  ],
  "revenueChangePct": 0.6,
  "website": "www.nationallife.com/our-story/our-foundation",
  "leadership": {
    "listedPeople": 15,
    "roleTitles": [
      { "title": "DIRECTOR", "count": 4 },
      { "title": "CHAIR", "count": 1 },
      { "title": "INVESTMENT OFFICER", "count": 1 },
      { "title": "PRESIDENT & CEO, DIRECTOR", "count": 1 },
      { "title": "TREASURER", "count": 1 }
    ],
    "titlesNotListed": 7
  },
  "grantRecipientCount": 735,
  "grantRecipientsTotal": 2608399,
  "topGrantRecipients": [
    { "name": "LET'S GROW KIDS", "city": "BURLINGTON", "state": "VT", "amount": 125000, "purpose": "CHILDREN SUPPORT" },
    { "name": "VERMONT FOODBANK", "city": "SOUTH BARRE", "state": "VT", "amount": 125000, "purpose": "FOODBANK" },
    { "name": "HUNGER FREE VERMONT", "city": "SOUTH BURLINGTON", "state": "VT", "amount": 125000, "purpose": "POVERTY SUPPORT" }
  ],
  "grantsToIndividuals": { "count": 22, "amount": 46588 },
  "grantApplication": {
    "acceptsUnsolicitedApplications": null,
    "formAndMaterials": "APPLICATION FORM OPENS ON JANUARY 1ST AND SHOULD BE SUBMITTED ONLINE: WWW.NATIONALLIFE.COM/OUR-STORY/GRANTS-AND-SPONSORSHIPS. ...",
    "deadlines": "GRANTS- MARCH 31ST; SPONSORSHIPS- REVIEWED ON ROLLING BASIS UNTIL YEARLY FUNDING EXHAUSTED.",
    "restrictions": "OUR GRANTS VARY IN SIZE AND WE RARELY FUND AN ENTIRE PROGRAM. WE DO NOT FUND NEW PROGRAMS. ..."
  },
  "masterFile": { "taxPeriod": "2024-12", "revenue": null, "income": 3519497, "assets": 27377919 },
  "eFiledReturnsOnRecord": 3,
  "sources": {
    "irsMasterFile": "https://www.irs.gov/pub/irs-soi/eo_vt.csv",
    "latestReturnXml": {
      "archive": "https://apps.irs.gov/pub/epostcard/990/xml/2025/2025_TEOS_XML_11B.zip",
      "file": "202543149349100024_public.xml"
    },
    "irsDownloadsPage": "https://www.irs.gov/charities-non-profits/form-990-series-downloads"
  }
}
```

More rows from the same run:

| Organization | City | Tax year | Revenue | Grants paid | Recipients listed | Website |
|---|---|---|---|---|---|---|
| GEORGE W MERGENS FOUNDATION | MILTON | 2024 | $590,805 | $1,000,230 | 95 (top: SAINT FRANCIS XAVIER SCHOOL, $50,000) | www.mergensfoundation.org |
| BEN & JERRYS FOUNDATION | S BURLINGTON | 2024 | $5,616,458 | $4,220,251 | 448 (top: TIDES FOUNDATION, $295,000) | www.benandjerrysfoundation.org |

### How it works

1. Downloads the IRS **Exempt Organizations Business Master File** for each chosen state (one CSV per state, updated monthly by the IRS) and applies your filters.
2. Looks up each organization's e-filed returns in an index of the IRS **Form 990 series e-file downloads** (2023–2026 releases, about 2.4 million returns). The returns sit in large ZIP archives on the IRS site; the tool reads only the one return it needs from each archive (HTTP range requests), never the whole archive.
3. If the IRS has published new archives since the index was built, it reads the IRS's current index file and picks up the newer returns too (`checkNewestIrsBatches`).
4. Parses the returns with fixed rules; nothing is guessed or AI-generated.

### Data handling and privacy

This tool describes **organizations**, not people.

- **Never output:** names of officers, directors, trustees or employees; anyone's compensation; the "in care of" person and street address from the master file; preparers; phone numbers; contact persons for grant applications.
- **Leadership** is reduced to counts (directors, officers, key employees) and role titles. A title is listed only if every word in it is a known role word, so a name typed into the title box is counted, never shown.
- **Grants to individuals** (scholarships, relief) are only counted and totalled, never named. Grant recipients are listed only when the filer identified them as organizations. "Attention" lines such as "ATTN …" or "C/O …" are removed from recipient names.
- Email addresses and phone numbers are removed from mission and application text.

### Limitations

- **Coverage:** only returns filed electronically and released by the IRS. Organizations filing the 990-N postcard (under $50,000), most churches and paper filers have no return here (`includeOrgsWithoutEfile` lists them with master-file figures).
- **Lag:** the IRS releases returns months after filing. A tax year 2024 return typically appears during 2025–2026.
- **As filed:** figures are as reported to the IRS, not audited. Fiscal years are labelled by the year they start (the IRS "tax year").
- **Size filters and sorting** use the IRS master-file amounts. Those can differ from the latest return shown (for example when the master file holds a newer or older period).
- Private-foundation returns don't carry a mission statement. Grant lists filed only as PDF attachments ("see attached statement") can't be read.
- City names are as written in the IRS file (`S BURLINGTON`, `ESSEX JCT`).

### Sources and attribution

Data: **U.S. Internal Revenue Service**, [EO Business Master File Extract](https://www.irs.gov/charities-non-profits/exempt-organizations-business-master-file-extract-eo-bmf) and [Form 990 Series Downloads](https://www.irs.gov/charities-non-profits/form-990-series-downloads). IRS content is a U.S. government work and may be freely copied; the IRS asks for credit, given here. This tool is not affiliated with or endorsed by the IRS.

# Actor input Schema

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

US states to search (two-letter codes or names, up to 10). Each state is one official IRS master-file download.

## `organizationType` (type: `string`):

Public charities, private foundations, or only grant-making (non-operating) private foundations. Based on the IRS foundation code.

## `makesGrants` (type: `boolean`):

Keep only organizations whose latest e-filed return reports grants paid (990-PF Part I line 25 / Part XIV, Form 990 Part I line 13 or Schedule I).

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

Optional: only these cities (as written in the IRS master file, e.g. BURLINGTON).

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

Optional: only ZIP codes starting with these digits (e.g. 054 or 05401).

## `nteeCodes` (type: `array`):

Optional: NTEE activity codes or prefixes, e.g. B (education), E (health), T (philanthropy & grantmaking), P20 (human services). Organizations without an NTEE code don't match.

## `keywords` (type: `array`):

Optional: any of these words in the organization's name or its mission statement (mission is read from the latest return).

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

501(c) subsection numbers to include, e.g. 3 for 501(c)(3) charities and foundations, 4 for social welfare, 6 for business leagues. Empty list = all.

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

Optional: minimum total assets in the IRS master file (latest return the IRS processed).

## `maxAssets` (type: `integer`):

Optional: maximum total assets in the IRS master file.

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

Optional: minimum total revenue in the IRS master file.

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

Optional: maximum total revenue in the IRS master file.

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

Optional: IRS exemption ruling year at or after this year (use it to find young organizations).

## `rulingYearTo` (type: `integer`):

Optional: IRS exemption ruling year at or before this year.

## `filedSinceYear` (type: `integer`):

Optional: only organizations whose latest e-filed return covers this tax year or later (drops inactive filers).

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

Which organizations come first (and are checked first): largest assets, largest revenue, newest ruling year, or name.

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

Maximum organizations to output (one charged result each).

## `maxOrganizationsToCheck` (type: `integer`):

Cap on how many matching organizations have their latest return read to apply 'makes grants' and mission keywords. Default: 4 x Max organizations.

## `maxFilingsPerOrg` (type: `integer`):

How many yearly returns to read for the revenue trend (1-6). A Form 990 also carries the prior year's figures, so 3 returns usually give 4 years.

## `includeGrantRecipients` (type: `boolean`):

List the largest grants to organizations from the latest return (name, city, state, amount, purpose). Grants to individuals are only counted, never named.

## `maxGrantRecipients` (type: `integer`):

How many of the largest grant recipients to list (0-100).

## `includeOrgsWithoutEfile` (type: `boolean`):

Also output organizations with no e-filed 990 in the IRS data (small 990-N filers, churches, paper filers). Their figures come from the master file only.

## `checkNewestIrsBatches` (type: `boolean`):

If the IRS has published returns since this tool's index was built, look them up too (adds a large index download when there's news).

## `onlyNew` (type: `boolean`):

Monitor mode: output only organizations that weren't in this monitor's previous results (first run outputs everything and sets the baseline).

## `onlyChanged` (type: `boolean`):

Monitor mode: output organizations that are new, filed a newer return (changeType NEW_FILING), or changed in the master file since the last run.

## `monitorId` (type: `string`):

Name for this monitor's memory (stored in the named key-value store nonprofit-990-prospects-state). Use different IDs for different searches.

## Actor input object example

```json
{
  "states": [
    "VT"
  ],
  "organizationType": "private-non-operating-foundation",
  "makesGrants": true,
  "subsections": [
    "3"
  ],
  "minAssets": 1000000,
  "sortBy": "assets",
  "maxResults": 25,
  "maxFilingsPerOrg": 3,
  "includeGrantRecipients": true,
  "maxGrantRecipients": 10,
  "includeOrgsWithoutEfile": false,
  "checkNewestIrsBatches": true,
  "onlyNew": false,
  "onlyChanged": false,
  "monitorId": "default"
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {
    "states": [
        "VT"
    ],
    "organizationType": "private-non-operating-foundation",
    "makesGrants": true,
    "minAssets": 1000000,
    "maxResults": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("signalloom/nonprofit-990-prospects").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 = {
    "states": ["VT"],
    "organizationType": "private-non-operating-foundation",
    "makesGrants": True,
    "minAssets": 1000000,
    "maxResults": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("signalloom/nonprofit-990-prospects").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 '{
  "states": [
    "VT"
  ],
  "organizationType": "private-non-operating-foundation",
  "makesGrants": true,
  "minAssets": 1000000,
  "maxResults": 25
}' |
apify call signalloom/nonprofit-990-prospects --silent --output-dataset

```

## MCP server setup

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

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/UzgR0UCUucbcu0vej/builds/lqEOxlplhgggWMXqz/openapi.json
