Zum Hauptinhalt springen

Grundlagen

Überblick

Diese Seite beschreibt die Eigenschaften, die für alle Kulturpool-APIs gelten: Basis-URL, Authentifizierung, Datenformate, HTTP-Statuscodes, Fehlerbehandlung und Caching.

Architektur​

Die Kulturpool API ist eine REST-API, die als Proxy zwischen Client-Anwendungen und den internen Diensten des Kulturpools fungiert:

EndpunktBackendBeschreibung
/v2/searchTypesenseVolltext- und Facettensuche über alle Sammlungen
/v2/search/federatedTypesenseAlle drei Sammlungen in einer Anfrage
/v2/similarTypesenseÄhnliche Objekte, inhaltlich oder visuell
/v2/similar/imageTypesense + CLIPÄhnliche Objekte zu einem hochgeladenen Bild — oder zu dessen Vektor, dann ohne CLIP
/v2/objectTypesenseEinzelne Kulturgüter als JSON-LD/EDM
/institutionsDirectus CMSTeilnehmende Institutionen
/contentDirectus CMSRedaktionelle Inhalte
/assetsDirectus CMSBilder und Medien mit Transformation
/oaiOAI-PMH-ServerMetadata Harvesting (über Reverse Proxy)

Der Proxy ergänzt dabei Authentifizierung gegenüber den Backends, Caching und Normalisierung der Antworten.

Endpunkte ohne Versionspräfix sind nicht versioniert und ändern sich nicht mit den Sammlungen — sie sprechen mit dem CMS, nicht mit dem Suchindex. Ihre Antworten tragen entsprechend keinen X-Kulturpool-API-Version- und keinen Deprecation-Header.

Basis-URL​

https://api.kulturpool.at

Daneben existiert eine Staging-Umgebung unter https://staging-api.kulturpool.at. Diese dient ausschließlich Testzwecken, kann jederzeit zurückgesetzt werden und sollte nicht produktiv verwendet werden.

Authentifizierung​

Die API ist öffentlich zugänglich und erfordert keine Authentifizierung. Es müssen keine API-Schlüssel, Tokens oder Header gesetzt werden.

Der für die Suche notwendige Typesense-Schlüssel wird serverseitig vom Proxy ergänzt.

CORS​

Alle Endpunkte senden Access-Control-Allow-Origin: *. Die APIs können damit direkt aus dem Browser heraus aufgerufen werden, ohne eigenen Proxy.

Datenformat​

Alle Antworten erfolgen im JSON-Format mit UTF-8-Kodierung — mit Ausnahme von /assets (Binärdaten bzw. Redirect) und /oai (XML).

Das konkrete Schema unterscheidet sich je nach Endpunkt:

EndpunktAntwortstruktur
/v2/search, /v2/similarTypesense-Antwort mit found, hits, facet_counts, … — /v2/similar/image zusätzlich vector
/v2/search/federated{ "results": [...] } — ein Ergebnis je Sammlung
/v2/object{ "metadata": {...} }
/institutions, /content{ "data": [...] } bzw. { "data": {...} }
/content (Index){ "data": [...] } — ohne Inhaltsblöcke, siehe Inhalte API
/assetsHTTP 302 Redirect auf das transformierte Bild
/oaiOAI-PMH XML

HTTP-Statuscodes​

CodeBedeutung
200 OKErfolgreiche Anfrage
302 FoundWeiterleitung (nur bei /assets)
400 Bad RequestDie Suchmaschine hat die Anfrage abgelehnt — die Meldung nennt den Grund
404 Not FoundRessource nicht gefunden
413 Payload Too LargeDie hochgeladene Datei ist zu groß
415 Unsupported Media TypeDateityp wird nicht unterstützt
422 Unprocessable EntityFehlende oder ungültige Parameter
429 Too Many RequestsAnfragegrenze erreicht — siehe Retry-After
500 Internal Server ErrorServerfehler
502 Bad GatewayEin Upstream-Dienst ist nicht erreichbar
503 Service UnavailableDer Dienst ist ausgelastet — siehe Retry-After

Fehlerbehandlung​

Fehler werden als JSON-Objekt mit einer detail-Eigenschaft zurückgegeben:

{
"detail": "Error fetching data from upstream API"
}

Bei Validierungsfehlern (422) liefert FastAPI eine strukturierte Beschreibung der betroffenen Felder:

{
"detail": [
{
"type": "missing",
"loc": ["query", "q"],
"msg": "Field required"
}
]
}

Caching​

Die API cached Antworten serverseitig in Redis. Die Gültigkeitsdauer unterscheidet sich je Endpunkt:

EndpunktServer-Cache
/v2/object3 Stunden
/institutions3 Stunden
/content3 Stunden
/v2/search, /v2/similarkein Proxy-Cache — Typesense cached intern (siehe Parameter use_cache)
/assetskein Proxy-Cache — Caching erfolgt im CMS und im Browser

Für die Suche lässt sich der Typesense-interne Cache pro Anfrage mit use_cache=false umgehen. Das ist insbesondere in Kombination mit sort_by=_rand() nötig, um bei jedem Aufruf eine neue Reihenfolge zu erhalten.

Anfragegrenzen​

Ein einziger Endpunkt ist begrenzt: POST /v2/similar/image, mit 10 Anfragen pro Minute je Client-Adresse (kurzfristig bis zu 4 am Stück). Er ist der einzige, der nennenswert Rechenzeit kostet — das Bild wird durch ein neuronales Netz geschickt. Alle anderen Endpunkte reichen eine Anfrage lediglich weiter und sind nicht begrenzt — auch die Wiederholung einer Bildsuche per GET /v2/similar/image?vector=…, die nichts mehr rechnet.

Die Grenze füllt sich fortlaufend wieder auf, nicht in festen Zeitfenstern — ein kurzer Schwung ist also erlaubt, ein Dauerfeuer nicht.

Über der Grenze antwortet die API mit 429 und einem Retry-After-Header, der die Wartezeit in Sekunden nennt. Eine abgelehnte Anfrage verbraucht kein Kontingent — ein Wiederholungsversuch schiebt den nächsten Erfolg nicht weiter hinaus.

Sind gerade zu viele Bildeinbettungen gleichzeitig unterwegs, antwortet die API mit 503 und Retry-After, statt die Anfrage unbegrenzt warten zu lassen.

Für größere Datenmengen nutzen Sie bitte die Datensets zum Herunterladen oder OAI-PMH statt paginierter Suchanfragen.

Health Check​

Der Status der API lässt sich jederzeit abfragen:

curl "https://api.kulturpool.at/health"
{
"status": "healthy",
"image_search": true
}

image_search sagt, ob /v2/similar/image auf diesem Server einsatzbereit ist.

Ältere Endpunkte​

Vor /v2 gab es /search und /object ohne Versionspräfix. Sie liefern dieselben Daten, antworten aber in der alten Feldstruktur und sind veraltet.

Abschaltung am 1. April 2027

/search und /object antworten bis einschließlich 31.03.2027 unverändert und werden am 1. April 2027 abgeschaltet. Jede Antwort trägt das Datum im Sunset-Header mit:

Deprecation: true
Sunset: Thu, 01 Apr 2027 00:00:00 GMT
Link: <https://api.kulturpool.at/reference/grundlagen/#legacy>; rel="deprecation"

Der Umstieg ist in aller Regel klein — /v2 voranstellen und diese Punkte prüfen:

altneu
doc.title[0]doc.title (ein String, kein Array)
doc.kp_iddoc.uuid
sort_by=titleSort:ascsort_by=titleKey:asc
doc.edmRights, edmRightsName, edmType als Einzelwertjeweils eine Liste
doc.edmRightsReusePolicy als Einzelwerteine Liste — für ein Abzeichen die freieste Regelung: OPEN vor RESTRICTED vor CLOSED
facet_by=publisher / contributor / issuedentfällt — publisher und contributor bleiben durchsuchbar, für Datierungen dateMin/dateMax
filter_by=edmRights:=…edmRightsName oder edmRightsReusePolicy
filter_by=dcRights:=…entfällt — dcRights wird weiter mitgeliefert
doc.fullViewMetadata nachladen/v2/object?id={uuid}, oder gleich include_fields=sourceRecord

Neue Integrationen sollten direkt auf /v2 aufsetzen.

Interaktive Referenz​

Eine automatisch aus dem Code generierte, interaktive Referenz aller Endpunkte und Parameter steht bereit unter: