home

Read before using this data

This page describes what is actually in the MyTown research corpus: where each table came from, which parts of it a language model wrote, what the table names overpromise, and which numbers are wrong if you add them up. It is generated from the served database itself, so the counts below are the counts you will get when you query.

Snapshot measured 2026-08-07 06:28 UTC. Database file dated 2026-08-07 06:21 UTC, 42.1 GB. 74 tables, 94,727,099 rows. Regenerate with venv/bin/python research_methodology.py.
74tables
94,727,099rows
84,945,794source records
3,799,780derived rows
3,437,756AI-derived rows
17scope warnings
  1. Three kinds of row, and why the difference matters
  2. Why a row count of 33 million is wrong
  3. Scope versus name: tables that promise more than they hold
  4. Hard row caps in the loaders
  5. How municipalities are matched, and how that fails
  6. Duplicates, amendments, and what you must not SUM
  7. Is this download the whole corpus?
  8. Measured error rates, and where there are none
  9. Table-by-table inventory
  10. Citing and reproducing

1. Three kinds of row, and why the difference matters

Every table here is one of three things. The distinction is not cosmetic: it decides whether a row is evidence, an inference, or a claim that still needs checking.

Source record

Copied essentially verbatim from an official public source. The government published these fields; this project moved them. If a value is wrong, the source is wrong. meetings, member_votes, cf_transactions, food_inspections and public_salaries are the clearest examples. Even here, what was collected is a choice: see the scope and cap sections.

Structured / derived

Produced by code, not by a model and not by a government: parsed out of a PDF, geocoded, rolled up, scored, or joined to a municipality by name. No language model is involved, so it is reproducible, but a derived value can still be wrong because the parse or the join was wrong. decision_geo, fiscal_health, police_stops_rollup and service_requests_rollup are derived. So is municipalities itself.

AI-derived

A language model read a document and wrote the content of the row. These rows are leads, not findings, and every one of them links back to the document it came from. briefs, decisions, roundups, matters and the extracted fields of surveillance_spending are AI-derived. Nothing in this class should be published without opening the linked source. Where a table records which model wrote a row, the column is called model.

Three tables mix classes in one table. member_votes is overwhelmingly copied from vendor roll-call APIs but contains a small regex-parsed remainder and a smaller model-extracted remainder. matters mixes an agenda API with model extraction. officials mixes an API with model extraction and has no column that separates the two. Filter on source and model before treating any of those three as uniform.

Unclassified in this generator, so treat as unknown provenance: _export_meta, _export_progress, assisted_contracts, audit_findings, datacenter_moratoriums, debt_issues, election_results, fac_audits, fac_findings, fec_candidates, fec_committee_links, fec_committees, fema_grants, lihtc_projects, lobbying_expenditures, ma_election_results, official_elections, openmeetings_findings, people, people_aliases, people_cf_bridge, people_cf_candidates, person_vote_stats, settlements, usda_rd_properties.

2. Why a row count of 33 million is wrong

The database file contains 99 SQLite tables holding 109,963,413 rows in total. That larger number is not the size of the corpus, and quoting it would be a mistake. 15,236,314 of those rows belong to 25 full-text search index tables and their internal shadow tables. They are a search index over rows that are already counted, not additional records.

The clearest proof is that each index has exactly as many rows as the table it indexes:

base tablerowsFTS indexrowsinternal shadow tables
briefs1,318,271briefs_fts =1,318,271briefs_fts_config, briefs_fts_data, briefs_fts_docsize, briefs_fts_idx
decisions486,268decisions_fts =486,268decisions_fts_config, decisions_fts_data, decisions_fts_docsize, decisions_fts_idx
meeting_attachments691,746meeting_attachments_fts =691,746meeting_attachments_fts_config, meeting_attachments_fts_data, meeting_attachments_fts_docsize, meeting_attachments_fts_idx
member_votes4,819,245member_votes_fts =4,819,245member_votes_fts_config, member_votes_fts_data, member_votes_fts_docsize, member_votes_fts_idx
settlements2,468settlements_fts =2,468settlements_fts_config, settlements_fts_data, settlements_fts_docsize, settlements_fts_idx

The corpus is 94,727,099 rows across 74 tables. The full-text tables are visible because Datasette shows everything in the file. There is no hidden dataset.

3. Scope versus name: tables that promise more than they hold

This is the section most likely to save you from publishing something false. Several table names read as national when the table holds one or two jurisdictions, and several row counts are the size of a fetch limit rather than the size of a dataset. The warnings below are computed automatically at generation time, not written by hand, by rules that look for: a single state holding more than 90% of rows, a handful of states holding essentially all of them, a row count equal to a loader cap or suspiciously round, fewer than eleven jurisdictions in a table of any size, no municipal join at all, and a snapshot that has fallen well behind the live database.

tablerowswhat the measurement shows
gov_payments1,483,357⚠ effectively 3 jurisdictions (TN, LA, FL) hold 100% of rows: the name suggests broader coverage than the table has
⚠ only 4 jurisdictions in the whole table
civic_records213,049⚠ 95% of rows are TN: the name suggests broader coverage than the table has
fac_audits170,436⚠ this snapshot holds 54% of the roughly 313,444 rows now live upstream: the snapshot predates a recent load
school_finance120,160⚠ 100% of rows are TX: the name suggests broader coverage than the table has
ma_election_results87,307⚠ 100% of rows are MA: the name suggests broader coverage than the table has
debt_issues77,086⚠ 100% of rows are CA: the name suggests broader coverage than the table has
staar_results53,631⚠ 100% of rows are TX: the name suggests broader coverage than the table has
local_sales_tax51,997⚠ 100% of rows are TX: the name suggests broader coverage than the table has
fac_findings50,666⚠ this snapshot holds 79% of the roughly 64,175 rows now live upstream: the snapshot predates a recent load
property_sales38,935⚠ effectively 2 jurisdictions (MA, FL) hold 100% of rows: the name suggests broader coverage than the table has
⚠ only 2 jurisdictions in the whole table
people_aliases21,636⚠ this snapshot holds 70% of the roughly 31,078 rows now live upstream: the snapshot predates a recent load
people20,469⚠ this snapshot holds 76% of the roughly 27,071 rows now live upstream: the snapshot predates a recent load
service_requests_rollup6,898⚠ only 6 jurisdictions in the whole table
openmeetings_findings4,073⚠ effectively 2 jurisdictions (MA, IA) hold 100% of rows: the name suggests broader coverage than the table has
warn_notices2,827⚠ effectively 3 jurisdictions (TX, OR, CA) hold 100% of rows: the name suggests broader coverage than the table has
audit_findings2,588⚠ 100% of rows are WA: the name suggests broader coverage than the table has
service_requests_recent100⚠ 100% of rows are LA: the name suggests broader coverage than the table has
The worked example. official_disclosures sounds like a national register of public officials' financial interests. It is a single state's filing index, and its row count was for months exactly 50,000, which was the loader's fetch limit rather than a count of anything: Washington publishes far more than that. The limit was removed from the loader on 2026-07-30 and the loaders now assert that a walk reached the count the source itself reports, but this snapshot still holds the truncated pull. A cap published as a row count is the most dangerous artefact in a data project, because it looks like a finding.

Two more that the name will mislead you about. state_votes is one state and one session, and it holds chamber vote totals rather than per-legislator votes. gov_payments mixes federal awards attached to a place by point of performance with genuine municipal disbursements under the same muni_id, so you must filter on source before saying a town paid a vendor.

4. Hard row caps in the loaders

Every cap below is read out of this repository's source at generation time. A cap means the loader stopped fetching, so the row count is a floor and the missing rows are not random: most loaders walk in a fixed order, so what is missing is one end of the dataset.

A cap in the code today is not the cap a table was loaded under. These limits are being raised as loaders are made to walk their sources completely, and a table keeps its truncated row count until it is re-pulled. So a row count here can reflect an older, lower limit than the one listed below, which is why section 3 flags suspiciously round counts independently of what the code currently says. The loaders now also compare what they fetched against the row count the source itself reports, and warn when a walk finishes short.
loaderconstantcapappliestable in this corpus
public_salaries.pyDEFAULT_MAX_ROWS2,000,000per municipalitypublic_salaries
socrata_cf.pyDEFAULT_MAX_ROWS1,000,000per Socrata datasetcf_transactions
netfile_enrich.pyMAX_ROWS500,000per filing agencycf_transactions
crime_arcgis.pyDEFAULT_MAX_ROWS400,000per citynot in this snapshot
crime_open_data.pyDEFAULT_MAX_ROWS400,000per citynot in this snapshot
gov_contracts.pyDEFAULT_MAX_ROWS250,000per Socrata datasetgov_contracts
nc_sboe.py--max-rows default150,000per runcf_transactions
tx_tec.py--max-rows default150,000per runcf_transactions
fec_enrich.py--max-rows default100,000per runcf_transactions
epa_environment.py--max-rows default30,000per statewater_violations
lobbying.pyDEFAULT_MAX_ROWSno capper Socrata datasetofficial_disclosures, lobbying_registrations

Beyond row caps, three text limits shape what the models ever saw: agenda and minutes text is truncated before a brief is written, extraction prompts see a few thousand characters of a document, and attachment text is truncated per document. A figure buried past those limits is absent from the derived tables even though the source document contains it. That is a coverage gap, not a contradiction.

5. How municipalities are matched, and how that fails

municipalities is the join key for most of this corpus: 8,372 rows covering 6,347 city, 1,297 school, 701 county, 27 district. It is a registry of governments whose agenda portal was located, which means its composition reflects which vendors sell in which states, not which places exist.

The unique key is not the name

The only unique constraint on the table is slug, a vendor client identifier. (name, state) is not unique. In this snapshot 282 name-and-state pairs are duplicated across 572 rows. Two causes: one physical city registered on two agenda platforms becomes two rows with two ids, and a city, a county and a school district very often share a name. 16 name-and-state pairs span more than one kind, including Box Elder County UT, Burnet County TX, Churchill County NV. Joining on a name will silently merge or split governments. Join on muni_id, and check kind.

How an external row becomes a muni_id

There is no Census place GEOID column on municipalities, so no dataset can be joined the authoritative way, by identifier. Every loader instead resolves a name and a state, and the loaders differ in how careful they are. Reading the code, there are four behaviours, in descending order of safety:

  1. Skip on ambiguity. The state financial loaders build a name-plus-kind index and refuse to attach a row that matches zero or several municipalities, logging the miss. warn_notices does the same and keeps the city and county text, so its text columns are more complete than its join.
  2. Delete ambiguous keys up front. The disclosure loader drops any duplicated name from its index, so an ambiguous name resolves to NULL rather than to the wrong town.
  3. Take the first or lowest match. Some loaders pick one row and print a warning. Given the duplicate pairs above, that is a real mislabelling risk.
  4. Scan free text for any municipality name. dot_projects assigns muni_id by searching a project description for a municipality name in that state. It is the weakest join here and should be treated as a hint.

The failure modes to expect

  • A mailing city is not the approving jurisdiction. Parcel and permit sources often carry a postal city. An address that mails to a city can sit in unincorporated county land, and the county, not the city, approved it.
  • County figures wearing a city's name. Several enrichment tables (air_quality, literacy, evictions, mobility_outcomes) are published at county grain and attached to the places inside that county. The value is the county's. A city spanning counties is approximated by one primary county.
  • A name that strips to another name. Normalisers that remove the word County make a county and a same-named town collide.
  • Same name, different state, and the state field is not always clean. 51 state values in this snapshot are still unnormalised (?, Alabama, Alaska, Alberta, Arizona, Arkansas, British Columbia, California, Colorado, Connecticut, Delaware, Florida, Georgia, Idaho, Illinois, Indiana, Iowa, Kansas, Kentucky, Louisiana, Maine, Maryland, Massachusetts, Michigan, Minnesota, Mississippi, Missouri, Montana, Nebraska, New Hampshire, New Jersey, New Mexico, New York, North Carolina, North Dakota, Ohio, Oklahoma, Ontario, Oregon, Pennsylvania, Rhode Island, South Carolina, South Dakota, Tennessee, Texas, Utah, Virginia, Washington, West Virginia, Wisconsin, Wyoming), a residue of a full-name to two-letter migration. Normalise before grouping by state.
  • Absence is usually coverage, not fact. No vote rows for a town almost always means that town does not publish roll calls, not that its council votes unanimously.

6. Duplicates, amendments, and what you must not SUM

This project published a number that was 2.9 times too high, and this is the section that exists because of it. On 2026-07-29 an external audit found that a headline surveillance-spending total had summed a single procurement once at each stage it appeared in the record, at committee, at council, at approval, at amendment and at renewal, and had also counted not to exceed authorisation ceilings as if they were payments. The corrected figure was roughly a third of the published one. The error was in the aggregation, not the rows: every individual row was grounded in a real document.

The same arithmetic, measured live from this snapshot:

aggregateline itemstotal
Naive SUM(amount) over every row, which is wrong4,390$2.23B
Deduplicated, stated amounts only, flagged rows and non-surveillance categories excluded2,486$784.8M

The naive total is 2.8 times the defensible one. The defensible figure covers 853 governments and 122 vendors, and it is still a floor rather than a measurement, because nothing in the record distinguishes an amendment from the original award.

What the difference is made of:

amount_typerowssumwhat it means
stated3,338$1.45Ba figure stated as an amount. The only class worth aggregating.
ceiling802$602.5Ma not-to-exceed or maximum authorisation. A cap, not a payment.
recommended116$75.0Ma staff recommendation. May never have been voted on.
estimated89$54.4Man estimate in the document.
proposed45$50.9Ma proposal. May never have passed.

Independently of that, dup_rank marks redundant copies of the same figure: 409 rows are ranked below the canonical one. 382 rows are flagged geo_suspect, meaning the city attribution disagrees with the source link, and 21 are flagged anomaly, meaning the figure is implausible for that jurisdiction and needs a human. Note that amount_type is recovered by regular expression from the quoted text, so it is a good filter and not a guarantee.

Tables that must never be naively summed

surveillance_spending
A discovery index of dollar figures found in meeting documents. The same procurement recurs at every procedural stage and there is no stage column. Use the deduplicated, stated-only filter, or count governments rather than dollars.
gov_payments
Federal awards and municipal disbursements share the table and the muni_id. Filter on source first. Summing across sources produces a number that describes nothing.
gov_contracts
amount means awarded value in one dataset, an encumbrance in another and an amount paid in a third, because the column mapping is heuristic across incompatible schemas. Never sum across dataset_id.
cf_transactions
Contributions and expenditures coexist and jurisdictions overlap, so a donor can appear at federal, state and local level. Filter on level, state and txn_type, and remember several loaders are capped, so a total is a floor.
matters
Unit counts, acreage and dollar values on model-extracted rows are per agenda item, and an item can be continued across meetings. Summing units across a project's whole approval path double counts the project.
meetings, meeting_attachments
Counting rows measures portal coverage, not civic activity. A town with more meetings here may simply have a more cooperative vendor.
*_rollup tables
Already aggregated. Summing a rollup across periods or categories re-aggregates, and the underlying detail is not in this database at all, so nothing here can be re-derived from first principles.

Before quoting any aggregate from this corpus, run the adversarial checks in claim_check.py in the MyTown repository. It implements nine tests, each of which exists because a real published claim failed it: duplicate inflation, unit confusion, category drift, definition drift, boundary pileup (a value clustering at a round number is usually a truncation), entity resolution, outlier plausibility, coverage versus capability, and source grounding. The surveillance_data_quality saved query on this site reports the same flags for the table above.

7. Is this download the whole corpus?

Mostly yes, and this is a correction to an earlier description of this database as a sample. The exporter copies every table in its list in full: the large tables are streamed in batches by primary key until exhausted, which is a complete copy done in pieces, not a sample. What you should actually expect is a point-in-time snapshot that lags the live database, rebuilt nightly.

Comparing this snapshot against approximate live row counts:

tablein this snapshotlive (approx)share
fac_audits170,436313,44454%
people_aliases21,63631,07870%
people20,46927,07176%
fac_findings50,66664,17579%
person_vote_stats20,46921,77394%
property_sales38,93541,01595%
lobbying_registrations4,518,2784,755,17495%
state_bills1,454,9041,459,307100%

The big narrative tables sit within a few percent of live, which is ordinary snapshot lag. Anything far below that is a table loaded after this snapshot was built, and the per-table inventory flags it. The live counts are planner estimates, deliberately read from catalogue statistics rather than by scanning a production table.

Two structural exceptions worth stating plainly. Some columns are stripped on export, including raw source payloads and internal error text, so the snapshot is narrower than the live schema even where it is complete in rows. And some tables that exist upstream are not exported at all, most importantly the full agenda and minutes TEXT: the derived tables here quote and link it, but the corpus of documents itself is not in this file.

surveillance_spending is not in the exporter's table list. It is built by a manual pipeline directly into the served file, so unlike every other table on this site it does not participate in the nightly rebuild and its contents reflect whenever that pipeline was last run by hand.

8. Measured error rates, and where there are none

One error rate here is actually measured. A checker extracts the hardest-to-fake claims from each AI-written brief, dollar figures and vote tallies, and tests whether each one is grounded in the source document. The matcher is deliberately aware of rounding, summing and approximation, so correctly rounding $5,283,795 to $5.28M, or summing two line items, is not counted as fabrication. Last run 2026-07-16 over 372,472 briefs that still had their source text stored:

resultcountshare
Briefs asserting no dollar figure or vote tally (nothing to ground)296,82179.7%
Briefs where every checkable claim was grounded73,56319.7%
Briefs with at least one claim the checker could not ground2,0880.6%

Read against briefs that make a checkable claim at all, the automated flag rate is 2.8%. At the level of individual claims, 295,138 of 297,775 dollar figures were grounded, a 99.1% grounding rate. Hand review of the flagged set found that most flags were correct summarisation the matcher could not follow rather than invention, which puts true fabrication under one percent. That is a good number and it is still not zero: a one-in-a-hundred error rate on a million rows is thousands of wrong rows, which is exactly why every AI-derived row links to its source.

The weak spot, stated because it is ours. Vote tallies ground far worse than dollar figures: only 185 of 281 tallies in the sample could be grounded, 66%. The commonest cause is structural, a brief written from an agenda naming a tally that an agenda cannot contain, which is the single likeliest place to find a fabrication in this corpus. Treat a vote tally in briefs as unverified. For actual votes use member_votes, which is copied from roll-call APIs.

Where there is no measured error rate

Saying so is more useful than an estimate. Not yet measured: extraction accuracy for decisions, matters and surveillance_spending, beyond the flag counts above and spot audits of individual ledgers; the precision of municipal name matching per loader; geocoding accuracy in decision_geo; the false-negative rate everywhere, which is the largest unknown in the project, since nothing here can tell you what a scraper never saw. Where an audit has been done it is a sample with a date, not a guarantee.

Two things that are enforced by construction rather than measured. A quoted passage in surveillance_spending is verified to appear verbatim in the source text before the row is stored, and the dollar figure must appear as money inside that quote. And unmatched rows are left NULL rather than being attached to a plausible municipality, so missing joins are visible as gaps instead of hiding as wrong answers.

9. Table-by-table inventory

Every table in the file, measured. Class is the provenance class from section 1. Span is the range of the most meaningful date column in the table, named in the cell; where the only date is an ingest timestamp it says so, because that is when the row was fetched, not when the event happened. Govts counts distinct muni_id, resolving through meetings where a table is keyed by meeting.

tableclassrowsspangovtsstatesrefresh
cf_transactionsSource record45,636,3501972-09-02 to 2202-06-30
txn_date
-57Weekly
food_inspectionsSource record10,413,1820002-12-06 to 2026-07-31
inspection_date
12212Monthly
professional_licensesSource record7,831,3481800-11-09 to 2090-05-01
issue_date
9139Monthly
member_votesSource record Structured / derived AI-derived4,819,2452026-07-18 to 2026-08-07 (ingest time)
created_at
98960Daily
lobbying_registrationsSource record4,518,2781905 to 3017
year
1,06115Monthly (Washington only; the federal loader is not scheduled)
public_salariesSource record3,539,7912012 to 2026
year
59710Monthly
business_formationsSource record3,105,3411864-03-05 to 2026-07-31
formation_date
3,34974Monthly
meetingsSource record2,034,8490006-12-16 to 9999-09-10
meeting_date
7,070107Hourly and daily
gov_contractsSource record1,767,3201990-11-16 to 2027-07-31
award_date
2878Monthly
gov_paymentsSource record1,483,3571974-09-01 to 2026-12-16
txn_date
43Manual, not scheduled
state_billsSource record1,454,9041985-02-05 to 2028-07-01
latest_action_date
-50Monthly
briefsAI-derived1,318,2712026-07-04 to 2026-08-07 (ingest time)
created_at
6,949107Hourly, plus continuous drain services
state_votesSource record1,175,1611969-12-31 to 2026-06-30
vote_date
-50Monthly
official_disclosuresStructured / derived1,065,7862004 to 2033
disclosure_year
34010Monthly
fema_grantsunclassified846,6272026-07-30 to 2026-08-01 (ingest time)
updated_at
3,76756-
lobbying_expendituresunclassified786,2351992 to 2104
year
2547-
meeting_attachmentsStructured / derived691,7462026-07-28 to 2026-08-06 (ingest time)
fetched_at
1,45468Continuous
decisionsAI-derived486,2682026-07-05 to 2026-08-07 (ingest time)
created_at
4,581100Hourly, plus drains
civic_recordsStructured / derived213,0491987-06-03 to 3200-12-31
issued_date
7930Manual, not scheduled
fac_auditsunclassified170,4362026-07-30 to 2026-08-01 (ingest time)
fetched_at
4,33057-
fec_committeesunclassified156,4742026-07-30 to 2026-08-03 (ingest time)
updated_at
---
school_financeSource record120,1602016 to 2025
year
7511Monthly
ma_election_resultsunclassified87,3072026-07-26 to 2026-08-03 (ingest time)
updated_at
2191-
evictionsSource record84,6452000 to 2018
year
4,45362Monthly
debt_issuesunclassified77,0861984-07-23 to 2026-12-31
sale_date
4122-
election_resultsunclassified75,3882026-07-20 to 2026-08-03 (ingest time)
created_at
92514-
fec_candidatesunclassified65,4552026-07-30 to 2026-08-03 (ingest time)
updated_at
---
fec_committee_linksunclassified62,3322026-07-30 to 2026-08-03 (ingest time)
updated_at
---
lihtc_projectsunclassified55,3452026-07-30 (ingest time)
updated_at
3,12956-
staar_resultsSource record Structured / derived53,6312019 to 2025
year
7511Monthly
local_sales_taxSource record51,9972013-01-01 to 2026-07-01
period_month
3191Monthly
fac_findingsunclassified50,6662026-07-30 to 2026-08-01 (ingest time)
fetched_at
1,84657-
dot_projectsStructured / derived44,7470 to POST YEAR
program_year
5878Manual, not scheduled
energy_plantsStructured / derived40,3422026-04 to 2026-05
period
1,71249Monthly
property_salesSource record38,9351887-12-16 to 2026-04-17
sale_date
22Monthly
mobility_outcomesStructured / derived33,7472026-07-29 to 2026-08-01 (ingest time)
updated_at
4,45370Monthly
water_violationsStructured / derived32,6611979 to 2026
year
2354Monthly rotation (each state at most quarterly)
mattersSource record AI-derived31,9172026-07-17 to 2026-07-30 (ingest time)
created_at
436Manual
assisted_contractsunclassified24,3082026-07-30 (ingest time)
updated_at
2,55955-
people_aliasesunclassified21,6362026-08-03 (ingest time)
updated_at
96958-
state_legislatorsSource record21,5962020-08-06 to 2026-08-01 (ingest time)
updated_at
-50Monthly
peopleunclassified20,4692026-08-03 (ingest time)
updated_at
96958-
person_vote_statsunclassified20,4692026-08-03 (ingest time)
updated_at
96958-
usda_rd_propertiesunclassified12,4202026-08-01 (ingest time)
updated_at
1,37753-
decision_geoStructured / derived11,3262026-07-09 (ingest time)
updated_at
1,48065Weekly
municipalitiesStructured / derived8,3722026-07-04 to 2026-08-07 (ingest time)
added_at
-113Continuous
service_requests_rollupStructured / derived6,8982025-08-01 to 2026-08-01
period_month
66Monthly
roundupsAI-derived6,3352026-07-05 to 2026-08-03 (ingest time)
created_at
2,74076Weekly
college_statsSource record6,1192023
year
1,28251Monthly
census_demographicsSource record5,5202026-07-09 to 2026-08-01 (ingest time)
updated_at
5,52070Monthly
muni_financialsStructured / derived4,8242007 to 2027
fiscal_year
1,1748Monthly
literacyStructured / derived4,4572017
year
4,45751Monthly
surveillance_spendingAI-derived4,3902013-06-03 to 2026-08-05
spend_date
-52Manual, not scheduled
bps_permitsSource record4,2802025 to 2026
year
4,01069Monthly
openmeetings_findingsunclassified4,0732026-08-01 (ingest time)
updated_at
2432-
muni_debtStructured / derived2,8362007 to 2025
fiscal_year
8747Monthly
warn_noticesSource record2,8272019-01-04 to 2026-07-29
notice_date
21812Monthly
audit_findingsunclassified2,5882015 to 2025
fiscal_year
981-
settlementsunclassified2,4682010-04-20 to 2026-07-28
meeting_date
40148-
fiscal_healthStructured / derived2,4092023
fiscal_year
2,40960Monthly
police_stops_rollupStructured / derived2,3841973 to 2020
year
4627Monthly
official_electionsunclassified1,5802026-08-03 (ingest time)
created_at
14513-
school_statsStructured / derived9652018
assessment_year
96544Monthly
people_cf_bridgeunclassified2832026-08-03 (ingest time)
updated_at
483-
officialsSource record AI-derived2372026-07-14 to 2026-07-19
first_seen_date
122Monthly
air_qualitySource record2312022 to 2024
year
7725Monthly
service_requests_recentSource record1002026-07-27
created_date
11Monthly
pension_stateSource record962023
year
-51Monthly
_export_progressunclassified712026-08-07 (ingest time)
updated_at
---
nonprofitsSource record502014 to 2024
tax_year
-13Monthly, skipped when there is nothing new to link
fiscal_stress_officialSource record492024
year
491Monthly
datacenter_moratoriumsunclassified35no date column-20-
people_cf_candidatesunclassified172026-08-03 (ingest time)
updated_at
81-
_export_metaunclassified2no date column---

What each table is, where it came from, and its caveat

_export_meta 2 rows, no date column
Not classified by this generator. Treat its provenance as unknown.
_export_progress 71 rows, 2026-08-07 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
air_quality Source record 231 rows, 2022 to 2024
Source: EPA AirData annual AQI-by-county summary files.
Scope as implemented: National, county grain. Refresh: Monthly. Built by: epa_environment.py air.
Jurisdiction key: air_quality.state, 77 governments, 25 distinct states, led by CA at 14% of rows.
Caveat: A city carries the AQI of the county containing it. County FIPS comes from the Census place-by-county crosswalk, so this is a county measurement attributed to a city, not a city measurement. days_unhealthy is a sum of four published day counts.
assisted_contracts 24,308 rows, 2026-07-30 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
audit_findings 2,588 rows, 2015 to 2025
Not classified by this generator. Treat its provenance as unknown.
bps_permits Source record 4,280 rows, 2025 to 2026
Source: Census Building Permits Survey place and county flat files.
Scope as implemented: 50 states and DC. Refresh: Monthly. Built by: census_bps.py.
Jurisdiction key: municipalities via muni_id, 4,010 governments, 69 distinct states, led by TX at 9% of rows.
Caveat: Unit counts and valuations are parsed from fixed-column text files. month=0 rows are annual totals, not January.
briefs AI-derived 1,318,271 rows, 2026-07-04 to 2026-08-07 (ingest time)
Source: Agenda documents from the meeting portals in `meetings`, plus OCR fallback.
Scope as implemented: National plus Canada. Refresh: Hourly, plus continuous drain services. Built by: brief.py (prompt in charter.py).
Jurisdiction key: meetings then municipalities via meeting_id, 6,949 governments, 107 distinct states.
Caveat: headline, summary, notable and tags are written by a language model. Every other column is mechanical. The model sees at most the first 20,000 characters of the agenda, so a long agenda is summarised from its front. The `model` column records which model wrote each row. Verify against the linked agenda before quoting.
business_formations Source record 3,105,341 rows, 1864-03-05 to 2026-07-31
Source: Census Business Formation Statistics bulk file; Colorado Secretary of State entity registry (Socrata).
Scope as implemented: BFS aggregates are national and have no muni_id. Entity-grain rows are Colorado only. Refresh: Monthly. Built by: business_formations.py.
Jurisdiction key: business_formations.state, 3,349 governments, 74 distinct states, led by CO at 88% of rows.
Caveat: Two different grains share one table. Filter on `grain` before doing anything. The `bfs` grain is a national/state time series; the `entity` grain is one Colorado business registration per row.
census_demographics Source record 5,520 rows, 2026-07-09 to 2026-08-01 (ingest time)
Source: Census ACS 5-year estimates, 2023 vintage.
Scope as implemented: 50 states and DC. Refresh: Monthly. Built by: census_enrich.py, census_school_enrich.py.
Jurisdiction key: municipalities via muni_id, 5,520 governments, 70 distinct states, led by TX at 21% of rows.
Caveat: Values are copied from ACS. The muni-to-geography match is derived: places and counties by normalised name, school districts by fuzzy name match. ACS values are 5-year estimates with margins of error that this table does not carry.
cf_transactions Source record 45,636,350 rows, 1972-09-02 to 2202-06-30
Source: FEC; Texas Ethics Commission; NC State Board of Elections; Florida Division of Elections; WA PDC and NY SBOE via Socrata; Louisiana Board of Ethics; NetFile (California local filers).
Scope as implemented: Federal committee-to-candidate money COMPLETE for cycles 2010-2026 (source='fec_bulk_pas2', FEC bulk pas2 files, every row); federal individual contributions only as a CAPPED slice (source='fec', OpenFEC API, 2024-08-05 onward); plus state-level TX / NC / FL / WA / NY / LA and California local. Louisiana state filings are narrowed to New Orleans offices. Refresh: Weekly. Built by: fec_bulk.py, fec_enrich.py, tx_tec.py, nc_sboe.py, fl_doe.py, socrata_cf.py, la_ethics.py, netfile_enrich.py.
Jurisdiction key: cf_transactions.state, 57 distinct states, led by US at 76% of rows.
Caveat: Three federal source keys that must never be summed together. `fec_bulk_pas2` is COMPLETE committee-to-candidate money, 2010-2026, no cap — this is the one to use as a denominator for 'did PAC X give to anyone in state Y'. `fec` is the OpenFEC API Schedule A slice: 592,194 rows against 415 million source rows for 2024+2026 alone, so an absence in it proves nothing, and it also holds txn_type='summary' REGISTRY rows whose NULL txn_date is correct and which must be excluded from money totals. `fec_bulk_oth` is committee-to-committee and OVERLAPS `fec_bulk_pas2` on the same FEC SUB_ID by design. In the bulk sources `txn_type` is 1:1 with FEC's TRANSACTION_TP: 'ie_for'/'ie_against' are INDEPENDENT EXPENDITURES and are legally not contributions. For the bulk rows `state` is the recipient candidate's FEDERAL OFFICE state, not a filing jurisdiction. Otherwise this is not national state-level campaign finance: it is six states plus California locals, most starting at 2022, several with per-source row caps (see the caps table).
civic_records Structured / derived 213,049 rows, 1987-06-03 to 3200-12-31
Source: Per-city building-permit and business-license endpoints (ArcGIS FeatureServer and Socrata).
Scope as implemented: Only cities whose endpoint was confirmed by hand. Refresh: Manual, not scheduled. Built by: civic_feed.py, hf_permits.py, civic_source_mapper.py.
Jurisdiction key: municipalities via muni_id, 79 governments, 30 distinct states, led by TN at 95% of rows.
Caveat: Record values are copied from each government API. The column MAPPING (which source field is the address, the issue date, the applicant) is sometimes chosen by a local model, which is shown field NAMES only and never record values, and whose guess is then validated against the data before anything is stored. No cell content is model-written. Per-source record caps apply.
⚠ 95% of rows are TN: the name suggests broader coverage than the table has
college_stats Source record 6,119 rows, 2023
Source: US Department of Education College Scorecard API; IPEDS finance via the Urban Institute API.
Scope as implemented: National-capable; the scheduled run covers 10 states. Refresh: Monthly. Built by: college_stats.py.
Jurisdiction key: college_stats.state, 1,282 governments, 51 distinct states, led by CA at 11% of rows.
Caveat: Institution-level, not municipal. Vintage is fixed (Scorecard 2023, IPEDS finance 2017). Unmatched institutions keep a NULL muni_id rather than being forced into a town.
datacenter_moratoriums 35 rows, no date column
Not classified by this generator. Treat its provenance as unknown.
debt_issues 77,086 rows, 1984-07-23 to 2026-12-31
Not classified by this generator. Treat its provenance as unknown.
decision_geo Structured / derived 11,326 rows, 2026-07-09 (ingest time)
Source: Census geocoder; Overture Maps buildings; FEMA National Flood Hazard Layer.
Scope as implemented: National, US only. Refresh: Weekly. Built by: geo_enrich_decisions.py.
Jurisdiction key: meetings then municipalities via meeting_id, 1,480 governments, 65 distinct states.
Caveat: The building and flood attributes are copied from Overture and FEMA at a geocoded point. But the seed address is regex-extracted from the model-written `decisions` JSON, so a row exists here only because a model named an address. A geocode is a point, not a parcel boundary. flood_zone defaults to 'X' when FEMA returns no feature, which is not the same as a survey saying the site is out of the floodplain.
decisions AI-derived 486,268 rows, 2026-07-05 to 2026-08-07 (ingest time)
Source: Meeting minutes documents from the portals in `meetings`.
Scope as implemented: National. Refresh: Hourly, plus drains. Built by: minutes.py (prompt in charter.py).
Jurisdiction key: meetings then municipalities via meeting_id, 4,581 governments, 100 distinct states.
Caveat: headline, summary, the `decisions` JSON (outcomes, tallies, awards) and tags are written by a language model over at most 20,000 characters of minutes text. This is the single most quotable and single most verify-first table on the site.
dot_projects Structured / derived 44,747 rows, 0 to POST YEAR
Source: State DOT ArcGIS layers of programmed / STIP projects.
Scope as implemented: 8 states: TX, FL, TN, NC, GA, OH, SC, AL. Refresh: Manual, not scheduled. Built by: dot_projects.py.
Jurisdiction key: dot_projects.state, 587 governments, 8 distinct states, led by TX at 43% of rows.
Caveat: muni_id is assigned by scanning a project's free-text name, description and termini for a municipality name in that state, accepting only a single unambiguous hit. That is the weakest municipal join in the corpus. is_highway is a keyword guess. Coordinates are a computed centroid of the project geometry.
election_results 75,388 rows, 2026-07-20 to 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
energy_plants Structured / derived 40,342 rows, 2026-04 to 2026-05
Source: EIA Open Data v2 (operating generator capacity, facility fuel).
Scope as implemented: National. Refresh: Monthly. Built by: eia_enrich.py.
Jurisdiction key: energy_plants.state, 1,712 governments, 49 distinct states, led by CA at 44% of rows.
Caveat: Generator rows are rolled up to plant level: nameplate MW is summed across generators and primary_fuel is whichever fuel holds the most nameplate MW. Plants attach to municipalities by county, so a plant is linked to every candidate place in a multi-county area rather than to the jurisdiction that permitted it.
evictions Source record 84,645 rows, 2000 to 2018
Source: Princeton Eviction Lab, county eviction prevalence file.
Scope as implemented: National, county grain. Refresh: Monthly. Built by: evictions.py.
Jurisdiction key: evictions.state, 4,453 governments, 62 distinct states, led by TX at 9% of rows.
Caveat: Licensed CC BY-NC-SA 4.0 (non-commercial), so it is in this research snapshot and deliberately excluded from the CC BY public data dump. A city row carries its county's figures. Read `data_type`: `observed` rows are court records, `estimated` rows are modelled.
fac_audits 170,436 rows, 2026-07-30 to 2026-08-01 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
fac_findings 50,666 rows, 2026-07-30 to 2026-08-01 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
fec_candidates 65,455 rows, 2026-07-30 to 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
fec_committee_links 62,332 rows, 2026-07-30 to 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
fec_committees 156,474 rows, 2026-07-30 to 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
fema_grants 846,627 rows, 2026-07-30 to 2026-08-01 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
fiscal_health Structured / derived 2,409 rows, 2023
Source: Computed over Census Annual Survey of State and Local Government Finances.
Scope as implemented: Every municipality present in the finance survey. Refresh: Monthly. Built by: fiscal_health.py.
Jurisdiction key: municipalities via muni_id, 2,409 governments, 60 distinct states, led by TX at 6% of rows.
Caveat: This is an index, not a record. debt_load_index combines four national percentile ranks under weights chosen in this repo, and debt_load_band bins that index at cutoffs chosen in this repo. It measures debt load, not solvency, and no rating agency or auditor endorses it. structural_deficit is simply revenue below expense in the survey year.
fiscal_stress_official Source record 49 rows, 2024
Source: New York State Comptroller, Fiscal Stress Monitoring System workbooks.
Scope as implemented: New York only. Refresh: Monthly. Built by: comptroller_debt.py.
Jurisdiction key: fiscal_stress_official.state, 49 governments, 1 distinct states, led by NY at 100% of rows.
Caveat: stress_score and stress_label are the State's own published values. Towns and villages are skipped so a village's score cannot be bound to a same-named city. Only the years published as .xlsx are loadable.
food_inspections Source record 10,413,182 rows, 0002-12-06 to 2026-07-31
Source: Municipal health-inspection datasets on Socrata.
Scope as implemented: 5 cities: Chicago, New York, Los Angeles, Dallas, Austin. Refresh: Monthly. Built by: food_inspections.py.
Jurisdiction key: municipalities via muni_id, 122 governments, 12 distinct states, led by NY at 43% of rows.
Caveat: Score and result scales are NOT comparable across cities: each health department grades on its own scale. If a dataset's jurisdiction did not resolve to exactly one tracked municipality, the whole dataset was skipped rather than guessed at.
gov_contracts Source record 1,767,320 rows, 1990-11-16 to 2027-07-31
Source: Municipal contract and procurement registers on Socrata; Atlanta Open Checkbook; Transparent Utah.
Scope as implemented: A curated handful of jurisdictions, not a national procurement index. Refresh: Monthly. Built by: gov_contracts.py, atlanta_checkbook.py, ut_transparent.py.
Jurisdiction key: municipalities via muni_id, 287 governments, 8 distinct states, led by GA at 82% of rows.
Caveat: Column mapping across wildly different source schemas is heuristic, so `amount` does not mean the same thing in every dataset (awarded value, encumbrance, and paid amount all land in it). A per-dataset row limit applies, and one dataset in this snapshot sits at exactly the limit in force when it was loaded. Do not sum across `dataset_id`.
gov_payments Source record 1,483,357 rows, 1974-09-01 to 2026-12-16
Source: NOLA Public Schools Act 370 workbooks; City of New Orleans BRASS; USAspending; Miami-Dade Clerk online checkbook.
Scope as implemented: A few named jurisdictions, plus federal awards. Refresh: Manual, not scheduled. Built by: school_payments.py, nola_contracts.py, usaspending.py, miamidade_checkbook.py.
Jurisdiction key: gov_payments.state, 4 governments, 3 distinct states, led by TN at 88% of rows.
Caveat: THIS TABLE MIXES TWO DIFFERENT THINGS. `usaspending` rows are FEDERAL awards attached to a municipality by place of performance, which is not the town spending the money. The other sources are genuine municipal disbursements. Always filter on `source` before saying a town paid a vendor. The table is also heavily weighted toward one school system.
⚠ effectively 3 jurisdictions (TN, LA, FL) hold 100% of rows: the name suggests broader coverage than the table has
⚠ only 4 jurisdictions in the whole table
lihtc_projects 55,345 rows, 2026-07-30 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
literacy Structured / derived 4,457 rows, 2017
Source: NCES PIAAC Skills Map, county layer (2017).
Scope as implemented: National, county grain. Refresh: Monthly. Built by: literacy_enrich.py.
Jurisdiction key: literacy.state, 4,457 governments, 51 distinct states, led by Texas at 9% of rows.
Caveat: Model-based small-area estimates, not a census of adults. A city gets the figures of its primary county, chosen as the county holding the largest share of the place's target adult population, so a city spanning counties is approximated by one of them.
lobbying_expenditures 786,235 rows, 1992 to 2104
Not classified by this generator. Treat its provenance as unknown.
lobbying_registrations Source record 4,518,278 rows, 1905 to 3017
Source: Washington Public Disclosure Commission lobbyist compensation (Socrata); federal Senate Lobbying Disclosure Act API.
Scope as implemented: Washington State, plus a small federal slice. Refresh: Monthly (Washington only; the federal loader is not scheduled). Built by: lobbying.py.
Jurisdiction key: lobbying_registrations.state, 1,061 governments, 15 distinct states, led by CA at 28% of rows.
Caveat: Not national. The Washington rows in this snapshot were pulled under a 50,000-row fetch limit that has since been removed from the loader, so the count here is a truncation rather than a total. No row in this table resolved to a municipality. The federal rows are a single filing year.
local_sales_tax Source record 51,997 rows, 2013-01-01 to 2026-07-01
Source: Texas Comptroller of Public Accounts, monthly city sales-tax allocations.
Scope as implemented: Texas cities only. Refresh: Monthly. Built by: tx_salestax.py.
Jurisdiction key: local_sales_tax.state, 319 governments, 1 distinct states, led by TX at 100% of rows.
Caveat: An allocation payment to a city, which lags the month the sales occurred. Where two municipality rows share a name in Texas, the lowest id wins the match.
⚠ 100% of rows are TX: the name suggests broader coverage than the table has
ma_election_results 87,307 rows, 2026-07-26 to 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
matters Source record AI-derived 31,917 rows, 2026-07-17 to 2026-07-30 (ingest time)
Source: Chicago City Clerk ELMS agenda API; language-model extraction over stored agenda and minutes text.
Scope as implemented: Chicago, plus whatever municipalities were passed to the extractor. Refresh: Manual. Built by: chicago_elms.py, matters_pg.py (live), matters.py (frozen).
Jurisdiction key: municipalities via muni_id, 43 governments, 6 distinct states, led by IL at 43% of rows.
Caveat: MIXED PROVENANCE IN ONE TABLE, distinguishable by the `model` column. `elms-api` rows are copied from Chicago's agenda API. Rows carrying a model name have their unit counts, acreage, height, dollar values and outcomes extracted by a language model from at most 7,000 characters of meeting text. The scheduled monthly job still points at the frozen pre-migration path, so this table advances only on manual runs.
meeting_attachments Structured / derived 691,746 rows, 2026-07-28 to 2026-08-06 (ingest time)
Source: Attachment and packet PDFs from Legistar, CivicClerk, CivicPlus, PrimeGov and Granicus.
Scope as implemented: National, wherever a portal exposes attachments. Refresh: Continuous. Built by: legistar_attachments.py, civicclerk_attachments.py, civicplus_attachments.py, platform_attachments.py.
Jurisdiction key: meetings then municipalities via meeting_id, 1,454 governments, 68 distinct states.
Caveat: The text is verbatim PDF text extraction, never summarised. It is truncated per document, so a long staff report is stored from its front. Scanned pages extract as empty text and are flagged ocr_needed, so an empty `text` means 'not read yet', not 'nothing there'. This table is a keyword-search surface, not a complete document archive.
meetings Source record 2,034,849 rows, 0006-12-16 to 9999-09-10
Source: About 40 municipal agenda-portal adapters (Legistar, CivicPlus, CivicClerk, Granicus, eScribe, BoardDocs, PrimeGov, BoardBook, ClerkBase and others).
Scope as implemented: United States plus Canada (Ontario, Quebec). Refresh: Hourly and daily. Built by: mytown.py fetch, adapters.py, agendacenter.py and ~35 more.
Jurisdiction key: municipalities via muni_id, 7,070 governments, 107 distinct states, led by MA at 10% of rows.
Caveat: Calendar metadata only: body, date, location and document links. Agenda and minutes TEXT lives in a separate table that is not exported here. Adapters run recency windows, so coverage thins the further back you look, and depth varies by vendor rather than by how much a town actually meets.
member_votes Source record Structured / derived AI-derived 4,819,245 rows, 2026-07-18 to 2026-08-07 (ingest time)
Source: Vendor roll-call APIs (Legistar, Legistar InSite, Chicago ELMS, BoardDocs, IQM2, CivicClerk, eScribe, CivicWeb); regex parsing of BoardBook minutes; language-model extraction from minutes text.
Scope as implemented: National. Refresh: Daily. Built by: votes_backfill.py and its per-platform modules, chicago_elms.py, boardbook_votes.py, officials.py.
Jurisdiction key: municipalities via muni_id, 989 governments, 60 distinct states, led by IL at 19% of rows.
Caveat: MIXED PROVENANCE IN ONE TABLE. The overwhelming majority is copied from vendor roll-call APIs. A small remainder is regex-parsed from minutes, and a smaller remainder is extracted by a language model. Use `source` and `model` to separate them. `contested` is derived from the yea/nay split. Absence of a vote row does not mean a unanimous vote: most local governments never publish per-member roll calls at all.
mobility_outcomes Structured / derived 33,747 rows, 2026-07-29 to 2026-08-01 (ingest time)
Source: Opportunity Insights / Opportunity Atlas county outcomes.
Scope as implemented: National, county grain. Refresh: Monthly. Built by: mobility.py.
Jurisdiction key: municipalities via muni_id, 4,453 governments, 70 distinct states, led by TX at 9% of rows.
Caveat: No explicit open licence upstream, so this is in the research snapshot and excluded from the public data dump. A county's outcome is written to every municipality in that county, so these are never town-level measurements. The figures describe adults who grew up there decades ago, not current residents.
muni_debt Structured / derived 2,836 rows, 2007 to 2025
Source: CA State Controller ByTheNumbers; NY Comptroller; CT OPM; MI Treasury; MN State Auditor; WI Department of Revenue; VA Auditor of Public Accounts.
Scope as implemented: 7 states: CA, NY, CT, MI, MN, WI, VA. Refresh: Monthly. Built by: comptroller_debt.py, ct_opm.py, mi_treasury.py, state_financials.py.
Jurisdiction key: muni_debt.state, 874 governments, 7 distinct states, led by CA at 42% of rows.
Caveat: Each state defines and categorises debt differently, so cross-state comparison is not sound. Per-capita figures are computed here. Municipal bond disclosure (EMMA) is deliberately excluded on terms-of-use grounds, so this is not a complete debt picture even in the seven states.
muni_financials Structured / derived 4,824 rows, 2007 to 2027
Source: Transparent Utah; CT OPM; CA State Controller; MN State Auditor; WI Department of Revenue; MI Treasury; VA Auditor of Public Accounts.
Scope as implemented: 7 states: UT, CT, CA, MN, WI, MI, VA. Refresh: Monthly. Built by: ut_transparent.py, ct_opm.py, ca_controller.py, state_financials.py, mi_treasury.py.
Jurisdiction key: muni_financials.state, 1,174 governments, 8 distinct states, led by UT at 70% of rows.
Caveat: Revenue and expense categories are mapped from each state's own chart of accounts into a shared set, so a category boundary is a judgement made here, not upstream. Some sources leave debt and fund balance NULL. Not comparable across states without reading the mapping.
municipalities Structured / derived 8,372 rows, 2026-07-04 to 2026-08-07 (ingest time)
Source: Self-registered by the portal adapters from vendor client identifiers.
Scope as implemented: United States plus Canada. Refresh: Continuous. Built by: ~30 adapters plus discover*.py.
Jurisdiction key: municipalities.state, 113 distinct states, led by TX at 15% of rows.
Caveat: THE JOIN KEY, AND THE MOST MISREAD TABLE HERE. The unique key is `slug`, a vendor client identifier, NOT (name, state). One physical city registered on two agenda platforms is two rows with two ids. There is no Census place GEOID column. `kind` separates city, county and school district, and those share names constantly. This is a registry of governments whose agenda portal was found, so it is not a roster of US municipalities and its state mix reflects vendor market share.
nonprofits Source record 50 rows, 2014 to 2024
Source: IRS Form 990 extracts via the ProPublica Nonprofit Explorer API.
Scope as implemented: Only EINs surfaced by linkage work; not municipal. Refresh: Monthly, skipped when there is nothing new to link. Built by: irs990.py.
Jurisdiction key: nonprofits.state, 13 distinct states, led by VA at 28% of rows.
Caveat: A tiny, purposive set of organisations, not a sample of anything. IRS 990 figures lag by years. No muni_id column.
official_disclosures Structured / derived 1,065,786 rows, 2004 to 2033
Source: Washington Public Disclosure Commission, Financial Affairs Disclosures (form F-1) via Socrata.
Scope as implemented: Washington State only. Refresh: Monthly. Built by: lobbying.py.
Jurisdiction key: official_disclosures.state, 340 governments, 10 distinct states, led by CA at 80% of rows.
Caveat: THE NAME OVERPROMISES BADLY. This is one state's F-1 filing index. `role` and `income_summary` are BUILT IN CODE by parsing the filing's office and candidacy arrays and joining them into a string: income_summary is office and jurisdiction context, NOT dollar holdings. Washington's open dataset does not expose itemised income or assets at all; those are records-request only. Most rows have no muni_id because most filers are not city officials.
official_elections 1,580 rows, 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
officials Source record AI-derived 237 rows, 2026-07-14 to 2026-07-19
Source: Chicago City Clerk ELMS person API; language-model extraction of named attendance from minutes text.
Scope as implemented: Chicago, plus a handful of Michigan municipalities. Refresh: Monthly. Built by: officials.py, chicago_elms.py.
Jurisdiction key: municipalities via muni_id, 12 governments, 2 distinct states, led by IL at 52% of rows.
Caveat: MIXED PROVENANCE AND NO COLUMN TO TELL THE HALVES APART. Chicago rows come from an API; the rest are model-extracted names and roles folded into a roster, where `role` is the most common role seen and meeting_count is a count of appearances. This is not an elected-officials directory and should not be used as one.
openmeetings_findings 4,073 rows, 2026-08-01 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
pension_state Source record 96 rows, 2023
Source: Census Annual Survey of Public Pensions (time series API).
Scope as implemented: All states, state grain only. Refresh: Monthly. Built by: fiscal_health.py.
Jurisdiction key: pension_state.state, 51 distinct states, led by WV at 2% of rows.
Caveat: State grain, split by state-administered versus locally-administered systems. There is no actuarial liability in this source, so NO FUNDED RATIO can be computed from it. holdings_to_benefits and gov_contrib_share are arithmetic done here.
people 20,469 rows, 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
people_aliases 21,636 rows, 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
people_cf_bridge 283 rows, 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
people_cf_candidates 17 rows, 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
person_vote_stats 20,469 rows, 2026-08-03 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
police_stops_rollup Structured / derived 2,384 rows, 1973 to 2020
Source: Stanford Open Policing Project.
Scope as implemented: Municipal agency files only, across roughly 40 states. Refresh: Monthly. Built by: open_policing.py.
Jurisdiction key: police_stops_rollup.state, 46 governments, 27 distinct states, led by NC at 19% of rows.
Caveat: A rollup: individual stops are aggregated to (agency, year, race) counts and the underlying stop records are NEVER STORED, here or in Postgres. search_rate and hit_rate are computed. Coverage is whichever agencies released data in whichever years, so a missing agency-year means no release, not no stops. Licensed ODC-BY; cite Pierson et al. (2020) as the row's `citation` column says.
professional_licenses Source record 7,831,348 rows, 1800-11-09 to 2090-05-01
Source: Washington Department of Labor and Industries contractor licences; Delaware Division of Professional Regulation (both Socrata).
Scope as implemented: Washington and Delaware only. Refresh: Monthly. Built by: licensing.py.
Jurisdiction key: professional_licenses.state, 913 governments, 9 distinct states, led by WA at 33% of rows.
Caveat: THE NAME OVERPROMISES. Two states, and two different kinds of licence: WA rows are construction contractors, DE rows are regulated professions. disciplinary_flag is derived by joining Delaware's separate disciplinary dataset, because Delaware's inline flag is uniformly 'N' at source. This snapshot was loaded under a per-state row limit; see section 4 for the limits currently in the loaders.
property_sales Source record 38,935 rows, 1887-12-16 to 2026-04-17
Source: Florida Department of Revenue cadastral ArcGIS layer; MassGIS statewide parcels.
Scope as implemented: Two municipalities: Hollywood FL and Worcester MA. Refresh: Monthly. Built by: property_records.py.
Jurisdiction key: property_sales.state, 2 governments, 2 distinct states, led by MA at 90% of rows.
Caveat: Two towns. Not a national parcel file, not a deed index. In the Florida source the city field is the POSTAL city on the parcel record, which is not necessarily the incorporated jurisdiction. Assessed value is not market value.
⚠ effectively 2 jurisdictions (MA, FL) hold 100% of rows: the name suggests broader coverage than the table has
⚠ only 2 jurisdictions in the whole table
public_salaries Source record 3,539,791 rows, 2012 to 2026
Source: California State Controller Government Compensation in California; Transparent Utah; nine curated municipal Socrata datasets.
Scope as implemented: California and Utah statewide, plus nine named jurisdictions. Refresh: Monthly. Built by: public_salaries.py, ca_controller.py, ut_transparent.py.
Jurisdiction key: municipalities via muni_id, 597 governments, 10 distinct states, led by NY at 56% of rows.
Caveat: Employee names are NULL with redacted=TRUE wherever the source withholds them, which includes all of the California statewide file. Pay-component definitions differ per source and are mapped heuristically, so `total_pay` is not a consistent quantity across datasets. Utah is structurally limited to the highest-paid employees per entity-year at source. This snapshot was loaded under a per-municipality row limit; see section 4 for the limits currently in the loaders.
roundups AI-derived 6,335 rows, 2026-07-05 to 2026-08-03 (ingest time)
Source: Second order: written from `briefs` and `decisions`, which are themselves model output.
Scope as implemented: Municipalities with at least three briefed meetings in the trailing two weeks. Refresh: Weekly. Built by: roundup.py (prompt in charter.py).
Jurisdiction key: municipalities via muni_id, 2,740 governments, 76 distinct states, led by MA at 10% of rows.
Caveat: THE LEAST DIRECT TABLE ON THE SITE. Model prose written over model output, two steps from any source document. article_html is a deterministic render of article_md. Useful as an index of what a town was doing; not evidence of anything.
school_finance Source record 120,160 rows, 2016 to 2025
Source: Texas Education Agency, Summarized PEIMS actual financial data.
Scope as implemented: Texas school districts only. Refresh: Monthly. Built by: tea_finance.py.
Jurisdiction key: municipalities via muni_id, 751 governments, 1 distinct states, led by TX at 100% of rows.
Caveat: One row per district, year and TEA function code. Function codes are Texas definitions and do not map onto other states' categories.
⚠ 100% of rows are TX: the name suggests broader coverage than the table has
school_stats Structured / derived 965 rows, 2018
Source: NCES Common Core of Data directory and F-33 finance, via the Urban Institute Education Data API.
Scope as implemented: National, only districts that matched. Refresh: Monthly. Built by: nces_enrich.py.
Jurisdiction key: municipalities via muni_id, 965 governments, 44 distinct states, led by TX at 78% of rows.
Caveat: The district-to-municipality match is a fuzzy name match with a token guard, and misses are recorded separately rather than being zero-filled, so a district absent here was not matched and is not necessarily missing upstream. Directory and finance years differ (finance lags), so per-pupil spending divides two different vintages.
service_requests_recent Source record 100 rows, 2026-07-27
Source: Municipal 311 datasets on Socrata.
Scope as implemented: A single city, 100 rows. Refresh: Monthly. Built by: service_requests.py.
Jurisdiction key: municipalities via muni_id, 1 governments, 1 distinct states, led by LA at 100% of rows.
Caveat: A deliberately tiny texture sample kept so you can see the shape of a 311 record. It is not data. Use the rollup, or query the city's portal directly.
⚠ 100% of rows are LA: the name suggests broader coverage than the table has
service_requests_rollup Structured / derived 6,898 rows, 2025-08-01 to 2026-08-01
Source: Municipal 311 and code-enforcement datasets on Socrata.
Scope as implemented: 6 cities. Refresh: Monthly. Built by: service_requests.py.
Jurisdiction key: municipalities via muni_id, 6 governments, 6 distinct states, led by TX at 30% of rows.
Caveat: Server-side monthly counts by category. The underlying 311 records DO NOT EXIST in this database or in Postgres; only the counts were fetched. Category taxonomies are per-city and not comparable. A count reflects reporting behaviour as much as conditions.
⚠ only 6 jurisdictions in the whole table
settlements 2,468 rows, 2010-04-20 to 2026-07-28
Not classified by this generator. Treat its provenance as unknown.
staar_results Source record Structured / derived 53,631 rows, 2019 to 2025
Source: Texas Education Agency TAPR broker; TEA results via the Cambium public reporting API.
Scope as implemented: Texas school districts, grades 3-8, reading and math. Refresh: Monthly. Built by: tea_staar.py, tea_staar_aggregate.py.
Jurisdiction key: municipalities via muni_id, 751 governments, 1 distinct states, led by TX at 100% of rows.
Caveat: Mixed within the table: the TAPR path copies published percentages, the aggregate path is count-native so its percentages are computed here. Small districts and small subgroups are masked at source, so a missing value is often suppression, not absence.
⚠ 100% of rows are TX: the name suggests broader coverage than the table has
state_bills Source record 1,454,904 rows, 1985-02-05 to 2028-07-01
Source: Open States / Plural Policy monthly database dump, topped up by their v3 API. Each row's source_url points at the state legislature's own site.
Scope as implemented: All 50 state legislatures upstream; check the flags below for what this snapshot actually holds. Refresh: Monthly. Built by: openstates.py.
Jurisdiction key: state_bills.state, 50 distinct states, led by IL at 13% of rows.
Caveat: This is the one tier above local government in the corpus, and it went national on 2026-07-30, so this snapshot may hold only the earlier single-state backfill: read the scope flag on this table before describing its coverage. Rows are only as fresh as the monthly dump. Bill coverage is not vote coverage, and neither is evidence that a bill became law.
state_legislators Source record 21,596 rows, 2020-08-06 to 2026-08-01 (ingest time)
Source: Open States / Plural Policy current-people files and monthly dump.
Scope as implemented: All 50 states; DC and territories excluded. Refresh: Monthly. Built by: openstates.py.
Jurisdiction key: state_legislators.state, 50 distinct states, led by NH at 7% of rows.
Caveat: A current snapshot, not a historical roster: it is overwritten as people change, so it cannot tell you who held a seat in a past year.
state_votes Source record 1,175,161 rows, 1969-12-31 to 2026-06-30
Source: Open States / Plural Policy monthly database dump, topped up by their v3 API.
Scope as implemented: All 50 state legislatures upstream; check the flags below for what this snapshot actually holds. Refresh: Monthly. Built by: openstates.py.
Jurisdiction key: state_votes.state, 50 distinct states, led by CA at 22% of rows.
Caveat: THE NAME OVERPROMISES IN TWO DIFFERENT WAYS. First, these are chamber vote TOTALS, not per-legislator votes: how a named legislator voted lives in a separate table that is NOT exported into this file. Second, roll-call depth is not the same number as bill coverage. Every state publishes some vote events, but a handful publish almost no machine-readable per-member roll calls at all, so a per-state count is the only honest way to describe this layer and a national row count is not. Read the scope flag on this table before describing its coverage.
surveillance_spending AI-derived 4,390 rows, 2013-06-03 to 2026-08-05
Source: MyTown's own municipal meeting corpus (agendas, minutes and staff reports). NOT a procurement register.
Scope as implemented: National, wherever the meeting corpus reaches. Refresh: Manual, not scheduled. Built by: surveillance_ledger_all.py, axon_ledger.py, flock_ledger.py, surveillance_integrity.py.
Jurisdiction key: surveillance_spending.state_norm, 52 distinct states, led by CA at 14% of rows.
Caveat: A DISCOVERY INDEX, NOT A SPENDING LEDGER. Each row is one dollar figure a model found in one meeting document. `amount` and `product` are model output; `quote` is model-selected but machine-verified to appear verbatim in the source text; `vendor` comes from a fixed vendor list, not from the model. amount_type, dup_rank, geo_suspect and anomaly are regex and SQL flags added after an audit. There is NO stage column: the same procurement recurs at committee, council, approval, amendment and renewal, so SUM(amount) over this table is meaningless. See the aggregation section.
usda_rd_properties 12,420 rows, 2026-08-01 (ingest time)
Not classified by this generator. Treat its provenance as unknown.
warn_notices Source record 2,827 rows, 2019-01-04 to 2026-07-29
Source: Texas Workforce Commission; Oregon HECC; California EDD WARN reports.
Scope as implemented: TX, OR and CA (plus stray out-of-state employers inside those feeds). Refresh: Monthly. Built by: warn_notices.py.
Jurisdiction key: warn_notices.state, 218 governments, 12 distinct states, led by TX at 83% of rows.
Caveat: Three states. California is current fiscal year only at source. A WARN notice is a notice of intent, so the layoff count is planned, not confirmed. Where a city name matched zero or several municipalities the muni_id is left NULL rather than guessed, so the city and county text columns are more complete than the join.
⚠ effectively 3 jurisdictions (TX, OR, CA) hold 100% of rows: the name suggests broader coverage than the table has
water_violations Structured / derived 32,661 rows, 1979 to 2026
Source: EPA Safe Drinking Water Information System via the Envirofacts API.
Scope as implemented: 4 states loaded so far, refreshed on a rotation. Refresh: Monthly rotation (each state at most quarterly). Built by: epa_environment.py water.
Jurisdiction key: water_violations.state, 235 governments, 4 distinct states, led by CA at 40% of rows.
Caveat: Individual violations are aggregated here to counts per water system and year. Keyed to the water system, joined to a municipality by the served-city name, and a system often serves more or fewer people than one town. A per-state row cap applies. A violation is a reporting or monitoring failure as often as a contaminant exceedance.

10. Citing and reproducing

The corpus is published under CC BY 4.0, except for two tables carried here for research use only and deliberately excluded from the public data dump: evictions is CC BY-NC-SA and non-commercial, and mobility_outcomes has no explicit open licence upstream. police_stops_rollup is ODC-BY and each row carries the citation its licence requires. Where a table has a source_url, cite the government source, not this site.

A defensible use of this corpus looks like this. Find the row here. Open its source_url or source_document and confirm the figure in the original. Check whether the table appears in the scope warnings or the caps table above. If you are aggregating, run claim_check.py first. Then cite the government document, and cite this site as how you found it.

Generated by research_methodology.py in the MyTown repository, from the served database. If a number on this page disagrees with a query on this site, the query is right and this page is stale: regenerate it.

Powered by Datasette