How it works Verification Transparency Platforms Blog Get early access
Transparency

See who answered — not just the headline number.

A poll that reads 75% one way can be 80% one audience. The number alone is not the finding; the composition behind it is. Here is exactly what we publish, what we withhold, and why the difference is a rule rather than a preference.

Result inspector — switch the source
Verified panel · same question
48%

Token-backed respondents. Composition published, cross-tabs you can filter.

Composition · by verified segmentpublished
Democrat61%
Republican34%
Independent47%
18–2963%
65 +39%
Ind · Northeastk<50
Verified onlyPartyRegion Age bandk ≥ 50 floorε = 0.5 attestation 0x9f3c…a71b

Specimen figures. MintVote is pre-testnet and publishes no live results.

The suppression floor

A cross-tab cell is only published when at least k = 50 people sit behind it — 100 when the dimension is sensitive. Below that, the cell is withheld, never estimated. A suppressed cell shows as suppressed rather than being quietly filled with a plausible number, because a plausible number is indistinguishable from a real one to a reader and is worse than an honest gap.

Suppression also cascades: hiding one cell while publishing its row total tells you the hidden value by subtraction, so complementary cells are suppressed too.

Why the counts carry noise

Even above the floor, exact counts leak. Publish the same cross-tab twice, once before and once after one person joins, and the difference is that person. So published counts carry calibrated Laplace noise: enough that no single individual's presence changes what you can conclude, little enough that the aggregate remains useful. Every release states the ε it spent.

The privacy budget

Noise on a single release is not sufficient on its own — ask enough noisy questions and the answers average out to the truth. Each poll therefore carries a cumulative privacy budget that is debited per query and enforced atomically. When it is exhausted, further queries are refused rather than served at a degraded guarantee. An identical repeated query is answered from cache at zero cost, so nobody can drain the budget by asking the same thing twice.

Rolling up instead of hiding

Geography is the sharpest re-identification lever in any survey, so a small state is not simply suppressed — it rolls up to the finest level that clears the floor, uniformly across the table. Uniformly matters: mixing levels within one table produces a chart that silently compares different things.

Queries we refuse

  • Secret-ballot polls. Refused outright. A ballot cast under a secrecy guarantee is never a row in an analytics table, whatever the aggregation.
  • Differencing attacks. A query whose population is a near-subset of an earlier release is refused, because the difference between the two is a handful of people.
  • Nested refinement. Repeatedly narrowing a previously released population is refused for the same reason, tracked across releases rather than per query.
  • Fine-grained dimensions. Precinct, ZIP and date of birth are stored but are not queryable. Only a small, governance-frozen set of coarse dimensions can ever appear in a GROUP BY, which removes the rare-combination attack structurally rather than hoping a threshold catches it.

Demographic cross-tabs come from an opt-in panel, never from binding elections. Joining states which attributes will be correlated and at what aggregation, and consent is versioned — if the terms change, previously consented members are not carried into new releases under the new terms. Revocation removes a member from future releases.

Verification collects the data. Publication is governed separately, and deliberately narrower. The two are not the same permission, and we do not treat them as one.

See the per-mode privacy posture →

Check the numbers rather than trusting them.

The explorer rebuilds every poll from on-chain events and shows the block it stopped at.

Open the explorer Analytics dashboard