About the C.L.E.A.N.® Standard app
Read why.
The C.L.E.A.N.® Standard app reads a packaged-food ingredient list and tells you whether anything in it belongs on a “watch” or “avoid” list. Every flag we raise comes with a public rationale and a cited source — tap any flagged ingredient to read the receipts.
This is not medical advice and does not replace reading the label yourself.
Why this app is different
Most ingredient-scanner apps give you a single green/yellow/red rating and ask you to trust the person or company behind it. This app does it differently:
- Every flag has a citation. When we mark an ingredient as “watch” or “avoid,” the entry carries a public rationale and at least one source link. No black-box scoring.
- The dictionary is auditable. The full list of ingredients we recognize is browsable. You can see every entry and the reasoning behind its tier.
- Verdicts are versioned. Each verdict is pinned to the dictionary version that produced it. A share link sent today still resolves to the same result next month, even if we update the underlying data.
- Honest about unknowns. If an ingredient isn’t in our dictionary, we say so instead of guessing. The verdict reflects what we actually know.
We’d rather have fewer ingredients with solid reasoning than a huge catalog of opinions.
What it does
You give the app an ingredient list one of three ways:
- Paste — copy the ingredients line from a label and drop it in the box.
- Barcode — type a GTIN / UPC and the app looks the product up in its catalog.
- Photo — pick a photo of the label and the server reads the text via OCR, then runs it like a paste.
The app splits the list into ingredients, matches each one against a dictionary, and rolls the per-ingredient tiers up into one overall verdict.
How to read the verdicts
The full dictionary is browsable. Click any matched ingredient on a verdict to see why it is rated the way it is, with citations.
What we do with your data
Pasted ingredient text is not logged server-side. The request body hits the classifier, the verdict comes back, and the body is not written to any database, file, or log on our side.
Barcodes and product lookups work differently. When you scan a barcode the GTIN goes to the server in the URL path (/v1/products/by-gtin/<gtin>), and when you share a barcode result the GTIN is in the share-link URL too. Standard server access logs (timestamp, IP, request path, status code) record request paths for operational reasons, so a scanned GTIN can appear in those logs. A GTIN is the same number printed on the package — it identifies the product, not you.
The only readable history of your scans — what you scanned and what the verdict said — lives in your own browser, in localStorage. (Our servers keep an anonymous scan tally: the scan kind, an outcome word, the barcode number on barcode scans, and the random install id — never label text, photos, or findings.)
- The “recent scans” list at the bottom of /scan — last 5 scans, kept on your device only.
- You can clear it via the Clear button on the recent-scans list, by opening browser devtools and running
localStorage.clear(), or by clearing site data for this origin.
The one way a scan’s content ends up kept on our side is a report you choose to send: pressing Send in “Report this scan” shares that scan with us, and we keep it for the window described on the privacy page. No report is ever sent without that press.
Where the dictionary comes from
The dictionary that drives the verdicts is a small, hand-curated list of food ingredients. Entries that are flagged (watch or avoid) carry a public rationale plus citations — typically a public USDA or PubChem reference, or a peer-reviewed paper — so the reasoning is visible. Entries that are simply on the acceptable list often carry neither: there is nothing to cite when the ingredient is uncontroversial (salt, oat flour).
Anyone disagreeing with a flagged tier can read the rationale and the cited source. There is no proprietary scoring magic — every flagging decision is auditable.
The dictionary is versioned. When you share a verdict link with a friend and the dictionary has been updated since, the app shows a banner on the receiver’s view explaining that the source data has changed.
Limitations you should know about
- It only knows what it has been told. If an ingredient is not in the dictionary, it shows as unknown and the verdict adapts accordingly.
- Locale matters. Match quality is best when the label language matches the browser language. Mixed-language labels work, but obscure spellings may not match.
- Photo OCR is text-only. If a photo is blurry, glare-y, or the ingredient list is too small, OCR returns empty and you will be asked to paste the text instead.
- Barcode lookups can miss. The product catalog is not exhaustive. If a barcode is not in the catalog, the app tells you and falls back to paste.
- This is a beta. The dictionary is small and growing, and the wording and styling will keep improving. If a verdict looks wrong to you, that feedback is exactly what this release is for.
Provenance on every verdict
Every verdict the app returns carries two provenance fields:
dictionary_version— the exact snapshot of the dictionary that produced this verdict.evaluated_at— the server timestamp at which the classifier ran.
Both are shown in the small footnote at the bottom of the verdict card. If a friend ever questions a verdict, those two fields are enough to reproduce it exactly.