matchdb stores names and addresses long: one row per string observed for an EIN, each tagged with the source that reported it, the source version, and how often and when it was seen. Nothing is merged away at load time. The BMF’s legal name, the spelling on the organization’s own 990, and the spelling fifty grantmakers wrote on Schedule I are three rows, not one.
This vignette lists the sources, what each one contributes, and how to choose among them.
The registry
md_sources() lists every upstream input with its URL. Nothing is fetched that is not in the registry.
library(matchdb)
md_sources()[, c("source", "feeds", "url")]| source | what it contributes |
|---|---|
| BMF (unified, geocoded) | every EIN the IRS has listed; legal name, DBA, in-care-of name, mailing address, ruling date, NTEE, subsection, group exemption |
| e-file 990 headers | the filer’s own legal name and DBA, former names, the mailing address on each return, websites |
| Schedule I | names and addresses grantmakers wrote for the EINs they paid (observed) |
| Schedule R | related organizations each filer disclosed, with names and addresses (observed, and relations) |
| Schedule R parts I, III, IV; Schedule C; affiliate listings; group-exemption metadata | relations between EINs: disregarded entities, related partnerships and corporations, group members |
| Form 1023-EZ approvals | legal name, address and NTEE at approval, 2014–2023 |
| 990-N e-Postcard | legal name, DBAs, mailing address and website of small organizations; the date the postcard filing stopped |
| automatic revocations | names, the last address, and revocation, posting and reinstatement dates |
| Part VII officers | name keys of officers, directors and key employees, used only to link EINs that share people. No titles, no compensation |
| mission and program text | the 990 Part III text, for review and classification |
| NCCS address history, crosswalks and geocodes | historical addresses, counties, CBSAs and census tracts |
How much each source contributes
Rows in name by class and source, build of 2026-11-01:
| class | source | rows |
|---|---|---|
| legal | bmf | 3,698,197 |
| legal | e_postcard | 1,534,620 |
| legal | revocations | 1,188,531 |
| legal | efile990 | 809,925 |
| legal | f1023ez | 512,470 |
| dba | bmf | 923,305 |
| dba | revocations | 238,758 |
| dba | e_postcard | 67,058 |
| dba | efile990 | 59,879 |
| former | efile990 | 204,926 |
| in_care_of | bmf | 1,429,600 |
| in_care_of | efile990 | 169,288 |
| observed | schedi | 1,767,331 |
| observed | schedr | 187,999 |
| observed | efile990 | 9,479 |
The observed rows under efile990 are the group-return rosters: a central organization listing its subordinates, each by its own name.
A name reported by several sources is several rows. When a reference is compiled, rows that normalize to the same name_key for the same EIN collapse into one row. That row takes its class from the strongest class among them (legal before dba before observed). Its spelling comes from the strongest class’s own rows, most frequent first.
First-party and third-party sources
The distinction that matters most is who wrote the string.
-
First-party: the IRS or the organization itself. That covers the BMF, the organization’s own 990 header, its 1023-EZ, its e-Postcard and the revocation list. These give the classes
legal,dba,formerandin_care_of. -
Third-party: another organization writing about this one. That covers a grantmaker on Schedule I and a related organization on Schedule R. These give the class
observed.
Third-party names are what make matchdb more than the BMF. A grantmaker writes AMERICAN RED CROSS, not AMERICAN NATIONAL RED CROSS, and a matcher that has seen that spelling can match it directly. But a third party can be wrong: a typo, the wrong EIN, or a fiscal sponsor’s EIN written for each of its projects. That is what corroboration measures and what the guards flag; see vignette("corroborators").
Choosing sources
md_spec(sources = ...) keeps only strings from the named sources:
# exactly what the BMF says, nothing else; this is pfmatch's reference
bmf_only <- md_spec(layers = "bmf_active", names = c("legal", "dba"),
addresses = "mailing", sources = "bmf")
# every source (the default)
everything <- md_spec(layers = "bmf_active", names = c("legal", "dba", "observed"),
addresses = c("mailing", "observed"), min_corroborators = 2)Usually you choose by class (names =, addresses =) rather than by source, and leave sources = NULL. The classes already separate first-party names from third-party ones. A source filter is useful mainly for reproducing a single-source frame, as the Phase 1 gate does. It also has a cost: names are collapsed across sources, so a source filter cuts across the precomputed statistics, and those statistics are then computed directly from the selected rows. The report says so.
The source codes md_spec() accepts:
names(md_name_sources())
#> "bmf" "efile990" "f1023ez" "schedi" "schedr" "e_postcard" "revocations"
names(md_address_sources())
#> "bmf" "efile990" "f1023ez" "schedi" "schedr" "meta_address" "e_postcard" "revocations"Provenance: every version is pinned
Some upstream URLs are moving pointers: latest/ changes without notice. Before any ingest reads a source, md_source_pin() downloads it and writes a PIN.dcf beside the copy with the URL, the upstream modification time, the size and the md5. The ingest reads the pinned copy, and the source_vintage table records which pinned version loaded each table. Two builds from the same pins are the same database.
con <- md_db(read_only = TRUE)
DBI::dbGetQuery(con, "SELECT source, version, table_name, local_md5, row_count
FROM source_vintage ORDER BY source")
md_db_close(con)The published database on S3 ships a MANIFEST.json with every pin, so a downloaded copy states exactly what it was built from:
md_fetch_db() # 11.8 GB
jsonlite::read_json(md_path("db", "MANIFEST.json"))$sourcesSeeing the sources for one organization
md_lookup() returns every name and address with its source: