If you give money to other organizations (a small family foundation, a giving circle, a donor-advised fund sponsor, a fiscal sponsor, a company matching employee gifts, a donation platform), you have to check that each recipient is still a charity the IRS recognizes. Groups lose their exemption every month: the IRS revokes it automatically when an organization skips its annual filing three years in a row.
The IRS lookup site, Tax Exempt Organization Search, checks one organization at a time. Paid services check in bulk. The data behind both is public, so I built charity-check, a free and open tool that does the bulk check on your own computer.
What it does
Give it the spreadsheet you already have, as long as it has an EIN column:
python charity_check.py grantees.csv -o checked.csv
It downloads three IRS files: Publication 78 (organizations eligible to receive tax-deductible gifts), the automatic-revocation list and, with --bmf, the Exempt Organizations Business Master File (1.96 million rows). It caches them and writes your file back with new columns for every row:
-
irs_status:eligible,revoked,listed_bmf_not_pub78(common for churches and group subordinates),exempt_not_501c3,review,not_foundorinvalid_ein - the Pub 78 deductibility code (PC, PF, SO, SONFI and so on) and what it means
- revocation and reinstatement dates
- the foundation code and ruling year, from the Master File
- flags worth a second look before a grant:
private_foundation,type3_non_functionally_integrated,foreign_address,group_subordinate,reinstated_after_revocationand others -
irs_checked_on, so the output can serve as your record
Spreadsheet damage is handled: EINs with dashes, without dashes, saved as 530196605.0, or missing the leading zero all work.
Why offline
A grantee list or a donor's matching requests are private. charity-check only downloads the public IRS files and does the matching locally, so your list never leaves your machine. It uses only the Python standard library, with nothing to install.
Limits, plainly
The IRS files lag by a few weeks. Group-exemption subordinates are not listed one by one, and churches don't have to apply for recognition, so not_found means "look it up", not "bad". For a large or unusual grant, confirm in TEOS. This is information from public IRS data, not legal or tax advice.
Code, tests and docs: https://github.com/munimv2/charity-check (MIT). Issues and ideas are welcome, especially from people who do grantee due diligence every month.
charity-check was made by MV2 of Munim, Inc. with AI agents, and the code and this post were written with AI.
Top comments (0)