Dieses Dokument gibt es nur auf Englisch.

Usage

ddb — a CLI for the Deutsche Digitale Bibliothek (DDB) v2 API. This is the use-case-driven cookbook; for the option reference see the README, and for domain terms the Glossary.

ddb [global options] <command> [command options]

The v2 read routes are public — no API key. Just run the commands.

Global options

Option Description
--base-url <url> API base URL (default …/2; only http:/https: accepted)
--timeout <ms> per-request timeout in ms (0 = no timeout)
--user-agent <ua> User-Agent header value
--max-retries <n> retries for transient 429/503 responses (0..10)
--max-response-bytes <n> cap the response body size in bytes (0 = unlimited; default 100 MiB)
--compact print JSON on a single line (for piping to jq)
-o, --output <file> write output to a file instead of stdout (refuses to overwrite an existing file unless --force)
--force overwrite the --output file if it already exists
-V, --version / -h, --help version / help

search — find objects

ddb search <query> [options]

v2 search is a Solr passthrough: the query and --filter use Solr syntax, and the response is native Solr JSON. Some starting points:

ddb search Goethe                         # simple keyword
ddb search "Weimarer Republik"            # phrase (quote it in your shell)
ddb search 'Goethe AND Faust'             # boolean operators
ddb search '*:*'                          # match everything (browse mode)
ddb search 'title:Faust'                  # field-scoped query
Option Description
--rows <n> number of documents (Solr rows, default 10)
--offset <n> offset of the first document (Solr start, paging)
--sort <spec> Solr sort, e.g. "score desc" or "id asc"
--fields <list> fields to return (Solr fl), e.g. id,label,type
--filter <fq> Solr filter query (repeatable), e.g. type_fct:mediatype_002
--facet <field> return counts for this facet field (repeatable)
--facet-limit <n> cap the number of values per facet
--collection <name> Solr collection (default search)
--handler <name> Solr request handler (default select)

The result shape is native Solr:

{
  "responseHeader": { "status": 0, "params": { "q": "Goethe", "rows": "10" } },
  "response": {
    "numFound": 99866,
    "start": 0,
    "docs": [ { "id": "…", "label": "…", "type": ["mediatype_002"] } ]
  },
  "facet_counts": { "facet_fields": { "type_fct": ["mediatype_003", 50024] } }
}

Filtering with facets

--filter <fq> narrows the result set with a Solr filter query; --facet <field> asks Solr to return value counts for a facet (to build the next filter):

# Images (a media-type code) from Berlin
ddb search '*:*' --filter type_fct:mediatype_002 --filter 'place_fct:"Berlin"'

# Two places at once (OR inside one filter query)
ddb search Bauhaus --filter 'place_fct:("Berlin" OR "Dessau")'

# Ask for the object-type distribution of a query, top 5 values
ddb search Goethe --rows 0 --facet objecttype_fct --facet-limit 5 \
  | jq '.facet_counts.facet_fields.objecttype_fct'

Facet counts arrive as a flat array [value, count, value, count, …], which can include values with count 0. To turn one into {value, count} objects and drop the zeros:

ddb search Bauhaus --rows 0 --facet place_fct --facet-limit 10 \
  | jq '.facet_counts.facet_fields.place_fct
        | [range(0; length; 2) as $i | {value: .[$i], count: .[$i+1]}]
        | map(select(.count > 0))'

Paging

# First page (1–10) then the next page (11–20)
ddb search Goethe --rows 10
ddb search Goethe --rows 10 --offset 10

When more documents match than were returned, ddb prints a note like Note: 99866 documents match; 10 shown. to stderr — page with --offset or narrow with --filter. Read response.numFound for the true total. A --rows 0 facet query gets no note.

item — object detail

ddb item <id> [--part <component>] [--lang <code>]

<id> is the exact 32-character id from a search result’s id. --part selects which component to fetch — most are JSON, a few are XML / a plain file and print raw (so > file.xml and piping keep them intact):

--part Returns Format
view (default) the data set a DDB frontend object page is built on JSON
aip the full Archive Information Package JSON
edm the Europeana Data Model record RDF/XML
binaries related binary files (thumbnails, media) and their URLs JSON
children child items (accepts --rows/--offset) JSON
parents the chain up the hierarchy: the object itself first, the institution last JSON
source the ingest source metadata JSON
source-description a description of the source record JSON
source-record the raw provider record (METS/MODS, LIDO, MARCXML) XML
iiif the IIIF Presentation manifest (only where present → else 404) JSON
citation a newspaper-issue citation file (only where applicable) BIB file

--lang <code> sets the preferred label language for view/aip/edm/binaries/source/source-description. An object without a record in that language answers 404 (exit 4); --lang en did so for every object tried on 2026-09-15, so retry without --lang before treating the id as wrong.

ID=$(ddb search Goethe --fields id | jq -r '.response.docs[0].id')
ddb item "$ID"
ddb item "$ID" --part edm -o object.edm.xml     # RDF/XML → file
ddb item "$ID" --part binaries | jq '.'
ddb item "$ID" --part children --rows 20         # first 20 children

version — connectivity check

ddb version        # e.g. 7.5

Useful to confirm the API is reachable and the CLI is wired up.

Scripting recipes

# Object ids + labels of the current page
ddb search Goethe | jq -r '.response.docs[] | "\(.id)\t\(.label)"'

# Total number of matches
ddb search Goethe | jq '.response.numFound'

# Top 10 providers for a query (flat facet array)
ddb search Goethe --rows 0 --facet provider_fct --facet-limit 10 \
  | jq '.facet_counts.facet_fields.provider_fct'

# Save a full result page to disk
ddb --output goethe.json search Goethe --rows 100

Exit codes

Code Meaning
0 success (help/version included); an empty result also exits 0
1 API/logical error, or a catch-all (includes an unexpected 403)
2 usage error (bad flags, unknown command, wrong-length item id, bad --base-url)
4 HTTP 404 (not found)
6 network / transport failure (DNS, connection, timeout, response size-cap)

Notes

Quelle auf GitHub ansehen →