Skip to content

Taxonomy

The taxonomy endpoints expose the shared vocabulary behind the catalogue: a three-level food category tree and a canonical tag vocabulary. Every product in the catalogue is classified with exactly one category slug plus any number of tag slugs, both drawn from these lists - so the same slug means the same shelf no matter which retailer or country a hit comes from.

Both endpoints are public (no API key) and cached - safe to call on page load or bundle locally.

Terminal window
curl "https://api.mealcp.com/v1/categories"
{
"categories": [
{
"slug": "bakery",
"name": "Bakery",
"level": 1,
"parent_slug": null,
"description": "Fresh or packaged baked goods. …"
},
{
"slug": "bread",
"name": "Bread",
"level": 2,
"parent_slug": "bakery",
"description": "Loaves, sliced bread, toast bread, …"
},
{
"slug": "bread/instore-fresh",
"name": "In-store / fresh bakery bread",
"level": 3,
"parent_slug": "bread",
"description": "In-store baked and fresh bakery bread. …"
}
]
}

The owned food category tree (max 3 levels) as flat rows. parent_slug is null for L1 roots; children reference their parent’s slug, so the tree is reconstructible without nesting. L3 slugs are path-like (parent/child).

  • slug - the stable identifier. Pass it as ?category= on search; it never changes and is safe to store.
  • name - display label for pickers and menus.
  • level - depth in the tree: L1 top-level domains (bakery, dairy-eggs), L2 families (bread), L3 leaves (bread/instore-fresh).
  • parent_slug - the parent’s slug, or null for L1 roots. Group rows by it to rebuild the nesting client-side.
  • description - a short human-readable summary - use it as tooltip or subtitle text in pickers.
  • Filter UIs: render L1 as top-level tabs and drill into L2/L3, reusing name and description verbatim.
  • Subtree queries: any level’s slug works as ?category= - the match covers the whole subtree, so category=bakery returns bread too. Ask for an entire aisle without listing its leaves.
  • Mapping your own taxonomy: attach your internal category ids to MealCP slugs once, and every search result in that subtree inherits the mapping.
Terminal window
curl "https://api.mealcp.com/v1/tags"
{
"tags": [
{ "slug": "contains-celery", "name": "Contains Celery", "type": "allergen" },
{ "slug": "contains-crustaceans", "name": "Contains Crustaceans", "type": "allergen" },
{ "slug": "contains-eggs", "name": "Contains Eggs", "type": "allergen" },
{ "slug": "contains-fish", "name": "Contains Fish", "type": "allergen" }
]
}

The canonical cross-cutting vocabulary: facts orthogonal to the primary category. type is one of dietary, lifestyle, certification, allergen. Tag slugs filter search via ?tag=.

Where the category tree answers what shelf is this on, tags answer attributes that cut across shelves: whether a product contains an allergen (slugs follow the contains-* pattern), fits a diet, or carries a certification. This is what lets a recipe assistant exclude contains-eggs across the whole catalogue in one filter, and what lets a nutrition app ground allergen answers in per-product data instead of assumptions.

Both endpoints cost 0 credits and are cached server-side. The trees change rarely, so most clients fetch them once at build or boot time and refresh daily rather than calling them on every request.

  • Group rows by parent_slug to reconstruct nesting; parent_slug: null marks the L1 roots.
  • L3 slugs are path-like (bread/instore-fresh), which keeps them unique without a separate id field.
  • description is a short human-readable summary - use it as tooltip or subtitle text in pickers.

Any category slug at any level works as ?category= on search, and any tag slug works as ?tag=. A category match covers its whole subtree, so ?category=bakery also returns bread and in-store fresh bakery bread. Facets combine in a single request - for example ?category=bread&tag=contains-eggs narrows bread down to products that contain egg.

?tag= takes one tag slug per request; stacking a tag on top of a category, brand, and price range is the usual pattern for dietary queries. To combine several tags, intersect the hit lists client-side.