Glossar
Ein Nachschlagewerk für die Fachbegriffe und projektspezifischen Begriffe, die in
dip-bundestag-cli verwendet werden. Die Fachsprache des DIP ist Deutsch; dieses
Glossar nennt neben dem deutschen Originalbegriff den in CLI und API verwendeten
englischen Begriff (sofern es einen gibt).
Übersetzungstabelle. Die CLI behält die deutschen Ressourcennamen bei (es sind die Pfade der API selbst); ihre englische Bedeutung steht hier:
Deutsch Englisch Vorgang procedure / legislative process Vorgangsposition procedure step / position within a procedure Drucksache printed paper Plenarprotokoll plenary protocol (minutes) Aktivität activity Person person (member / actor) Wahlperiode electoral term / legislative period Bundestag the federal parliament Bundesrat the federal council (states’ chamber)
DIP
DIP – Dokumentations- und Informationssystem für Parlamentsmaterialien.
Der Katalog des Bundestages mit Daten zu parlamentarischen Abläufen: wer was
eingebracht hat, die zugehörigen Dokumente, die Plenardebatten und die handelnden
Personen. Im Browser unter dip.bundestag.de; die
maschinenlesbare API, die dieses Tool kapselt, liegt unter
search.dip.bundestag.de/api/v1.
Bundestag. Das deutsche Bundesparlament (die gewählte Kammer). Der Bundesrat ist die Kammer, in der die sechzehn Länder vertreten sind. Das DIP enthält Materialien beider Organe.
API-Schlüssel. Das DIP verlangt einen API-Schlüssel, der als HTTP-Header
Authorization: ApiKey <key> gesendet wird. Der Schlüssel ist nicht mitgeliefert –
geben Sie ihn über --api-key oder die Umgebungsvariable DIP_API_KEY an; andernfalls
entfällt der Header und die API antwortet mit 401. Flag, Variable und Bibliothek
(apiKey) kürzen den Schlüssel gleich (normaliseApiKey) und lehnen einen ab, den ein
HTTP-Header nicht tragen kann (Exit 2, DipValidationError). Der Bundestag veröffentlicht einen
öffentlichen Schlüssel auf seiner
Hilfeseite zur DIP-API (dort 2026 als
gültig bis Ende Mai 2027 angegeben); einen persönlichen Schlüssel erhalten Sie auf
Anfrage bei parlamentsdokumentation@bundestag.de. Der CLI-Befehl obtain-key liest
den Schlüssel dieser Seite aus dem JSON-Dokument, das der Content-Dienst des DIP
dahinter ausliefert, weicht notfalls auf das bundesAPI-README aus und prüft den
Schlüssel vor der Ausgabe gegen die Live-API – er schlägt also fehl, statt einen von
der API abgelehnten Schlüssel auszugeben.
Ressourcen (Endpoints)
Jede Ressource steht unter /api/v1/<resource> mit einem Listen-Endpoint
(/<resource>) und einem Einzel-Endpoint (/<resource>/<id>) bereit. Die CLI bildet
das als <resource> list und <resource> get <id> ab.
Vorgang. Ein Gesetzgebungs- oder parlamentarischer Prozess – z. B. ein
Gesetzentwurf, ein Antrag oder eine Anfrage –, der von der Einbringung bis zum
Abschluss verfolgt wird. Die zentrale Einheit, die Dokumente, Aktivitäten und Personen
miteinander verbindet. CLI: vorgang. Client: client.vorgaenge.
Vorgangsposition. Ein einzelner Schritt innerhalb eines Vorgangs – ein Ereignis
in seinem Verlauf (z. B. eine erste Lesung, eine Ausschussüberweisung, eine
Abstimmung). Ein Vorgang hat viele Vorgangspositionen. CLI: vorgangsposition.
Client: client.vorgangspositionen.
Drucksache. Ein förmliches parlamentarisches Dokument – Gesetzentwürfe, Anträge,
Berichte, Antworten auf Anfragen usw. –, identifiziert durch eine Drucksachennummer
innerhalb einer Wahlperiode. CLI: drucksache. Client: client.drucksachen.
Drucksache-Text. Dieselben Drucksachen, jedoch mit dem extrahierten Volltext
des Dokuments in der Antwort (ein eigener, umfangreicherer Endpoint).
CLI: drucksache-text. Client: client.drucksacheText.
Plenarprotokoll. Das stenografische Protokoll einer Plenarsitzung des Bundestages
oder des Bundesrates. CLI: plenarprotokoll. Client: client.plenarprotokolle.
Plenarprotokoll-Text. Die Plenarprotokolle mit dem extrahierten Volltext des
Protokolls. CLI: plenarprotokoll-text. Client: client.plenarprotokollText.
Aktivität. Eine erfasste Handlung einer Person innerhalb eines Vorgangs – z. B.
eine Rede, eine Frage, eine Unterschrift unter einem Antrag. Verknüpft eine Person mit
einem Vorgang. CLI: aktivitaet. Client: client.aktivitaeten.
Person. Eine in den Materialien vorkommende Person – typischerweise ein:e
Abgeordnete:r, aber auch andere Akteure. CLI: person. Client: client.personen.
Kennungen, Filter & Paginierung
id. Jedes Ressourcendokument hat eine numerische id, die der get-Endpoint
(drucksache get 123456) und der Filter f.id verwenden. Das CLI-Flag --id ist eine
Kurzform für f.id und kann mehrfach angegeben werden (eine ganze Zahl, siehe unten). Die
ID für get wird zuerst getrimmt, eine mitkopierte "282486 " findet also das Dokument.
Eine leere ID, . oder ..
wird vor jeder Anfrage abgelehnt (CLI Exit 2, Bibliothek DipValidationError, dieselbe
Meldung): get("") oder get(".") würde sonst den Sammel-Endpoint abfragen und die
Liste liefern, get("..") die API-Wurzel.
f.*-Filter. DIP-Filter sind Query-Parameter mit dem Präfix f., z. B. f.titel
(Titel), f.id, f.wahlperiode, f.datum.start / f.datum.end (Datumsbereich),
f.vorgangstyp, f.dokumentart, f.aktualisiert.start (Zeitraum der letzten
Aktualisierung). Jeder Listen-Endpoint hat seine eigene Menge (LIST_FILTERS, aus der
OpenAPI-Beschreibung des DIP): f.vorgang gibt es nur bei vorgangsposition, f.person
nur bei person und aktivitaet. Das DIP ignoriert einen unbekannten Filter und
liefert die ganze ungefilterte Liste, daher lehnen list() der Bibliothek und die CLI
einen Schlüssel ab, der nicht zur Menge der Ressource gehört (die CLI mit Exit 2);
list(params, { allowUnknownFilters: true }) sendet ihn trotzdem, für einen später vom
DIP ergänzten Filter. Die übrigen reicht sie über --filter key=value
(mehrfach angebbar) unverändert weiter; nur das erste = trennt Schlüssel und Wert, ein Wert darf also
selbst = enthalten. Wird derselbe Schlüssel wiederholt, werden wiederholte
Query-Schlüssel gesendet (?f.id=1&f.id=2), die das DIP als ODER-Menge behandelt.
Ein leerer Filterwert, eine leere --id oder ein leerer --cursor wird ebenfalls
abgelehnt (Exit 2), und list() der Bibliothek lehnt einen leeren Parameternamen oder
-wert, ein leeres Array und ein leeres Array-Element vor jeder Anfrage mit
DipValidationError ab: Das DIP behandelt einen leeren Parameter als keinen Filter.
Die ganzzahligen Filter (INTEGER_FILTERS: f.id, f.wahlperiode, f.vorgang, f.drucksache, f.plenarprotokoll, f.aktivitaet, f.person_id, f.vorgangsposition_id und f.vorgangstyp_notation, in der
OpenAPI-Beschreibung des DIP alle ganzzahlig) nehmen eine nicht negative ganze Zahl – auf
der Kommandozeile nur Ziffern (auch --id), in der Bibliothek eine Ziffernfolge oder eine
Zahl; alles andere lehnt die CLI mit Exit 2 und list() mit DipValidationError ab
(integerFilterProblem), denn das DIP beantwortet f.wahlperiode=abc mit einem
irreführenden 400 … Invalid cursor.
cursor. Die Listen-Endpoints des DIP sind cursorbasiert paginiert. Eine
Listenantwort enthält einen cursor; geben Sie ihn über --cursor (CLI) oder
{ cursor } (Bibliothek) zurück, um die nächste Seite abzurufen. Der Cursor ist
opak – behandeln Sie ihn als Token, nicht als Zahl. Ändert sich der zurückgegebene
Cursor nicht mehr, ist das Ende erreicht. Senden Sie mit jedem Cursor dieselben Filter
erneut: Das DIP bindet einen Cursor nicht an die Abfrage, aus der er stammt, daher
blättert ein Cursor ohne die Filter durch die ganze ungefilterte Liste. Deshalb wird ein
Cursor ohne jeden Filter abgelehnt: --cursor ohne --filter oder --id ist in der CLI
ein Bedienfehler (Exit-Code 2), und list() der Bibliothek wirft DipValidationError
(cursorWithoutFiltersProblem), außer { allowUnfilteredCursor: true } wird übergeben,
um die ungefilterte Liste absichtlich zu durchblättern.
numFound. Die Gesamtzahl der Dokumente, die zu einer Listenabfrage passen (über
alle Seiten hinweg); sie steht in der Listenhülle neben den documents der aktuellen
Seite.
documents. Das Array der Ressourcendokumente auf der aktuellen Seite einer
Listenantwort. Jedes wird als unverändertes rohes JsonObject bereitgestellt (die
Nutzdaten je Ressource sind umfangreich und ressourcenspezifisch und werden daher
nicht auf typisierte Felder eingeschränkt).
Wahlperiode. Die nummerierte Legislaturperiode des Bundestages (z. B. die
- Wahlperiode). Die meisten Ressourcen haben ein Feld
wahlperiodeund lassen sich mitf.wahlperiodefiltern; Dokumentnummern gelten jeweils innerhalb einer Wahlperiode.
Vorgangstyp. Die Einordnung eines Vorgangs (z. B. Gesetzgebung, Antrag,
Kleine Anfrage). Filterbar über f.vorgangstyp.
Dokumentart. Ob ein Dokument eine Drucksache oder ein Plenarprotokoll ist.
Filterbar über f.dokumentart bei vorgang, vorgangsposition und aktivitaet. Die
Art einer Drucksache (Antrag, Gesetzentwurf, Antwort, …) steht in drucksachetyp und
ist über f.drucksachetyp filterbar.
Datum. Das Datum, auf das ein Dokument bzw. eine Aktivität datiert ist. Die
Filterung nach Datumsbereich nutzt f.datum.start und f.datum.end (ISO
YYYY-MM-DD). Der Query-Builder serialisiert Date-Werte zu vollständigen
ISO-8601-Zeitpunkten in UTC (2024-01-01T00:00:00.000Z), die das DIP für
f.aktualisiert.* akzeptiert, für f.datum.* aber nicht (HTTP 400 Invalid date).
In der Bibliothek wird f.datum.* daher als Zeichenkette "YYYY-MM-DD" übergeben: Ein
Date ist ein Zeitpunkt, und eine lokale Mitternacht wie new Date(2024, 0, 1) in Berlin
ist 2023-12-31T23:00:00.000Z, also der Vortag.
Zuordnung. Manche Ressourcen lassen sich nach Kammer bzw. Zuordnung filtern
(f.zuordnung), um Materialien des Bundestages (BT) von denen des Bundesrates
(BR) zu unterscheiden.
API-Verhalten & Fehler
Basis-URL. Standardmäßig https://search.dip.bundestag.de; überschreibbar mit
--base-url (CLI) oder baseUrl (Bibliothek). Alle Ressourcenpfade liegen unter
/api/v1, das der Client selbst anhängt: Die Basis-URL ist der Host (plus ein etwaiges
Pfadpräfix eines Spiegels) ohne diesen Teil. CLI und Bibliothek (validateBaseUrl)
lehnen vor jeder Anfrage mit derselben Begründung eine URL ab, die sich nicht parsen
lässt, nicht http:/https: ist, auf /api/v1 endet, Leerraum am Rand oder im
Inneren enthält, eine Query bzw. ein Fragment hat oder im Benutzernamen oder Passwort ein
% enthält, das keine gültige Escape-Sequenz einleitet (ein wörtliches % wird %25
geschrieben) (Bibliothek: DipValidationError,
nicht DipNetworkError). Zugangsdaten darin
(user:password@) werden gesendet, in allem, was die CLI ausgibt, und in den Fehlern der
Bibliothek aber zu ***@ geschwärzt.
Rate-Limiting. Das DIP begrenzt die Anfragerate; bei Überschreitung antwortet die
API mit 429. Der Client wiederholt 429 und 503 sowie eine mitten in der
Anfrage abgebrochene Verbindung automatisch
(--max-retries, 0–10, Standard 2) mit linearem Backoff, oder wartet das Retry-After
der Antwort ab, wenn es länger ist (nie kürzer, sodass Retry-After: 0 keine Salve
auslöst). Ein Retry-After über 30 s wird nicht wiederholt, und die Fehlermeldung
nennt die verlangte Wartezeit. Jede Wiederholung ist ein Log-Eintrag WARN von dip.http
(HTTP 503 from host: retry 1 of 3 in 2 s); die Bibliothek bietet sie als onRetry an. Die
Bibliothek hat dieselbe Grenze (MAX_RETRIES, maxRetries) und lehnt einen Wert
außerhalb mit DipValidationError ab, ebenso ein negatives oder gebrochenes Timeout oder
Größenlimit.
Entfernen von Zugangsdaten bei Weiterleitungen. Der API-Schlüssel (sowie
X-API-Key / Cookie und ein user:password@ der Basis-URL) geht nur an den Origin
der Basis-URL. Eine Weiterleitung auf einen anderen Origin — anderer Host, Port oder
anderes Schema, auch http→https — lässt ihn weg, sodass er nie an einen anderen Host als
den angesteuerten gelangt. Weiterleitungen innerhalb desselben Origins behalten ihn,
auch mit absolutem Location. Ein 401 nach einer solchen Weiterleitung sagt nichts über
den Schlüssel, und die Fehlermeldung sagt das („use an https base URL“ bei http→https).
Fehlertypen. errors.ts: DipApiError (Nicht-2xx-Antwort,
enthält status/detail/url/method/body sowie isRetryable für 429/503),
DipNetworkError (Transportfehler/Timeout, nie eine ungültige Basis-URL), DipParseError (ungültiges JSON, oder ein 2xx-Body, der keine DIP-Liste und kein DIP-Dokument ist: null, [], ein Fehlerobjekt),
DipUsageError (ein Bedienfehler, keine Anfrage gesendet) und dessen Unterklasse
DipValidationError (die Bibliothek hat eine Eingabe vor jeder Anfrage abgelehnt:
Invalid <name>: <reason>), alle abgeleitet von DipError. Exit-Codes: 0 bei Erfolg, 2 bei Bedienfehlern, 4 bei 404, 1 bei
jedem anderen Laufzeitfehler (auch bei 401, wenn der Schlüssel fehlt oder abgelaufen
ist).
Log-Eintrag (log record). Jede Diagnosezeile, die die CLI nach stderr schreibt: ein
Zeitstempel, eine Stufe (ERROR, WARN, INFO) und ein Thema dip.<Bereich>, als Text
(im Stil von log4j) oder mit --log-format jsonl als ein JSON-Objekt pro Zeile. Die
Bereiche: cli (Bedienfehler, Meldungen von commander, unerwartete Fehler), api (die
Antworten der API: ein Fehlerstatus und eine fehlerhafte Antwort — ungültiges JSON, die
falsche Form, ein leerer Body), http (die Verbindung, die Klartext-Warnung und je Wiederholung eine WARN-Zeile vor dem Warten), config,
obtain-key und output (die -o-Datei, Schreibfehler auf stdout). Ein Eintrag ist
immer eine Zeile; Steuerzeichen darin werden maskiert.
Bibliothek & Interna. Begriffe zum TypeScript-Client und seinen Interna –
DipClient, Ressourcengruppen, die Request-Engine, Transport, Retry/Backoff, Fehlertypen, Query-Builder – stehen jetzt in DEVELOPING.md.