Is this E-number additive authorised in this food category?
The EU Union list authorises a couple — additive plus food category — never an additive on its own. One offline call returns the dated verdict, the level as published, and the group behind it.
By Matthias Begot · · Updated
There is no such thing as an “authorised food additive” in EU law. Regulation
(EC) No 1333/2008 authorises a couple — (additive, food category) — at a
level published for that couple, at a date. An agent validating a recipe, a
label or an import that asks “is E 250 allowed?” has asked a question the Union
list does not answer. GET /label/food/additive
answers the question that exists: is this additive authorised in this food
category, at what maximum level, under which conditions — served word for
word, versioned by the consolidated text in force at the queried date, from a
local store with no network call and no secret.
Why “is this additive allowed?” is the wrong question
The Union list is a positive list. The European Commission states the rule plainly: all additives in the EU must be authorised and listed with conditions of use in the positive list, following a safety assessment and a demonstrated technological need. Nothing outside the list is permitted; nothing inside it is permitted everywhere.
That structure is visible in the annex itself. Annex II splits into parts that only make sense together — Part C defines the groups of additives (Group I, Group II, Group III, Group IV), Part D is the food category system, and Part E carries the authorised additives and their conditions of use per food category. The authorisation lives in Part E, indexed by a category code. Strip the category and there is no row to read.
Sodium nitrite makes the point. E 250 is authorised in heat-treated meat products and is not authorised in unflavoured milk. Both are facts about the same E number, and neither is a property of E 250.
The endpoint refuses to answer the abstract question
This is enforced in the response shape rather than in a disclaimer:
- with
food_category→ averdict(authorised/not_authorised) and theauthorisations[]published for that couple; - without
food_category→ noverdictfield at all. You getauthorised_in, an inventory of the categories where an authorisation exists, and nothing more.
An inventory is not a claim. An agent that receives no verdict cannot
accidentally read one, because the field is absent rather than null.
What a verdict actually contains
GET /label/food/additive?e_number=E250&food_category=08.3.2
The identity key is an E number (template-validated before any lookup —
E 160a(i) is a legal shape) or the exact published name. The category code
is the one published in the annex (08.3.2); Annex III parts are addressed as
III.1 to III.5. An optional date serves the consolidated version in force
at that date rather than today’s.
The answer carries the parts that a compliance decision depends on:
| Field | What it gives you |
|---|---|
verdict | authorised / not_authorised — only when a category was supplied |
authorisations[] | One entry per published line covering the couple |
max_level | Verbatim — "55", "500 mg/kg", "quantum satis" |
restrictions | As published, line breaks and periods of application included |
footnotes[] | Verbatim { number, text } |
via_group | The group the authorisation is actually published under |
amending_act | The amending regulation, with CELEX and OJ date |
version | consolidated_ref, applicable_from, applicable_to |
The verbatim rule is not fastidiousness. Guidance on reading the Union list is explicit that the footnotes and notes in Annexes II and III form part of the authorisation — a level quoted without them is not the authorisation. So the service never paraphrases them, and never converts a level into a number when the regulation did not publish one.
quantum satis stays a phrase
quantum satis is a regulatory instruction — no maximum level is imposed, use
no more than needed to achieve the intended effect. It is not a missing value
waiting to be filled in with a default. Serialising it as null, -1 or
999999 would hand an agent a number the legislator declined to write. It is
returned as the words.
Group authorisations are resolved, not hidden
Many rows are published for a group rather than for the additive by name.
E 250 in heat-treated meat products is authorised through the combined entry
E 249 - 250, published under the wording “Nitrites”. The response says so:
the line is stored as published, resolved at read time, and via_group reports
which group carried it, alongside published_as for the wording used.
The honesty runs the other way too. A combined range whose composition is not
published in Part C is not expanded by guesswork. If no published
authorisation is found for the couple, not_authorised means exactly that — no
published authorisation was found — and nothing stronger.
The levels move, and the dates are the point
A compliance answer that is not dated is not an answer. The Union list is amended continuously, and the amendments carry their own application dates:
- Nitrites and nitrates — Commission Regulation (EU) 2023/2108 of 6 October 2023 lowered the maximum levels of E 249–250 and E 251–252. The new levels apply from 9 October 2025 (general meat products dropping from 150 to 80 mg/kg, sterilised meat products from 100 to 55), with cheese categories phased across 9 October 2025, 2026 and 2027.
- Additives for vulnerable populations — Commission Regulations (EU) 2026/189 and (EU) 2026/196, published on 29 January 2026, revised uses in categories intended for infants, young children and foods for special medical purposes — shellac (E 904) in FSMP tablets in the first, a set of hydrocolloids (E 407, E 410, E 412, E 414, E 415, E 440, E 1450) in the second.
An agent holding a level scraped last year is holding a level that may have been
superseded on a date it never recorded. Two mechanisms keep this straight: the
restrictions text carries the period of application as published (so a couple
with a transition returns both lines, each dated), and version.consolidated_ref
names the consolidated text the answer came from — for instance the EUR-Lex
consolidation of 18 February 2026.
Reading the result honestly
not_authorisedis a billed 200. Under a positive list, “no published authorisation for this couple at this date” is the information the agent paid for. The x402 golden rule holds: the agent pays for the answer to its question, not for a row.not_authorisedis dated, not a safety judgment. It reports the state of the Union list at the queried date. It says nothing about toxicology.- An unknown additive is a
404, not anot_authorised. There is nothing to answer about, so nothing is billed. A known additive with no authorisation in the requested category is the billed 200. The two are never confused. - Scope is the Union list. Flavourings (Regulation (EC) No 1334/2008), food enzymes (No 1332/2008), novel foods, allergen labelling and the nutrition declaration are out. So is any dose computation: the endpoint returns the level authorised for a couple, never the level of an additive in a finished product, and never a cumulation across ingredients.
- Freshness is a snapshot, honestly dated. A missed refresh keeps serving
the last good snapshot with
provenance.freshness.as_oftelling the truth about it — it never becomes a 5xx.
Where it sits in the x402 loop
No signup precedes the call:
- Discover the endpoint in the live catalog, call it, receive the
402challenge. - Pay — sign the chosen rail and replay the request.
- Read —
verdict,max_levelas published,restrictionswith their period of application,footnotes, and thevia_groupthat explains the row. - Branch — clear the recipe, flag the category, or route the couple to a human with the amending act cited.
The Quickstart walks the full discover → 402 → pay →
replay cycle with runnable snippets. Price and accepted rails are served live by
the catalog, never pinned in an article.
Chain it with the rest of the label family
Food additives are one regulated wording problem among several, and the same discipline applies across them:
GET /label/cosmetic/ingredient— restrictions and annex entries under Regulation (EC) No 1223/2009.GET /label/claims/check— whether a nutrition or health claim wording is authorised, rejected with its official motive, or simply absent from the register.GET /label/chem/classify— harmonised CLP classification, versioned by ATP.
Used for what it is — a dated, verbatim reading of a positive list, indexed by
the couple the legislator actually authorised — /label/food/additive lets an
agent answer “may I put this in that?” before a recipe ships or a shipment
clears. For the full field reference and error codes, see the
GET /label/food/additive documentation; for
how agents discover and call Invoket endpoints, see
For agents.