How Dossier scores things
Every number in this app should be checkable. This page is where the working is
written down; the product pages link back to it.
The short version
A food score is 60% nutritional quality, 30% additives, 10% organic
certification. A cosmetic score is 60% ingredient hazard, 25% fragrance
allergens, 15% irritation risk. Your profile then applies **named, bounded
adjustments** on top, and every one of them is itemised on the product page.
If we don't have enough data, you get no number rather than a made-up one.
Nutritional quality (60%)
This is our own implementation of the Nutri-Score 2023 algorithm published by
Santé publique France. Nutri-Score is a registered mark and this is not an
official implementation of it — but the algorithm is public, and we follow it.
Points are counted against thresholds for energy, sugars, saturated fat and salt
(negative), and fibre, protein and fruit/vegetable/legume content (positive).
Different tables apply to beverages and to fats, oils, nuts and seeds; cheese and
red meat have their own protein rules; water is graded A outright. Non-nutritive
sweeteners in drinks carry a penalty, which is new in the 2023 revision.
We validate our implementation against Open Food Facts' own computation across
hundreds of real products. Where we disagree with them, that has to be written
down with a reason or the build fails.
The resulting point score is mapped to 0–100 using anchors derived from the same
grade cutoffs, so the number and the letter can never contradict each other.
If energy, sugars, saturated fat or salt is missing, there is no score. The
other pillars can't carry a food score on their own.
Additives (30%)
**The pillar is set by the highest risk level present, not by how many additives
there are.** A product isn't twice as risky for containing two lecithins, and a
long list of harmless thickeners shouldn't add up to the same penalty as one
substance whose approval was withdrawn. This matches how Yuka describes its own
additive scoring.
Risk comes from regulatory standing — not from an additive's reputation.
| Risk level | Meaning | Pillar score |
|---|
|---|---|---|
| No risk | No safety concern; several are nutrients | 100 |
|---|---|---|
| Low risk | Authorised with an ADI, no active safety signal | 75 |
| Moderate risk | Contested — open re-evaluation, IARC classification, or restricted for a subgroup | 40 |
| Hazardous | Approval withdrawn or banned in the EU | 0 |
A hazardous additive also caps the whole product score at 25. Without that,
strong nutrition on the other 60% could average away a substance the EU has taken
off the market, which is exactly the kind of laundering a scoring app shouldn't
do. It also raises a flag above the score, with its source.
Additives already penalised by Nutri-Score — sweeteners in drinks — are not
charged twice.
**Anything not in our table is reported as "not assessed". That means we have no
data on it, not that it's safe.**
Organic certification (10%)
Kept to match Yuka's weighting, and labelled for what it is.
Organic certification under Regulation (EU) 2018/848 is a farming standard.
It tells you how the ingredients were grown. It is not a measure of nutritional
quality, and an organic biscuit is still a biscuit. We include it because it's
what people expect from this kind of app, not because the evidence says it
changes health outcomes. Treat it as a preference weighting.
"Is that a lot?"
A number on a label is close to meaningless on its own. Very few people can say
whether 56 g of sugar per 100 g is unusual for a chocolate spread.
So every nutrient is also compared against the other products Open Food Facts
puts in the same category — the actual things next to it on the shelf. You get
the percentile and the category's typical value: *"higher than 94% of hazelnut
spreads. Typical is 9.5 g."*
Two rules keep this honest:
- Below 12 comparable products we say nothing. A "higher than average" claim
drawn from six products is noise dressed up as insight.
- Unremarkable nutrients are dropped, rather than padding the page with rows
saying "about average".
For fibre and protein the wording flips, because being high there is good news.
This tells you how a product compares with its shelf. It doesn't tell you whether
the shelf is a good idea — a chocolate spread with the least sugar of any
chocolate spread is still a chocolate spread, and the score says so.
Cosmetics
### Is there anything carcinogenic in it?
The question people actually bring to a cosmetics scanner, answered directly
rather than folded into a number.
Ingredients with an IARC carcinogenicity classification carry it explicitly, at
the top of the page, naming the group and what it means:
| Group | Meaning | How we treat it |
|---|
|---|---|---|
| 1 | Carcinogenic to humans | Verdict is AVOID; the score is capped at 20 |
|---|---|---|
| 2A | Probably carcinogenic to humans | Verdict is AVOID; the score is capped at 20 |
| 2B | Possibly carcinogenic to humans | A warning above the score |
| 3 | Not classifiable | Not reported — it isn't a finding |
An ingredient prohibited under Annex II of the EU Cosmetics Regulation caps the
score the same way. Capping only the hazard *pillar* wasn't enough: the allergen
and irritation pillars would pull a banned-substance product back up to a
comfortable-looking 43.
An uncertain (fuzzy) match can never make a claim this serious — it is reported
as "possibly contains", never as fact, and never triggers a cap.
### The table
Our INCI table covers the ingredients EU regulation actually restricts,
prohibits, or requires to be declared, plus the common inert ones so that
coverage means something. A typical cosmetic ingredient list still contains
things we have nothing to say about.
So every cosmetic page shows coverage: how much of that product we actually
assessed, weighted by position (INCI lists run in descending concentration, so
the first few ingredients matter more than the last few). Below 50% coverage we
refuse to give a number, though we still report what we found.
Matching runs exact → synonym → CAS → a tightly bounded fuzzy match. A fuzzy
match can never produce a definitive claim, counts for half weight, and never
bridges a digit difference — PEG-8 is not PEG-100, CI 77891 is not CI 77491.
Position only counts where position means something. INCI lists run in
descending concentration, so it's tempting to discount whatever sits near the
end. But preservatives, fragrance allergens and CMR substances are *always* near
the end — they're used at fractions of a percent, which is exactly why they're
regulated by concentration limit rather than by position. So a surfactant's
irritancy is discounted for being late in the list, and a restricted preservative
is not.
Fragrance allergens are a labelling fact, not a defect. They're named on the
label precisely so people who react to them can avoid them, so they only weigh
heavily if you've told us you're fragrance-sensitive.
Your profile
Two mechanically different things happen, and the difference matters.
Hard flags never touch the number. If a product contains something you're
allergic to, we say AVOID and show you why — and we leave the score exactly where
it was. Zeroing it would destroy the audit trail and tell you something false: the
product's nutritional quality hasn't changed, it's simply not relevant to you.
Condition adjustments are bounded and named. Telling us you have high blood
pressure weights salt more heavily. The adjustment is capped, it's derived from
the salt points the product already scored, and it appears on the page as its own
line with its reasoning and source. The invariant is enforced by test:
final score = base score + the sum of the listed adjustments
Every point of difference is attributable to exactly one named rule. If it
weren't, this page would be a lie.
We never show a personalised Nutri-Score letter. The letter is a registered
public-health mark with a fixed meaning; adjusting it would misrepresent it. We
adjust our own 0–100 figure and show the official grade unchanged alongside.
When we won't give you a number
- A required nutriment is missing
- Nutri-Score doesn't apply to the category (supplements, alcohol above 1.2% ABV,
infant food)
- Overall data confidence is too low
- For cosmetics, ingredient coverage is under 50%
In all of these you get a page explaining what we know, what's missing, and a
link to fill the gap in — Open Food Facts is crowd-sourced, so gaps are fixable.
Between "confident" and "refusing" there's a middle band where the score is shown
as approximate, with a hatched border and wording that says so.
Where the data comes from
Product data comes from Open Food Facts and
Open Beauty Facts, used under the
ODbL. It's crowd-sourced, which
means it's free, enormous, and uneven — which is why the completeness figure is
on every page.
Our own tables cite EFSA opinions, IARC classifications, EU regulations, WHO
guidance and clinical guidelines. Every claim in them carries a source, and the
build fails if a citation doesn't resolve or if a table hasn't been reviewed in
18 months.
What this isn't
Dossier has no medical review behind it. It reads labels faster than you can and
shows its working; it doesn't know your bloodwork, your medication, or the rest
of your diet. If you're managing a health condition, your clinician or dietitian
knows things this app cannot.