Usage

mastr — a CLI for the Marktstammdatenregister (MaStR). No API key needed.

mastr [global options] <command> [command options]

Global options

Option Description
--base-url <url> API base URL (default https://www.marktstammdatenregister.de/MaStR; http/https, a path prefix is fine, no ?query, #fragment, whitespace or control characters; a user:password@ is sent as Basic auth, never printed, and a literal % in it is written %25). A remote plain-http: URL logs one WARN record of mastr.http on stderr before the first request, requests to <host> are sent unencrypted (http:, not https:) — the base URL's credentials are sent unencrypted to <host> … when it carries a user:password@; loopback hosts (localhost, 127.0.0.0/8, ::1) and https: don’t warn, and stdout and the exit code are unchanged
--timeout <ms> time limit per request in ms, whole response included (0 = no timeout; at most 2147483647)
--user-agent <ua> User-Agent header value (not blank; Latin-1 without control characters, tab is fine)
--max-retries <n> retries for transient 429/503 responses and reset connections (0..10; each waits 200 ms, 400 ms, … or the server’s Retry-After when that is longer, up to 30 s — a longer one waits the 30 s cap, then retries). Each retry logs one WARN record of mastr.http before it waits (HTTP 503 from host: retry 1 of 3 in 2 s).
--max-response-bytes <n> cap the response body size in bytes (0 = unlimited; default 100 MiB)
--log-format <format> how errors, warnings and notes are written to stderr: text (default; log4j style, 2026-10-09T14:03:12.481Z WARN [mastr.http] …) or jsonl (one JSON object per line: ts, level, topic, msg). stdout is not affected
--compact print JSON on a single line (for piping to jq)
--iso-dates rewrite MaStR /Date(ms)/ timestamps to ISO-8601: a date-only value (sent as UTC midnight) as YYYY-MM-DD, a timestamp in German time (Europe/Berlin) with an explicit offset, e.g. 2020-02-20T17:28:35.250+01:00 (milliseconds only when not zero)
-V, --version / -h, --help version / help

Commands

Command Dataset
mastr stromerzeugung electricity-generation units (~9.06M)
mastr stromverbrauch electricity-consumption units
mastr gaserzeugung gas-generation units
mastr gasverbrauch gas-consumption units
mastr filters <category> the filterable columns (names, types, dropdown codes) for a category

Search options (the four data commands)

Option Description
--page <n> 1-based page (default 1)
--page-size <n> rows per page (1..5000, default 25)
--sort <spec> FieldKey-asc or FieldKey-desc, e.g. Bruttoleistung-desc. FieldKey is a record field name of that category, not a FilterName (Bruttoleistung exists only in stromerzeugung; see Capacity fields)
--filter <spec> filter expression (see below); repeatable — several are joined with ~and~
--total print only the total match count, not the rows (a one-row request, the library’s count(); --page and --page-size are ignored)

Each data command prints { total, data }: total is the full match count (respects the filter), data is the current page.

Filter syntax

FilterName~op~'value'~and~FilterName~op~'value'~…
# Solar (Energieträger 2495) units in operation (Betriebs-Status 35)
mastr stromerzeugung --filter "Energieträger~eq~'2495'~and~Betriebs-Status~eq~'35'" --total

# Wind (2497) or solar (2495) units: a comma list inside one dropdown value
mastr stromerzeugung --filter "Energieträger~eq~'2497,2495'" --total

# Wind (2497) units above 5,000 kW gross
mastr stromerzeugung --filter "Energieträger~eq~'2497'~and~Bruttoleistung der Einheit~gt~'5000'" --total

The register ignores a FilterName it doesn’t know and returns the unfiltered result; the CLI refuses such a name before sending (with “did you mean”). --filter may be given several times; the conditions are joined with ~and~. Every other option given twice is a usage error (exit 2).

Examples

mastr stromerzeugung --total                        # 9562366 (2026-10-05)
mastr stromerzeugung --page-size 5 --iso-dates      # first 5 units, ISO dates
mastr filters stromerzeugung --compact | jq '.[] | {FilterName, Type}'
mastr gasverbrauch --sort "MaximaleGasbezugsLeistung-desc" --page-size 10 --compact | jq '.data'

Exit codes

Code Meaning
0 success (help/version included); an empty result also exits 0
1 API/logical error (e.g. the server’s Errors field, or {"Error":true} for a filter value it can’t read or an unknown --sort key), or a catch-all
2 usage error (bad flags, unknown command, an option other than --filter given twice, a malformed --filter — shape, operator, ~or~, a FilterName the category doesn’t have, a dropdown code it doesn’t list — or a bad --page-size, redirecting base URL)
4 HTTP 404
6 network / transport failure (DNS, connection, timeout, response size-cap)

Notes

Capacity fields per category

The rows differ per category; Bruttoleistung/Nettonennleistung exist only in stromerzeugung (sorting another category by them returns 0 rows).

Category Capacity fields (record keys, usable in --sort) Unit
stromerzeugung Bruttoleistung (gross), Nettonennleistung (net) kW
stromverbrauch none in the rows (only the flag EinheitenUeber50MW) —
gaserzeugung Erzeugungsleistung (gas generation); gas storage: MaxEinspeicherleistung, MaxAusspeicherleistung (injection / withdrawal) and MaxArbeitsvolumen (working gas volume) storage: kWh/h, volume kWh (as the register’s detail page shows); Erzeugungsleistung: not stated in the rows
gasverbrauch MaximaleGasbezugsLeistung (maximum gas intake) not stated in the rows

The matching filters are Bruttoleistung der Einheit (stromerzeugung), Gaserzeugungsleistung and Maximale Gasbezugsleistung — check the exact names with mastr filters <category>.

View the source on GitHub →