Usage
Practical, use-case-driven examples for the dip CLI — a command-line client for
the Bundestag DIP API (search.dip.bundestag.de), covering Vorgänge,
Drucksachen, Plenarprotokolle, Aktivitäten and Personen of the German Bundestag
and Bundesrat. Every command prints JSON to stdout, so the examples below pipe
into jq where it helps.
Install
npm i -g @maschinenlesbar.org/dip-bundestag-cli
This installs the dip binary. Without a global install you can run the same
commands via node dist/src/cli/index.js … after npm run build.
Authentication
DIP requires an API key, sent as Authorization: ApiKey <key>. Supply it either
way:
# As an environment variable (recommended)
export DIP_API_KEY=your-personal-key
dip vorgang list
# Or per-invocation (note: a global option, so it goes BEFORE the command)
dip --api-key your-personal-key vorgang list
Precedence is --api-key > DIP_API_KEY > none. No key is bundled — when
neither is supplied the Authorization header is omitted and requests return
401. The Bundestag publishes a public key on its
DIP API help page (stated there in
2026 as valid until the end of May 2027); a personal key can be requested from
parlamentsdokumentation@bundestag.de.
Use cases
The examples assume DIP_API_KEY is exported. Filters are passed verbatim to DIP
via --filter <key=value> (repeatable); --id is shorthand for the repeatable
f.id filter.
Search Drucksachen by title
Find printed papers whose title matches a keyword.
dip drucksache list --filter f.titel=Klimaschutz
The response is a cursor-paginated envelope with numFound, documents and a
cursor. To list just the titles:
dip drucksache list --filter f.titel=Klimaschutz \
| jq -r '.documents[].titel'
Filter Drucksachen by Wahlperiode
Scope a search to a single electoral term (e.g. the 20th Wahlperiode).
dip drucksache list --filter f.titel=Bürgergeld --filter f.wahlperiode=20
Multiple --filter flags are combined into one query. Add --compact if you
want each result on a single line for easier downstream processing.
Browse Vorgänge by date range
Procedures dated within a given window, using DIP’s date-range filter keys.
dip vorgang list \
--filter f.datum.start=2024-01-01 \
--filter f.datum.end=2024-03-31
Dates are ISO YYYY-MM-DD. Count how many matched without scrolling the JSON:
dip vorgang list --filter f.datum.start=2024-01-01 --filter f.datum.end=2024-03-31 \
| jq '.numFound'
Filter Vorgänge by procedure type
Narrow procedures to a specific Vorgangstyp (e.g. a Gesetzgebung procedure).
dip vorgang list \
--filter f.vorgangstyp=Gesetzgebung \
--filter f.wahlperiode=20
Inspect a single Vorgang and its positions
Look up one procedure by id, then list the Vorgangspositionen attached to it.
# The procedure itself
dip vorgang get 282486
# Its positions (Vorgangspositionen) for the same procedure
dip vorgangsposition list --filter f.vorgang=282486 \
| jq -r '.documents[].vorgangsposition'
get <id> takes the id as a positional argument and returns the full document.
Pull a Drucksache with full text
Retrieve printed papers including their extracted body text, then read the text of the first hit.
dip drucksache-text list --filter f.titel=Haushaltsgesetz --filter f.wahlperiode=20 \
| jq -r '.documents[0].text'
Use drucksache for metadata only, drucksache-text when you need the document
body. The same <resource> / <resource>-text split applies to Plenarprotokolle.
Search Plenarprotokolle and grab a full transcript
Find plenary protocols, then fetch one complete transcript by id.
# List protocols for a term
dip plenarprotokoll list --filter f.wahlperiode=20 \
| jq -r '.documents[] | "\(.id)\t\(.dokumentnummer)\t\(.datum)"'
# Fetch the full text of one protocol
dip plenarprotokoll-text get 5678 | jq -r '.text' > protokoll.txt
Filter materials by chamber (Bundestag vs Bundesrat)
Restrict results to Bundestag (BT) or Bundesrat (BR) materials via the
Zuordnung filter.
dip drucksache list --filter f.wahlperiode=20 --filter f.zuordnung=BT
Look up a Person (member)
Find members by name, then fetch one full record by id.
# Search by surname
dip person list --filter f.person=Merkel \
| jq -r '.documents[] | "\(.id)\t\(.titel)"'
# Fetch one person record
dip person get 7240
Use the f.person filter for member names (f.titel is not a valid key for the
person endpoint and is silently ignored).
List recent Aktivitäten and save them to a file
Activities updated since a given date, written to disk instead of stdout.
dip --output aktivitaeten.json aktivitaet list \
--filter f.aktualisiert.start=2024-05-01T00:00:00 --filter f.wahlperiode=20
The f.aktualisiert.start / f.aktualisiert.end filters expect a full ISO
date-time (YYYY-MM-DDThh:mm:ss); a bare date is rejected with 400 Invalid
date-time. (The f.datum.start / f.datum.end filters used above accept a
plain YYYY-MM-DD date.)
-o, --output <file> is a global option (place it before the command). It is
also how you save binary downloads. It refuses to overwrite an existing file
(exits with an error) so a mistyped path cannot clobber your data; add --force
to overwrite deliberately.
Paginate through a large result set
List endpoints are cursor-paginated: pass the cursor from one page back via
--cursor to get the next.
# First page — capture the cursor
CURSOR=$(dip vorgang list --filter f.wahlperiode=20 | jq -r '.cursor')
# Next page
dip vorgang list --filter f.wahlperiode=20 --cursor "$CURSOR"
Fetch several documents by id at once
--id is repeatable and maps to DIP’s f.id OR-set, so one call can fetch
multiple records.
dip drucksache list --id 123456 --id 123457 --id 123458 \
| jq -r '.documents[] | "\(.id)\t\(.titel)"'
Global options
Global options go before the command (e.g. dip --api-key … vorgang list):
| Option | Description |
|---|---|
-V, --version |
Print the CLI version |
--base-url <url> |
API base URL (default https://search.dip.bundestag.de) |
--api-key <key> |
DIP API key (env DIP_API_KEY) |
--timeout <ms> |
Time limit per request in milliseconds, reading the whole response included (at most 2147483647) |
--user-agent <ua> |
User-Agent header value |
--max-retries <n> |
Retries for transient 429/503 responses |
--max-response-bytes <n> |
Cap response body size in bytes (0 = unlimited; default 100 MiB) |
--compact |
Print JSON on a single line instead of pretty-printed |
-o, --output <file> |
Write output to this file instead of stdout (refuses to overwrite an existing file) |
--force |
With -o, overwrite the output file if it already exists |
-h, --help |
Show help (also available per command, e.g. dip vorgang list --help) |
Commands: vorgang, vorgangsposition, drucksache, drucksache-text,
plenarprotokoll, plenarprotokoll-text, aktivitaet, person — each with
list [--cursor <c>] [--id <id> …] [--filter key=value …] and get <id>.