Skip to content

Pet diet (public)

Members can record what each of their pets eats. An owner may choose to show the pet’s current food publicly, for example on the pet’s public page or an animal listing. This read gives you that public part, and nothing else: it is 404 for every pet whose owner did not opt in.

GET /api/diet/v1/public/animals/{animalId}/diet

Anonymous: no token. animalId is the pet’s id (a UUID). Responses use the standard envelope (data, resultCode); properties whose value is null are left out.

AnswerWhendata
200, resultCode Diet_Public_GT_Resource_SUThe owner shows the pet’s food publicly.the public diet (below)
404, Diet_Public_GT_Resource_FLThe owner has not opted in, no diet is recorded, or there is no such pet. The three are not told apart.none

The same answer is served at GET /api/diet/v1/animals/{animalId}/diet/public for callers that already send a signed-in United Pet Club token. Use the anonymous route unless you have that token anyway.

{
"data": {
"animalId": "…",
"since": "2026-10-01",
"items": [
{
"roleCode": "MAIN",
"foodKindCode": "KIBBLE",
"sourceCode": "PET_FOOD",
"productName": "…",
"brandName": "…",
"petFoodProductId": "…",
"petFoodVariantId": "…",
"startedOn": "2026-10-01"
},
{
"roleCode": "TOPPER",
"foodKindCode": "HOME_MADE_RECIPE",
"sourceCode": "RECIPE",
"recipeId": "…",
"startedOn": "2026-10-01"
}
]
},
"resultCode": "Diet_Public_GT_Resource_SU"
}

The values above illustrate the shape; ids and names are elided.

PropertyMeaning
animalIdThe pet.
sinceThe day the current diet started (YYYY-MM-DD).
itemsThe foods the pet eats now, in the owner’s order. Foods the owner stopped are not listed.
items[].roleCodeMAIN, TREAT, SUPPLEMENT, TOPPER or MEDICATED.
items[].foodKindCodeKIBBLE, WET, RAW, FREEZE_DRIED, DEHYDRATED, FRESH_COOKED, HOME_MADE_RECIPE, TREAT, CHEW, SUPPLEMENT, TOPPER or MILK_REPLACER.
items[].sourceCodePET_FOOD (a food from the pet-food catalog), RECIPE (a recipe from the recipes catalog) or CUSTOM (described by the owner).
items[].productName, items[].brandNameThe catalog names, for a PET_FOOD item whose product is public.
items[].petFoodProductId, items[].petFoodVariantIdThe catalog product and package, for the same items. Read the label with GET /api/pet-food/v1/products/{petFoodProductId}.
items[].recipeIdThe recipe, for a RECIPE item.
items[].startedOnThe day the pet started on this food (YYYY-MM-DD).
  • Amounts, schedules, preparation and notes. The public diet says what, never how much or when.
  • Prescriptions and recalls. Whether a food is a prescription diet, and any recall notice on it, stay private to the owner and the people they share the pet with.
  • Foods not yet in the public catalog. A food the owner added that is still waiting for review is listed by its role and kind only: no names, no catalog ids.
  • Names of custom foods. A CUSTOM item is listed by its role and kind only.

Show an item without names by its kind (for example “Kibble” for KIBBLE).

  • It can disappear at any time. The owner can turn public sharing off; when a pet changes owner, sharing is turned off until the new owner turns it on. Treat a 404 as “nothing to show”, and do not keep a copy longer than you would keep any other public page content.
  • It changes when the diet changes. A new diet gets a new since; read it again rather than assuming a food is still fed.

Members’ pets’ foods and recorded outcomes count in totals about each catalog food (pet food research, part of the United Pet Club Platform Agreement). Two anonymous reads return those totals, and nothing else: every number covers at least 10 pets, is rounded to the nearest 5, and numbers that would let someone work out a smaller group are withheld too. There is no row-level data and no export.

GET /api/diet/v1/public/research/foods?species=DOG&breedGroup=MEDIUM&ageBand=ADULT&take=10
ParameterValues
speciesRequired. A species code from the pet-food catalog, for example DOG or CAT.
breedGroupOptional. The breed’s size class: TOY, SMALL, MEDIUM, LARGE, GIANT, MIXED, UNKNOWN.
ageBandOptional. Age when the pet started the food: JUNIOR (under 1 year), ADULT (1 to 7), SENIOR (7 and over), UNKNOWN.
take1 to 50 foods, default 10.

An unknown code answers 400 Diet_Research_VL_Request_RJ. Otherwise 200 Diet_Research_GT_Resource_SU with data:

PropertyMeaning
speciesCode, breedGroupCode, ageBandCodeThe filters applied.
level0 species only, 1 one filter, 2 both filters.
builtAtUtcWhen the statistics were last rebuilt (nightly); null before the first build.
threshold, roundedTo10 and 5.
disclaimerCodeDiet_Disclaimer_GT_Research_SU, the “statistics, not advice” notice: show it with the numbers (Using the statistics).
foods[]Most-eaten first: productId, productName, brandName, productSlug, petCount, outcomes, medianDaysOnFood.

outcomes is { improved, noChange, worsened, notAssessed }: each pet’s latest outcome on the food, as its owner recorded it. A null count is withheld, not zero: show it as “withheld” and never compute it from the others. medianDaysOnFood is rounded to 5 days, or null.

GET /api/diet/v1/public/research/products/{productId}

Always 200. data = { productId, builtAtUtc, threshold, roundedTo, disclaimerCode, species[], shifts[] }. Each species[] entry has speciesCode, petCount, outcomes, medianDaysOnFood and breakdowns[] ({ dimensionCode, cells[{ value, petCount, outcomes, medianDaysOnFood }] } for BREED_GROUP, AGE_BAND, SEX_NEUTER, TIME_ON_FOOD, CONDITION). Each shifts[] entry compares a reformulation: versionNo, effectiveFrom, changeNote, and before / after ({ petCount, outcomes }, pets assessed in the year before the new label and since). Empty lists mean nothing is published for that food yet. A missing breakdown row is withheld.

  • Both reads send Cache-Control: public, max-age=900; the numbers change at most once a night.
  • Always show the disclaimer: the numbers come from owners who chose to share, are not veterinary advice and are not a ranking of food quality.
  • Do not combine readings over time to infer changes for small groups, and do not present a count as exact.