OParl-Aggregations-API¶
mandari stellt die gespiegelten Ratsinformationen aller angebundenen Kommunen als eigene, OParl-1.1-konforme Datenquelle bereit. Statt viele kommunale OParl-Endpunkte einzeln abzufragen, genügt ein einziger Endpunkt. Dazu kommen mandari-Anreicherungen wie Volltexte, Zusammenfassungen und stabile Datei-Adressen.
- Lesend, anonym, JSON: keine Authentifizierung nötig
- CORS offen:
Access-Control-Allow-Origin: * - Rate-Limit: 120 Anfragen pro Minute je IP-Adresse, darüber HTTP 429
- Spezifikation: oparl.org/spezifikation
Einstiegspunkt¶
Von dort hangelst du dich über die verlinkten Objekte durch alle Daten:
Endpunkte¶
| Endpunkt | Inhalt |
|---|---|
GET /oparl/v1/ | JSON-Übersicht über die API |
GET /oparl/v1/system | OParl-System-Objekt (Einstiegspunkt) |
GET /oparl/v1/bodies | Liste aller Kommunen (paginiert) |
GET /oparl/v1/body/<uuid> | Einzelne Kommune |
GET /oparl/v1/body/<uuid>/organizations | Gremien der Kommune (paginiert, filterbar) |
GET /oparl/v1/body/<uuid>/people | Personen der Kommune (paginiert, filterbar) |
GET /oparl/v1/body/<uuid>/meetings | Sitzungen der Kommune (paginiert, filterbar) |
GET /oparl/v1/body/<uuid>/papers | Vorlagen und Drucksachen der Kommune (paginiert, filterbar) |
GET /oparl/v1/body/<uuid>/locations | Orte der Kommune (Vendor-Erweiterung, paginiert) |
GET /oparl/v1/<typ>/<uuid> | Objekt-Endpunkte aller Typen |
Objekttypen für <typ>: body, organization, person, membership, meeting, agendaitem, paper, consultation, file, location, legislativeterm.
Einbettungen gemäß OParl 1.1: Body.legislativeTerm, Person.membership, Meeting.agendaItem, Meeting.location, Meeting.invitation und auxiliaryFile, Paper.consultation, Paper.mainFile und auxiliaryFile werden als vollständige Objekte eingebettet. Alle übrigen Referenzen sind URLs auf diese API.
Pagination¶
Listen liefern 100 Objekte pro Seite (?page=N), sortiert nach modified aufsteigend. Diese Sortierung ist stabil und damit ideal für inkrementelle Clients. Die Antwort folgt dem OParl-Listen-Envelope:
{
"data": ["..."],
"pagination": {
"totalElements": 150,
"elementsPerPage": 100,
"currentPage": 1,
"totalPages": 2
},
"links": {
"first": ".../meetings",
"self": ".../meetings",
"next": ".../meetings?page=2",
"last": ".../meetings?page=2"
}
}
Zusätzlich werden die Links als HTTP-Link-Header mit rel="first|prev|next|last" ausgeliefert.
Zeitfilter¶
Alle Listen unterstützen created_since, created_until, modified_since und modified_until. Die Filter sind inklusiv und kombinierbar.
# Alle Sitzungen, die seit dem 1. Juni 2026 (UTC) geändert wurden
curl "https://mandari.de/oparl/v1/body/<uuid>/meetings?modified_since=2026-06-01T00%3A00%3A00%2B00%3A00"
# Das Z-Suffix ist ebenfalls gültig
curl "https://mandari.de/oparl/v1/body/<uuid>/meetings?modified_since=2026-06-01T00:00:00Z"
Zeitstempel brauchen eine Zeitzone
Zeitstempel müssen eine explizite Zeitzone enthalten (+01:00, +00:00 oder Z). Zeitstempel ohne Zeitzone sind mehrdeutig und werden mit HTTP 400 und einer klaren Fehlermeldung abgelehnt. Das + in URLs als %2B kodieren.
Die Filter arbeiten auf denselben Werten, die als created und modified ausgeliefert werden: den OParl-Zeitstempeln der Quelle, ersatzweise dem Zeitpunkt der Spiegelung in mandari.
Gelöschte Objekte (Tombstones)¶
Objekte, die im Quellsystem gelöscht wurden, werden in mandari nicht physisch gelöscht, sondern markiert. Die API verhält sich dabei standardkonform:
-
Objekt-Endpunkte liefern gelöschte Objekte weiterhin mit HTTP 200 aus, als gekürztes Objekt mit ausschließlich den Pflichtfeldern:
{ "id": "https://mandari.de/oparl/v1/paper/<uuid>", "type": "https://schema.oparl.org/1.1/Paper", "created": "2024-01-01T00:00:00+00:00", "modified": "2026-07-01T12:00:00+00:00", "deleted": true }modifiedentspricht dem Löschzeitpunkt, alle weiteren Attribute entfallen. -
Listen ohne Filter (und mit reinen
created_*- odermodified_until-Filtern) enthalten gelöschte Objekte nicht. - Listen mit
modified_sinceenthalten die passenden gelöschten Objekte als Tombstones. Inkrementelle Clients bekommen Löschungen so zuverlässig mit, ohne Voll-Sync. - Eingebettete Referenzen wie
Meeting.agendaItemoderPaper.consultationlassen gelöschte Objekte aus. Tombstones erscheinen nur als Top-Level-Objekte.
Eine physische Löschung erfolgt ausschließlich auf ausdrückliche Aufforderung einer Kommune, siehe Crawler und Opt-out.
Dateien¶
accessUrl und downloadUrl zeigen auf den mandari-Dokumentproxy (/insight/dokumente/<uuid>/preview/ bzw. mit ?download=1). Das hat zwei Vorteile:
- stabil erreichbar, auch wenn der kommunale Quellserver gerade offline ist
- datenschutzfreundlich, weil sich der Client nicht mit dem Server der Kommune verbindet
Die Original-URL bleibt als mandari:originalAccessUrl erhalten. Der extrahierte Volltext (text) wird nur am Objekt-Endpunkt /oparl/v1/file/<uuid> ausgeliefert, nicht in eingebetteten Datei-Objekten.
Vendor-Attribute¶
Ergänzende Felder tragen das Präfix mandari: und können von Standard-Clients ignoriert werden.
| Attribut | Objekt | Inhalt |
|---|---|---|
mandari:originalId | alle | Original-URL des Objekts im kommunalen Quellsystem |
mandari:slug, mandari:displayName | Body | URL-Slug und Anzeigename der Kommune |
mandari:locationList | Body | URL der Orte-Liste |
mandari:summary | Paper | Automatisch erstellte Zusammenfassung, falls vorhanden |
mandari:originalAccessUrl | File | Original-Datei-URL beim Quellserver |
mandari:sha256, mandari:pageCount | File | SHA-256-Hash und Seitenzahl |
mandari:locationName, mandari:locationAddress | Meeting | Ortsangabe als Text, falls kein Location-Objekt auflösbar |
mandari:vote | AgendaItem | Abstimmungsergebnis in Summen (method, result, yes, no, abstain), wenn die Quelle es liefert |
mandari:rollCall | AgendaItem | Einzelstimmen bei namentlicher Abstimmung, wenn die Quelle es liefert |
Die beiden Abstimmungsfelder stammen aus Kommunen, die mandari Session nutzen. Details unter OParl-API je Kommune.
Einschränkungen¶
- Nicht abgebildete Referenzen: Felder ohne Gegenstück im Datenmodell (
Meeting.participant,Paper.originatorPerson,originatorOrganization,underDirectionOf,relatedPaper,Organization.subOrganizationOf,AgendaItem.resolutionFile) werden ausgelassen, statt Original-URLs durchzureichen. - Lizenz: Die Lizenz der Quelldaten wird, soweit die Kommune sie angibt, am Body-Objekt (
license) durchgereicht. Eine übergreifende Lizenzangabe am System-Objekt ist noch offen. - Protokolle (
invitation,resultsProtocol,verbatimProtocol) undPaper.mainFilewerden über die Original-Rohdaten zugeordnet. Fehlt diese Zuordnung, erscheinen die Dateien unterauxiliaryFile.
Fair Use¶
- Bitte inkrementell synchronisieren (
modified_since) statt Vollabzüge zu wiederholen. - Setze einen aussagekräftigen
User-Agentmit Kontaktmöglichkeit. - Fragen zur Anbindung beantworten wir über mandari.de/kontakt/.
Betreibst du mandari selbst? Die Betriebsparameter der API stehen in der Konfigurationsreferenz.