Before you sell your data, know what a buyer will find.
We assess the health of your data estate, what is legal to share, and where your business can earn from it, so you know exactly what you can sell.
Your database
One data domain, never written to
Metadata Enrichment Engine
In your Azure, every column enriched
Public comparables
Similar data products and their published prices, every source checked by a person
The monetization analysiscode counts and rates, AI drafts and researches
Data health
Every statement with the query that proves it
Sharing rules
Remove or mask, handle with care, or share as is
Sellable by period
Each use rated per period
Buyer's view
The gaps a buyer finds first
Where to earn
Products, buyers, value ranges
- Governance specialistChecks every verdict, sharing rule and source
- Your data ownerSets the cut-offs and approves
- Readiness overviewThe verdict, uses by period, sharing rules
- Health summaryWith the evidence and query for each statement
- Business assessmentWho would buy, what to package, indicative value
- The enriched inventoryDescriptions, sensitivity, quality rules
You were told to make the data pay. Nobody can say what is sellable.
Leadership believes the data is an asset. But nobody can say what is sellable, what can safely be shared, what a buyer would find, or who would pay. So every outside request starts from zero, and legal says no to everything.
Four answers you can take to the board
Every column described and rated for sensitivity, with quality rules where your business needs them.
A plain-language health summary where every statement points to its evidence and the query that proves it.
Each use rated by period, the gaps a buyer would find first, and which columns to remove, mask or share as is.
Candidate data products, who might buy each, and an indicative value range with its basis stated.
Every answer, with its evidence
indiv20.memo_textBased on: your documentationDrafted from the column's profile and the FEC data dictionary.
A note the filer added to the contribution, such as why it was refunded or whom it was earmarked for. Free text; may name people.
Public is set only by a person, never by the engine.
| Column | Level | Identifies a person | Why |
|---|---|---|---|
name | Confidential | Directly | A person's name |
zip_code | Confidential | Indirectly | Where a person lives |
occupation | Confidential | Indirectly | Describes a donor |
memo_text | Confidential | Possibly | Free text that may name people |
cmte_id | Internal | No | A committee, not a person |
Contribution date must fall inside the filing's two-year election cycle
FEC campaign finance · plain-language summary
Bottom line: You can trust this data to uniquely identify election-cycle filings for committees, candidates, individuals, and expenditures across every cycle from 1980 through 2020, but before linking a contribution to the candidate it supports, or selling any of this data, a few linkage gaps and sensitivity issues need the data owner's sign-off.
What you can rely on it for
- Every identifier is unique, so a given filing ID always points to one record: 142 of 142 uniqueness checks pass, and 883 of 911 code-list checks pass.
- No cycle or table family is missing: committee, candidate, individual, PAC-to-candidate, and other-transaction tables cover every cycle from 1980 to 2020, candidate-committee linkage tables from 2000, and operating-expenditure tables from 2004.
- Nearly every record can be placed in the right cycle by date - only about 1 in 2,400 records lack a usable date.
What to watch
- Linking a committee to its candidate can also fail: in cm12 and cm14, as many as 1 in 2 committee records don't match a known candidate ID.
- Linking a candidate's own committee to a known committee ID fails as often as 1 in 43 in some candidate-committee tables, and as rarely as about 1 in 30,600 in the 2020 individual contributions file.
Crosswalk row 1
Bottom line: You can trust this data to uniquely identify election-cycle filings for committees, candidates, individuals, and expenditures across every cycle from 1980 through 2020
Evidence, counted on the full data
- 142 of 142 uniqueness checks pass, across 142 tables, each counted over the whole table; 883 of 911 code-list checks pass
- ccl: 11 tables, election cycles 2000-2020; cm: 21 tables, election cycles 1980-2020; cn: 21 tables, election cycles 1980-2020; and more
Query to reproduce it
SELECT COUNT(*), COUNTIF(check_passes), COUNT(DISTINCT table_name) FROM `dm-demo`.dq_results.v_check WHERE schema_name = 'fec' AND rule_type = 'unique';returns 142 · 142 · 142/*bq*/ select table_name from `bigquery-public-data.fec.INFORMATION_SCHEMA.TABLES` order by 1;returns candidate_2016; candidate_2018; … 146 rows in all1 more query in the full crosswalk.
Crosswalk row 2
Before linking a contribution to the candidate it supports, or selling any of this data, a few linkage gaps and sensitivity issues need the data owner's sign-off
Evidence, counted on the full data
- Rule "Every value in cand_id matches a cand_id in candidate_2016 " fails in 12 table(; and more
- Rule "Every value in cmte_id matches a cmte_id in cm16 " fails in 7 table(s); and more
The queries for the other 1 findings this sums up are in their own rows below.
Query to reproduce it
SELECT COUNT(*), COUNTIF(cand_id IS NULL), COUNTIF(NOT cand_id IS NULL AND TRIM(cand_id) = '') FROM `bigquery-public-data.fec.cm14`;returns 14,905 · 0 · 9,488SELECT COUNT(*) FROM `bigquery-public-data.fec.candidate_committee_2016` WHERE NOT cmte_id IS NULL AND NOT (CAST(cmte_id AS STRING) IN (SELECT CAST(cmte_id AS STRING) FROM `bigquery-public-data.fec.cm16` WHERE NOT cmte_id IS NULL));returns 1291 more query in the full crosswalk.
Crosswalk row 3
Every identifier is unique, so a given filing ID always points to one record: 142 of 142 uniqueness checks pass, and 883 of 911 code-list checks pass
Evidence, counted on the full data
- 142 of 142 uniqueness checks pass, across 142 tables, each counted over the whole table; 883 of 911 code-list checks pass
Query to reproduce it
SELECT COUNT(*), COUNTIF(check_passes), COUNT(DISTINCT table_name) FROM `dm-demo`.dq_results.v_check WHERE schema_name = 'fec' AND rule_type = 'unique';returns 142 · 142 · 142SELECT COUNT(*), COUNTIF(check_passes) FROM `dm-demo`.dq_results.v_check WHERE schema_name = 'fec' AND rule_type = 'allowed_values';returns 911 · 883Crosswalk row 4
No cycle or table family is missing: committee, candidate, individual, PAC-to-candidate, and other-transaction tables cover every cycle from 1980 to 2020, candidate-committee linkage tables from 2000, and operating-expenditure tables from 2004
Evidence, counted on the full data
- ccl: 11 tables, election cycles 2000-2020; cm: 21 tables, election cycles 1980-2020; cn: 21 tables, election cycles 1980-2020; indiv: 21 tables, election cycles 1980-2020; oppexp: 9 tables, election cycles 2004-2020; oth: 21 tables, election cycles 1980-2020; and more
Query to reproduce it
/*bq*/ select table_name from `bigquery-public-data.fec.INFORMATION_SCHEMA.TABLES` order by 1;returns candidate_2016; candidate_2018; … 146 rows in allCrosswalk row 5
Nearly every record can be placed in the right cycle by date - only about 1 in 2,400 records lack a usable date
Evidence, counted on the full data
- (bad date): 103 records in 22 tables; (no date): 102,627 records in 61 tables; (stray dates): 73,860 records in 81 tables. Together 176,590 of 425,368,299 dated records (about 1 in 2,400)
Query to reproduce it
SELECT cycle_label, SUM(records), COUNT(*) FROM `dm-demo`.dq_results.cycle_volume WHERE schema_name = 'fec' AND cycle_label IN ('(no date)', '(stray dates)', '(bad date)') GROUP BY 1;returns bad date; no date; …SELECT records FROM `dm-demo`.dq_results.cycle_volume WHERE schema_name = 'fec' AND NOT records IS NULL;returns 23; 14; … 344 rows in allCrosswalk row 6
Linking a committee to its candidate can also fail: in cm12 and cm14, as many as 1 in 2 committee records don't match a known candidate ID
Evidence, counted on the full data
- Rule "Every value in cand_id matches a cand_id in candidate_2016 " fails in 12 table(s). cm12: 9,119 of 14,455 (1 in 2); cm14: 9,488 of 14,905 (1 in 2)
Query to reproduce it
SELECT COUNT(*), COUNTIF(cand_id IS NULL), COUNTIF(NOT cand_id IS NULL AND TRIM(cand_id) = '') FROM `bigquery-public-data.fec.cm12`;returns 14,455 · 0 · 9,118SELECT COUNT(*), COUNTIF(cand_id IS NULL), COUNTIF(NOT cand_id IS NULL AND TRIM(cand_id) = '') FROM `bigquery-public-data.fec.cm14`;returns 14,905 · 0 · 9,488Crosswalk row 7
Linking a candidate's own committee to a known committee ID fails as often as 1 in 43 in some candidate-committee tables, and as rarely as about 1 in 30,600 in the 2020 individual contributions file
Evidence, counted on the full data
- Rule "Every value in cmte_id matches a cmte_id in cm16 " fails in 7 table(s). candidate_committee_2016: 129 of 6,407 (1 in 50); candidate_committee_2018: 167 of 7,180 (1 in 43); candidate_committee_2020: 121 of 7,055 (1 in 58); ccl16: 129 of 6,407 (1 in 50); ccl18: 167 of 7,180 (1 in 43); and more
Query to reproduce it
SELECT COUNT(*) FROM `bigquery-public-data.fec.candidate_committee_2016` WHERE NOT cmte_id IS NULL AND NOT (CAST(cmte_id AS STRING) IN (SELECT CAST(cmte_id AS STRING) FROM `bigquery-public-data.fec.cm16` WHERE NOT cmte_id IS NULL));returns 129SELECT COUNT(*) FROM `bigquery-public-data.fec.candidate_committee_2016`;returns 6,407Chicago crime · plain-language summary
Bottom line: This data reliably supports year-over-year crime trend analysis across all 26 years (2001-2026) and neighborhood-level analysis from 2002 onward, but location fields have real gaps and five columns need handling before any sale.
What you can rely on it for
- Every year from 2001 through 2026 is present, with no year loaded twice, so trend analysis covers the full 26-year span.
- Identifier and code fields are clean with one exception: nearly all identifying columns are unique, and every crime-type and location code checked matches the official fixed lists.
- From 2002 on, ward and community area are usable for neighborhood-level work — fill rates jump from 0.9% (ward) and 1.3% (community area) in 2001 to about 73% in 2002 and reach 100% by 2003.
- The crime-type codes (iucr, fbi_code) and location_description values in this file largely match what the City of Chicago already publishes.
What to watch
- A join on case_number will occasionally pull in a duplicate incident: about 1 in 13,700 records in the file is an extra copy, 630 records in total.
- Neighborhood analysis effectively starts in 2002 — ward and community area weren't collected before then, so 2001 records can't be placed in a ward or neighborhood.
Crosswalk row 1
Bottom line: This data reliably supports year-over-year crime trend analysis across all 26 years (2001-2026) and neighborhood-level analysis from 2002 onward, but location fields have real gaps and five columns need handling before any sale
Evidence, counted on the full data
- 1 of 2 uniqueness checks pass, across 1 tables, each counted over the whole table; and more
- 26 years present, 2001-2026: 485,977 records in 2001, 166,806 in 2026 (latest year may be; and more
The queries for the other 5 findings this sums up are in their own rows below.
Query to reproduce it
SELECT COUNT(*), COUNTIF(check_passes), COUNT(DISTINCT table_name) FROM `dm-demo`.dq_results.v_check WHERE schema_name = 'chicago_crime' AND rule_type = 'unique';returns 2 · 1 · 1SELECT cycle_year, records FROM `dm-demo`.dq_results.cycle_volume WHERE schema_name = 'chicago_crime' AND table_name = 'crime' AND NOT cycle_year IS NULL ORDER BY 1 NULLS LAST;returns 2001 · 485,977; 2002 · 486,843; … 26 rows in all1 more query in the full crosswalk.
Crosswalk row 2
Every year from 2001 through 2026 is present, with no year loaded twice, so trend analysis covers the full 26-year span
Evidence, counted on the full data
- 26 years present, 2001-2026: 485,977 records in 2001, 166,806 in 2026 (latest year may be partial). Largest drop between full years: 2020, -18.7%; largest rise: 2022, +14.5%. Years flagged as unusually low or high: 0
Query to reproduce it
SELECT cycle_year, records FROM `dm-demo`.dq_results.cycle_volume WHERE schema_name = 'chicago_crime' AND table_name = 'crime' AND NOT cycle_year IS NULL ORDER BY 1 NULLS LAST;returns 2001 · 485,977; 2002 · 486,843; … 26 rows in allSELECT COUNT(*) FROM `dm-demo`.dq_results.cycle_volume WHERE schema_name = 'chicago_crime' AND NOT flag IS NULL;returns 0Crosswalk row 3
Identifier and code fields are clean with one exception: nearly all identifying columns are unique, and every crime-type and location code checked matches the official fixed lists
Evidence, counted on the full data
- 1 of 2 uniqueness checks pass, across 1 tables, each counted over the whole table; 10 of 10 code-list checks pass
Query to reproduce it
SELECT COUNT(*), COUNTIF(check_passes), COUNT(DISTINCT table_name) FROM `dm-demo`.dq_results.v_check WHERE schema_name = 'chicago_crime' AND rule_type = 'unique';returns 2 · 1 · 1SELECT COUNT(*), COUNTIF(check_passes) FROM `dm-demo`.dq_results.v_check WHERE schema_name = 'chicago_crime' AND rule_type = 'allowed_values';returns 10 · 10Crosswalk row 4
From 2002 on, ward and community area are usable for neighborhood-level work — fill rates jump from 0.9% (ward) and 1.3% (community area) in 2001 to about 73% in 2002 and reach 100% by 2003
Evidence, counted on the full data
- 2001: filled in 6,390 of 485,977 (1.3%); 2002: filled in 354,223 of 486,843 (72.8%); 2003: filled in 475,952 of 476,013 (100.0%)
- 2001: filled in 4,411 of 485,977 (0.9%); 2002: filled in 353,756 of 486,843 (72.7%); 2003: filled in 475,988 of 476,013 (100.0%)
Query to reproduce it
SELECT `year` AS y, COUNTIF(community_area IS NULL) AS m, COUNT(*) AS n FROM `bigquery-public-data.chicago_crime.crime` WHERE `year` BETWEEN 2002 AND 2026 GROUP BY 1 HAVING COUNT(*) >= 1000 ORDER BY 1 NULLS LAST;returns 2002 · 132,620 · 486,843; 2003 · 61 · 476,013; … 25 rows in allSELECT `year` AS y, COUNTIF(ward IS NULL) AS m, COUNT(*) AS n FROM `bigquery-public-data.chicago_crime.crime` WHERE `year` BETWEEN 2002 AND 2026 GROUP BY 1 HAVING COUNT(*) >= 1000 ORDER BY 1 NULLS LAST;returns 2002 · 133,087 · 486,843; 2003 · 25 · 476,013; … 25 rows in allCrosswalk row 5
The crime-type codes (iucr, fbi_code) and location_description values in this file largely match what the City of Chicago already publishes
Evidence, counted on the full data
- iucr: 418 of 418 values found in City of Chicago Data Portal (Chicago Police Department) (1 tables); primary_type: 33 of 34 values found in City of Chicago Data Portal — Chicago Police Department Illinois Uniform Crime Reporting (IUCR) Codes (1 tables); and more
AI research: the query reads what the AI matched; a person confirms it.
Query to reproduce it
SELECT column_name, ANY_VALUE(values_matched), ANY_VALUE(values_total), ANY_VALUE(source_name), COUNT(*) FROM `dm-demo`.dq_results.public_recommendation WHERE schema_name = 'chicago_crime' AND recommend_public GROUP BY 1;returns Chicago Police Department; IUCR; … 4 rows in allCrosswalk row 6
A join on case_number will occasionally pull in a duplicate incident: about 1 in 13,700 records in the file is an extra copy, 630 records in total
Evidence, counted on the full data
- 526 case_number values repeat, adding 630 extra records out of 8,648,866 (about 1 in 13,700 records is an extra copy). Rule "No value in case_number appears more than once" fails in 1 table(s). crime (records dated 2001-2026): 526 of 8,648,866 (about 1 in 16,400).
Query to reproduce it
SELECT COUNT(*) FROM (SELECT case_number FROM `bigquery-public-data.chicago_crime.crime` WHERE NOT case_number IS NULL GROUP BY case_number HAVING COUNT(*) > 1);returns 526Crosswalk row 7
Neighborhood analysis effectively starts in 2002 — ward and community area weren't collected before then, so 2001 records can't be placed in a ward or neighborhood
Evidence, counted on the full data
- almost all of this gap is from before 2002, when ward was not yet collected; and more
- almost all of this gap is from before 2002, when community_area was not yet collected; and more
The queries for the other 1 findings this sums up are in their own rows below.
Query to reproduce it
SELECT `year` AS y, COUNTIF(ward IS NULL) AS m, COUNT(*) AS n FROM `bigquery-public-data.chicago_crime.crime` WHERE `year` BETWEEN 2002 AND 2026 GROUP BY 1 HAVING COUNT(*) >= 1000 ORDER BY 1 NULLS LAST;returns 2002 · 133,087 · 486,843; 2003 · 25 · 476,013; … 25 rows in allSELECT `year` AS y, COUNTIF(community_area IS NULL) AS m, COUNT(*) AS n FROM `bigquery-public-data.chicago_crime.crime` WHERE `year` BETWEEN 2002 AND 2026 GROUP BY 1 HAVING COUNT(*) >= 1000 ORDER BY 1 NULLS LAST;returns 2002 · 132,620 · 486,843; 2003 · 61 · 476,013; … 25 rows in allFEC campaign finance · readiness overview
Sellable for 4 of 6 uses, one of them from 2016. Remove or mask 305 identifying columns first.
! Sellable with conditionsWhat can it be sold for?
| Use | 1980–1992 | 1994–2004 | 2006–2014 | 2016–2020 | Verdict |
|---|---|---|---|---|---|
| Committee and candidate directoryLook up any committee or candidate by IDIDs unique in 142 of 142 tables, counted in full; 883 of 911 code-list checks pass | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready, all years |
| Money flows by election cycleTotals raised and spent, cycle by cycleAll 21 cycles present, none loaded twice; 1 in 2,400 dated records has no usable date | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready, all years |
| Donors by locationWhere contributions come fromCity and state filled in 97.6% to over 99.9% of donor records, by period | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready, all years |
| Donors by employerWhich employers' staff give, and how muchEmployer filled 73.5%, 81.2%, 91.5%, 96.6% by period; 2016–2020 holds 91% of donor records; Occupation isn't in the data before 2004 | ✕ Not ready73.5% filled | ! Caveat81.2% filled | ! Caveat91.5% filled | ✓ Ready | ! Ready from 2016 |
| Candidate linked to their committeeTie each candidate to their campaign moneyPrincipal committee missing for 1 in 5 to 1 in 9 candidates, every cycle | ! Caveat1 in 6 missing | ! Caveat1 in 6 missing | ! Caveat1 in 6 missing | ! Caveat1 in 6 missing | ! Caveat, all years |
| Primary versus general spendingSplit spending by election stageElection type filled 3.9%, 7.1%, 68.2%, 65.0% by period; Missing in 37% of all donor records | ✕ Not ready3.9% filled | ✕ Not ready7.1% filled | ✕ Not ready68.2% filled | ✕ Not ready65.0% filled | ✕ Not ready |
"Filled" is the share of records that carry the value a use depends on. ✓ Ready: 95% or more · ! Caveat: 80–95%, or a known limit a buyer must be told · ✕ Not ready: under 80% · cut-offs proposed until the data owner sets them
Chicago crime · readiness overview
Sellable for 5 of 6 uses, one of them from 2003. Mask the street block and take care with coordinates first.
✓ SellableWhat can it be sold for?
| Use | 2001–2002 | 2003–2010 | 2011–2018 | 2019–2026 | Verdict |
|---|---|---|---|---|---|
| Citywide crime trend by yearCrime volume, year over yearAll 26 years present, none loaded twice, none flagged abnormally high or low | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready, all years |
| Case-level countsCount incidents without double-counting526 case numbers repeat, 630 extra records: about 1 in 13,700 | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready, all years |
| Crime mappingPlot incidents on a mapCoordinates filled 98.1%, 99.2%, 98.9%, 98.5% by period; Worst year 2021: 1 in 29 missing | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready, all years |
| Location type analysisStreet, residence, store and so onLocation description filled 99.4% or more in every period | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready | ✓ Ready, all years |
| Neighborhood analysis (ward, community area)Crime by ward or community areaWard and community area weren't collected before 2002; 2002 is 72.7% filled; 2003 onward 99.9% or more | ✕ Not ready36.8% filled | ✓ Ready | ✓ Ready | ✓ Ready | ! Ready from 2003 |
| Long-run trend by crime categoryOne crime type across 26 yearsOnly 243 of 418 IUCR codes and 85 of 218 location types appear in both 2001 and 2026; Categories were added or retired, so long-run comparisons need a mapping | ! Caveatcodes change | ! Caveatcodes change | ! Caveatcodes change | ! Caveatcodes change | ! Caveat, all years |
"Filled" is the share of records that carry the value a use depends on. ✓ Ready: 95% or more · ! Caveat: 80–95%, or a known limit a buyer must be told · ✕ Not ready: under 80% · cut-offs proposed until the data owner sets them
Examples on public data (FEC campaign finance, Chicago crime). The first three screens are illustrative. The health summary and readiness overview are real counts on those public datasets; their verdicts show the method, not advice on whether these datasets may be sold. None of it is a client result.
One fixed fee, for one data domain
One data domain · eight weeks · Metadata Enrichment Engine included
- Metadata Enrichment Engine installed in your Azure, read-only on Snowflake or Azure SQL
- Every column described and rated for sensitivity, with quality rules where you need them
- A health summary with the query behind every counted figure
- A readiness overview approved by your data owner, and a business assessment of candidate products, buyers and indicative value ranges
- A 90-minute readout with your sponsor, data owner and legal or privacy lead
Prefer two steps? Metadata Enrichment Engine at $48,000, then the analysis at $32,000. Same work, same total price; it takes longer end to end.
For Metadata Enrichment Engine clients
Already have Metadata Enrichment Engine?
On the domain the engine already enriched. About five weeks.
Add-ons
$12,000 for the engine plus $16,000 for the analysis. Much of the analysis carries over.
The analysis run again on the same domain once the data has changed.
No license fee from us. The engine stays installed and your team can rerun it, on your own Azure and database compute. Listing or selling the data is a separate, later step.
What leaders ask us first
Can AI tell us what our data is worth?
Legal will never let us sell this.
We can just list it on a marketplace.
How do we know your findings are right?
Will you find us a buyer?
Can we buy it in steps?
Know what you can sell before anyone asks
Eight weeks, one fixed fee, and a one-page answer for your board.