# Foundation Grants Scraper - Grantmaker & Funder Leads (`scrapesage/foundation-grants-scraper`) Actor

Extract US foundation grants & grantmaker leads from official IRS Form 990-PF & 990 Schedule I e-file data: funder, recipient, grant amount & purpose, assets, payout, trustees & contact phone. Grant prospecting + B2B lead-gen + monitoring. No browser, no key.

- **URL**: https://apify.com/scrapesage/foundation-grants-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Lead generation, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 grant records

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## Foundation Grants Scraper — Grantmaker & Funder Leads (Who Funds Whom)

Extract the **US foundation funding flow** straight from official **IRS Form 990-PF (Part XV) and Form 990 (Schedule I)** e-file data — every **grant** a private foundation or grantmaking public charity paid, with the **funder, the recipient, the amount, and the stated purpose**. Then profile each grantmaker — assets, total giving, payout ratio, trustees, and a contact phone — as a ready-to-use lead.

This is the data behind paywalled grant-prospecting tools (Foundation Directory, grant databases), rebuilt from the public IRS source. No login, no API key, no browser.

### Why this foundation grants scraper?

Most "nonprofit 990" scrapers stop at organization firmographics (revenue, assets, officers). They don't give you the part that matters for grant prospecting and funder intelligence: **the grants themselves — who gave money to whom, how much, and why.** This actor parses the raw IRS e-file XML to ship the **richest grant + grantmaker dataset in the category**.

| Data | Typical 990 scrapers | This actor |
|---|---|---|
| Grant edges (funder → recipient, amount, purpose) | ❌ | ✅ from 990-PF Part XV + 990 Schedule I |
| Recipient name, EIN & full address | ❌ | ✅ |
| Reverse lookup — "who funds this nonprofit?" | ❌ | ✅ `recipientNameQuery` |
| Foundation assets (FMV), total giving & **payout ratio** | partial | ✅ |
| Trustees / officers with titles & compensation | partial | ✅ |
| Foundation **contact phone** | ❌ | ✅ (on the filing) |
| Filter by funder state, recipient state, grant amount | ❌ | ✅ |
| Lead score (0–100) per grant & per funder | ❌ | ✅ |
| Only-new monitoring for a fresh-grants feed | ❌ | ✅ opt-in |
| No per-run start fee | varies | ✅ |

### Use cases

- **Grant prospecting** — nonprofits and grant writers find funders that give to causes, regions, or peer organizations like theirs. Use `recipientNameQuery` to see exactly who funds a comparable nonprofit, then pitch the same foundations.
- **Funder / grantmaker lead generation** — sell to foundations: grant-management software, mission-aligned investing, foundation accounting/audit, philanthropy advisory, donor-advised-fund services. Score funders by `assetsFMV`, `totalGrantsPaid` and `payoutRatioPct` and reach the trustees.
- **Philanthropy & competitive intelligence** — map a foundation's giving portfolio, track where the biggest funders deploy capital, and benchmark payout ratios against the 5% private-foundation minimum.
- **Wealth & relationship mapping** — foundation trustees and officers are high-net-worth decision-makers; the trustee list is a relationship-mapping seed.
- **Due diligence & verification** — confirm a grantmaker exists, what it gave, and to whom, from the authoritative IRS source.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) — the free plan is enough to try this actor.
2. Open the **Foundation Grants Scraper**, pick a `year` and your filters (funder/recipient state, name, amount), and click **Start**.
3. Watch grant and funder records stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML, or RSS — or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

> **Tip:** for a fast first look, set `maxZipParts: 1` and `sortBy: "none"` to sample one ~100 MB data part. For complete results, leave `maxZipParts: 0` (scan the whole year).

### Input

```json
{
    "years": ["2024"],
    "formTypes": ["990PF"],
    "outputMode": "grants",
    "funderStates": ["CA"],
    "minGrantAmount": 25000,
    "sortBy": "amount",
    "maxResults": 2000
}
````

Reverse lookup — find every foundation that funded a specific organization:

```json
{
    "years": ["2024"],
    "formTypes": ["990PF", "990"],
    "recipientNameQuery": "stanford university",
    "outputMode": "grants",
    "maxResults": 1000
}
```

- **years** — IRS processing years (each is a separate official dataset). Empty = latest available.
- **formTypes** — `990PF` (private foundations, Part XV grants paid) and/or `990` (public-charity grantmakers, Schedule I).
- **outputMode** — `grants` (funding-flow edges), `funders` (grantmaker profiles), or `both`.
- **funderEins** — targeted lookup of specific foundations by EIN (fast).
- **funderNameQuery / funderStates / funderCities** — filter the grantmaker.
- **recipientNameQuery / recipientStates** — filter the recipient (the reverse-lookup engine).
- **minGrantAmount / maxGrantAmount / minFunderAssets** — size filters.
- **withFunderPhoneOnly / includeTrustees / minLeadScore** — quality controls.
- **sortBy** — `amount` (largest first, scans the full year) or `none` (fastest, file order).
- **maxZipParts** — limit how many ~100 MB data parts to download for a quick sample (0 = all).
- **monitorMode / monitorKey** — emit only records not seen on previous runs of the same key.

### Output

Grant record (`recordType: "grant"`):

```json
{
    "recordType": "grant",
    "grantType": "paid",
    "formType": "990-PF",
    "taxYear": "2022",
    "funderName": "Fischer Owen Orthopedic Fund",
    "funderEin": "61-6168361",
    "funderCity": "Pittsburgh",
    "funderState": "PA",
    "funderPhone": "(412) 442-3927",
    "funderType": "Private Foundation",
    "recipientName": "Norton Healthcare System",
    "recipientEin": null,
    "recipientCity": "Louisville",
    "recipientState": "KY",
    "recipientZip": "40232-5070",
    "recipientAddress": "224 East Broadway, Louisville, KY 40232-5070",
    "recipientStatus": "PC",
    "amount": 376672,
    "purpose": "GENERAL SUPPORT",
    "funderProfileUrl": "https://projects.propublica.org/nonprofits/organizations/616168361",
    "leadScore": 76
}
```

Funder record (`recordType: "funder"`):

```json
{
    "recordType": "funder",
    "foundationType": "Public Charity",
    "name": "Digital Green Foundation",
    "ein": "26-2418959",
    "phone": "(301) 706-2648",
    "state": "CA",
    "assetsFMV": 22334356,
    "totalGrantsPaid": 3108509,
    "grantsCount": 5,
    "payoutRatioPct": 13.9,
    "topGrant": { "recipientName": "Precision Development", "amount": 588147 },
    "trustees": [{ "name": "Kentaro Toyama", "title": "Chair", "compensation": 0 }],
    "trusteeCount": 19,
    "profileUrl": "https://projects.propublica.org/nonprofits/organizations/262418959",
    "leadScore": 80
}
```

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it monthly with `monitorMode` to catch newly published filings as a fresh-grants feed.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, grant-tracker update) the moment a run finishes.

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/foundation-grants-scraper').call({
    years: ['2024'],
    formTypes: ['990PF'],
    funderStates: ['NY'],
    minGrantAmount: 50000,
    outputMode: 'both',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} grant & funder records`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new funder leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored search finds new grants.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "find foundations in California that gave grants over $100k for education" and let it run this scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **nonprofit, grant & funding intelligence stack**:

- **[Nonprofit & IRS 990 Scraper](https://apify.com/scrapesage/nonprofit-990-scraper)** — tax-exempt org firmographics, multi-year financials & officers (the org side of this grant data).
- **[US Federal Grants Scraper](https://apify.com/scrapesage/us-federal-grants-scraper)** — open federal grant opportunities & awards from Grants.gov.
- **[USAspending Scraper](https://apify.com/scrapesage/usaspending-scraper)** — federal awards, contractors & recipient leads.
- **[SBA Loan Leads Scraper](https://apify.com/scrapesage/sba-loan-leads-scraper)** — 7(a)/504 small-business loan recipients.
- **[GSA eLibrary Scraper](https://apify.com/scrapesage/gsa-elibrary-scraper)** — federal contract schedule holders with contacts.
- **[Financial Advisor & Broker Scraper](https://apify.com/scrapesage/financial-advisor-scraper)** — FINRA + SEC investment advisers & firms.
- **[TaxBuzz Scraper](https://apify.com/scrapesage/taxbuzz-scraper)** — tax preparers, CPAs & accountant leads.
- **[FEC Campaign Finance Scraper](https://apify.com/scrapesage/fec-campaign-finance-scraper)** — donors, PACs & lobbying intelligence.

### Tips

- **Complete vs. fast**: `maxZipParts: 0` (default) scans the whole year for complete results; `maxZipParts: 1` + `sortBy: "none"` samples quickly and cheaply.
- **Find a funder's full portfolio**: set `funderEins` (or `funderNameQuery`) and `outputMode: "both"` to get the foundation profile plus every grant it paid.
- **Reverse prospecting**: `recipientNameQuery` (optionally with a recipient state) lists every foundation that funded a given organization — the fastest way to build a target funder list.
- **Bigger funders only**: `minFunderAssets` and `minGrantAmount` focus the run on high-capacity grantmakers and meaningful gifts.
- **Fresh feed**: combine [Schedules](https://docs.apify.com/platform/schedules) with `monitorMode` to receive only newly published grants each run.

### FAQ

**Where does the data come from?** The official IRS Form 990 e-file public datasets (`apps.irs.gov`) — Form 990-PF Part XV (grants and contributions paid by private foundations) and Form 990 Schedule I (grants by public charities). It's the authoritative US source for foundation giving.

**Why are some recipient EINs blank?** Private foundations (990-PF) generally are not required to report the recipient's EIN, so that field is often empty for 990-PF grants. Public-charity grants (990 Schedule I) usually include the recipient EIN.

**How current is the data?** IRS releases e-filed returns on a rolling basis; a foundation's fiscal-year filing is typically processed 1–2 years later. Pick the most recent `years` for the freshest grants, or run several years for history.

**Can I export to Google Sheets, CSV, or Excel?** Yes — one click in the dataset view, or automatically on every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**Is this legal?** This actor uses only publicly available IRS data. You are responsible for using the data in compliance with applicable laws.

**A field is null — why?** Some filings genuinely omit a phone, purpose, or recipient address. Fields are `null` only when the data doesn't exist in the filing, not because the scraper skipped them.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

## `years` (type: `array`):

IRS processing years to pull, e.g. \["2024","2023"]. Each year is a separate official dataset of returns the IRS processed that year (a 990-PF for fiscal year 2022 is usually processed in 2023–2024). Leave empty to use the latest available year.

## `formTypes` (type: `array`):

990-PF = private foundations (the classic grantmakers; Part XV grants paid). 990 = public charities that make grants (community foundations, donor-advised funds, United Ways — Schedule I). Adding 990 finds more grantmakers but scans more filings.

## `outputMode` (type: `string`):

grants = one record per grant (funder → recipient, amount, purpose). funders = one profile per foundation (assets, total giving, payout, trustees). both = emit both record types.

## `funderEins` (type: `array`):

Look up specific foundations by EIN (9 digits, dashes optional), e.g. \["13-1684331"]. When set, only these foundations are extracted (fast, targeted).

## `funderNameQuery` (type: `string`):

Keep only foundations whose name contains this text (case-insensitive), e.g. "family foundation".

## `funderStates` (type: `array`):

Two-letter state codes of the foundation, e.g. \["CA","NY"]. Empty = all states.

## `funderCities` (type: `array`):

Foundation city names (case-insensitive), e.g. \["NEW YORK"]. Empty = all cities.

## `recipientStates` (type: `array`):

Keep only grants to recipients in these two-letter states, e.g. \["TX"]. (Grants output only.)

## `recipientNameQuery` (type: `string`):

Reverse lookup — keep only grants whose recipient name contains this text (case-insensitive), e.g. "university" or a specific nonprofit name. Find who funds an organization.

## `minGrantAmount` (type: `integer`):

Keep only grants of at least this amount.

## `maxGrantAmount` (type: `integer`):

Keep only grants of at most this amount.

## `minFunderAssets` (type: `integer`):

Keep only foundations whose end-of-year fair-market-value assets are at least this amount (targets larger, higher-capacity funders).

## `withFunderPhoneOnly` (type: `boolean`):

Drop records whose foundation has no phone number on the filing.

## `includeTrustees` (type: `boolean`):

Attach the foundation's trustees, directors and key employees (name, title, compensation) — the decision-makers. Applies to funder profiles.

## `minLeadScore` (type: `integer`):

Keep only records with a derived lead score (0–100) at or above this value.

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

none = fastest (recommended): emit results in file order and stop as soon as maxResults is reached. amount = largest grants / wealthiest funders first — this must scan the ENTIRE year, so it is much slower; on very large years or short run timeouts the run stops early and returns the largest found so far (never times out). When using amount, narrow with filters (funderStates, minGrantAmount, funderEins) or raise the run timeout.

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

Maximum number of records to return.

## `maxZipParts` (type: `integer`):

Each IRS year is split into ~100 MB ZIP parts. Limit how many are downloaded for a quick sample (e.g. 1). 0 = scan all parts (complete results). Ignored for targeted EIN lookups that finish early.

## `monitorMode` (type: `boolean`):

Remember records already returned (by funder/recipient/amount/year signature) and emit ONLY new ones on the next run of the same monitor key — ideal for a scheduled fresh-grants feed. Works alongside Apify Schedules.

## `monitorKey` (type: `string`):

Namespace for monitor-mode memory. Use a distinct key per saved configuration so their 'seen' lists don't collide.

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

Optional. The IRS public 990 datasets are downloaded directly and need no proxy; leave disabled unless your network requires one.

## Actor input object example

```json
{
  "years": [
    "2024"
  ],
  "formTypes": [
    "990PF"
  ],
  "outputMode": "grants",
  "funderEins": [],
  "funderStates": [],
  "funderCities": [],
  "recipientStates": [],
  "withFunderPhoneOnly": false,
  "includeTrustees": true,
  "sortBy": "none",
  "maxResults": 1000,
  "maxZipParts": 0,
  "monitorMode": false,
  "monitorKey": "default",
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All extracted grant and grantmaker records as JSON items in the default dataset.

# 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 = {
    "years": [
        "2024"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/foundation-grants-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 = { "years": ["2024"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/foundation-grants-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "years": [
    "2024"
  ]
}' |
apify call scrapesage/foundation-grants-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/foundation-grants-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Foundation Grants Scraper - Grantmaker & Funder Leads",
        "description": "Extract US foundation grants & grantmaker leads from official IRS Form 990-PF & 990 Schedule I e-file data: funder, recipient, grant amount & purpose, assets, payout, trustees & contact phone. Grant prospecting + B2B lead-gen + monitoring. No browser, no key.",
        "version": "0.1",
        "x-build-id": "WaEkr7zqBVj6pKTke"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/scrapesage~foundation-grants-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-scrapesage-foundation-grants-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/scrapesage~foundation-grants-scraper/runs": {
            "post": {
                "operationId": "runs-sync-scrapesage-foundation-grants-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/scrapesage~foundation-grants-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-scrapesage-foundation-grants-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "years": {
                        "title": "Filing years",
                        "type": "array",
                        "description": "IRS processing years to pull, e.g. [\"2024\",\"2023\"]. Each year is a separate official dataset of returns the IRS processed that year (a 990-PF for fiscal year 2022 is usually processed in 2023–2024). Leave empty to use the latest available year.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "formTypes": {
                        "title": "Form types",
                        "type": "array",
                        "description": "990-PF = private foundations (the classic grantmakers; Part XV grants paid). 990 = public charities that make grants (community foundations, donor-advised funds, United Ways — Schedule I). Adding 990 finds more grantmakers but scans more filings.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "990PF",
                                "990"
                            ],
                            "enumTitles": [
                                "990-PF (private foundations)",
                                "990 Schedule I (public-charity grantmakers)"
                            ]
                        },
                        "default": [
                            "990PF"
                        ]
                    },
                    "outputMode": {
                        "title": "Output",
                        "enum": [
                            "grants",
                            "funders",
                            "both"
                        ],
                        "type": "string",
                        "description": "grants = one record per grant (funder → recipient, amount, purpose). funders = one profile per foundation (assets, total giving, payout, trustees). both = emit both record types.",
                        "default": "grants"
                    },
                    "funderEins": {
                        "title": "Funder EINs (targeted lookup)",
                        "type": "array",
                        "description": "Look up specific foundations by EIN (9 digits, dashes optional), e.g. [\"13-1684331\"]. When set, only these foundations are extracted (fast, targeted).",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "funderNameQuery": {
                        "title": "Funder name contains",
                        "type": "string",
                        "description": "Keep only foundations whose name contains this text (case-insensitive), e.g. \"family foundation\"."
                    },
                    "funderStates": {
                        "title": "Funder states (filter)",
                        "type": "array",
                        "description": "Two-letter state codes of the foundation, e.g. [\"CA\",\"NY\"]. Empty = all states.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "funderCities": {
                        "title": "Funder cities (filter)",
                        "type": "array",
                        "description": "Foundation city names (case-insensitive), e.g. [\"NEW YORK\"]. Empty = all cities.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "recipientStates": {
                        "title": "Recipient states (filter)",
                        "type": "array",
                        "description": "Keep only grants to recipients in these two-letter states, e.g. [\"TX\"]. (Grants output only.)",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "recipientNameQuery": {
                        "title": "Recipient name contains",
                        "type": "string",
                        "description": "Reverse lookup — keep only grants whose recipient name contains this text (case-insensitive), e.g. \"university\" or a specific nonprofit name. Find who funds an organization."
                    },
                    "minGrantAmount": {
                        "title": "Min grant amount (USD)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only grants of at least this amount."
                    },
                    "maxGrantAmount": {
                        "title": "Max grant amount (USD)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only grants of at most this amount."
                    },
                    "minFunderAssets": {
                        "title": "Min foundation assets (USD)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Keep only foundations whose end-of-year fair-market-value assets are at least this amount (targets larger, higher-capacity funders)."
                    },
                    "withFunderPhoneOnly": {
                        "title": "Only records with a funder phone",
                        "type": "boolean",
                        "description": "Drop records whose foundation has no phone number on the filing.",
                        "default": false
                    },
                    "includeTrustees": {
                        "title": "Include trustees / officers",
                        "type": "boolean",
                        "description": "Attach the foundation's trustees, directors and key employees (name, title, compensation) — the decision-makers. Applies to funder profiles.",
                        "default": true
                    },
                    "minLeadScore": {
                        "title": "Minimum lead score",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Keep only records with a derived lead score (0–100) at or above this value."
                    },
                    "sortBy": {
                        "title": "Sort by",
                        "enum": [
                            "none",
                            "amount"
                        ],
                        "type": "string",
                        "description": "none = fastest (recommended): emit results in file order and stop as soon as maxResults is reached. amount = largest grants / wealthiest funders first — this must scan the ENTIRE year, so it is much slower; on very large years or short run timeouts the run stops early and returns the largest found so far (never times out). When using amount, narrow with filters (funderStates, minGrantAmount, funderEins) or raise the run timeout.",
                        "default": "none"
                    },
                    "maxResults": {
                        "title": "Max results",
                        "minimum": 1,
                        "maximum": 500000,
                        "type": "integer",
                        "description": "Maximum number of records to return.",
                        "default": 1000
                    },
                    "maxZipParts": {
                        "title": "Max ZIP parts to scan (advanced)",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Each IRS year is split into ~100 MB ZIP parts. Limit how many are downloaded for a quick sample (e.g. 1). 0 = scan all parts (complete results). Ignored for targeted EIN lookups that finish early.",
                        "default": 0
                    },
                    "monitorMode": {
                        "title": "Monitor mode (only new records)",
                        "type": "boolean",
                        "description": "Remember records already returned (by funder/recipient/amount/year signature) and emit ONLY new ones on the next run of the same monitor key — ideal for a scheduled fresh-grants feed. Works alongside Apify Schedules.",
                        "default": false
                    },
                    "monitorKey": {
                        "title": "Monitor key",
                        "type": "string",
                        "description": "Namespace for monitor-mode memory. Use a distinct key per saved configuration so their 'seen' lists don't collide.",
                        "default": "default"
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Optional. The IRS public 990 datasets are downloaded directly and need no proxy; leave disabled unless your network requires one.",
                        "default": {
                            "useApifyProxy": false
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
