How we score

Short version: we read the ingredient list on the label, grade every single ingredient, and add up what looks like a nutritious bowl and what looks like marketing. The same rules are applied to every product, with no per-product human override.

In one sentence: the headline score rewards lots of real meat and vegetables, few fillers and additives, and a label that tells you the truth; the opposite lands low. Four further dimensions, shown on every product page, measure what the label and the public record can verify beyond the recipe.

Evidence behind the score

The ingredient tiers and processing weights are grounded in peer-reviewed studies and veterinary guidance, not just brand marketing. We keep a living list of the sources that inform the model.

Browse the research & evidence →

The five steps, in plain English

  1. We read the label. We take the ingredient list exactly as it is printed on the bag or tin, word for word.
  2. We work out how much is in it. UK law only requires percentages for the headline ingredients. For the rest, we use the order of the list. By law, ingredients are listed from heaviest to lightest, so a longer list position means less.
  3. We grade every ingredient. Each of the 963 known ingredients is graded as good, medium or poor. Named meats and fish score well; cheap fillers, artificial colours and vague “by-products” score badly.
  4. We add it all up. Good ingredients pull the score up. Fillers, additives and undeclared “other” stuff pull it down. Labels that print real percentages get a small bonus for transparency.
  5. We sanity-check the results. Clearly excellent recipes should land at the top and clearly filler-heavy ones at the bottom, and that is what the model produces. You can read the label yourself and see why a product scored the way it did.

The five dimensions

The 1-100 headline is the Recipe score, computed with the same rules as before; the coefficients were re-calibrated, so individual scores may have moved by a few points. Four further dimensions sit alongside it on every product page, each computed from stored data and expandable to show its working.

Recipe (the headline score)

Ingredient quality and specificity, dry-matter composition, transparency of printed quantities, processing type and additives. This is the published 1-100 score, and the only dimension that feeds the headline number.

Nutritional

How the declared analytical constituents compare with FEDIAF reference ranges, scored on a dry-matter basis. Confidence markers (high, medium, low) show how much was actually declared; missing data is shown, never imputed silently.

Transparency

How much the manufacturer discloses, measured against the FEDIAF Code of Good Labelling Practice and Regulation 767/2009. Mandatory items dominate the weighting.

Safety

Recall and safety-notice history, time-decayed. This dimension never feeds the headline score, and the incident list is always shown next to the number.

Evidence

How much evidence supports the claims made on the pack and product page: manufacturer assertion versus cited research. No claims on file means "nothing to verify", not a zero.

The evidence for each rule

Every scoring decision above exists because of a specific piece of published evidence - not because it sounds right. The full source list lives on the research page.

Named cuts beat bare species names

“Chicken breast / beef liver” score higher than plain “chicken / beef”, which could legally be frames or mechanically recovered meat.

Why: Protein quality varies enormously with the actual tissue used; unspecified sources cannot be judged.

Dry-matter normalisation

Percentages are compared on a dry-matter basis: fresh meat is ~72% water, meat meal ~8%, so wet and dry recipes are converted before comparison.

Why: Comparing as-fed percentages flatters wet foods; moisture changes misrepresent nutrient content.

Fresh frozen & raw rank above kibble

Minimally processed formats get a scoring advantage over high-heat extruded kibble.

Why: Frozen raw, freeze-dried and fresh diets showed higher amino-acid digestibility and metabolisable energy than extruded food; fresh foods keep more available lysine and fewer AGEs than kibble.

Shelf-stable “fresh” gets no fresh bonus

Ambient-stable fresh food (steam-cooked in a sealed pack, e.g. retorted trays) is scored on recipe alone - no minimal-processing advantage.

Why: Retort sterilisation is process-wise identical to canning. Wet/retorted foods had the worst AGEs and lysine damage of all formats tested; in human food, canning causes the largest heat-labile vitamin losses and multiplies AGEs.

Extrusion & high-heat drying drag scores down

Extruded and baked dry foods rank below gently processed formats.

Why: Extrusion and 160–180°C drying measurably reduce available lysine and other nutrients.

Additive penalties are moderate, not extreme

Artificial colours are penalised most (they exist only to impress buyers); approved preservatives get small penalties.

Why: A systematic review found approved additives show no measurable harm within regulatory limits - so we penalise non-disclosure and cosmetic additives, not safety.

Grain-inclusive is not penalised per se

Grains are fine as part of a recipe; only filler dominance (high carb, low meat) drags a score down.

Why: Controlled trials found no DCM signal or taurine effect from grain-free vs grain-inclusive diets; formulation quality matters more than grain ideology.

Transparency is rewarded three times

Printing some percentages earns a clear-label bonus; ~fully quantifying the recipe (95%+ of mass declared) earns a full-disclosure bonus; declaring exactly which additives are used (with doses) earns a small transparency bonus.

Why: A label that discloses quantities lets you verify the recipe - the whole basis of this site. Undeclared products are not penalised beyond missing the bonuses, since not publishing is not proof of poor quality.

    What lifts a score

    • A high share of named meat, fish and meat meal
    • Vegetables, fruit and useful oils instead of fillers
    • A clear, honest label with percentages printed for (nearly) every ingredient
    • Declaring exactly which additives are used (small transparency bonus)
    • Few or no artificial colours, flavours and preservatives

    What drags a score down

    • Filler-heavy recipes - wheat, maize or rice making up most of the bowl
    • Vague ingredients such as “meat derivatives” or “animal by-products”
    • Artificial additives and colourings
    • A lot of the recipe not declared by weight

    What the headline score does not look at

    The 1-100 headline is the Recipe score: it ignores the price, the brand's reputation, the bag design and whether a specific dog happens to be allergic to something. A cheap food with a great ingredient list can outscore an expensive one, and vice versa. Recall history and claim evidence are shown separately in the Safety and Evidence dimensions and never feed the headline number.

    Advanced: the exact model, data and weights

    For the curious: this is the precise, reproducible machinery behind the plain-English version above.

    The full pipeline

    1. Parse the ingredient list as declared on the packaging, extracting percentages where present and expanding grouped ingredients (e.g. Chicken 60% (Chicken, Chicken Liver)).
    2. Strip marketing terms. Words like premium, natural, human-grade, free-range carry no nutritional information and are removed before matching.
    3. Estimate missing quantities. The undeclared remainder is distributed across the remaining ingredients, weighting earlier-listed ingredients more heavily (labels list ingredients in descending order of weight).
    4. Match each ingredient against the glossary of 963 ingredients, each classified (meat, carb, oil, veg, supplement, additive…) and tiered from published nutritional guidance.
    5. Compute features: category percentages, average ingredient-quality score, count and share of poor ingredients, clear-label flag, additive penalties, processing type.
    6. Predict the rating with a linear model. The exact weights are listed below, and every score on this site can be recomputed from them.

    Current model

    Version
    v2 live
    Type
    linear
    Features
    40
    Trained
    2026-09-05
    Weights hash
    3ba8a7f5861bf20e

    How the model is calibrated

    The coefficient table below is not hand-tuned per product, and it is not fitted to health outcomes. It is fitted against our pinned v1 baseline algorithm, which encodes our editorial judgements about what a good label looks like. This makes the model internally consistent with those judgements, not externally validated against health outcomes. That distinction matters: the score is a reproducible reading of the label, not a proven prediction about your dog.

    When a new version is trained, we measure how far its scores drift from the v1 baseline across the whole catalogue, and any drift has to be explained in the release note before the version can be published. We deliberately do not publish the error figures: they measure agreement with our own earlier algorithm, not accuracy against any external truth, and a small number would read as more validation than it is.

    Model changelog

    Named algorithm versions. One version is live on the site at a time; drafts are trained and tested locally before being published. Every release has a public write-up of what changed and why.

    Model coefficients

    The exact weights applied to each Recipe feature (plus per-processing-type terms). Every stored rating keeps its full feature vector, so any score can be recomputed from this table. The other four dimensions use fixed published parameters rather than learned coefficients; they ship in the same published weights file under their own blocks.

    FeatureCoefficient
    Base score (bias)32.3358
    Average ingredient quality (avgIngredientScore)9.9153
    Meat share of dry matter (meatPctDM)0.1160
    Carb share of dry matter (carbPctDM)-0.1126
    Oil share of dry matter (oilPctDM)-0.0883
    Vegetable share of dry matter (vegPctDM)-0.0018
    Additive share of dry matter (additivePctDM)0.1772
    Supplement share of dry matter (supplementPctDM)-0.0089
    Other share of dry matter (otherPctDM)-0.3710
    Unrecognised share of dry matter (unknownPctDM)-0.0224
    Recipe graded poor (poorPct)-0.0447
    Poor-quality meat in recipe (poorMeatPct)-0.1819
    Number of poor ingredients (poorCount)-0.8680
    Largest single poor ingredient (poorMaxPct)0.0564
    Undeclared quantities (missingPct)-0.1309
    Prints ingredient percentages (clearLabel)3.1945
    Complete diet (complete)1.7032
    Frozen or chilled fresh (isFresh)11.4401
    High meat (30%+ of dry matter) (highMeat)-0.5058
    Low meat (under 10% of dry matter) (lowMeat)-1.9883
    High carb and low meat (highCarbLowMeat)-1.2497
    Meat share × printed percentages (meatClearLabel)-0.0733
    Meat share × fresh (meatFresh)-0.3386
    Fresh × high meat (freshHighMeat)16.4755
    Additive penalty (additivePenalty)0.2356
    Processing multiplier (processingMult)32.3358
    Processing: Raw (proc_raw)13.3220
    Processing: Fresh Chilled (proc_fresh-chilled)7.7119
    Processing: Fresh Frozen (proc_fresh-frozen)6.5831
    Processing: Fresh Refrigerated (proc_fresh-refrigerated)4.8570
    Processing: Fresh Shelf (proc_fresh-shelf)0.0721
    Processing: Dry Freeze Dried (proc_dry-freeze-dried)11.1272
    Processing: Dry Air Dried (proc_dry-air-dried)9.3200
    Processing: Dry Cold Pressed (proc_dry-cold-pressed)4.5685
    Processing: Dry Baked (proc_dry-baked)-2.3206
    Processing: Dry Extruded (proc_dry-extruded)-6.9960
    Processing: Dry Semi Moist (proc_dry-semi-moist)-6.8331
    Processing: Dry Muesli (proc_dry-muesli)-10.7109
    Processing: Wet Pate (proc_wet-pate)2.9350
    Processing: Wet Chunks (proc_wet-chunks)2.2925

    Ingredient glossary

    CategoryTierCount
    additivegood4
    additivemedium21
    additivepoor34
    carbgood16
    carbmedium53
    carbpoor25
    fibregood12
    fibremedium32
    fibrepoor3
    meatgood156
    meatmedium78
    meatpoor14
    mineralgood9
    mineralmedium11
    oilgood25
    oilmedium19
    oilpoor2
    othergood3
    othermedium21
    otherpoor7
    otherunknown1
    supplementgood137
    supplementmedium43
    supplementpoor5
    veggood172
    vegmedium58
    vegpoor2

    Assumptions register

    Every score rests on the assumptions below. Each is a deliberate choice, listed with what breaks if it turns out to be wrong for a given product.

    AssumptionWhy we make itWhat breaks if it is wrong
    Missing moisture is estimated per ingredient categoryLabels only have to print moisture above 14%. Estimating it lets wet and dry foods be compared on a dry-matter basis.That product's composition shares shift. Scores move a little; rankings between similar products rarely do.
    Undeclared quantities are estimated from list orderUK law requires percentages only for headline ingredients, but does require the list itself in descending order of weight.The split between minor ingredients is approximate. Printed percentages are always used exactly as declared.
    Processing type comes from storage instructions, not the product name"Fresh" on the bag can mean frozen, chilled or shelf-stable retort, which are very different processes.A misclassified product gets the wrong processing adjustment. The storage instructions are shown on the product page so you can check.
    "Complete" and "complementary" are taken at label valueThese are legal declarations made by the manufacturer; we do not test any product ourselves.A complementary food could be presented as complete or vice versa. Report it and we correct the record.
    Additive transparency counts presence, not dosesWhether a label lists "Vitamin A" or "Vitamin A 1,500 IU/kg", the only signal reliably available across the whole catalogue is that the section exists.A bare list of names gets the same small transparency credit as a fully dosed one.

    Check a score yourself

    Every number in a score is published, so you can check the arithmetic with a calculator:

    1. Open the product page and expand "Recipe: how the 1-100 score is calculated". Each row shows the feature value taken from the label, the published coefficient, and the contribution that results from multiplying them.
    2. Add the contributions together with the processing-type offset and any label bonuses. If the total lands above 100 or below 1, it is pulled back to 100 or 1; otherwise it stays as it is. The result should match the displayed score; contributions are rounded to two decimals, so allow a rounding difference.

    What you can check this way is the arithmetic: every contribution comes from the published coefficient table, and nothing else feeds the score. The one step you cannot redo by hand is turning the raw label into feature values in the first place: that relies on the dry-matter conversion and list-order estimation described above, whose per-category figures are not published.

    The weights for every published version are kept, and historical scores stay checkable under their original version. If your recomputation differs from the site, tell us: we treat it as a bug and answer publicly.

    Brand attribution

    Products are matched to their manufacturer brand from the product name, URL and ingredient list. Every assignment is stored with a timestamp and a confidence, so you can audit it in the provenance section of any product page. Errors are possible, and provenance lets you check each one.