Grundlagen
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:
| Endpunkt | Backend | Beschreibung |
|---|---|---|
/v2/search | Typesense | Volltext- und Facettensuche über alle Sammlungen |
/v2/search/federated | Typesense | Alle drei Sammlungen in einer Anfrage |
/v2/similar | Typesense | Ähnliche Objekte, inhaltlich oder visuell |
/v2/similar/image | Typesense + CLIP | Ähnliche Objekte zu einem hochgeladenen Bild — oder zu dessen Vektor, dann ohne CLIP |
/v2/object | Typesense | Einzelne Kulturgüter als JSON-LD/EDM |
/institutions | Directus CMS | Teilnehmende Institutionen |
/content | Directus CMS | Redaktionelle Inhalte |
/assets | Directus CMS | Bilder und Medien mit Transformation |
/oai | OAI-PMH-Server | Metadata 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:
| Endpunkt | Antwortstruktur |
|---|---|
/v2/search, /v2/similar | Typesense-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 |
/assets | HTTP 302 Redirect auf das transformierte Bild |
/oai | OAI-PMH XML |
HTTP-Statuscodes
| Code | Bedeutung |
|---|---|
200 OK | Erfolgreiche Anfrage |
302 Found | Weiterleitung (nur bei /assets) |
400 Bad Request | Die Suchmaschine hat die Anfrage abgelehnt — die Meldung nennt den Grund |
404 Not Found | Ressource nicht gefunden |
413 Payload Too Large | Die hochgeladene Datei ist zu groß |
415 Unsupported Media Type | Dateityp wird nicht unterstützt |
422 Unprocessable Entity | Fehlende oder ungültige Parameter |
429 Too Many Requests | Anfragegrenze erreicht — siehe Retry-After |
500 Internal Server Error | Serverfehler |
502 Bad Gateway | Ein Upstream-Dienst ist nicht erreichbar |
503 Service Unavailable | Der 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:
| Endpunkt | Server-Cache |
|---|---|
/v2/object | 3 Stunden |
/institutions | 3 Stunden |
/content | 3 Stunden |
/v2/search, /v2/similar | kein Proxy-Cache — Typesense cached intern (siehe Parameter use_cache) |
/assets | kein 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.
/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:
| alt | neu |
|---|---|
doc.title[0] | doc.title (ein String, kein Array) |
doc.kp_id | doc.uuid |
sort_by=titleSort:asc | sort_by=titleKey:asc |
doc.edmRights, edmRightsName, edmType als Einzelwert | jeweils eine Liste |
doc.edmRightsReusePolicy als Einzelwert | eine Liste — für ein Abzeichen die freieste Regelung: OPEN vor RESTRICTED vor CLOSED |
facet_by=publisher / contributor / issued | entfä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:
- Swagger UI: https://api.kulturpool.at/docs
- ReDoc: https://api.kulturpool.at/redoc
- OpenAPI-Schema: https://api.kulturpool.at/openapi.json