Glossary
A reference for the domain concepts and project-specific terms used throughout
lobbyregister-cli. The Lobbyregister domain is German; this glossary gives the
term used in the CLI/API alongside the original German where one exists.
Scope. This tool wraps a single open endpoint — the JSON search of the German Lobbyregister (
/sucheJson). The terms below are the ones actually surfaced by the client’s types, the search parameters and the two CLI commands. The register entries themselves are large, schema-versioned JSON documents that the client passes through untyped (see RegisterEntry), so their internal field names are deliberately not enumerated here.
The Lobbyregister
Lobbyregister. The public German federal register of interest
representatives (“Lobbyisten”) who lobby the Bundestag (the federal
parliament) and the federal government. Operated by the German Bundestag and
published at lobbyregister.bundestag.de.
Interest representative (Interessenvertreter). A person or organisation registered in the Lobbyregister. Each is described by one register entry.
Lobbyregistergesetz (LobbyRG). The German Lobby Register Act, the legal basis that mandates the register and its public disclosure. (Background only — not a field the client reads.)
Resource & endpoint
/sucheJson. The single open (no-auth) endpoint this client calls: a JSON
search over the register, served from the base URL
https://www.lobbyregister.bundestag.de. getJson issues a GET against it.
The human-facing equivalent is the website’s search page; the response echoes
that page’s URL in searchUrl.
Open data / read-only. The /sucheJson endpoint requires no API key,
no token and no login. This client implements only this read-only GET; it
never writes.
Search request
q (query). The free-text query string. Optional — omit q to match the
whole register; a blank q ("" or whitespace) is rejected, by the CLI and the
library alike, before any request. On the CLI it is the positional [query] argument to
search and count. A query beginning with a dash must be passed after a --
separator (e.g. search -- -Energie). The server also matches text that the response
doesn’t contain (such as the activity description on an entry’s register page), so an
entry can match without the term appearing anywhere in its JSON.
sort. The result sort order, passed through verbatim (case-sensitive); a
blank value is rejected before any request. The
values are those of the register’s website search: RELEVANCE_DESC (the default with a query), REGISTRATION_DESC (first published),
UPDATE_DESC (last updated), INACTIVITY_DESC (went inactive), NAME_ASC,
FINANCIALEXPENSES_DESC (declared spend), DONATIONAMOUNT_DESC, MEMBERSHIPFEES_DESC,
NUMBEROFREGULATORYPROJECTS_DESC, NUMBEROFSTATEMENTS_DESC, NUMBEROFFTE_DESC,
NUMBEROFENTRUSTEDPERSONS_DESC, NUMBEROFCONTRACTS_DESC, NUMBEROFMEMBERS_DESC,
NUMBEROFMEMBERSHIPS_DESC — each also in the other direction (_ASC / _DESC). The live endpoint ignores an unrecognised value (HTTP 200) and falls back
to its default order rather than rejecting it. The library then adds
sortIgnored: { requested, applied } to the result, from the order echoed in
searchParameters.sortOrder, and the CLI warns on stderr. CLI: search --sort <order>.
Filters (filter[<attribute>][<value>]). The facet filters of the register’s
website search, which /sucheJson accepts as filter[<attribute>][<value>]=true
and echoes back in searchParameters.facets. Examples: revolvingdoordata=true
(an entry records a recent public office for its lobbyist, a legal representative,
an entrusted person or a contractor — far more entries than carry the
recentGovernmentFunctionPresent flag, which covers only the lobbyist),
revolvingdoorpersontypes, revolvingdoorareas, activelobbyist,
fieldsofinterest (FOI_ENERGY, sub-fields as FOI_WORK|FOI_WORK_POLICY),
activity, legalform, donationsreceived (DONATIONS_RECEIVED,
DONATIONS_NOT_RECEIVED, DONATIONS_INFORMATION_MISSING_FISCAL_YEAR — not true),
ftepresent (true = an FTE figure was declared, including the entries that declared
0 FTE; not “has staff”). Values of one attribute are alternatives, different
attributes must all match. The API ignores an unknown attribute (and would return
everything) and matches nothing for an unknown value, so the CLI and the library accept
only the known attributes and value codes (--allow-unknown-filters, or
allowUnknownFilters in the library, opts out). Both parts are trimmed, the attribute
is compared case-insensitively (sent in lower case), the value is matched
case-insensitively and sent in the register’s spelling, and a sub-field code as the
entries carry it (FOI_EU_LAWS) is sent with its parent (FOI_EUROPEAN_UNION|FOI_EU_LAWS):
the register matches a sub-field only in that form, and the parent can’t be read off
the code. CLI: search/count --filter <attribute=value> (repeatable); library:
SearchParams.filters, SEARCH_FILTER_ATTRIBUTES, SEARCH_FILTER_VALUES.
page / pageSize. A 1-based page number and a page size (both integers
= 1;
pageneedspageSize). A live probe (2026-06) showed/sucheJsonignores them: it always returns the fullresultsarray regardless. So they are not sent; the client (SearchParams, and through it the CLI’s--page/--page-size) downloads the whole set and slicesresultsclient-side; the reportedresultCountis always the true total. Because every run fetches the set again and the relevance order (RELEVANCE_DESC) differs between identical requests, pages from separate runs are only consistent under a date sort such asREGISTRATION_DESC. CLI:search --page <n> --page-size <n>.
Search response
SearchResult (the envelope). The typed top-level shape returned by
/sucheJson: resultCount plus the results array, with optional metadata
fields ($schema, source, sourceUrl, sourceDate, jsonDocumentationUrl,
searchUrl, searchParameters).
resultCount. The total number of register entries matching the query — the
true total, independent of how many entries are actually returned or sliced.
This is the single number reported by the count command.
results. The array of matching register entries (each a RegisterEntry).
Duplicate versions. The API can return more than one version of the same register
entry: on 2026-09-26 R000534 came back twice (registerEntryDetails.registerEntryId
84196, valid from 2026-08-20, and 85248, valid from 2026-09-10), and resultCount
counted both. The CLI passes the data through unchanged; to count or rank entries,
keep one per registerNumber (the newest registerEntryDetails.validFromDate), e.g.
jq 'group_by(.registerNumber) | map(max_by(.registerEntryDetails.validFromDate))'.
RegisterEntry. One register entry — a registered interest representative.
Typed as a raw JsonObject (a faithful, untyped JSON document) because entries
are large and schema-versioned; the client does not guess their internal shape.
$schema. A URL naming the JSON Schema that each results entry conforms to
(the register’s published, versioned document schema).
source / sourceUrl / sourceDate. Provenance metadata for the data set:
its name, a canonical URL, and the date it was produced.
searchUrl. The human-facing search-page URL that corresponds to the same
query, suitable for opening in a browser.
searchParameters. The parameters the server interpreted for this search,
echoed back as a JSON object: queryString, sortOrder, facets (the filters it
applied, as {attribute, value}) and numberRanges.
jsonDocumentationUrl. A URL to the documentation of the JSON response
format.
CLI commands
search [query]. Run a search and print the full SearchResult envelope.
--results-only prints just the results array; --compact prints single-line
JSON. Supports --page, --page-size, --sort and --filter (see above).
count [query]. Print only the match count: { query, resultCount } (with
filters listed when --filter was given). A thin wrapper over search that reads
back resultCount; the API has no count-only mode, so it downloads every matching
record, just like search. Takes the optional query, --filter and
the global options.
Log record. Every diagnostic line the CLI writes to stderr: a timestamp, a level
(ERROR, WARN, INFO) and a topic lobbyregister.<area>, as text (log4j style) or with
--log-format jsonl as one JSON object per line. The areas: cli (usage errors,
commander’s messages, unexpected errors), api (the API’s answers and the notes on them:
an error status, a malformed answer — bad JSON, the wrong shape or content type —, a filter
the reply did not echo, the ignored --sort, relevance-order paging), http (the
connection, the cleartext warning, and one WARN per retry before it waits) and output (a failed write to stdout). A record is
always one line; control characters in it are escaped.
Exit codes
Exit codes. The CLI maps outcomes to process exit codes: 0 success;
2 usage / argument-validation errors (unknown/missing command, unknown option,
invalid option value, or no command given); 4 on 404 from the API; 1 for
any other error (network, parse, or other non-404 HTTP status). A 400 exits 1
and prints the API’s error detail; only when the API sends no detail does the CLI add
a hint to check --sort. --help / --version return 0.
Library & internals. Terms for the TypeScript client and its internals —
LobbyregisterClient, the request engine, transport, retry/backoff, error types, query builder, redirect behaviour — now live in DEVELOPING.md.