Zum Inhalt

Datensatz hochladen per API

Dieser Guide beschreibt, wie eine CSV-Datei samt Metadaten über die ODI-API hochgeladen wird. Der Ablauf gliedert sich in drei Phasen: Schema-ID ermitteln → Metadaten-IDs ermitteln → Token abrufen → CSV hochladen. Datei und Metadaten werden dabei in einem einzigen HTTP-Multipart-Request übergeben.

Das Backend validiert die hochgeladene CSV-Datei automatisch gegen das angegebene Schema. Nur bei erfolgreicher Validierung wird der Datensatz angelegt.

Umgebungen

Alle Requests in diesem Guide sind für beide Umgebungen verfügbar. Wähle die passende Umgebung über die Tabs bei den Beispiel-Requests aus. Die Zugangsdaten (Client-ID, Client-Secret) sind umgebungsspezifisch und werden vom ODI-Team bereitgestellt.

Voraussetzungen

  • Client-ID und Client-Secret eines Keycloak Service Accounts liegen vor
  • CSV-Datei ist lokal vorhanden, Encoding und Delimiter sind bekannt
  • Schema ist bekannt und vorhanden (siehe Schema-ID ermitteln)
  • Metadaten sind bekannt (siehe Metadaten-IDs abrufen):
    • Katalog-Name (catalogue), z. B. opendata-sh
    • Lizenz-ID (licenseId), z. B. http://dcat-ap.de/def/licenses/cc-zero
    • Publisher-ID (publisherId), z. B. dataport
    • Kategorie-IDs (categoryIdsJsonString), z. B. ["envi"]
    • Raumbezug-ID (spatialReferenceId), z. B. http://dcat-ap.de/def/politicalGeocoding/stateKey/01

Vorgehen

1. Schema-ID ermitteln

Das Schema definiert die erwartete Struktur der hochzuladenden CSV-Datei. schemaId und schemaVersion sind Pflichtfelder im Upload-Request.

Das Schema-Repository ist unter schema.odi.schleswig-holstein.de/schemas erreichbar. Dort sind alle verfügbaren Schemas mit ihren IDs und Versionen aufgelistet. Die Schema-ID und die Schemaversion befindet sich auf der Schema-Detailseite.

Das Schema-Repository ist unter schema-repo-frontend.schema-repo.frostcluster.da23.dsecurecloud.de/schemas erreichbar. Dort sind alle verfügbaren Schemas mit ihren IDs und Versionen aufgelistet. Die Schema-ID und die Schemaversion befindet sich auf der Schema-Detailseite.

Vorgehen:

  1. Schema-Repository öffnen.
  2. Passendes Schema identifizieren.
  3. Schema-ID (z. B. 8569) und Version (z. B. 1.3.1) notieren.

Tip

Die verfügbaren Schemas können auch über die Schema-Repository API abgerufen werden.

2. Metadaten-IDs abrufen

Mehrere Pflichtfelder des Upload-Requests referenzieren Objekte, die im Metadaten-Service verwaltet werden. Eine Übersicht aller verfügbaren IDs und Endpunkte ist unter Metadaten-IDs abrufen zu finden.

Häufig verwendete Werte:

Feld Wert Kommentar
catalogue opendata-sh
licenseId http://dcat-ap.de/def/licenses/cc-zero Creative Commons CC Zero
licenseId http://dcat-ap.de/def/licenses/dl-zero-de/2.0 Datenlizenz Deutschland Zero 2.0
licenseId http://dcat-ap.de/def/licenses/officialWork Amtliches Werk
spatialReferenceId http://dcat-ap.de/def/politicalGeocoding/stateKey/01 Bundesland Schleswig-Holstein
categoryIdsJsonString ["envi"] Umwelt
categoryIdsJsonString ["tran"] Verkehr
categoryIdsJsonString ["gove"] Regierung und öffentlicher Sektor

3. Token abrufen

Eine Anleitung zum Abrufen eines gültigen JWT-Tokens findet sich unter Token abrufen.

4. CSV-Datei hochladen

Zum Hochladen einer CSV-Datei genügt ein einziger Request.

Beim Hochladen wird die CSV-Datei automatisch gegen das angegebene Schema validiert. Im Fehlerfall wird ein Validierungsbericht im frictionless-Report-Format zurückgeliefert – ein Beispiel der Fehlerreports befindet sich weiter unten.

Nach dem erfolgreichen Hochladen wird der Datensatz im Datenkatalog angelegt. Dabei werden folgende Dateien automatisch erzeugt:

Enthält das Schema Geo-Informationen, werden zusätzlich angelegt:

  • GeoJSON-Datei
  • GeoParquet-Datei
  • WFS-Service
  • WMS-Service
  • Kartenansicht (Link zum Masterportal)

Endpunkt

POST https://staging-backend.odi.schleswig-holstein.de/upload/csv

POST https://staging-backend.staging.frostcluster.da23.dsecurecloud.de/upload/csv

Felder

Feld Pflicht Typ Beschreibung Quelle
catalogue Pflicht string Katalog, in dem der Datensatz gespeichert wird Metadaten-Service /catalogs
title Pflicht JSON-Objekt Titel des Datensatzes (mehrsprachig) frei wählbar
description Pflicht JSON-Objekt Beschreibung (mehrsprachig) frei wählbar
schemaId Pflicht string ID des Schemas im Schema-Repository Schema-Repository
schemaVersion Pflicht string Version des Schemas Schema-Repository
delimiter Pflicht string Trennzeichen der CSV-Datei (z. B. ; oder ,) bekannt aus Datei
encoding Pflicht string Zeichenkodierung (z. B. UTF-8) bekannt aus Datei
quote Pflicht string Anführungszeichen-Zeichen (z. B. ") bekannt aus Datei
file Pflicht binary Die CSV-Datei lokal
startDate Pflicht string Startdatum des Datensatz-Zeitraums im ISO-8601-Format (z. B. 2024-01-01) bekannt
endDate Optional string Enddatum des Datensatz-Zeitraums im ISO-8601-Format (z. B. 2024-12-31)
licenseId Pflicht string ID der Lizenz Metadaten-Service /licenses
datasetId Pflicht string Frei wählbare ID des Datensatzes frei wählbar
publisherId Pflicht string ID des Herausgebers Metadaten-Service /publisher
categoryIdsJsonString Pflicht string (JSON) JSON-Array der Kategorie-IDs als String Metadaten-Service /categories
spatialReferenceId Pflicht string ID des Raumbezugs Metadaten-Service /places
draft Pflicht string "true" = Draft anlegen; "false" = veröffentlichen

Info

title und description sind mehrsprachige JSON-Objekte, z. B.: {"de": "Windkraftanlagen", "en": "Wind turbines"} Sie werden als JSON-String im multipart-Body übergeben.

Beispiel-Request

Der access_token wird im Abschnitt Token abrufen ermittelt.

curl --request POST \
  --url https://staging-backend.odi.schleswig-holstein.de/upload/csv \
  --header 'authorization: Bearer <access_token>' \
  --header 'content-type: multipart/form-data' \
  --form catalogue=opendata-sh \
  --form 'title={"de":"Windkraftanlagen"}' \
  --form 'description={"de":"Dieser Datensatz enthält Daten und Standorte von genehmigungspflichtigen Windkraftanlagen in Schleswig-Holstein."}' \
  --form schemaId=7269 \
  --form schemaVersion=1.2.2 \
  --form 'delimiter=;' \
  --form encoding=UTF-8 \
  --form 'quote="' \
  --form file=@/pfad/zur/windkraftanlagen.csv \
  --form startDate=2026-01-01 \
  --form licenseId=http://dcat-ap.de/def/licenses/cc-zero \
  --form datasetId=windkraftanlagen-2026 \
  --form publisherId=dataport \
  --form 'categoryIdsJsonString=["ener", "envi"]' \
  --form spatialReferenceId=http://dcat-ap.de/def/politicalGeocoding/stateKey/01 \
  --form draft=false
curl --request POST \
  --url https://staging-backend.staging.frostcluster.da23.dsecurecloud.de/upload/csv \
  --header 'authorization: Bearer <access_token>' \
  --header 'content-type: multipart/form-data' \
  --form catalogue=opendata-sh \
  --form 'title={"de":"Windkraftanlagen"}' \
  --form 'description={"de":"Dieser Datensatz enthält Daten und Standorte von genehmigungspflichtigen Windkraftanlagen in Schleswig-Holstein."}' \
  --form schemaId=7269 \
  --form schemaVersion=1.2.2 \
  --form 'delimiter=;' \
  --form encoding=UTF-8 \
  --form 'quote="' \
  --form file=@/pfad/zur/windkraftanlagen.csv \
  --form startDate=2026-01-01 \
  --form licenseId=http://dcat-ap.de/def/licenses/cc-zero \
  --form datasetId=windkraftanlagen-2026 \
  --form publisherId=dataport \
  --form 'categoryIdsJsonString=["ener", "envi"]' \
  --form spatialReferenceId=http://dcat-ap.de/def/politicalGeocoding/stateKey/01 \
  --form draft=false

Beispiel-Response (Erfolg)

{
  "datasetId": "windkraftanlagen-2026",
  "datasetUrl": "https://opendata.schleswig-holstein.de/dataset/windkraftanlagen-2026"
}

Beispiel-Response (Fehlerfall - Validierung fehlgeschlagen)

{
  "status": "error",
  "type": "invalid file",
  "message": "Validation of Csv-File was not valid!",
  "context": "CsvUploadService",
  "errors": [
    {
      "description": "The cell \"Harburg\" in row at position \"2\" and field \"KREIS\" at position \"1\" does not conform to a constraint: constraint \"enum\" is \"['Dithmarschen', 'Kiel', 'Lübeck', 'Nordfriesland', 'Hzgt.Lauenburg', 'Ostholstein', 'Plön', 'Pinneberg', 'Rendsburg-Eckernförde', 'Segeberg', 'Schleswig-Flensburg', 'Steinburg', 'Stormarn']\"",
      "index": 2,
      "field": "KREIS"
    }
  ]
}

Fehlercodes

HTTP-Status Bedeutung Mögliche Ursache / Lösung
400 Ungültige Anfrage Pflichtfeld fehlt, falsches Format oder CSV entspricht nicht dem Schema
401 Nicht authentifiziert Token fehlt oder abgelaufen → neuen Token abrufen
403 Keine Berechtigung Service Account hat nicht die erforderliche Rolle
413 Datei zu groß Datei übersteigt das serverseitige Größenlimit
500 Interner Serverfehler Kontakt zum ODI-Support aufnehmen

Beispiel-Response (403 – Keine Berechtigung): Tritt auf, wenn der Service Account keine Schreibrechte für den angegebenen Publisher hat oder keine Berechtigung für den Upload eingerichtet wurde.

{
  "status": "error",
  "type": "forbidden",
  "message": "CsvUploadService"
}

Als Draft speichern (optional)

Optional: Als Draft speichern

Durch Setzen von draft=true im Upload-Request wird der Datensatz zunächst als Entwurf angelegt und ist öffentlich noch nicht sichtbar. Dies empfiehlt sich, wenn der Datensatz vor der Veröffentlichung noch manuell geprüft werden soll. Wir die Freigabe sind entsprechende Rechte im Datenkatalog erforderlich.

Nächste Schritte