Website: English · Deutsch — command reference, guides and API docs
Check Germany's official product-warning portal
(lebensmittelwarnung.de) from your terminal.
lebensmittel is a command-line tool over the portal's official RSS feeds — the
current recalls (Rückrufe) for food, cosmetics, and consumer products, narrowable
by federal state and product type, as clean JSON you can pipe straight into
jq.
--state bayern, --type lebensmittel, combined
or alone; both are applied server-side by the feed.--since <date>, --search <term>, --limit <n>.--compact for scripting, -o <file>
to write to disk.Want to use this as a TypeScript library, or curious how it parses the RSS feeds with zero dependencies? See DEVELOPING.md.
npm i -g @maschinenlesbar.org/lebensmittelwarnung-cli
This installs the lebensmittel command. Requires Node.js 20+. No API key.
Check it works:
lebensmittel warnings --limit 1 | jq '.[0].title'
# The 5 most recent recalls, product name + reason
lebensmittel warnings --limit 5 | jq -r '.[] | "\(.title) — \(.reason // "?")"'
# Only recalls affecting Bavaria
lebensmittel warnings --state bayern | jq length
# Only food recalls since the start of the month
lebensmittel warnings --type lebensmittel --since 2026-07-01 \
| jq -r '.[] | "\(.pubDate | split(" ")[1:4] | join(" "))\t\(.title)"'
# Search current recalls by product name
lebensmittel warnings --search schokolade | jq -r '.[].title'
| Command | What it shows |
|---|---|
warnings |
Current product warnings (recalls), filterable by --state / --type / --since / --search / --limit |
states |
The valid --state Bundesland slugs (offline) |
types |
The valid --type product-type slugs (offline) |
New to terms like Rückruf, Grund der Meldung or the Bundesland slugs? The Glossary decodes every one.
warnings options| Option | Meaning |
|---|---|
--state <slug> |
Only warnings for one Bundesland — server-side filter. One of the 16 slugs from lebensmittel states (e.g. bayern, nordrheinwestfalen). An unknown slug is a usage error. |
--type <slug> |
Only warnings for one product type — server-side filter. One of lebensmittel, kosmetischemittel, bedarfsgegenstaende, mittelzumtaetowieren, babyundkinderprodukte. |
--since <YYYY-MM-DD> |
Only warnings published on or after this date, counted in German time (Europe/Berlin), client-side. |
--search <term> |
Only warnings whose product title contains this text, case-insensitive (client-side). |
--limit <n> |
Return at most n warnings, in feed order (most recent first). |
--state and --type are validated against the fixed slug lists, so a typo fails
at parse time (exit 2) rather than silently returning the full, unfiltered feed.
Each item carries typed accessors plus a generic fields map and the raw HTML:
{
"title": "ja! Beerenmischung, tiefgefroren, 750 Gramm Beutel",
"link": "https://www.lebensmittelwarnung.de/.../Meldung.html",
"pubDate": "Wed, 8 Jul 2026 16:00:00 +0200",
"published": "2026-07-08T14:00:00.000Z",
"reason": "Krankheitserreger",
"manufacturer": "Eurogroup España Frutas y Verduras S.A.U., …",
"affectedStates": ["Nordrhein-Westfalen", "Bayern", "…"],
"lotNumbers": "L-26085",
"bestBefore": "Mindesthaltbarkeitsdatum: 15.03.2028",
"packaging": "750 Gramm",
"imageUrls": ["https://www.lebensmittelwarnung.de/.../Bild.jpg?__blob=normal&v=1"],
"fields": { "Bildquelle": "© Firma …", "Grund der Meldung": "Krankheitserreger", "…": "…" },
"rawDescription": "<img …/><br/><b>Grund der Meldung:</b> …"
}
The typed fields are extracted from the feed's HTML <description>; fields is the
complete label→value map (a superset, so a label this CLI does not model first-class
is still there), and rawDescription keeps the original markup.
Every command prints JSON to stdout; diagnostics go to stderr, so piping into
jq stays clean.
# Reasons, grouped and counted (a warning can carry several, joined with ", ")
lebensmittel warnings | jq -r '[.[] | (.reason // "?") | split(", ")[]] | group_by(.)[] | "\(.[0]): \(length)"'
# Recalls affecting a given Land (the same set --state hamburg returns)
lebensmittel warnings | jq -r '.[] | select(.affectedStates | index("Hamburg")) | .title'
# All image URLs in the current recalls
lebensmittel warnings | jq -r '.[].imageUrls[]?'
Use --compact for single-line JSON and -o <file> to write to a file — both are
global options that work before or after the command.
Exit codes make the CLI easy to use in scripts:
| Code | Meaning |
|---|---|
0 |
Success (also --help / --version) |
2 |
Bad usage / invalid argument (nothing was sent) |
4 |
Not found (404 from the server) |
6 |
Network / transport failure (DNS, connection, timeout, size cap) |
1 |
Any other error — including a non-RSS response (HTML shell) or an empty body |
command not found: lebensmittel — the global npm bin directory isn't on your
PATH. Run npm bin -g to find it and add it.1 / "received an HTML page" — the feed URL returned the website's HTML
shell instead of RSS (it may have moved). Check --base-url.1 / "Empty response … legacy JSON API" — the old
megov.bayern.de JSON API (bundesAPI spec) is defunct and returns an empty
body; this CLI uses the RSS feeds instead and does not touch it. If you see this,
a proxy or a wrong --base-url returned an empty body.--state/--type are validated, so
an unknown value exits 2. --search/--since that match nothing return [].Given before or after the command, e.g. lebensmittel --compact warnings:
| Option | Description |
|---|---|
-V, --version |
Print the version number |
-h, --help |
Show help for the program or a command |
--compact |
Print JSON on a single line instead of pretty-printed |
-o, --output <file> |
Write output to this file instead of stdout |
--base-url <url> |
API base URL (default https://www.lebensmittelwarnung.de) |
--timeout <ms> |
Time limit per request, reading the whole response included (default 30000; 0 = none; at most 2147483647) |
--user-agent <ua> |
User-Agent header value |
--max-retries <n> |
Retries for transient 429/503 responses (0..10, default 2) |
--max-response-bytes <n> |
Cap response body size in bytes (0 = unlimited; default 100 MiB) |
This CLI is a client — it accesses data it does not own or redistribute. The warnings are © the publishing Länder / the BVL and licensed separately from this tool's code. See DATA_LICENSE.md.
lebensmittelwarnung.de — the portal's content is copyright-protected. Reuse is allowed only unaltered, in full, and with the prescribed source citation (
Portal www.lebensmittelwarnung.de, [Jahr]: [Titel], [URL], Stand: [Datum]); partial/excerpted use and mixing with other sources are not permitted, and once a warning is withdrawn upstream you must delete your copy. This tool provides access; it does not grant you those rights — read DATA_LICENSE.md.
Dual-licensed — use it under either:
See LICENSING.md for details, and CONTRIBUTING.md for the contribution policy (this project does not accept external code contributions). Commercial enquiries: sebs@2xs.org.