IRS 990 Scraper icon

Lead generation

IRS 990 Scraper — Nonprofit Officer Comp

Scrape IRS Form 990 nonprofit officer compensation and key financials as structured rows via the ProPublica Nonprofit Explorer API — bulk EIN lookup or name/state search, one row per filing year, 990 / 990EZ / 990PF field mapping — export to JSON or CSV. No key, no login.

Free Apify credit covers a first run. No credit card to try.

What this Actor scrapes

One ResultRow per (EIN, tax year) filing. Every row carries the same 21 columns regardless of which input mode you used. Data is published by ProPublica under their Terms of Use (IRS source data is public domain).

What we handle for you

  • Two input modeseins (explicit list) and searchQuery (name search). Pydantic XOR validator enforces exactly one before any network call. EIN normaliser accepts 13-1684331, 131684331, or integer forms.
  • Formtype-correct field mapping — officer comp lives in compnsatncurrofcr on 990/990EZ and compofficers on 990PF. We pick the right field for each form so you never get a null officer-comp row for a private foundation.
  • Year-window filteringstartYear and endYear default to the last 3 calendar years. Out-of-window filings are dropped silently.
  • Computed total compensation and benefits — sum of officer comp + non-officer salaries + payroll tax + pension + other benefits, computed per filing. Null only when all 5 components are null; never falsely zero.
  • State filter (search mode) — pass stateFilter=CA to scope a name search to a single state via search.json?state[id]=.
  • Multi-form support — 990, 990EZ, and 990PF all produce clean rows. Unknown formtypes are logged and dropped (forward-compatible with new IRS forms).
  • We handle retries with exponential backoffRetry-After headers honoured for 429 and 503 responses; up to 5 attempts per request before we surface a clear error.
  • We rotate browser fingerprintscurl-cffi with Chrome 131 TLS impersonation so the upstream sees real-browser TLS handshakes, not a Python script.
  • We rotate proxies on every block — Apify Proxy support via the BUYPROXIES94952 group keeps requests flowing through fresh exit IPs.
  • Pydantic v2 input and output models — form_type validated against the enum ("990" / "990EZ" / "990PF"); EINs zero-padded to 9 digits; typed rows guaranteed.

Use cases

  • Nonprofit executive-pay benchmarking — bulk-pull officer compensation for a list of 100–1,000 peer organisations to benchmark CEO/CFO pay against revenue and asset size.
  • Investigative journalism — flag nonprofits where officer comp is an outsized fraction of revenue or expenses; spot rapid year-over-year jumps across sector-wide datasets.
  • Foundation due diligence — research a foundation's officer payroll and asset trajectory before applying for a grant or entering a partnership.
  • Charity-rating data pipelines — feed a structured 990 dataset into your own scoring model without writing a ProPublica wrapper from scratch.
  • Academic research — build multi-year panel datasets on nonprofit-sector compensation and finances for economics or public-policy papers.
  • State-level nonprofit-sector reports — combine stateFilter with a broad searchQuery (e.g. "foundation") to enumerate an entire state's nonprofit landscape in one run.
  • Prospect research for nonprofit-tech vendors — enrich your CRM with 990-derived financials for sales outreach to development directors at larger organisations.

Input

Paste this into the Apify Console, or send it as the run input over the API. Proxy settings are on by default; you rarely need to touch them.

FieldTypeRequiredWhat it does
eins array no Explicit IRS Employer Identification Numbers to fetch (9 digits, hyphens optional, e.g. 13-1684331 or 131684331). XOR with searchQuery.
searchQuery string no Free-text search across nonprofit names. Resolves to a list of EINs via ProPublica's search.json endpoint, capped by maxOrgs. XOR with eins.
stateFilter string no USPS 2-letter state code (e.g. CA, NY, TX). Applied to search mode only; ignored in eins mode.
startYear integer no Earliest tax_prd_yr to include. Defaults to current year minus 3.
endYear integer no Latest tax_prd_yr to include. Defaults to current year.
maxOrgs integer no Hard cap on EINs resolved from searchQuery. Ignored in eins mode.
useProxy boolean no Route requests through Apify Proxy (BUYPROXIES94952). ProPublica does not currently rate-limit datacenter IPs; leave off unless you see 429.
{
  "eins": [
    "131684331"
  ],
  "maxOrgs": 100,
  "useProxy": false
}

Output

One row per result, schema-validated before it is written. Export JSON, CSV, Excel or XML from the run, or read it over the API.

einorganization_nameorganization_urlstatecityntee_codesubsection_codetax_yeartax_period_endform_typepdf_urlofficer_comp_usdother_salaries_wages_usdpayroll_taxes_usdpension_contributions_usdother_employee_benefits_usd

{
  "ein": "131684331",
  "organization_name": "Metropolitan Museum of Art",
  "organization_url": "https://projects.propublica.org/nonprofits/organizations/131684331",
  "state": "NY",
  "city": "New York",
  "ntee_code": "A51",
  "subsection_code": 3,
  "tax_year": 2022,
  "tax_period_end": "2022-06",
  "form_type": "990",
  "pdf_url": "https://projects.propublica.org/nonprofits/organizations/131684331/202341349349303881/full",
  "officer_comp_usd": 4872543,
  "other_salaries_wages_usd": 198345612,
  "payroll_taxes_usd": 15234871,
  "pension_contributions_usd": 18924301,
  "other_employee_benefits_usd": 22341887,
  "total_comp_and_benefits_usd": 259719214,
  "total_revenue_usd": 412345678,
  "total_functional_expenses_usd": 389234512,
  "total_assets_end_usd": 5234123456,
  "scraped_at": "2024-03-15T14:22:31Z"
}

Pricing

EventPriceWhen
Actor start$0.20Once per run, covers warm-up and proxy session setup.
Result row emitted$0.0030Per result written to the dataset.

You pay only for results that land. Cap any run with maxTotalChargeUsd. See pricing & billing for worked examples.

Limitations

  • Per-officer breakdown (name / title / hours / individual comp from Part VII Section A) — that detail lives only in the 990 PDF and is not exposed by ProPublica's structured API. v1 emits the aggregate Part IX line 5 / 990PF Part I line 15 officer-compensation total. Per-officer PDF parsing is on the v2 roadmap.
  • Compensation from related organisations (Schedule J Part II) — same reason; PDF-only.
  • Filings older than approximately 2010 — ProPublica's structured coverage does not extend earlier.
  • Annual filing cadence — 990s file annually, often with an 18-month lag. This Actor provides historical and benchmark data, not a real-time feed.
  • 990-N (e-Postcard) — the very smallest nonprofits file 990-N, which has no financial detail. These organisations are not returned.

FAQ

What is an IRS 990 scraper?
An IRS 990 scraper extracts structured data from Form 990 filings — the annual information returns that US tax-exempt organisations must file with the IRS. ProPublica's Nonprofit Explorer API is the most reliable public source for this data; this Actor wraps it with formtype-correct field mapping and computed compensation totals.
How does this differ from ProPublica's bulk download?
ProPublica offers a bulk CSV of their structured API output. This Actor adds three things: (1) formtype-correct officer-comp field selection across 990, 990EZ, and 990PF so you never get null values for private foundations; (2) a computed total_comp_and_benefits_usd field; and (3) on-demand EIN or name-search queries without downloading the entire bulk file.
What is a nonprofit data API?
A nonprofit data API is a programmatic interface for accessing information about tax-exempt organisations — typically financial data, officer compensation, mission statements, and EIN identifiers sourced from IRS Form 990 filings. ProPublica's Nonprofit Explorer API is the canonical free source; this Actor structures its output into typed rows.
How do I do a form 990 data download for a specific sector?
Use searchQuery mode with a sector keyword (e.g. "hospital", "education", "housing") and optionally set stateFilter. Set maxOrgs to control the batch size. The resulting dataset exports as CSV, JSON, Excel, or XML from the Apify Console.
Does this support 990PF (private foundations)?
Yes. 990PF officer comp lives in a different API field (compofficers) than the standard 990/990EZ field (compnsatncurrofcr). We pick the correct field per filing so private foundations always return a populated officer_comp_usd value.
Can I use this for nonprofit officer compensation data research?
Yes. The Actor is designed for exactly this use case — benchmarking executive pay across peer organisations, building sector-wide compensation panels, and conducting foundation due-diligence research. Set startYear and endYear to build multi-year panels.
What is the 990 financial data API pricing?
$0.003 per row plus a $0.05 start fee. A 100-org, 3-year window run produces roughly 300 rows and costs approximately $0.95. There is no subscription or minimum spend.
Is the underlying data public domain?
IRS Form 990 data is public domain. ProPublica's Nonprofit Explorer API is subject to their Terms of Use, which permits commercial use.

Ready to run it?

Open the listing on Apify, paste the input above, and watch rows land. If it ever breaks, it is our problem before it is yours.

Related Actors

Teams that run this also run