{"openapi":"3.1.0","info":{"title":"Smart Trees API","description":"API für Smarte Bäume","version":"1.0.0"},"servers":[{"url":"https://api.smart-trees.de","description":"Smart Trees"}],"paths":{"/login":{"post":{"tags":["Zugang und Authentifizierung"],"summary":"Login Endpoint","description":"Login-Endpunkt für Username/Passwort → JWT.\n(Wird auch von Swagger über OAuth2PasswordBearer genutzt.)","operationId":"login_endpoint_login_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_login_endpoint_login_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/trees":{"get":{"tags":["Bäume und Sensordaten"],"summary":"Liste aller Bäume mit wählbaren Feldern.","description":"Gibt alle aktiven Bäume zurück. Standardmäßig werden nur die wichtigsten Felder geliefert (`tree_id`, `name`, `dataname`, `nickname`, `tree_category`, `lat`, `lon`). Über den Parameter `fields` können beliebige Felder aus dem Datensatz gewählt werden. Mit `fields=*` werden alle verfügbaren Felder zurückgegeben. Über `search` kann ein JSON-Filter übergeben werden, z. B. `search={\\\"height_min_m\\\":\\\"> 23\\\",\\\"name\\\":\\\"like %Eiche%\\\"}`.","operationId":"handle_trees_v1_trees_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Optionale Filterung auf tree-IDs, z. B. tree-001. Mit '*' werden alle aktiven Bäume durchsucht.","title":"Tree Id"},"description":"Optionale Filterung auf tree-IDs, z. B. tree-001. Mit '*' werden alle aktiven Bäume durchsucht."},{"name":"fields","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Felder, die zurückgegeben werden sollen. Standardfelder: tree_id, name, dataname, nickname, tree_category, lat, lon. Mit fields=* werden alle Felder zurückgegeben.","title":"Fields"},"description":"Felder, die zurückgegeben werden sollen. Standardfelder: tree_id, name, dataname, nickname, tree_category, lat, lon. Mit fields=* werden alle Felder zurückgegeben."},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-Suchfilter als String. Beispiele: {\"height_min_m\":\"> 23\"}, {\"name\":\"like %Ahorn%\"}, {\"lat\":\">= 53\",\"tree_category\":\"Straßenbaum\"}.","title":"Search"},"description":"JSON-Suchfilter als String. Beispiele: {\"height_min_m\":\"> 23\"}, {\"name\":\"like %Ahorn%\"}, {\"lat\":\">= 53\",\"tree_category\":\"Straßenbaum\"}."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tree-data":{"get":{"tags":["Bäume und Sensordaten"],"summary":"Alle verfügbaren Daten von Bäumen.","description":"Listet alle verfügbaren Daten von smarten Bäumen inkl. Sensordaten auf. Optional kann nach spezifischen Baum-IDs und einem Zeitbereich gefiltert werden.","operationId":"handle_apps_v1_tree_data_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Optionale Filterung auf tree-IDs, z. B. tree-001","title":"Tree Id"},"description":"Optionale Filterung auf tree-IDs, z. B. tree-001"},{"name":"bucket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bucket-Intervall, z. B. '30 minutes', '6 hours'; None = Standard der Funktionen","title":"Bucket"},"description":"Bucket-Intervall, z. B. '30 minutes', '6 hours'; None = Standard der Funktionen"},{"name":"from_time","in":"query","required":false,"schema":{"type":"string","description":"Startzeit, z. B. 'now-1d' oder ISO-Zeitstempel","default":"now-1d","title":"From Time"},"description":"Startzeit, z. B. 'now-1d' oder ISO-Zeitstempel"},{"name":"to_time","in":"query","required":false,"schema":{"type":"string","description":"Endzeit, z. B. 'now' oder ISO-Zeitstempel","default":"now","title":"To Time"},"description":"Endzeit, z. B. 'now' oder ISO-Zeitstempel"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Maximale Anzahl Datensätze (Pagination)","default":10,"title":"Limit"},"description":"Maximale Anzahl Datensätze (Pagination)"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset für Pagination","default":0,"title":"Offset"},"description":"Offset für Pagination"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/trees/{tree_id}":{"post":{"tags":["Bäume und Sensordaten"],"summary":"Legt einen neuen Baum-Datensatz an","description":"Erstellt einen neuen Datensatz mit der angegebenen tree_id. Das Feld 'name' ist Pflicht. Weitere Felder sind optional.","operationId":"insert_tree_v1_trees__tree_id__post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"path","required":true,"schema":{"type":"string","title":"Tree Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"JSON-Objekt mit den Feldern des neuen Baums. 'name' ist Pflicht. Mehrsprachige Inhalte werden in den JSON-Feldern 'description' und 'attributes' erwartet.","examples":{"default":{"summary":"Beispiel für neuen Baum","value":{"name":"Platane am Rathaus","species":"Platanus × acerifolia","latitude":52.52,"longitude":13.405,"description":{"de":"Aktualisierte Beschreibung deutsch","en":"English description"},"attributes":{"de":{"bluete":"April-Mai"},"en":{"flowering":"April-May"}}}}},"title":"Payload"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Bäume und Sensordaten"],"summary":"Aktualisiert einzelne Felder eines Baums","description":"Nimmt ein JSON-Objekt im Request-Body entgegen und aktualisiert gezielt nur die enthaltenen Felder. tree_id ist nicht updatebar.","operationId":"update_tree_v1_trees__tree_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"path","required":true,"schema":{"type":"string","title":"Tree Id"}},{"name":"expected_updated_at","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Optionaler Versionswert (optimistic locking). Nur wenn DB.updated_at exakt passt, wird aktualisiert.","title":"Expected Updated At"},"description":"Optionaler Versionswert (optimistic locking). Nur wenn DB.updated_at exakt passt, wird aktualisiert."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"JSON-Objekt mit den zu aktualisierenden Feldern (ohne tree_id).","examples":{"default":{"summary":"Beispiel-Update","value":{"name":"Platane am Rathaus","nickname":"Rathausbaum","height_min_m":8.5,"height_max_m":11.2,"attributes":{"de":{"bluete":"April-Mai","besonderheit":"Sehr trockenheitsresistent"},"en":{"flowering":"April-May","special_feature":"Highly drought-resistant"}},"is_active":true}}},"title":"Payload"},"examples":{"partial_text_update":{"summary":"Nur Textfelder aktualisieren","value":{"name":"Neue Bezeichnung","nickname":"Kurzname","description":{"de":"Aktualisierte Beschreibung","en":"Updated description"}}},"json_fields_update":{"summary":"JSON-Felder gezielt aktualisieren","value":{"attributes":{"de":{"laub":"sommergruen","pflege":"mittel"},"en":{"foliage":"deciduous","maintenance":"medium"}},"place_props":{"district":"Mitte","surface":"Rasen"}}}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/trees/{tree_id}/images":{"post":{"tags":["Bäume und Sensordaten"],"summary":"Lädt ein Bild hoch und speichert es im JSON-Feld images","description":"Nimmt genau eine Multipart-Datei entgegen, speichert sie im Dateisystem und aktualisiert das Feld images in trees.trees als JSON-Liste.","operationId":"upload_tree_images_v1_trees__tree_id__images_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"path","required":true,"schema":{"type":"string","title":"Tree Id"}},{"name":"expected_updated_at","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Optionaler Versionswert (optimistic locking). Nur wenn DB.updated_at exakt passt, wird aktualisiert.","title":"Expected Updated At"},"description":"Optionaler Versionswert (optimistic locking). Nur wenn DB.updated_at exakt passt, wird aktualisiert."}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_tree_images_v1_trees__tree_id__images_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/trees/{tree_id}/images/{file_name}":{"delete":{"tags":["Bäume und Sensordaten"],"summary":"Löscht ein einzelnes Bild aus images","description":"Entfernt einen Bild-Eintrag anhand file_name aus dem JSON-Feld images und löscht die zugehörige Datei aus dem Upload-Ordner.","operationId":"delete_tree_image_v1_trees__tree_id__images__file_name__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"path","required":true,"schema":{"type":"string","title":"Tree Id"}},{"name":"file_name","in":"path","required":true,"schema":{"type":"string","title":"File Name"}},{"name":"expected_updated_at","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Optionaler Versionswert (optimistic locking). Nur wenn DB.updated_at exakt passt, wird aktualisiert.","title":"Expected Updated At"},"description":"Optionaler Versionswert (optimistic locking). Nur wenn DB.updated_at exakt passt, wird aktualisiert."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps":{"get":{"tags":["TTN Sensordaten und Geräte"],"summary":"Apps mit Sensor- und Wetterdaten","description":"Liefert pro Baum App-Informationen und aggregierte Sensor-/Wetterdaten.","operationId":"handle_apps_v1_apps_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Filter auf bestimmte tree-IDs","default":"tree-001","title":"Tree Id"},"description":"Filter auf bestimmte tree-IDs"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sensors":{"get":{"tags":["TTN Sensordaten und Geräte"],"summary":"Alle über LoraWAN gesendete TTN-Sensor-Daten pro Baum","description":"Direkter Zugriff auf fn_sensor_data, optional nach tree-IDs gefiltert.","operationId":"handle_sensors_v1_sensors_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Optionale Filterung auf tree-IDs, z. B. tree-001 tree-002 je nach item mehrfach möglich","title":"Tree Id"},"description":"Optionale Filterung auf tree-IDs, z. B. tree-001 tree-002 je nach item mehrfach möglich"},{"name":"bucket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bucket-Intervall, z. B. '30 minutes', '6 hours'; None = Standard","title":"Bucket"},"description":"Bucket-Intervall, z. B. '30 minutes', '6 hours'; None = Standard"},{"name":"from_time","in":"query","required":false,"schema":{"type":"string","description":"Startzeit, z. B. 'now-7d' oder ISO-Zeitstempel","default":"now-7d","title":"From Time"},"description":"Startzeit, z. B. 'now-7d' oder ISO-Zeitstempel"},{"name":"to_time","in":"query","required":false,"schema":{"type":"string","description":"Endzeit","default":"now","title":"To Time"},"description":"Endzeit"},{"name":"order","in":"query","required":false,"schema":{"enum":["asc","desc"],"type":"string","description":"Sortierreihenfolge von time_at: asc oder desc","default":"desc","title":"Order"},"description":"Sortierreihenfolge von time_at: asc oder desc"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/devices":{"get":{"tags":["TTN Sensordaten und Geräte"],"summary":"Devices (latest per device_id)","description":"Liefert pro device_id den jeweils neuesten Datensatz aus ttn_timeseries.ttn_devices.","operationId":"handle_devices_v1_devices_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Filter auf bestimmte tree-IDs (mehrfach möglich)","title":"Tree Id"},"description":"Filter auf bestimmte tree-IDs (mehrfach möglich)"},{"name":"device_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Filter auf bestimmte device-IDs (mehrfach möglich)","title":"Device Id"},"description":"Filter auf bestimmte device-IDs (mehrfach möglich)"},{"name":"app_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Filter auf bestimmte app-IDs (mehrfach möglich)","title":"App Id"},"description":"Filter auf bestimmte app-IDs (mehrfach möglich)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/devices/{device_id}":{"patch":{"tags":["TTN Sensordaten und Geräte"],"summary":"Aktualisiert Metadaten eines TTN-Geräts","description":"Aktualisiert gezielt einzelne Felder aller Datensätze für die angegebene device_id in ttn_timeseries.ttn_devices. Gesperrte Felder (device_id, dev_eui, join_eui, dev_addr) dürfen nicht verändert werden. Gibt den neuesten Datensatz (nach received_at) nach dem Update zurück.","operationId":"update_device_v1_devices__device_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"device_id","in":"path","required":true,"schema":{"type":"string","title":"Device Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"JSON-Objekt mit den zu aktualisierenden Feldern. Gesperrte Felder werden abgelehnt.","examples":{"default":{"summary":"Beispiel-Update","value":{"title":"Baum-Sensor Mitte","tree_id":"tree-042","brand_id":"dragino","model_id":"lht65","sensoren":{"temperature":true,"humidity":true},"description":{"info":"Standort Rathaus"},"latitude":52.52,"longitude":13.405}}},"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/gateways":{"get":{"tags":["TTN Sensordaten und Geräte"],"summary":"Gateways (latest per gateway_id)","description":"Liefert pro gateway_id den jeweils neuesten Datensatz; Filter über gateway_id ODER gateway_eui.","operationId":"handle_gateways_v1_gateways_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"gateway","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Werte können gateway_id oder gateway_eui sein (mehrfach möglich)","title":"Gateway"},"description":"Werte können gateway_id oder gateway_eui sein (mehrfach möglich)"},{"name":"from_time","in":"query","required":false,"schema":{"type":"string","description":"Startzeit, z. B. 'now-30d' oder ISO-Zeitstempel","default":"now-30d","title":"From Time"},"description":"Startzeit, z. B. 'now-30d' oder ISO-Zeitstempel"},{"name":"to_time","in":"query","required":false,"schema":{"type":"string","description":"Endzeit","default":"now","title":"To Time"},"description":"Endzeit"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/weather-data":{"get":{"tags":["Wetterstationen und DWD Quellen"],"summary":"Wetter-Stationen (LoraWAN TTN-Daten)","description":"Direkter Zugriff auf die Funktion fn_weather_data().","operationId":"handle_weather_v1_weather_data_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"weather_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Stations-IDs; mehrfach angeben möglich, z. B. weather_id=weather-001&weather_id=weather-002","default":["weather-001"],"title":"Weather Id"},"description":"Stations-IDs; mehrfach angeben möglich, z. B. weather_id=weather-001&weather_id=weather-002"},{"name":"bucket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Bucket-Intervall, z. B. '30 minutes', '6 hours'; None = Standard","title":"Bucket"},"description":"Bucket-Intervall, z. B. '30 minutes', '6 hours'; None = Standard"},{"name":"from_time","in":"query","required":false,"schema":{"type":"string","description":"Startzeit, z. B. 'now-7d' oder ISO-Zeitstempel","default":"now-7d","title":"From Time"},"description":"Startzeit, z. B. 'now-7d' oder ISO-Zeitstempel"},{"name":"to_time","in":"query","required":false,"schema":{"type":"string","description":"Endzeit z. B. 'now-7d' oder ISO-Zeitstempel","default":"now","title":"To Time"},"description":"Endzeit z. B. 'now-7d' oder ISO-Zeitstempel"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/weather-station":{"get":{"tags":["Wetterstationen und DWD Quellen"],"summary":"Liste aller Wetterstationen mit wählbaren Feldern.","description":"Gibt alle aktiven Wetterstationen zurück. Standardmäßig werden nur die wichtigsten Felder geliefert (`id`, `name`, `provider`, `station_type`, `lat`, `lon`, `is_active`). Über den Parameter `fields` können beliebige Felder aus dem Datensatz gewählt werden. Mit `fields=*` werden alle verfügbaren Felder zurückgegeben. Über `search` kann ein JSON-Filter übergeben werden, z. B. `search={\"provider\":\"DWD\",\"lat\":\">= 52\"}`.","operationId":"handle_weather_stations_v1_weather_station_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"station_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Optionale Filterung auf Stations-IDs. Mit '*' werden alle aktiven Stationen zurückgegeben.","title":"Station Id"},"description":"Optionale Filterung auf Stations-IDs. Mit '*' werden alle aktiven Stationen zurückgegeben."},{"name":"fields","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Felder, die zurückgegeben werden sollen. Standardfelder: id, name, provider, station_type, lat, lon, is_active. Mit fields=* werden alle Felder zurückgegeben.","title":"Fields"},"description":"Felder, die zurückgegeben werden sollen. Standardfelder: id, name, provider, station_type, lat, lon, is_active. Mit fields=* werden alle Felder zurückgegeben."},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"JSON-Suchfilter als String. Beispiele: {\"provider\":\"DWD\"}, {\"station_type\":\"ilike %meteo%\"}, {\"lat\":\">= 52\",\"is_active\":\"true\"}.","title":"Search"},"description":"JSON-Suchfilter als String. Beispiele: {\"provider\":\"DWD\"}, {\"station_type\":\"ilike %meteo%\"}, {\"lat\":\">= 52\",\"is_active\":\"true\"}."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Wetterstationen und DWD Quellen"],"summary":"Legt eine neue Wetterstation an","description":"Erstellt einen neuen Datensatz in weather.weatherstation. Das Feld 'name' ist Pflicht. Die ID wird automatisch vergeben und im Response zurückgegeben.","operationId":"insert_weather_station_v1_weather_station_post","security":[{"OAuth2PasswordBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"JSON-Objekt mit den Feldern der neuen Wetterstation. 'name' ist Pflicht.","examples":{"default":{"summary":"Beispiel für neue Wetterstation","value":{"name":"Station Mitte","provider":"DWD","provider_id":"10384","station_type":"synop","latitude":52.52,"longitude":13.405,"altitude_m":35.0,"is_active":true}}},"title":"Payload"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/weather-station/{station_id}":{"patch":{"tags":["Wetterstationen und DWD Quellen"],"summary":"Aktualisiert einzelne Felder einer Wetterstation","description":"Nimmt ein JSON-Objekt im Request-Body entgegen und aktualisiert gezielt nur die enthaltenen Felder in weather.weatherstation. id ist nicht updatebar.","operationId":"update_weather_station_v1_weather_station__station_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}},{"name":"expected_updated_at","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Optionaler Versionswert (optimistic locking). Nur wenn DB.updated_at exakt passt, wird aktualisiert.","title":"Expected Updated At"},"description":"Optionaler Versionswert (optimistic locking). Nur wenn DB.updated_at exakt passt, wird aktualisiert."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"JSON-Objekt mit den zu aktualisierenden Feldern (ohne id).","examples":{"default":{"summary":"Beispiel-Update","value":{"name":"DWD Kiel-Holtenau","provider":"DWD","station_type":"synop","place":"Kiel","latitude":54.3795,"longitude":10.1452,"is_active":true}}},"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Wetterstationen und DWD Quellen"],"summary":"Löscht eine Wetterstation","description":"Löscht den Datensatz mit der angegebenen station_id aus weather.weatherstation dauerhaft. Gibt 404 zurück, wenn die Station nicht gefunden wird.","operationId":"delete_weather_station_v1_weather_station__station_id__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"station_id","in":"path","required":true,"schema":{"type":"string","title":"Station Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dwd-current":{"get":{"tags":["Wetterstationen und DWD Quellen"],"summary":"DWD Wetter aktuell (Bright Sky)","description":"Zugriff auf https://api.brightsky.dev/current_weather","operationId":"handle_dwd_current_v1_dwd_current_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"lat","in":"query","required":false,"schema":{"type":"number","description":"Breitengrad (z. B. 54.3233 für Kiel)","default":"54.3233","title":"Lat"},"description":"Breitengrad (z. B. 54.3233 für Kiel)"},{"name":"lon","in":"query","required":false,"schema":{"type":"number","description":"Längengrad (z. B. 10.1228 für Kiel)","default":"10.1228","title":"Lon"},"description":"Längengrad (z. B. 10.1228 für Kiel)"},{"name":"at_time","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Zeitpunkt (ISO oder 'now-2h'); None = aktuell","title":"At Time"},"description":"Zeitpunkt (ISO oder 'now-2h'); None = aktuell"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dwd-hourly":{"get":{"tags":["Wetterstationen und DWD Quellen"],"summary":"DWD Wetter stündlich (Bright Sky)","description":"Zugriff auf https://api.brightsky.dev/weather","operationId":"handle_dwd_hourly_v1_dwd_hourly_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"lat","in":"query","required":false,"schema":{"type":"number","description":"Breitengrad (z. B. 54.3233 für Kiel)","default":54.3233,"title":"Lat"},"description":"Breitengrad (z. B. 54.3233 für Kiel)"},{"name":"lon","in":"query","required":false,"schema":{"type":"number","description":"Längengrad (z. B. 10.1228 für Kiel)","default":10.1228,"title":"Lon"},"description":"Längengrad (z. B. 10.1228 für Kiel)"},{"name":"from_time","in":"query","required":false,"schema":{"type":"string","description":"Startzeit (ISO oder 'now-24h') -> BrightSky 'date' (Pflicht)","default":"now-24h","title":"From Time"},"description":"Startzeit (ISO oder 'now-24h') -> BrightSky 'date' (Pflicht)"},{"name":"to_time","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Endzeit (ISO oder 'now') -> BrightSky 'last_date' (optional)","title":"To Time"},"description":"Endzeit (ISO oder 'now') -> BrightSky 'last_date' (optional)"},{"name":"tz","in":"query","required":false,"schema":{"type":"string","description":"Zeitzone (IANA), z. B. Europe/Berlin","default":"Europe/Berlin","title":"Tz"},"description":"Zeitzone (IANA), z. B. Europe/Berlin"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dwd-sources":{"get":{"tags":["Wetterstationen und DWD Quellen"],"summary":"DWD Quellen/Stationen (Bright Sky)","description":"Zugriff auf https://api.brightsky.dev/sources","operationId":"handle_dwd_sources_v1_dwd_sources_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"lat","in":"query","required":false,"schema":{"type":"number","description":"Breitengrad (z. B. 54.3233 für Kiel)","default":54.3233,"title":"Lat"},"description":"Breitengrad (z. B. 54.3233 für Kiel)"},{"name":"lon","in":"query","required":false,"schema":{"type":"number","description":"Längengrad (z. B. 10.1228 für Kiel)","default":10.1228,"title":"Lon"},"description":"Längengrad (z. B. 10.1228 für Kiel)"},{"name":"max_dist","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Optional: maximale Distanz in Metern (z. B. 30000 = 30 km)","default":30000,"title":"Max Dist"},"description":"Optional: maximale Distanz in Metern (z. B. 30000 = 30 km)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/dwd-synop":{"get":{"tags":["Wetterstationen und DWD Quellen"],"summary":"DWD SYNOP (Bright Sky)","description":"Zugriff auf https://api.brightsky.dev/synop (Station wird via /sources als SYNOP-Quelle ermittelt).","operationId":"handle_dwd_synop_v1_dwd_synop_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"lat","in":"query","required":false,"schema":{"type":"number","description":"Breitengrad (Stationssuche via /sources)","default":54.3233,"title":"Lat"},"description":"Breitengrad (Stationssuche via /sources)"},{"name":"lon","in":"query","required":false,"schema":{"type":"number","description":"Längengrad (Stationssuche via /sources)","default":10.1228,"title":"Lon"},"description":"Längengrad (Stationssuche via /sources)"},{"name":"max_dist","in":"query","required":false,"schema":{"type":"integer","description":"Maximale Stationsdistanz in Metern (nur /sources)","default":50000,"title":"Max Dist"},"description":"Maximale Stationsdistanz in Metern (nur /sources)"},{"name":"dwd_station_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"DWD Station-ID(s)","title":"Dwd Station Id"},"description":"DWD Station-ID(s)"},{"name":"wmo_station_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"WMO Station-ID(s)","title":"Wmo Station Id"},"description":"WMO Station-ID(s)"},{"name":"source_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"integer"}},{"type":"null"}],"description":"BrightSky source_id(s)","title":"Source Id"},"description":"BrightSky source_id(s)"},{"name":"from_time","in":"query","required":false,"schema":{"type":"string","description":"Startzeit (ISO oder 'now-2h')","default":"now-2h","title":"From Time"},"description":"Startzeit (ISO oder 'now-2h')"},{"name":"to_time","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Endzeit (ISO oder 'now'); None => automatisch 3h Fenster","title":"To Time"},"description":"Endzeit (ISO oder 'now'); None => automatisch 3h Fenster"},{"name":"tz","in":"query","required":false,"schema":{"type":"string","description":"Zeitzone (IANA)","default":"Europe/Berlin","title":"Tz"},"description":"Zeitzone (IANA)"},{"name":"units","in":"query","required":false,"schema":{"type":"string","description":"Einheiten: 'dwd' oder 'si'","default":"dwd","title":"Units"},"description":"Einheiten: 'dwd' oder 'si'"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tree/species":{"get":{"tags":["Baumkataster und Artenkatalog"],"summary":"Baumarten","description":"Abfrage der Tabelle tree_species (Filter: name_de/name_en/species_name_bot/species_id).","operationId":"handle_species_v1_tree_species_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"species_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"integer"}},{"type":"null"}],"title":"Species Id"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Suchbegriffe — durchsucht name_de, name_en, species_name_bot","title":"Search"},"description":"Suchbegriffe — durchsucht name_de, name_en, species_name_bot"},{"name":"search_description","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Suchbegriffe — durchsucht description","title":"Search Description"},"description":"Suchbegriffe — durchsucht description"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":1,"default":500,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","default":"name_de","title":"Order By"}},{"name":"order_dir","in":"query","required":false,"schema":{"type":"string","default":"asc","title":"Order Dir"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tree/species/{species_id}":{"post":{"tags":["Baumkataster und Artenkatalog"],"summary":"Legt eine neue Baumart an","description":"Erstellt einen neuen Datensatz in trees.tree_species mit der angegebenen species_id. Mindestens eines der Namensfelder muss gesetzt sein.","operationId":"insert_species_v1_tree_species__species_id__post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"species_id","in":"path","required":true,"schema":{"type":"integer","title":"Species Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"JSON-Objekt mit den Feldern der neuen Baumart.","examples":{"default":{"summary":"Beispiel für neue Baumart","value":{"species_name_bot":"Acer platanoides","name_de":"Spitzahorn","name_en":"Norway maple"}}},"title":"Payload"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Baumkataster und Artenkatalog"],"summary":"Aktualisiert einzelne Felder einer Baumart","description":"Nimmt ein JSON-Objekt im Request-Body entgegen und aktualisiert gezielt nur die enthaltenen Felder. species_id ist nicht updatebar.","operationId":"update_species_v1_tree_species__species_id__patch","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"species_id","in":"path","required":true,"schema":{"type":"integer","title":"Species Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"JSON-Objekt mit den zu aktualisierenden Feldern (ohne species_id).","examples":{"default":{"summary":"Beispiel-Update","value":{"name_de":"Spitz-Ahorn","description_de":"Beliebter Straßenbaum mit dichter Krone.","attributes_de":{"laub":"sommergruen"}}}},"title":"Payload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tree/species/{species_id}/images":{"post":{"tags":["Baumkataster und Artenkatalog"],"summary":"Lädt ein Bild für eine Baumart hoch","description":"Nimmt genau eine Multipart-Datei entgegen, speichert sie im Dateisystem und aktualisiert das Feld images in trees.tree_species als JSON-Liste.","operationId":"upload_species_images_v1_tree_species__species_id__images_post","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"species_id","in":"path","required":true,"schema":{"type":"integer","title":"Species Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_species_images_v1_tree_species__species_id__images_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tree/species/{species_id}/images/{file_name}":{"delete":{"tags":["Baumkataster und Artenkatalog"],"summary":"Löscht ein einzelnes Species-Bild aus images","description":"Entfernt einen Bild-Eintrag anhand file_name aus dem JSON-Feld images und löscht die zugehörigen Dateien aus dem Upload-Ordner.","operationId":"delete_species_image_v1_tree_species__species_id__images__file_name__delete","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"species_id","in":"path","required":true,"schema":{"type":"integer","title":"Species Id"}},{"name":"file_name","in":"path","required":true,"schema":{"type":"string","title":"File Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tree/inventory":{"get":{"tags":["Baumkataster und Artenkatalog"],"summary":"Alle Bäume in Kiel","description":"Abfrage der Tabelle tree_inventory (Filter: species_name/species_name_bot/tree_source_id/species_id).","operationId":"handle_inventory_v1_tree_inventory_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"tree_source_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"integer"}},{"type":"null"}],"description":"Filter nach tree_source_id (eindeutige Baum-Quell-IDs)","title":"Tree Source Id"},"description":"Filter nach tree_source_id (eindeutige Baum-Quell-IDs)"},{"name":"species_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"integer"}},{"type":"null"}],"description":"Filter nach species_id","title":"Species Id"},"description":"Filter nach species_id"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Suchbegriffe — durchsucht species_name, species_name_bot, species_i18n","title":"Search"},"description":"Suchbegriffe — durchsucht species_name, species_name_bot, species_i18n"},{"name":"search_description","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Suchbegriffe — durchsucht description (jsonb)","title":"Search Description"},"description":"Suchbegriffe — durchsucht description (jsonb)"},{"name":"min_species_count","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Minimum Anzahl der Bäume dieser Art (species_count >= Wert)","title":"Min Species Count"},"description":"Minimum Anzahl der Bäume dieser Art (species_count >= Wert)"},{"name":"max_species_count","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Maximum Anzahl der Bäume dieser Art (species_count <= Wert)","title":"Max Species Count"},"description":"Maximum Anzahl der Bäume dieser Art (species_count <= Wert)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":1,"default":500,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","default":"species_name","title":"Order By"}},{"name":"order_dir","in":"query","required":false,"schema":{"type":"string","default":"asc","title":"Order Dir"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/tree/inventory/spatial":{"get":{"tags":["Baumkataster und Artenkatalog"],"summary":"Räumlicher Filter für Bäume","description":"Abfrage per Bounding-Box auf geom mit optionalem species_id- und species_count-Filter.","operationId":"handle_inventory_spatial_v1_tree_inventory_spatial_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"min_lng","in":"query","required":false,"schema":{"type":"number","description":"Minimale Longitude der Bounding-Box (Default: Innenstadt Kiel)","default":10.115,"title":"Min Lng"},"description":"Minimale Longitude der Bounding-Box (Default: Innenstadt Kiel)"},{"name":"min_lat","in":"query","required":false,"schema":{"type":"number","description":"Minimale Latitude der Bounding-Box (Default: Innenstadt Kiel)","default":54.3,"title":"Min Lat"},"description":"Minimale Latitude der Bounding-Box (Default: Innenstadt Kiel)"},{"name":"max_lng","in":"query","required":false,"schema":{"type":"number","description":"Maximale Longitude der Bounding-Box (Default: Innenstadt Kiel)","default":10.155,"title":"Max Lng"},"description":"Maximale Longitude der Bounding-Box (Default: Innenstadt Kiel)"},{"name":"max_lat","in":"query","required":false,"schema":{"type":"number","description":"Maximale Latitude der Bounding-Box (Default: Innenstadt Kiel)","default":54.335,"title":"Max Lat"},"description":"Maximale Latitude der Bounding-Box (Default: Innenstadt Kiel)"},{"name":"species_id","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"integer"}},{"type":"null"}],"description":"Filter nach species_id","title":"Species Id"},"description":"Filter nach species_id"},{"name":"min_species_count","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Minimum Anzahl der Bäume dieser Art (species_count >= Wert)","title":"Min Species Count"},"description":"Minimum Anzahl der Bäume dieser Art (species_count >= Wert)"},{"name":"max_species_count","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Maximum Anzahl der Bäume dieser Art (species_count <= Wert)","title":"Max Species Count"},"description":"Maximum Anzahl der Bäume dieser Art (species_count <= Wert)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":1,"default":500,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/geo/districts":{"get":{"tags":["Geodaten zu Bezirken und Gemeinden"],"summary":"geoJSON der Kreisgrenzen  bzw. Kreisfreie Städtegrenzen nach ARS (Area Regionalization System)","description":"Liefert geoJSON der Kreisgrenzen nach ARS aus geo.district. Z.B. KielRegion: \"01002\",\"01057\",\"01058\"","operationId":"handle_districts_v1_geo_districts_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"ars","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Filter ARS-Codes nach Kreise, KielRegion entspricht: 01 Schleswig-Holstein, 01002 Kiel, 01057 Kreis Plön, 01058 Kreis Rendsburg-Eckernförde","default":["01002","01057","01058"],"title":"Ars"},"description":"Filter ARS-Codes nach Kreise, KielRegion entspricht: 01 Schleswig-Holstein, 01002 Kiel, 01057 Kreis Plön, 01058 Kreis Rendsburg-Eckernförde"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/geo/municipality":{"get":{"tags":["Geodaten zu Bezirken und Gemeinden"],"summary":"geoJSON der Gemeindegrenzen nach ARS (Area Regionalization System)","description":"Liefert geoJSON der Gemeindegrenzen und Kommunengrenzen nach ARS aus geo.district. Z.B.KielRegion: \"01002\",\"01057\",\"01058\"","operationId":"handle_municipality_v1_geo_municipality_get","security":[{"OAuth2PasswordBearer":[]}],"parameters":[{"name":"ars","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Filter auf bestimmte ARS-Codes: 01002 Kiel, 01057 Kreis Plön, 01058 Kreis Rendsburg-Eckernförde","default":["01002","01057","01058"],"title":"Ars"},"description":"Filter auf bestimmte ARS-Codes: 01002 Kiel, 01057 Kreis Plön, 01058 Kreis Rendsburg-Eckernförde"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"Body_login_endpoint_login_post":{"properties":{"grant_type":{"anyOf":[{"type":"string","pattern":"^password$"},{"type":"null"}],"title":"Grant Type"},"username":{"type":"string","title":"Username"},"password":{"type":"string","format":"password","title":"Password"},"scope":{"type":"string","title":"Scope","default":""},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"format":"password","title":"Client Secret"}},"type":"object","required":["username","password"],"title":"Body_login_endpoint_login_post"},"Body_upload_species_images_v1_tree_species__species_id__images_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"Eine Bilddatei (nur JPG/JPEG)."},"image_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Description","description":"Optionale Bildbeschreibung (z. B. Blatt, Frucht, Rinde)."}},"type":"object","required":["file"],"title":"Body_upload_species_images_v1_tree_species__species_id__images_post"},"Body_upload_tree_images_v1_trees__tree_id__images_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File","description":"Eine Bilddatei (nur JPG/JPEG)."},"image_description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Description","description":"Optionale Bildbeschreibung (z. B. Standort oder Motiv)."}},"type":"object","required":["file"],"title":"Body_upload_tree_images_v1_trees__tree_id__images_post"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"OAuth2PasswordBearer":{"type":"oauth2","flows":{"password":{"scopes":{},"tokenUrl":"login"}}}}},"tags":[{"name":"Zugang und Authentifizierung","description":"Authentifizierung und Token-Login."},{"name":"Bäume und Sensordaten","description":"Anlage, Aktualisierung und Abfrage von Baum-Stammdaten und Baumdetails."},{"name":"TTN Sensordaten und Geräte","description":"IoT-Daten aus dem TTN-Umfeld, inklusive Apps, Sensoren, Geräte und Gateways."},{"name":"Wetterstationen und DWD Quellen","description":"Aktuelle und historische Wetterinformationen sowie DWD-bezogene Datenquellen."},{"name":"Baumkataster und Artenkatalog","description":"Artenlisten, Inventardaten und zugehoerige Kataloginformationen."},{"name":"Geodaten zu Bezirken und Gemeinden","description":"GeoJSON- und Verwaltungsdaten zu Bezirken, Kreisen und Gemeinden."}]}